diff --git a/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift b/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift index dfd125a45..5255ee13f 100644 --- a/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift @@ -18,6 +18,7 @@ public struct MiniPlayer: View { @State var expanded = false @State var offset: CGFloat = 0 + @State var showVoiceSheet = false @Namespace private var animation let minExpandedHeight = UIScreen.main.bounds.height / 3 @@ -40,9 +41,9 @@ public struct MiniPlayer: View { action: { switch audioSession.state { case .playing: - audioSession.pause() + _ = audioSession.pause() case .paused: - audioSession.unpause() + _ = audioSession.unpause() default: break } @@ -102,6 +103,15 @@ public struct MiniPlayer: View { ) } + func viewArticle() { + if let item = audioSession.item { + NSNotification.pushReaderItem(objectID: item.objectID) + withAnimation(.easeIn(duration: 0.1)) { + expanded = false + } + } + } + // swiftlint:disable:next function_body_length func playerContent(_ item: LinkedItem) -> some View { GeometryReader { geom in @@ -153,7 +163,6 @@ public struct MiniPlayer: View { playPauseButtonItem .frame(width: 28, height: 28) - .matchedGeometryEffect(id: "PlayPauseButton", in: animation) stopButton .frame(width: 28, height: 28) @@ -170,6 +179,9 @@ public struct MiniPlayer: View { .foregroundColor(.appGrayTextContrast) .frame(maxWidth: .infinity, alignment: expanded ? .center : .leading) .matchedGeometryEffect(id: "ArticleTitle", in: animation) + .onTapGesture { + viewArticle() + } HStack { Spacer() @@ -235,6 +247,22 @@ public struct MiniPlayer: View { } HStack { + Menu { + Button("1.0×", action: {}) + Button("1.2×", action: {}) + Button("1.5×", action: {}) + Button("1.7×", action: {}) + Button("2.0×", action: {}) + } label: { + VStack { + Text("1.0×") + .font(.appCallout) + .lineLimit(0) + } + .contentShape(Rectangle()) + } + .padding(8) + Button( action: { self.audioSession.skipBackwards(seconds: 30) }, label: { @@ -246,7 +274,6 @@ public struct MiniPlayer: View { playPauseButtonItem .frame(width: 64, height: 64) .padding(32) - .matchedGeometryEffect(id: "PlayPauseButton", in: animation) Button( action: { self.audioSession.skipForward(seconds: 30) }, @@ -255,6 +282,19 @@ public struct MiniPlayer: View { .font(.appTitleTwo) } ) + + Menu { + Button("View Article", action: { viewArticle() }) + Button("Change Voice", action: { showVoiceSheet = true }) + } label: { + VStack { + Image(systemName: "ellipsis") + .font(.appCallout) + .frame(width: 20, height: 20) + } + .contentShape(Rectangle()) + } + .padding(8) } } } @@ -266,6 +306,8 @@ public struct MiniPlayer: View { ) .onTapGesture { withAnimation(.easeIn(duration: 0.08)) { expanded = true } + }.sheet(isPresented: $showVoiceSheet) { + changeVoiceView } } } @@ -287,6 +329,29 @@ public struct MiniPlayer: View { } } + var changeVoiceView: some View { + NavigationView { + VStack { + List { + ForEach(["Jenny", "Guy"], id: \.self) { name in + Button(action: {}) { + Text(name) + } + .buttonStyle(PlainButtonStyle()) + } + } + .padding(.top, 32) + .listStyle(.plain) + Spacer() + } + .navigationBarTitle("Change Voice") + .navigationBarTitleDisplayMode(.inline) + .navigationBarItems(leading: Button(action: { self.showVoiceSheet = false }) { + Image(systemName: "chevron.backward") + }) + } + } + func onDragChanged(value: DragGesture.Value) { if value.translation.height > 0, expanded { offset = value.translation.height diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift index b18c1c177..869351085 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift @@ -1,3 +1,4 @@ +import CoreData import Models import Services import SwiftUI @@ -112,6 +113,11 @@ import Views viewModel.pushFeedItem(item: linkedItem) viewModel.selectedLinkItem = linkedItem.objectID } + .onReceive(NSNotification.pushReaderItemPublisher) { notification in + if let objectID = notification.userInfo?["objectID"] as? NSManagedObjectID { + viewModel.handleReaderItemNotification(objectID: objectID) + } + } .onOpenURL { url in withoutAnimation { viewModel.linkRequest = nil diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift index 12e199f99..0366e03a7 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift @@ -34,6 +34,10 @@ import Views from: Date(timeIntervalSinceReferenceDate: 0) ) + func handleReaderItemNotification(objectID: NSManagedObjectID) { + selectedLinkItem = objectID + } + var cursor: String? // These are used to make sure we handle search result diff --git a/apple/OmnivoreKit/Sources/Services/NSNotification+Operation.swift b/apple/OmnivoreKit/Sources/Services/NSNotification+Operation.swift index fbcf2663c..a80e0e0c3 100644 --- a/apple/OmnivoreKit/Sources/Services/NSNotification+Operation.swift +++ b/apple/OmnivoreKit/Sources/Services/NSNotification+Operation.swift @@ -1,8 +1,10 @@ +import CoreData import Foundation import Models public extension NSNotification { static let PushJSONArticle = Notification.Name("PushJSONArticle") + static let PushReaderItem = Notification.Name("PushReaderItem") static let OperationSuccess = Notification.Name("OperationSuccess") static let OperationFailure = Notification.Name("OperationFailure") static let ReaderSettingsChanged = Notification.Name("ReaderSettingsChanged") @@ -11,6 +13,10 @@ public extension NSNotification { NotificationCenter.default.publisher(for: PushJSONArticle) } + static var pushReaderItemPublisher: NotificationCenter.Publisher { + NotificationCenter.default.publisher(for: PushReaderItem) + } + static var operationSuccessPublisher: NotificationCenter.Publisher { NotificationCenter.default.publisher(for: OperationSuccess) } @@ -38,6 +44,14 @@ public extension NSNotification { ) } + static func pushReaderItem(objectID: NSManagedObjectID) { + NotificationCenter.default.post( + name: NSNotification.PushReaderItem, + object: nil, + userInfo: ["objectID": objectID] + ) + } + static func operationSuccess(message: String) { NotificationCenter.default.post(name: NSNotification.OperationSuccess, object: nil, userInfo: ["message": message]) }