-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a72a667
commit a48ec3e
Showing
14 changed files
with
427 additions
and
22 deletions.
There are no files selected for viewing
15 changes: 15 additions & 0 deletions
15
DemoApp/Resources/Assets/Assets.xcassets/feedback-logo.imageset/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"images" : [ | ||
{ | ||
"filename" : "feedback-logo.pdf", | ||
"idiom" : "universal" | ||
} | ||
], | ||
"info" : { | ||
"author" : "xcode", | ||
"version" : 1 | ||
}, | ||
"properties" : { | ||
"preserves-vector-representation" : true | ||
} | ||
} |
Binary file added
BIN
+130 KB
DemoApp/Resources/Assets/Assets.xcassets/feedback-logo.imageset/feedback-logo.pdf
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
DemoApp/Sources/Components/Feedback/CallEndedViewModifier.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// | ||
// Copyright © 2024 Stream.io Inc. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import StreamVideo | ||
import SwiftUI | ||
|
||
private struct CallEndedViewModifier<Subview: View>: ViewModifier { | ||
|
||
private final class CallEndedViewModifierState: ObservableObject { | ||
@Published var call: Call? | ||
@Published var isPresentingSubview: Bool = false | ||
|
||
init() {} | ||
} | ||
|
||
private var notificationCenter: NotificationCenter | ||
private var subviewProvider: (Call?) -> Subview | ||
|
||
@StateObject private var state: CallEndedViewModifierState = .init() | ||
|
||
init( | ||
notificationCenter: NotificationCenter, | ||
@ViewBuilder subviewProvider: @escaping (Call?) -> Subview | ||
) { | ||
self.notificationCenter = notificationCenter | ||
self.subviewProvider = subviewProvider | ||
} | ||
|
||
func body(content: Content) -> some View { | ||
content | ||
.sheet(isPresented: $state.isPresentingSubview) { | ||
subviewProvider(state.call) | ||
} | ||
.onReceive( | ||
notificationCenter.publisher(for: .init(CallNotification.callEnded)) | ||
) { notification in | ||
guard let call = notification.object as? Call else { | ||
log.warning("Received CallNotification.callEnded but the object isn't a call.") | ||
state.isPresentingSubview = false | ||
return | ||
} | ||
|
||
guard state.call?.cId != call.cId else { | ||
return | ||
} | ||
|
||
log.debug("Received CallNotification.callEnded for call:\(call.cId)") | ||
state.call = call | ||
state.isPresentingSubview = true | ||
} | ||
} | ||
} | ||
|
||
extension View { | ||
|
||
@ViewBuilder | ||
public func onCallEnded( | ||
notificationCenter: NotificationCenter = .default, | ||
@ViewBuilder _ content: @escaping (Call?) -> some View | ||
) -> some View { | ||
modifier( | ||
CallEndedViewModifier( | ||
notificationCenter: notificationCenter, | ||
subviewProvider: content | ||
) | ||
) | ||
} | ||
} |
155 changes: 155 additions & 0 deletions
155
DemoApp/Sources/Components/Feedback/DemoFeedbackView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
// | ||
// Copyright © 2024 Stream.io Inc. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import StreamVideo | ||
import StreamVideoSwiftUI | ||
import SwiftUI | ||
|
||
@available(iOS 15.0, *) | ||
struct DemoFeedbackView: View { | ||
|
||
@Environment(\.dismiss) private var dismiss | ||
@Environment(\.openURL) private var openURL | ||
@Injected(\.appearance) private var appearance | ||
|
||
@State private var email: String = "" | ||
@State private var comment: String = "" | ||
@State private var rating: Int = 1 | ||
@State private var isSubmitting = false | ||
|
||
private var call: Call | ||
private var isSubmitEnabled: Bool { !email.isEmpty && !isSubmitting } | ||
|
||
init(_ call: Call) { | ||
self.call = call | ||
} | ||
|
||
var body: some View { | ||
ScrollView { | ||
VStack(spacing: 32) { | ||
Image(.feedbackLogo) | ||
|
||
VStack(spacing: 8) { | ||
Text("How is your call going?") | ||
.font(appearance.fonts.headline) | ||
.foregroundColor(appearance.colors.text) | ||
.lineLimit(1) | ||
|
||
Text("All feedback is celebrated!") | ||
.font(appearance.fonts.subheadline) | ||
.foregroundColor(.init(appearance.colors.textLowEmphasis)) | ||
.lineLimit(2) | ||
} | ||
.frame(maxWidth: .infinity, alignment: .center) | ||
.multilineTextAlignment(.center) | ||
|
||
VStack(spacing: 27) { | ||
VStack(spacing: 16) { | ||
TextField( | ||
"Email Address", | ||
text: $email, | ||
prompt: Text("Email Address *") | ||
) | ||
.textFieldStyle(DemoTextfieldStyle()) | ||
|
||
DemoTextEditor(text: $comment, placeholder: "Message") | ||
} | ||
|
||
HStack { | ||
Text("Rate Quality") | ||
.font(appearance.fonts.body) | ||
.foregroundColor(.init(appearance.colors.textLowEmphasis)) | ||
.frame(maxWidth: .infinity, alignment: .leading) | ||
|
||
DemoStarRatingView(rating: $rating) | ||
} | ||
} | ||
|
||
HStack { | ||
Button { | ||
resignFirstResponder() | ||
openURL(.init(string: "https://getstream.io/video/#contact")!) | ||
} label: { | ||
Text("Contact Us") | ||
} | ||
.frame(maxWidth: .infinity) | ||
.foregroundColor(appearance.colors.text) | ||
.padding(.vertical, 4) | ||
.clipShape(Capsule()) | ||
.overlay(Capsule().stroke(Color(appearance.colors.textLowEmphasis), lineWidth: 1)) | ||
|
||
Button { | ||
resignFirstResponder() | ||
isSubmitting = true | ||
Task { | ||
do { | ||
try await call.collectUserFeedback( | ||
rating: rating, | ||
reason: """ | ||
\(email) | ||
\(comment) | ||
""" | ||
) | ||
Task { @MainActor in | ||
dismiss() | ||
} | ||
isSubmitting = false | ||
} catch { | ||
log.error(error) | ||
dismiss() | ||
isSubmitting = false | ||
} | ||
} | ||
} label: { | ||
if isSubmitting { | ||
ProgressView() | ||
} else { | ||
Text("Submit") | ||
} | ||
} | ||
.frame(maxWidth: .infinity) | ||
.foregroundColor(appearance.colors.text) | ||
.padding(.vertical, 4) | ||
.background(isSubmitEnabled ? appearance.colors.accentBlue : appearance.colors.lightGray) | ||
.disabled(!isSubmitEnabled) | ||
.clipShape(Capsule()) | ||
} | ||
|
||
Spacer() | ||
} | ||
.padding(.horizontal) | ||
} | ||
.withModalNavigationBar(title: "", closeAction: { dismiss() }) | ||
} | ||
} | ||
|
||
struct DemoStarRatingView: View { | ||
var rating: Binding<Int> | ||
|
||
private var range: ClosedRange<Int> | ||
|
||
init( | ||
rating: Binding<Int>, | ||
minRating: Int = 1, | ||
maxRating: Int = 5 | ||
) { | ||
self.rating = rating | ||
range = minRating...maxRating | ||
} | ||
|
||
var body: some View { | ||
HStack { | ||
ForEach(range, id: \.self) { index in | ||
Image(systemName: index <= rating.wrappedValue ? "star.fill" : "star") | ||
.resizable() | ||
.frame(width: 30, height: 30) | ||
.foregroundColor(.yellow) | ||
.onTapGesture { | ||
rating.wrappedValue = index | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.