From d075b03a57a210f24db11d6a6fe535444deb2ccb Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Tue, 30 Aug 2022 15:00:37 -0700 Subject: [PATCH 1/6] open web reader when user taps on image in expanded audio player --- .../App/Views/AudioPlayer/MiniPlayer.swift | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift b/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift index dfd125a45..8043979bd 100644 --- a/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift @@ -16,6 +16,7 @@ public struct MiniPlayer: View { @Environment(\.colorScheme) private var colorScheme: ColorScheme private let presentingView: AnyView + @State private var webReaderItem: LinkedItem? @State var expanded = false @State var offset: CGFloat = 0 @Namespace private var animation @@ -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 } @@ -91,6 +92,7 @@ public struct MiniPlayer: View { Button( action: { withAnimation(.interactiveSpring()) { + self.webReaderItem = nil self.expanded = false } }, @@ -141,6 +143,11 @@ public struct MiniPlayer: View { .frame(width: dim, height: dim) .cornerRadius(6) } + .onTapGesture { + if expanded { + webReaderItem = item + } + } if !expanded { Text(item.unwrappedTitle) @@ -285,6 +292,12 @@ public struct MiniPlayer: View { } } } + .sheet(item: $webReaderItem) { + LinkItemDetailView( + linkedItemObjectID: $0.objectID, + isPDF: $0.isPDF + ) + } } func onDragChanged(value: DragGesture.Value) { @@ -297,6 +310,7 @@ public struct MiniPlayer: View { withAnimation(.interactiveSpring()) { if value.translation.height > minExpandedHeight { expanded = false + webReaderItem = nil } offset = 0 } From 41a5603593c20f01f452829a5003579e0d7a40c5 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Wed, 31 Aug 2022 06:56:18 -0700 Subject: [PATCH 2/6] use nsnotification to open web reader when selected from audio session --- .../Sources/App/Views/AudioPlayer/MiniPlayer.swift | 12 ++---------- .../Sources/App/Views/Home/HomeFeedViewIOS.swift | 6 ++++++ .../Sources/App/Views/Home/HomeFeedViewModel.swift | 4 ++++ .../Services/NSNotification+Operation.swift | 14 ++++++++++++++ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift b/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift index 8043979bd..52ed4f824 100644 --- a/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift @@ -16,7 +16,6 @@ public struct MiniPlayer: View { @Environment(\.colorScheme) private var colorScheme: ColorScheme private let presentingView: AnyView - @State private var webReaderItem: LinkedItem? @State var expanded = false @State var offset: CGFloat = 0 @Namespace private var animation @@ -92,7 +91,6 @@ public struct MiniPlayer: View { Button( action: { withAnimation(.interactiveSpring()) { - self.webReaderItem = nil self.expanded = false } }, @@ -145,7 +143,8 @@ public struct MiniPlayer: View { } .onTapGesture { if expanded { - webReaderItem = item + expanded = false + NSNotification.pushReaderItem(objectID: item.objectID) } } @@ -292,12 +291,6 @@ public struct MiniPlayer: View { } } } - .sheet(item: $webReaderItem) { - LinkItemDetailView( - linkedItemObjectID: $0.objectID, - isPDF: $0.isPDF - ) - } } func onDragChanged(value: DragGesture.Value) { @@ -310,7 +303,6 @@ public struct MiniPlayer: View { withAnimation(.interactiveSpring()) { if value.translation.height > minExpandedHeight { expanded = false - webReaderItem = nil } offset = 0 } diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewIOS.swift index 35eb891ab..a883cd790 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 755e3e979..75b34bca4 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift @@ -33,6 +33,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]) } From 4aca2c1c8f20f0c69e8956de1b7211b992057506 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Wed, 31 Aug 2022 06:57:21 -0700 Subject: [PATCH 3/6] require two taps on mini player to open reader view --- .../OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift b/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift index 52ed4f824..2b2526762 100644 --- a/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift @@ -141,7 +141,7 @@ public struct MiniPlayer: View { .frame(width: dim, height: dim) .cornerRadius(6) } - .onTapGesture { + .onTapGesture(count: 2) { if expanded { expanded = false NSNotification.pushReaderItem(objectID: item.objectID) From 1c9e73e2c7f94f06494f62b40d5bbb5aa14a06d0 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 2 Sep 2022 11:38:19 +0800 Subject: [PATCH 4/6] Move tap gesture to the article title, use an animation on transition --- .../Sources/App/Views/AudioPlayer/MiniPlayer.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift b/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift index 2b2526762..f168e0090 100644 --- a/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift @@ -141,12 +141,6 @@ public struct MiniPlayer: View { .frame(width: dim, height: dim) .cornerRadius(6) } - .onTapGesture(count: 2) { - if expanded { - expanded = false - NSNotification.pushReaderItem(objectID: item.objectID) - } - } if !expanded { Text(item.unwrappedTitle) @@ -176,6 +170,12 @@ public struct MiniPlayer: View { .foregroundColor(.appGrayTextContrast) .frame(maxWidth: .infinity, alignment: expanded ? .center : .leading) .matchedGeometryEffect(id: "ArticleTitle", in: animation) + .onTapGesture { + NSNotification.pushReaderItem(objectID: item.objectID) + withAnimation(.easeIn(duration: 0.1)) { + expanded = false + } + } HStack { Spacer() From 111029a3f664728542377d34d27507905745e958 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 2 Sep 2022 12:33:15 +0800 Subject: [PATCH 5/6] Add menus for view article, changing play rate Also removes the matched geom for animations on the play/pause button, this lets these buttons just get replaces and the animation looks a bit better. --- .../App/Views/AudioPlayer/MiniPlayer.swift | 45 ++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift b/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift index f168e0090..b227fad5e 100644 --- a/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift @@ -102,6 +102,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 +162,6 @@ public struct MiniPlayer: View { playPauseButtonItem .frame(width: 28, height: 28) - .matchedGeometryEffect(id: "PlayPauseButton", in: animation) stopButton .frame(width: 28, height: 28) @@ -171,10 +179,7 @@ public struct MiniPlayer: View { .frame(maxWidth: .infinity, alignment: expanded ? .center : .leading) .matchedGeometryEffect(id: "ArticleTitle", in: animation) .onTapGesture { - NSNotification.pushReaderItem(objectID: item.objectID) - withAnimation(.easeIn(duration: 0.1)) { - expanded = false - } + viewArticle() } HStack { @@ -241,6 +246,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: { @@ -252,7 +273,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) }, @@ -261,6 +281,19 @@ public struct MiniPlayer: View { .font(.appTitleTwo) } ) + + Menu { + Button("View Article", action: { viewArticle() }) + Button("Change Voice", action: {}) + } label: { + VStack { + Image(systemName: "ellipsis") + .font(.appCallout) + .frame(width: 20, height: 20) + } + .contentShape(Rectangle()) + } + .padding(8) } } } From 4b04d3bbc9530ac1a7d3ae8306cdcf432c4ce548 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 2 Sep 2022 13:16:36 +0800 Subject: [PATCH 6/6] Add a non-working sheet for changing voice --- .../App/Views/AudioPlayer/MiniPlayer.swift | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift b/apple/OmnivoreKit/Sources/App/Views/AudioPlayer/MiniPlayer.swift index b227fad5e..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 @@ -284,7 +285,7 @@ public struct MiniPlayer: View { Menu { Button("View Article", action: { viewArticle() }) - Button("Change Voice", action: {}) + Button("Change Voice", action: { showVoiceSheet = true }) } label: { VStack { Image(systemName: "ellipsis") @@ -305,6 +306,8 @@ public struct MiniPlayer: View { ) .onTapGesture { withAnimation(.easeIn(duration: 0.08)) { expanded = true } + }.sheet(isPresented: $showVoiceSheet) { + changeVoiceView } } } @@ -326,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