compiling but haven't tested anything
This commit is contained in:
@@ -10,12 +10,15 @@ import FirebaseFirestoreSwift
|
|||||||
import FirebaseFirestore
|
import FirebaseFirestore
|
||||||
|
|
||||||
enum ConvoState: String, Codable {
|
enum ConvoState: String, Codable {
|
||||||
case connected
|
case initialized
|
||||||
case disconnected
|
case active
|
||||||
|
case complete
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Convo: Identifiable, Codable {
|
struct Convo: Identifiable, Codable {
|
||||||
|
// channel name for agora's purposes
|
||||||
@DocumentID var id: String? = UUID().uuidString
|
@DocumentID var id: String? = UUID().uuidString
|
||||||
|
|
||||||
var leaderUserId: String
|
var leaderUserId: String
|
||||||
var receiverUserId: String
|
var receiverUserId: String
|
||||||
|
|
||||||
@@ -23,10 +26,10 @@ struct Convo: Identifiable, Codable {
|
|||||||
|
|
||||||
var state: ConvoState
|
var state: ConvoState
|
||||||
|
|
||||||
var Users: [String]?
|
var users: [String] = []
|
||||||
|
|
||||||
@ServerTimestamp var startedTimestamp: Date?
|
@ServerTimestamp var startedTimestamp: Date?
|
||||||
@ServerTimestamp var endedTimestamp: Date?
|
var endedTimestamp: Date?
|
||||||
}
|
}
|
||||||
|
|
||||||
//struct DetailConvo: Convo {
|
//struct DetailConvo: Convo {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ enum UserStatus: String, Codable {
|
|||||||
case online
|
case online
|
||||||
case offline
|
case offline
|
||||||
case background
|
case background
|
||||||
|
case inConvo
|
||||||
}
|
}
|
||||||
|
|
||||||
struct User: Identifiable, Codable {
|
struct User: Identifiable, Codable {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class FirestoreService {
|
|||||||
case users = "users"
|
case users = "users"
|
||||||
case messages = "messages"
|
case messages = "messages"
|
||||||
case userFriends = "user_friends" // associating a user to
|
case userFriends = "user_friends" // associating a user to
|
||||||
|
case convos = "convos"
|
||||||
}
|
}
|
||||||
|
|
||||||
private var db = Firestore.firestore()
|
private var db = Firestore.firestore()
|
||||||
@@ -183,3 +184,32 @@ extension FirestoreService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// convos
|
||||||
|
extension FirestoreService {
|
||||||
|
func createConvo(convo: Convo, completion: @escaping((_ state: ServiceState) -> ())) {
|
||||||
|
do {
|
||||||
|
let _ = try db.collection(Collection.convos.rawValue).addDocument(from: convo)
|
||||||
|
|
||||||
|
completion(ServiceState.success("convo created"))
|
||||||
|
} catch {
|
||||||
|
print("error in creating convo \(error.localizedDescription)")
|
||||||
|
completion(ServiceState.error(ServiceError(description: error.localizedDescription)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateConvo(convo: Convo, completion: @escaping((_ state: ServiceState) -> ())) {
|
||||||
|
do {
|
||||||
|
if convo.id != nil {
|
||||||
|
let _ = try db.collection(Collection.convos.rawValue).document(convo.id!).setData(from: convo)
|
||||||
|
completion(ServiceState.success("Updated convo in firestore service"))
|
||||||
|
} else {
|
||||||
|
completion(ServiceState.error(ServiceError(description: "No convo id given to firestore service")))
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
print("error in updating convo \(error.localizedDescription)")
|
||||||
|
completion(ServiceState.error(ServiceError(description: error.localizedDescription)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ import FirebaseAuth
|
|||||||
import Firebase
|
import Firebase
|
||||||
|
|
||||||
class AgoraService {
|
class AgoraService {
|
||||||
func getAgoraUserToken(channelName: String) {
|
lazy var functions = Functions.functions()
|
||||||
|
|
||||||
|
func getAgoraUserTokenServer(channelName: String) {
|
||||||
let currentUser = Auth.auth().currentUser
|
let currentUser = Auth.auth().currentUser
|
||||||
currentUser?.getIDTokenForcingRefresh(true) { idToken, error in
|
currentUser?.getIDTokenForcingRefresh(true) { idToken, error in
|
||||||
if let error = error {
|
if let error = error {
|
||||||
@@ -45,4 +47,29 @@ class AgoraService {
|
|||||||
dataTask.resume()
|
dataTask.resume()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAgoraTokenCF(channelName: String, completion: @escaping((_ token: String?) -> ())) {
|
||||||
|
// validate channelName
|
||||||
|
|
||||||
|
|
||||||
|
functions.httpsCallable("agoraToken").call(["channelName": channelName]) {[weak self] result, error in
|
||||||
|
if let error = error as NSError? {
|
||||||
|
if error.domain == FunctionsErrorDomain {
|
||||||
|
let code = FunctionsErrorCode(rawValue: error.code)
|
||||||
|
let message = error.localizedDescription
|
||||||
|
let details = error.userInfo[FunctionsErrorDetailsKey]
|
||||||
|
|
||||||
|
print(message)
|
||||||
|
}
|
||||||
|
completion(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let data = result?.data as? [String: Any], let token = data["token"] as? String {
|
||||||
|
print("got agora token from cloud function")
|
||||||
|
completion(token)
|
||||||
|
} else {
|
||||||
|
completion(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ struct ConvoFooterView: View {
|
|||||||
Button {
|
Button {
|
||||||
print("disconnecting user now ")
|
print("disconnecting user now ")
|
||||||
|
|
||||||
|
self.convoVM.selectedConvoId = nil
|
||||||
self.convoVM.leaveConvo()
|
self.convoVM.leaveConvo()
|
||||||
|
|
||||||
// show success or failure toast
|
// show success or failure toast
|
||||||
|
|||||||
@@ -7,18 +7,16 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import AgoraRtcKit
|
import AgoraRtcKit
|
||||||
|
import Firebase
|
||||||
|
|
||||||
class ConvoViewModel: NSObject, ObservableObject {
|
class ConvoViewModel: NSObject, ObservableObject {
|
||||||
private var testingUIMode = true
|
|
||||||
|
|
||||||
@Published var selectedConvoId:String? = nil
|
@Published var selectedConvoId:String? = nil
|
||||||
@Published var connectionState: AgoraConnectionStateType? = nil
|
@Published var connectionState: AgoraConnectionStateType? = nil
|
||||||
|
|
||||||
let firestoreService = FirestoreService()
|
let firestoreService = FirestoreService()
|
||||||
|
let agoraService = AgoraService()
|
||||||
|
|
||||||
let testConvos: [Convo] = [
|
@Published var relevantConvos: [Convo] = []
|
||||||
Convo(id: "testChannel", leaderUserId: "VWVPKCrNmMeZlkEeZxuJ0Wsgq0C3", receiverUserId: "zd6PpD3TmnQUDoy6noS9aZpuPWr1", agoraToken: "006c8dfd65deb5c4741bd564085627139d0IAAqbHMFow9oQ8BN0WCkFrkGBTqFTjlbr6tJmFH5judwbnZXrgMAAAAAEADQ943gC8nOYQEAAQALyc5h", state: .connected)
|
|
||||||
]
|
|
||||||
|
|
||||||
var agoraKit: AgoraRtcEngineKit?
|
var agoraKit: AgoraRtcEngineKit?
|
||||||
|
|
||||||
@@ -26,15 +24,68 @@ class ConvoViewModel: NSObject, ObservableObject {
|
|||||||
return self.selectedConvoId != nil
|
return self.selectedConvoId != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
override init() {
|
var convosListener: ListenerRegistration? = nil
|
||||||
super.init()
|
|
||||||
|
private var db = Firestore.firestore()
|
||||||
|
|
||||||
|
private var allConvos: [Convo] = []
|
||||||
|
|
||||||
|
private var relevancyAcceptance = 0.6
|
||||||
|
|
||||||
|
func activateDataListener(activeFriendsIds: [String]) {
|
||||||
// initiate convo listener to get all relevant convos
|
// initiate convo listener to get all relevant convos
|
||||||
// any convo that is active
|
// any convo that is active
|
||||||
// and any of my active friends are in that convo
|
// and any of my active friends or I am in that convo
|
||||||
// if am being "called" catch that and join the convo/channel
|
// if am being "called" catch that and join the convo/channel
|
||||||
|
var scopeUserIds: [String] = []
|
||||||
|
scopeUserIds += activeFriendsIds
|
||||||
|
|
||||||
// only show convos in which I know a majority of the people inside
|
// I want to get back convos that involve me
|
||||||
|
if let userId = AuthSessionStore.getCurrentUserId() {
|
||||||
|
scopeUserIds.append(userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
print("the scope of users to search for convos is \(scopeUserIds)")
|
||||||
|
|
||||||
|
self.convosListener = db.collection("convos").whereField("state", isEqualTo: ConvoState.active.rawValue).whereField("users", arrayContainsAny: scopeUserIds)
|
||||||
|
.addSnapshotListener { querySnapshot, error in
|
||||||
|
print("convos listener")
|
||||||
|
guard let documents = querySnapshot?.documents else {
|
||||||
|
print("Error fetching convos \(error!)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.allConvos.removeAll()
|
||||||
|
self.relevantConvos.removeAll()
|
||||||
|
|
||||||
|
for document in querySnapshot!.documents {
|
||||||
|
let convo:Convo? = try? document.data(as: Convo.self)
|
||||||
|
|
||||||
|
if convo == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
self.allConvos.append(convo!)
|
||||||
|
}
|
||||||
|
|
||||||
|
// only show convos in which I know a majority of the people inside
|
||||||
|
// use relevancyAcceptance value
|
||||||
|
self.relevantConvos = self.allConvos.filter{convo in
|
||||||
|
var relevancyCount = 0
|
||||||
|
// go through all users in this convo
|
||||||
|
for user in convo.users {
|
||||||
|
if scopeUserIds.contains(user) {
|
||||||
|
relevancyCount += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if Double(relevancyCount / convo.users.count) > self.relevancyAcceptance {
|
||||||
|
print("this convo counts as relevant!!!")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// initiate agora engine
|
// initiate agora engine
|
||||||
self.initializeAgoraEngine()
|
self.initializeAgoraEngine()
|
||||||
@@ -42,6 +93,8 @@ class ConvoViewModel: NSObject, ObservableObject {
|
|||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
// deinit the firestore listener
|
// deinit the firestore listener
|
||||||
|
self.convosListener?.remove()
|
||||||
|
|
||||||
// deinit the agora engine
|
// deinit the agora engine
|
||||||
print("deiniting and cleaning up convo view model/agora services")
|
print("deiniting and cleaning up convo view model/agora services")
|
||||||
|
|
||||||
@@ -54,35 +107,55 @@ class ConvoViewModel: NSObject, ObservableObject {
|
|||||||
@param: friendId: the second person in the convo...the receiver
|
@param: friendId: the second person in the convo...the receiver
|
||||||
**/
|
**/
|
||||||
func startConvo(friendId: String) {
|
func startConvo(friendId: String) {
|
||||||
if testingUIMode {
|
// TODO: need to make sure the other user is online or already did in view
|
||||||
print("testing mode...not doing anything")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
// making sure this user is authenticated
|
||||||
if let userId = AuthSessionStore.getCurrentUserId() {
|
if let userId = AuthSessionStore.getCurrentUserId() {
|
||||||
|
let channelName = UUID().uuidString
|
||||||
|
|
||||||
|
// get a new agora token from cloud function
|
||||||
|
self.agoraService.getAgoraTokenCF(channelName: channelName) {[weak self] token in
|
||||||
|
if token == nil {
|
||||||
|
print("error in getting token")
|
||||||
|
}
|
||||||
|
|
||||||
|
let users = [userId] // just one user now, and that's me...but no one has joined yet
|
||||||
|
// only considered joined when I have officially joined the agora channel
|
||||||
|
|
||||||
|
var convo = Convo(id: channelName, leaderUserId: userId, receiverUserId: friendId, agoraToken: token!, state: .initialized, users: [], startedTimestamp: nil, endedTimestamp: nil)
|
||||||
|
|
||||||
|
// create a convo/channel in db to notify the other user with proper attributes
|
||||||
|
self?.firestoreService.createConvo(convo: convo) {[weak self] res in
|
||||||
|
switch res {
|
||||||
|
case .success:
|
||||||
|
// join the convo myself
|
||||||
|
self?.joinConvo(channelName: channelName, agoraToken: token!)
|
||||||
|
case .error(let error):
|
||||||
|
print(error)
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func joinConvo(channelName: String, agoraToken: String) {
|
||||||
|
// ensure that this user leaves all other channels
|
||||||
|
if self.isInCall() {
|
||||||
|
self.leaveConvo()
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to make sure the other user is online
|
self.agoraKit?.setDefaultAudioRouteToSpeakerphone(true)
|
||||||
|
// finally join channel
|
||||||
// get a new agora token from cloud function
|
self.agoraKit?.joinChannel(byToken: agoraToken, channelId: channelName, info: nil, uid: 0, joinSuccess: nil)
|
||||||
|
|
||||||
// create a convo/channel in db to notify the other user with proper attributes
|
|
||||||
|
|
||||||
// join the convo myself
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Allow user to join an active convo
|
Allow user to join an active convo
|
||||||
*/
|
*/
|
||||||
func joinConvo() {
|
func joinConvo() {
|
||||||
if testingUIMode {
|
|
||||||
print("testing mode...not doing anything")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the convo is active and includes 2 people in it currently...shouldn't be shown if not anyway
|
// ensure the convo is active and includes 2 people in it currently...shouldn't be shown if not anyway
|
||||||
|
|
||||||
// ensure that this user leaves all other channels
|
// ensure that this user leaves all other channels
|
||||||
@@ -90,9 +163,7 @@ class ConvoViewModel: NSObject, ObservableObject {
|
|||||||
self.leaveConvo()
|
self.leaveConvo()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.agoraKit?.setDefaultAudioRouteToSpeakerphone(true)
|
let convo = self.relevantConvos.first {convo in
|
||||||
|
|
||||||
let convo = self.testConvos.first {convo in
|
|
||||||
convo.id == self.selectedConvoId
|
convo.id == self.selectedConvoId
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,25 +173,19 @@ class ConvoViewModel: NSObject, ObservableObject {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: if the convo has more than 10 people, stop user from joining...that's too expensive...
|
// TODO: if the convo has more than 10 people, stop user from joining...that's too expensive...
|
||||||
|
|
||||||
|
|
||||||
let convoAgoraToken:String = convo!.agoraToken
|
let convoAgoraToken:String = convo!.agoraToken
|
||||||
let channelName:String = convo!.id!
|
let channelName:String = convo!.id!
|
||||||
|
|
||||||
|
|
||||||
|
self.agoraKit?.setDefaultAudioRouteToSpeakerphone(true)
|
||||||
// finally join channel
|
// finally join channel
|
||||||
self.agoraKit?.joinChannel(byToken: convoAgoraToken, channelId: channelName, info: nil, uid: 0, joinSuccess: nil)
|
self.agoraKit?.joinChannel(byToken: convoAgoraToken, channelId: channelName, info: nil, uid: 0, joinSuccess: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// anyone can leave at any time
|
// anyone can leave at any time
|
||||||
func leaveConvo() {
|
func leaveConvo() {
|
||||||
if testingUIMode {
|
|
||||||
print("testing mode...not doing anything")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
agoraKit?.leaveChannel(nil)
|
agoraKit?.leaveChannel(nil)
|
||||||
|
|
||||||
// if I am the second person in the room, then end the convo
|
// if I am the second person in the room, then end the convo
|
||||||
@@ -143,19 +208,87 @@ extension ConvoViewModel: AgoraRtcEngineDelegate {
|
|||||||
|
|
||||||
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) {
|
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) {
|
||||||
print("I did join channel")
|
print("I did join channel")
|
||||||
|
|
||||||
// set my user status to in convo
|
|
||||||
|
|
||||||
// leave channel if it's just me
|
// TODO: play a sound when I join the channel
|
||||||
|
|
||||||
|
// TODO: leave channel if it's just me
|
||||||
|
|
||||||
|
|
||||||
|
var convo = self.relevantConvos.first {convo in
|
||||||
|
convo.id == self.selectedConvoId
|
||||||
|
}
|
||||||
|
if convo == nil {
|
||||||
|
print("no such convo found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let userId = AuthSessionStore.getCurrentUserId() {
|
||||||
|
// set my user status to in convo/red
|
||||||
|
self.firestoreService.updateUserStatus(userId: userId, userStatus: .inConvo) {[weak self] res in
|
||||||
|
print(res)
|
||||||
|
|
||||||
|
switch res {
|
||||||
|
case .success:
|
||||||
|
// update convo in database users array to let them know I am there
|
||||||
|
|
||||||
|
convo?.users.append(userId)
|
||||||
|
convo?.state = .active
|
||||||
|
|
||||||
|
self?.firestoreService.updateConvo(convo: convo!) {[weak self] res in
|
||||||
|
print(res)
|
||||||
|
}
|
||||||
|
case .error(let error):
|
||||||
|
print(error)
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func rtcEngine(_ engine: AgoraRtcEngineKit, didLeaveChannelWith stats: AgoraChannelStats) {
|
func rtcEngine(_ engine: AgoraRtcEngineKit, didLeaveChannelWith stats: AgoraChannelStats) {
|
||||||
// leave channel if I am the only one in it
|
|
||||||
|
|
||||||
print("I did leave channel")
|
print("I did leave channel")
|
||||||
|
|
||||||
|
var convo = self.relevantConvos.first {convo in
|
||||||
|
convo.id == self.selectedConvoId
|
||||||
|
}
|
||||||
|
if convo == nil {
|
||||||
|
print("no such convo found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
self.selectedConvoId = nil
|
if let userId = AuthSessionStore.getCurrentUserId() {
|
||||||
|
// set my user status to online
|
||||||
|
self.firestoreService.updateUserStatus(userId: userId, userStatus: .online) {[weak self] res in
|
||||||
|
print(res)
|
||||||
|
|
||||||
|
switch res {
|
||||||
|
case .success:
|
||||||
|
//update convo in database to show that I left...if I am the last person, also close out the channel
|
||||||
|
|
||||||
|
let updatedUsers: [String] = convo!.users.filter{ arrUserId in
|
||||||
|
return arrUserId != userId
|
||||||
|
}
|
||||||
|
|
||||||
|
convo!.users = updatedUsers
|
||||||
|
|
||||||
|
// if I am the last one in the convo, then end the convo
|
||||||
|
if convo!.users.count == 1 && convo!.users[0] == userId {
|
||||||
|
convo!.state = .complete
|
||||||
|
convo!.endedTimestamp = Date()
|
||||||
|
}
|
||||||
|
|
||||||
|
self?.firestoreService.updateConvo(convo: convo!) {[weak self] res in
|
||||||
|
self?.selectedConvoId = nil
|
||||||
|
print("left convo officially in our db as well")
|
||||||
|
}
|
||||||
|
case .error(let error):
|
||||||
|
print(error)
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
|
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ struct ConvosView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView([.horizontal]) {
|
ScrollView([.horizontal]) {
|
||||||
HStack {
|
HStack {
|
||||||
ForEach(0..<self.vm.testConvos.count, id: \.self) {index in
|
ForEach(0..<self.vm.relevantConvos.count, id: \.self) {index in
|
||||||
let currConvo = self.vm.testConvos[index]
|
let currConvo = self.vm.relevantConvos[index]
|
||||||
ZStack(alignment: .topTrailing) {
|
ZStack(alignment: .topTrailing) {
|
||||||
Circle()
|
Circle()
|
||||||
.foregroundColor(self.vm.selectedConvoId == currConvo.id ? Color.green : NirvanaColor.dimTeal.opacity(0.2))
|
.foregroundColor(self.vm.selectedConvoId == currConvo.id ? Color.green : NirvanaColor.dimTeal.opacity(0.2))
|
||||||
@@ -51,7 +51,7 @@ struct ConvosView: View {
|
|||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
// if not in a call already
|
// if not in a call already
|
||||||
if !self.vm.isInCall() {
|
if !self.vm.isInCall() {
|
||||||
self.vm.selectedConvoId = self.vm.testConvos[index].id!
|
self.vm.selectedConvoId = self.vm.relevantConvos[index].id!
|
||||||
self.vm.joinConvo()
|
self.vm.joinConvo()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ struct ProfilePicturesOverlappedView: View {
|
|||||||
.frame(width: indvAvatarWidth)
|
.frame(width: indvAvatarWidth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ struct CircleGridView: View {
|
|||||||
// MARK: data entry point
|
// MARK: data entry point
|
||||||
let activeFriends = self.authSessionStore.friendsArr
|
let activeFriends = self.authSessionStore.friendsArr
|
||||||
let inboxUsers = self.authSessionStore.inboxUsersArr
|
let inboxUsers = self.authSessionStore.inboxUsersArr
|
||||||
let convos = self.convoVM.testConvos
|
let convos = self.convoVM.relevantConvos
|
||||||
|
|
||||||
ScrollViewReader {scrollReaderValue in
|
ScrollViewReader {scrollReaderValue in
|
||||||
ScrollView([.horizontal, .vertical], showsIndicators: false) {
|
ScrollView([.horizontal, .vertical], showsIndicators: false) {
|
||||||
@@ -73,7 +73,7 @@ struct CircleGridView: View {
|
|||||||
) {
|
) {
|
||||||
// live convos
|
// live convos
|
||||||
ForEach(0..<convos.count, id: \.self) {value in
|
ForEach(0..<convos.count, id: \.self) {value in
|
||||||
let currConvo = self.convoVM.testConvos[value]
|
let currConvo = self.convoVM.relevantConvos[value]
|
||||||
|
|
||||||
GeometryReader {gridProxy in
|
GeometryReader {gridProxy in
|
||||||
let scale = getScale(proxy: gridProxy, itemNumber: value, userId: nil, convoId: currConvo.id)
|
let scale = getScale(proxy: gridProxy, itemNumber: value, userId: nil, convoId: currConvo.id)
|
||||||
@@ -115,7 +115,7 @@ struct CircleGridView: View {
|
|||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
// if not in a call already
|
// if not in a call already
|
||||||
if !self.convoVM.isInCall() {
|
if !self.convoVM.isInCall() {
|
||||||
self.convoVM.selectedConvoId = self.convoVM.testConvos[value].id!
|
self.convoVM.selectedConvoId = self.convoVM.relevantConvos[value].id!
|
||||||
self.convoVM.joinConvo()
|
self.convoVM.joinConvo()
|
||||||
|
|
||||||
// if had selected an individual, don't want them in here anymore
|
// if had selected an individual, don't want them in here anymore
|
||||||
@@ -123,9 +123,6 @@ struct CircleGridView: View {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.convoVM.selectedConvoId = nil
|
|
||||||
self.convoVM.leaveConvo()
|
|
||||||
}
|
}
|
||||||
.animation(
|
.animation(
|
||||||
Animation.easeInOut(duration: self.convoVM.selectedConvoId == currConvo.id ? 2 : 4
|
Animation.easeInOut(duration: self.convoVM.selectedConvoId == currConvo.id ? 2 : 4
|
||||||
@@ -335,6 +332,9 @@ struct CircleGridView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.animateLiveConvos = true
|
self.animateLiveConvos = true
|
||||||
|
|
||||||
|
// TODO: called once, have to refresh page to make it update on new friends added and such
|
||||||
|
self.convoVM.activateDataListener(activeFriendsIds: self.authSessionStore.friendsArr)
|
||||||
}
|
}
|
||||||
} // scrollview reader
|
} // scrollview reader
|
||||||
}
|
}
|
||||||
@@ -462,9 +462,13 @@ extension CircleGridView {
|
|||||||
private func handleTap(gridItemIndex: Int, friendId: String) {
|
private func handleTap(gridItemIndex: Int, friendId: String) {
|
||||||
print("tap gesture activated")
|
print("tap gesture activated")
|
||||||
|
|
||||||
// if friend is online, start call immediately
|
// if friend and I are online, start call immediately
|
||||||
|
if self.authSessionStore.relevantUsersDict[friendId]?.userStatus == .online
|
||||||
|
&& self.authSessionStore.user?.userStatus == .online {
|
||||||
|
self.convoVM.startConvo(friendId: friendId)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// clearing the player to make room for this friend's convo or to deselect this user
|
// clearing the player to make room for this friend's convo or to deselect this user
|
||||||
self.queuePlayer.removeAllItems()
|
self.queuePlayer.removeAllItems()
|
||||||
|
|||||||
@@ -83,8 +83,14 @@ struct CircleNavigationView: View {
|
|||||||
.foregroundColor(Color.green)
|
.foregroundColor(Color.green)
|
||||||
case .offline:
|
case .offline:
|
||||||
Circle()
|
Circle()
|
||||||
default:
|
.frame(width: 10, height: 10)
|
||||||
|
.foregroundColor(Color.red)
|
||||||
|
case .inConvo:
|
||||||
Circle()
|
Circle()
|
||||||
|
.frame(width: 10, height: 10)
|
||||||
|
.foregroundColor(Color.orange)
|
||||||
|
default:
|
||||||
|
EmptyView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -103,7 +109,13 @@ struct CircleNavigationView: View {
|
|||||||
.frame(width: 10, height: 10)
|
.frame(width: 10, height: 10)
|
||||||
.foregroundColor(Color.green)
|
.foregroundColor(Color.green)
|
||||||
case .offline:
|
case .offline:
|
||||||
EmptyView()
|
Circle()
|
||||||
|
.frame(width: 10, height: 10)
|
||||||
|
.foregroundColor(Color.red)
|
||||||
|
case .inConvo:
|
||||||
|
Circle()
|
||||||
|
.frame(width: 10, height: 10)
|
||||||
|
.foregroundColor(Color.orange)
|
||||||
default:
|
default:
|
||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ extension InnerCircleViewModel {
|
|||||||
extension InnerCircleViewModel {
|
extension InnerCircleViewModel {
|
||||||
func getAgoraToken() {
|
func getAgoraToken() {
|
||||||
if let uid = AuthSessionStore.getCurrentUserId() {
|
if let uid = AuthSessionStore.getCurrentUserId() {
|
||||||
self.agoraService.getAgoraUserToken(channelName: uid)
|
self.agoraService.getAgoraUserTokenServer(channelName: uid)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print("no user authenticated to get an agora token")
|
print("no user authenticated to get an agora token")
|
||||||
|
|||||||
Reference in New Issue
Block a user