Skip to content

Commit

Permalink
fix: skip actions now properly skip
Browse files Browse the repository at this point in the history
  • Loading branch information
ErrorErrorError committed Dec 19, 2023
1 parent 2e634df commit 609dc12
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 83 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "search.badge.questionmark.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
137 changes: 70 additions & 67 deletions Sources/Features/Search/SearchFeature+View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,84 +25,87 @@ extension SearchFeature.View: View {
showStatusBarBackground = offset.y <= -2.9 // FIXME: SafeAreaInset affects the offset of this
} content: {
WithViewStore(store, observe: \.searchResult) { viewStore in
LoadableView(loadable: viewStore.state) { searchResult in
if searchResult.items.isEmpty {
WithViewStore(store, observe: \.query) { queryStore in
StatusView(
title: "No Results",
description: "for \"\(queryStore.state)\"",
assetImage: "search"
)
}
} else {
LazyVGrid(
columns: [.init(.adaptive(minimum: 120), alignment: .top)],
alignment: .leading
) {
ForEach(searchResult.items) { item in
VStack(alignment: .leading) {
FillAspectImage(url: item.posterImage)
.aspectRatio(2 / 3, contentMode: .fit)
.cornerRadius(12)
ZStack {
LoadableView(loadable: viewStore.state) { searchResult in
if searchResult.items.isEmpty {
WithViewStore(store, observe: \.query) { queryStore in
StatusView(
title: "No Results",
description: "for \"\(queryStore.state)\"",
assetImage: "search.badge.questionmark"
)
}
} else {
LazyVGrid(
columns: [.init(.adaptive(minimum: 120), alignment: .top)],
alignment: .leading
) {
ForEach(searchResult.items) { item in
VStack(alignment: .leading) {
FillAspectImage(url: item.posterImage)
.aspectRatio(2 / 3, contentMode: .fit)
.cornerRadius(12)

Text(item.title ?? "Title Unavailable")
.font(.footnote)
}
.contentShape(Rectangle())
.onTapGesture {
viewStore.send(.didTapPlaylist(item))
Text(item.title ?? "Title Unavailable")
.font(.footnote)
}
.contentShape(Rectangle())
.onTapGesture {
viewStore.send(.didTapPlaylist(item))
}
}
}
}
.padding(.horizontal)
.padding(.horizontal)

if let nextPage = searchResult.nextPage {
LoadableView(loadable: nextPage) { nextPageId in
LazyView {
Spacer()
.frame(height: 1)
.onAppear {
store.send(.view(.didShowNextPageIndicator(nextPageId)))
}
}
} failedView: { _ in
Button {
// TODO: Allow refetch when paging failed
} label: {
Image(systemName: "arrow.clockwise")
.font(.body)
.padding(4)
if let nextPage = searchResult.nextPage {
LoadableView(loadable: nextPage) { nextPageId in
LazyView {
Spacer()
.frame(height: 1)
.onAppear {
store.send(.view(.didShowNextPageIndicator(nextPageId)))
}
}
} failedView: { _ in
Button {
// TODO: Allow refetch when paging failed

Check warning on line 71 in Sources/Features/Search/SearchFeature+View.swift

View workflow job for this annotation

GitHub Actions / run-swiftformat

Indent code in accordance with the scope level. (indent)
} label: {
Image(systemName: "arrow.clockwise")
.font(.body)
.padding(4)
}
.contentShape(Rectangle())
} waitingView: {
ProgressView()
.padding(.vertical, 8)
}
.contentShape(Rectangle())
} waitingView: {
ProgressView()
.padding(.vertical, 8)
}
}
}
} failedView: { _ in
// TODO: Make error more explicit
StatusView(
title: .init(localizable: "Search Failed"),
description: .init(localizable: "Failed to retrieve items."),
image: .asset("search.trianglebadge.exclamationmark"),
foregroundColor: .red
)
} loadingView: {
WithViewStore(store, observe: \.query) { queryStore in
} failedView: { _ in
// TODO: Make error more explicit

Check warning on line 85 in Sources/Features/Search/SearchFeature+View.swift

View workflow job for this annotation

GitHub Actions / run-swiftformat

Indent code in accordance with the scope level. (indent)
StatusView(
title: .init(localizable: "Search Failed"),
description: .init(localizable: "Failed to retrieve items."),
image: .asset("search.trianglebadge.exclamationmark"),
foregroundColor: .red
)
} loadingView: {
WithViewStore(store, observe: \.query) { queryStore in
StatusView(
title: "Searching...",
description: "for \"\(queryStore.state)\"",
assetImage: "search.badge.clock"
)
}
} pendingView: {
StatusView(
title: "Searching...",
description: "for \"\(queryStore.state)\"",
assetImage: "search.badge.clock"
title: .init(localizable: "Search Empty"),
description: "Type to start searching.",
systemImage: "magnifyingglass"
)
}
} pendingView: {
StatusView(
title: .init(localizable: "Search Empty"),
description: "Type to start searching.",
systemImage: "magnifyingglass"
)
}
.animation(.easeInOut(duration: 0.2), value: viewStore.state.didFinish)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Features/VideoPlayer/Components/ProgressBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ struct ProgressBar: View {
let percentageX = value.location.x / proxy.size.width

dragged = dragged ?? .init(progress: progress, initial: percentageX)
viewState.send(.didSkipTo(time: dragged?.progress ?? .zero))
viewState.send(.didSeekTo(time: dragged?.progress ?? .zero))
dragged?(percentageX)
}
.onEnded { _ in
Expand Down
15 changes: 11 additions & 4 deletions Sources/Features/VideoPlayer/VideoPlayerFeature+Reducer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,21 @@ extension VideoPlayerFeature: Reducer {
case let .view(.didTapLink(linkId)):
return state.clearForChangedLinkIfNeeded(linkId)

case let .view(.didSkipTo(time)):
case let .view(.didSeekTo(time)):
return .merge(
state.delayDismissOverlayIfNeeded(),
.run { _ in
await playerClient.seek(time)
}
.run { await playerClient.seek(time) }
)

case let .view(.didSkipTo(time)):
if let totalDuration = state.player.playback?.totalDuration, totalDuration != .zero {
let progress = time / totalDuration
return .merge(
state.delayDismissOverlayIfNeeded(),
.run { await playerClient.seek(progress) }

Check warning on line 85 in Sources/Features/VideoPlayer/VideoPlayerFeature+Reducer.swift

View workflow job for this annotation

GitHub Actions / run-swiftformat

Replace consecutive spaces with a single space. (consecutiveSpaces)
)
}

case .view(.didTogglePlayback):
let isPlaying = state.player.playback?.state == .playing
let playRate = state.playerSettings.speed
Expand Down
17 changes: 6 additions & 11 deletions Sources/Features/VideoPlayer/VideoPlayerFeature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ public struct VideoPlayerFeature: Feature {
case didSkipBackwards
case didChangePlaybackRate(Double)
case didSkipTo(time: CGFloat)
case didSeekTo(time: CGFloat)
case didTapGroupOption(MediaSelectionOption?, for: MediaSelectionGroup)
case didTapSource(Playlist.EpisodeSource.ID)
case didTapServer(Playlist.EpisodeServer.ID)
Expand Down Expand Up @@ -167,13 +168,9 @@ public struct VideoPlayerFeature: Feature {
@Dependency(\.playerClient.player) var player

@SwiftUI.State var enablePiP = false

@SwiftUI.State var gravity = AVLayerVideoGravity.resizeAspect

@SwiftUI.State var pipSupported = true

@SwiftUI.State var pipPossible = true

@SwiftUI.State var pipStatus = PiPStatus.restoreUI

@MainActor
Expand All @@ -183,9 +180,7 @@ public struct VideoPlayerFeature: Feature {
}

@Dependency(\.dismiss) var dismiss

@Dependency(\.moduleClient) var moduleClient

@Dependency(\.playerClient) var playerClient

public init() {}
Expand Down Expand Up @@ -322,15 +317,14 @@ extension VideoPlayerFeature.State {

extension VideoPlayerFeature.View {
struct SkipActionViewState: Equatable {
@CasePathable
@dynamicMemberLookup
enum Action: Hashable, CustomStringConvertible {
case times(Playlist.EpisodeServer.SkipTime)
case next(Double, Playlist.Group.ID, Playlist.Group.Variant.ID, PagingID, Playlist.Item.ID)

var isEnding: Bool {
if case let .times(time) = self {
return time.type == .ending
}
return false
self.times?.type == .ending
}

var action: VideoPlayerFeature.Action {
Expand Down Expand Up @@ -397,7 +391,8 @@ extension VideoPlayerFeature.View {

if let currentEpisode = state.selectedItem.value,
let episodes = state.selectedPage.value?.items.value,
let index = episodes.firstIndex(where: { $0.id == currentEpisode.id }), (index + 1) < episodes.endIndex {
let index = episodes.firstIndex(where: \.id == currentEpisode.id),
(index + 1) < episodes.endIndex {
let nextEpisode = episodes[index + 1]

if let ending = actions.first(where: \.isEnding), case let .times(type) = ending {
Expand Down

0 comments on commit 609dc12

Please sign in to comment.