Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide calls in the demo app #182

Merged
merged 11 commits into from
Oct 13, 2023
20 changes: 20 additions & 0 deletions DemoApp/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,26 @@
<string>streamvideo</string>
</array>
</dict>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>$(GOOGLE_CLIENT_ID)</string>
<key>CFBundleURLSchemes</key>
<array>
<string>$(GOOGLE_CLIENT_ID)</string>
</array>
</dict>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>$(REVERSED_GOOGLE_CLIENT_ID)</string>
<key>CFBundleURLSchemes</key>
<array>
<string>$(REVERSED_GOOGLE_CLIENT_ID)</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>1</string>
Expand Down
14 changes: 14 additions & 0 deletions DemoApp/Resources/GoogleSignIn.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>$(GOOGLE_CLIENT_ID)</string>
<key>REVERSED_CLIENT_ID</key>
<string>$(REVERSED_GOOGLE_CLIENT_ID)</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>io.getstream.iOS.VideoDemoApp</string>
</dict>
</plist>
2 changes: 2 additions & 0 deletions DemoApp/Sources/Components/AppEnvironment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ extension AppEnvironment {

enum Variable: String {
case JWTExpiration = "JWT_EXPIRATION"
case googleClientId = "GOOGLE_CLIENT_ID"
case googleReversedClientId = "REVERSED_GOOGLE_CLIENT_ID"
}

static func contains(_ argument: Argument) -> Bool {
Expand Down
17 changes: 14 additions & 3 deletions DemoApp/Sources/Components/Router.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import StreamVideo
import StreamVideoSwiftUI
import SwiftUI
import WebRTC
import GoogleSignIn

@MainActor
final class Router: ObservableObject {
Expand Down Expand Up @@ -76,9 +77,13 @@ final class Router: ObservableObject {
if AppEnvironment.configuration == .test, AppEnvironment.contains(.mockJWT) {
return
} else if let userCredentials = AppState.shared.unsecureRepository.loadCurrentUser() {
appState.currentUser = userCredentials.userInfo
appState.userState = .loggedIn
handleLoggedInUserCredentials(userCredentials, deeplinkInfo: .empty)
if userCredentials.userInfo.id.contains("@getstream") {
GIDSignIn.sharedInstance.restorePreviousSignIn { [weak self] _,_ in
self?.setupUser(with: userCredentials)
ipavlidakis marked this conversation as resolved.
Show resolved Hide resolved
}
} else {
setupUser(with: userCredentials)
}
} else {
try await handleGuestUser(deeplinkInfo: .empty)
}
Expand All @@ -104,6 +109,12 @@ final class Router: ObservableObject {
}
}
}

private func setupUser(with userCredentials: UserCredentials) {
appState.currentUser = userCredentials.userInfo
appState.userState = .loggedIn
handleLoggedInUserCredentials(userCredentials, deeplinkInfo: .empty)
}

private func handleGuestUser(
deeplinkInfo: DeeplinkInfo
Expand Down
27 changes: 27 additions & 0 deletions DemoApp/Sources/Components/Storage/UnsecureRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ protocol UserRepository {

func removeCurrentUser()

func userFavorites() -> [String]

func addToFavorites(userId: String)

func removeFromFavorites(userId: String)
}

protocol VoIPTokenHandler {
Expand Down Expand Up @@ -48,6 +53,7 @@ final class UnsecureRepository: UserRepository, VoIPTokenHandler, PushTokenHandl
case pushToken = "stream.video.push.token"
case lastRunConfiguration = "stream.video.last.run.configuration"
case lastRunBaseURL = "stream.video.last.run.baseURL"
case userFavorites = "stream.video.favorites"
}

private let defaults: UserDefaults
Expand Down Expand Up @@ -112,6 +118,7 @@ final class UnsecureRepository: UserRepository, VoIPTokenHandler, PushTokenHandl
defaults.set(nil, forKey: Key.token.rawValue)
defaults.set(nil, forKey: Key.voIPPushToken.rawValue)
defaults.set(nil, forKey: Key.pushToken.rawValue)
defaults.set(nil, forKey: Key.userFavorites.rawValue)
}

func save(configuration: AppEnvironment.Configuration) {
Expand All @@ -135,4 +142,24 @@ final class UnsecureRepository: UserRepository, VoIPTokenHandler, PushTokenHandl
}
return .init(rawValue: lastBaseURLString)
}

func userFavorites() -> [String] {
get(for: .userFavorites) ?? [String]()
}

func addToFavorites(userId: String) {
var favorites = userFavorites()
if !favorites.contains(userId) {
favorites.append(userId)
set(favorites, for: .userFavorites)
}
}

func removeFromFavorites(userId: String) {
var favorites = userFavorites()
favorites.removeAll { id in
id == userId
}
set(favorites, for: .userFavorites)
}
}
9 changes: 7 additions & 2 deletions DemoApp/Sources/DemoApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import SwiftUI
import StreamVideo
import StreamVideoSwiftUI
import WebRTC
import GoogleSignIn

@main
struct DemoApp: App {
Expand All @@ -32,15 +33,19 @@ struct DemoApp: App {
WindowGroup {
ZStack {
if appState.userState == .loggedIn {
DemoCallContainerView(callId: appState.deeplinkInfo.callId)
NavigationView {
DemoCallContainerView(callId: appState.deeplinkInfo.callId)
.navigationBarHidden(true)
}
.navigationViewStyle(.stack)
} else {
if AppEnvironment.configuration.isRelease {
LoadingView()
} else {
NavigationView {
LoginView() { router.handleLoggedInUserCredentials($0, deeplinkInfo: .empty) }
}
.navigationViewStyle(StackNavigationViewStyle())
.navigationViewStyle(.stack)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct SimpleCallingView: View {

var body: some View {
VStack {
DemoCallingTopView()
DemoCallingTopView(callViewModel: viewModel)

Spacer()

Expand Down Expand Up @@ -112,9 +112,13 @@ struct SimpleCallingView: View {
}
}
.onAppear {
CallService.shared.registerForIncomingCalls()
self.text = callId
joinCallIfNeeded(with: callId)
}
.onReceive(appState.$activeCall) { call in
viewModel.setActiveCall(call)
}
}

private func joinCallIfNeeded(with callId: String, callType: String = .default) {
Expand Down
10 changes: 10 additions & 0 deletions DemoApp/Sources/Views/CallView/DemoCallingTopView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import Foundation
import SwiftUI
import StreamVideo
import StreamVideoSwiftUI
import GoogleSignIn

struct DemoCallingTopView: View {

@Injected(\.streamVideo) var streamVideo

@ObservedObject var callViewModel: CallViewModel
@State var logoutAlertShown = false

var body: some View {
Expand Down Expand Up @@ -40,6 +42,14 @@ struct DemoCallingTopView: View {
}

Spacer()

if GIDSignIn.sharedInstance.currentUser != nil {
martinmitrevski marked this conversation as resolved.
Show resolved Hide resolved
NavigationLink {
DemoCallsView(callViewModel: callViewModel)
} label: {
Text("Calls")
}
}
}
.alert(isPresented: $logoutAlertShown) {
Alert(
Expand Down
109 changes: 109 additions & 0 deletions DemoApp/Sources/Views/CallView/DemoCallsView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
//
// Copyright © 2023 Stream.io Inc. All rights reserved.
//

import NukeUI
import StreamVideo
import StreamVideoSwiftUI
import SwiftUI

struct DemoCallsView: View {

@Environment(\.presentationMode) var presentationMode

@StateObject var viewModel: DemoCallsViewModel

init(callViewModel: CallViewModel) {
_viewModel = StateObject(wrappedValue: DemoCallsViewModel(callViewModel: callViewModel))
}

var body: some View {
ScrollView {
LazyVStack(alignment: .leading) {
if viewModel.favorites.count > 0 {
Text("Favorites")
.font(.headline)
ForEach(viewModel.favorites) { employee in
StreamEmployeeView(viewModel: viewModel, employee: employee)
}
}

Text("Stream employees")
.font(.headline)
ForEach(viewModel.streamEmployees) { employee in
StreamEmployeeView(viewModel: viewModel, employee: employee)
}
}
.padding()
}
.onAppear {
viewModel.loadEmployees()
}
.toolbar(content: {
ToolbarItem(placement: .principal) {
Text("Stream calls")
.bold()
}

ToolbarItem(placement: .topBarTrailing) {
if viewModel.groupCallParticipants.count > 0 {
Button(action: {
viewModel.startCall(with: viewModel.groupCallParticipants)
viewModel.groupCallParticipants = []
presentationMode.wrappedValue.dismiss()
}, label: {
Text("Call the group")
})
} else {
Button(action: {
viewModel.groupCall.toggle()
}, label: {
Text("Group Call")
})
}
}
})
}
}

struct StreamEmployeeView: View {

@Environment(\.presentationMode) var presentationMode

@ObservedObject var viewModel: DemoCallsViewModel
var employee: StreamEmployee

var body: some View {
HStack {
LazyImage(imageURL: employee.imageURL)
.frame(width: 60, height: 60)
.clipShape(Circle())
Text(employee.name)
Spacer()

if viewModel.groupCall {
Button(action: {
viewModel.groupSelectionTapped(for: employee)
}, label: {
Image(
systemName: viewModel.groupCallParticipants.contains(employee) ? "checkmark.circle.fill" : "circle"
)
})
}

Button(action: {
viewModel.startCall(with: [employee])
presentationMode.wrappedValue.dismiss()
}, label: {
Image(systemName: "phone.fill")
})

Button(action: {
viewModel.favoriteTapped(for: employee)
}, label: {
Image(systemName: employee.isFavorite ? "star.fill" : "star")
})
}
.id("\(employee.id)-\(employee.isFavorite)")
}
}
Loading
Loading