decent clean up
This commit is contained in:
@@ -10,6 +10,8 @@ import AgoraRtcKit
|
|||||||
|
|
||||||
|
|
||||||
class ConvoViewModel: NSObject, ObservableObject {
|
class ConvoViewModel: NSObject, ObservableObject {
|
||||||
|
private var testingUIMode = true
|
||||||
|
|
||||||
@Published var selectedConvoId:String? = nil
|
@Published var selectedConvoId:String? = nil
|
||||||
|
|
||||||
let firestoreService = FirestoreService()
|
let firestoreService = FirestoreService()
|
||||||
@@ -41,12 +43,23 @@ class ConvoViewModel: NSObject, ObservableObject {
|
|||||||
deinit {
|
deinit {
|
||||||
// deinit the firestore listener
|
// deinit the firestore listener
|
||||||
// deinit the agora engine
|
// deinit the agora engine
|
||||||
|
print("deiniting and cleaning up convo view model/agora services")
|
||||||
|
|
||||||
|
AgoraRtcEngineKit.destroy()
|
||||||
|
|
||||||
|
self.leaveConvo()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@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 {
|
||||||
|
print("testing mode...not doing anything")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if let userId = AuthSessionStore.getCurrentUserId() {
|
if let userId = AuthSessionStore.getCurrentUserId() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -64,6 +77,12 @@ class ConvoViewModel: NSObject, ObservableObject {
|
|||||||
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
|
||||||
@@ -83,6 +102,10 @@ class ConvoViewModel: NSObject, ObservableObject {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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!
|
||||||
|
|
||||||
@@ -92,19 +115,18 @@ class ConvoViewModel: NSObject, ObservableObject {
|
|||||||
|
|
||||||
// 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
|
||||||
|
|
||||||
self.selectedConvoId = nil
|
self.selectedConvoId = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// if you are the second to last person in the convo and you leave, you end the convo
|
|
||||||
private func endConvo() {
|
|
||||||
self.leaveConvo()
|
|
||||||
|
|
||||||
AgoraRtcEngineKit.destroy()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ConvoViewModel {
|
extension ConvoViewModel {
|
||||||
@@ -118,6 +140,8 @@ 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
|
// leave channel if it's just me
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ struct CircleFooterView: View {
|
|||||||
@EnvironmentObject var navigationStack: NavigationStack
|
@EnvironmentObject var navigationStack: NavigationStack
|
||||||
@EnvironmentObject var authSessionStore: AuthSessionStore
|
@EnvironmentObject var authSessionStore: AuthSessionStore
|
||||||
@EnvironmentObject var innerCircleVM: InnerCircleViewModel
|
@EnvironmentObject var innerCircleVM: InnerCircleViewModel
|
||||||
|
@EnvironmentObject var convoVM: ConvoViewModel
|
||||||
|
|
||||||
@Binding var selectedFriendIndex: String?
|
@Binding var selectedFriendIndex: String?
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ struct CircleGridView: View {
|
|||||||
@EnvironmentObject var innerCircleVM: InnerCircleViewModel
|
@EnvironmentObject var innerCircleVM: InnerCircleViewModel
|
||||||
@EnvironmentObject var authSessionStore: AuthSessionStore
|
@EnvironmentObject var authSessionStore: AuthSessionStore
|
||||||
@EnvironmentObject var navigationStack: NavigationStack
|
@EnvironmentObject var navigationStack: NavigationStack
|
||||||
|
@EnvironmentObject var convoVM: ConvoViewModel
|
||||||
|
|
||||||
@State var queuePlayer = AVQueuePlayer()
|
@State var queuePlayer = AVQueuePlayer()
|
||||||
@State var timeObserverToken: Any?
|
@State var timeObserverToken: Any?
|
||||||
@@ -51,6 +52,8 @@ struct CircleGridView: View {
|
|||||||
@State var alertText = ""
|
@State var alertText = ""
|
||||||
@State var alertSubtext = ""
|
@State var alertSubtext = ""
|
||||||
|
|
||||||
|
@State var animateLiveConvos = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
// main communication hub
|
// main communication hub
|
||||||
// TODO: client side, sort the honeycomb from top left to bottom right
|
// TODO: client side, sort the honeycomb from top left to bottom right
|
||||||
@@ -59,6 +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
|
||||||
|
|
||||||
ScrollViewReader {scrollReaderValue in
|
ScrollViewReader {scrollReaderValue in
|
||||||
ScrollView([.horizontal, .vertical], showsIndicators: false) {
|
ScrollView([.horizontal, .vertical], showsIndicators: false) {
|
||||||
@@ -67,16 +71,81 @@ struct CircleGridView: View {
|
|||||||
alignment: .center,
|
alignment: .center,
|
||||||
spacing: Self.spacingBetweenRows
|
spacing: Self.spacingBetweenRows
|
||||||
) {
|
) {
|
||||||
|
// live convos
|
||||||
|
ForEach(0..<convos.count, id: \.self) {value in
|
||||||
|
let currConvo = self.convoVM.testConvos[value]
|
||||||
|
|
||||||
|
GeometryReader {gridProxy in
|
||||||
|
let scale = getScale(proxy: gridProxy, itemNumber: value, userId: nil, convoId: currConvo.id)
|
||||||
|
|
||||||
|
ZStack(alignment: .topTrailing) {
|
||||||
|
Circle()
|
||||||
|
.foregroundColor(self.getBubbleTint(convoId: currConvo.id))
|
||||||
|
|
||||||
|
ZStack {
|
||||||
|
Color.clear
|
||||||
|
ProfilePictureOverlap()
|
||||||
|
.shadow(color: Color.black.opacity(0.2), radius: 10, x: 0, y: 20)
|
||||||
|
}
|
||||||
|
|
||||||
|
Text("+2")
|
||||||
|
.padding(5)
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundColor(Color.white)
|
||||||
|
.background(NirvanaColor.dimTeal)
|
||||||
|
.cornerRadius(100)
|
||||||
|
|
||||||
|
// ZStack(alignment: .bottom) {
|
||||||
|
// Color.clear
|
||||||
|
//
|
||||||
|
// Text("kev, sarth...")
|
||||||
|
// .foregroundColor(NirvanaColor.teal)
|
||||||
|
// .font(.caption)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
.scaleEffect(self.animateLiveConvos ? scale + 0.2 : scale)
|
||||||
|
.padding(scale * 5)
|
||||||
|
} // geometry reader
|
||||||
|
.offset(
|
||||||
|
x: honeycombOffSetX(value),
|
||||||
|
y: 0
|
||||||
|
)
|
||||||
|
.id(currConvo.id) // id for scrollviewreader
|
||||||
|
.frame(height: Self.size)
|
||||||
|
.onTapGesture {
|
||||||
|
// if not in a call already
|
||||||
|
if !self.convoVM.isInCall() {
|
||||||
|
self.convoVM.selectedConvoId = self.convoVM.testConvos[value].id!
|
||||||
|
self.convoVM.joinConvo()
|
||||||
|
|
||||||
|
// if had selected an individual, don't want them in here anymore
|
||||||
|
self.selectedFriendIndex = nil
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.convoVM.selectedConvoId = nil
|
||||||
|
self.convoVM.leaveConvo()
|
||||||
|
}
|
||||||
|
.animation(
|
||||||
|
Animation.easeInOut(duration: self.convoVM.selectedConvoId == currConvo.id ? 2 : 4
|
||||||
|
).repeatForever(autoreverses: true),
|
||||||
|
value: self.animateLiveConvos
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// active friends
|
// active friends
|
||||||
ForEach(0..<activeFriends.count, id: \.self) {value in
|
ForEach(0..<activeFriends.count, id: \.self) {value in
|
||||||
|
let adjustedValue = value + convos.count
|
||||||
let friendId = activeFriends[value]
|
let friendId = activeFriends[value]
|
||||||
|
|
||||||
GeometryReader {gridProxy in
|
GeometryReader {gridProxy in
|
||||||
let scale = getScale(proxy: gridProxy, itemNumber: value, userId: friendId)
|
let scale = getScale(proxy: gridProxy, itemNumber: adjustedValue, userId: friendId)
|
||||||
|
|
||||||
ZStack(alignment: .topTrailing) {
|
ZStack(alignment: .topTrailing) {
|
||||||
Circle()
|
Circle()
|
||||||
.foregroundColor(self.getBubbleTint(friendIndex: value, friendDbId: friendId)) // different color for a selected user
|
.foregroundColor(self.getBubbleTint(friendDbId: friendId)) // different color for a selected user
|
||||||
.blur(radius: 8)
|
.blur(radius: 8)
|
||||||
.cornerRadius(100)
|
.cornerRadius(100)
|
||||||
|
|
||||||
@@ -103,7 +172,7 @@ struct CircleGridView: View {
|
|||||||
.padding(scale * 5)
|
.padding(scale * 5)
|
||||||
} // geometry reader
|
} // geometry reader
|
||||||
.offset(
|
.offset(
|
||||||
x: honeycombOffSetX(value),
|
x: honeycombOffSetX(adjustedValue),
|
||||||
y: 0
|
y: 0
|
||||||
)
|
)
|
||||||
.id(friendId) // id for scrollviewreader
|
.id(friendId) // id for scrollviewreader
|
||||||
@@ -164,7 +233,7 @@ struct CircleGridView: View {
|
|||||||
// inbox users
|
// inbox users
|
||||||
ForEach(0..<inboxUsers.count, id: \.self) {inboxValue in
|
ForEach(0..<inboxUsers.count, id: \.self) {inboxValue in
|
||||||
let inboxUserId = inboxUsers[inboxValue]
|
let inboxUserId = inboxUsers[inboxValue]
|
||||||
let adjustedValue = inboxValue + activeFriends.count // IMPORTANT: accounting for the active friends iterations
|
let adjustedValue = inboxValue + activeFriends.count + convos.count // IMPORTANT: accounting for the active friends iterations
|
||||||
GeometryReader {gridProxy in
|
GeometryReader {gridProxy in
|
||||||
let scale = getScale(proxy: gridProxy, itemNumber: adjustedValue, userId: inboxUserId) * 0.75 // don't want inbox to match size of active
|
let scale = getScale(proxy: gridProxy, itemNumber: adjustedValue, userId: inboxUserId) * 0.75 // don't want inbox to match size of active
|
||||||
|
|
||||||
@@ -226,7 +295,7 @@ struct CircleGridView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stale state for adding a contact
|
// stale state for adding a contact
|
||||||
let staleAdjustedValue = activeFriends.count + inboxUsers.count
|
let staleAdjustedValue = activeFriends.count + inboxUsers.count + convos.count
|
||||||
GeometryReader {gridProxy in
|
GeometryReader {gridProxy in
|
||||||
let scale = getScale(proxy: gridProxy, itemNumber: staleAdjustedValue, userId: nil) * 0.75 // adjusting size as stale states should be the smallest
|
let scale = getScale(proxy: gridProxy, itemNumber: staleAdjustedValue, userId: nil) * 0.75 // adjusting size as stale states should be the smallest
|
||||||
Button {
|
Button {
|
||||||
@@ -263,7 +332,9 @@ struct CircleGridView: View {
|
|||||||
// scrolling to first person in grid
|
// scrolling to first person in grid
|
||||||
if self.authSessionStore.friendsArr.count > 0 {
|
if self.authSessionStore.friendsArr.count > 0 {
|
||||||
scrollReaderValue.scrollTo(self.selectedFriendIndex)
|
scrollReaderValue.scrollTo(self.selectedFriendIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.animateLiveConvos = true
|
||||||
}
|
}
|
||||||
} // scrollview reader
|
} // scrollview reader
|
||||||
}
|
}
|
||||||
@@ -283,7 +354,7 @@ struct CircleGridView: View {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getBubbleTint(friendIndex: Int, friendDbId: String) -> Color {
|
private func getBubbleTint(friendDbId: String) -> Color {
|
||||||
// TODO: check if I listened to the message before or not
|
// TODO: check if I listened to the message before or not
|
||||||
if self.haveNewMessageFromFriend(friendDbId: friendDbId) { // this friend has a message for me
|
if self.haveNewMessageFromFriend(friendDbId: friendDbId) { // this friend has a message for me
|
||||||
return Color.orange.opacity(0.8)
|
return Color.orange.opacity(0.8)
|
||||||
@@ -295,6 +366,14 @@ struct CircleGridView: View {
|
|||||||
|
|
||||||
return NirvanaColor.dimTeal.opacity(0.2)
|
return NirvanaColor.dimTeal.opacity(0.2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func getBubbleTint(convoId: String?) -> Color {
|
||||||
|
if convoId != nil && convoId == self.convoVM.selectedConvoId {
|
||||||
|
return NirvanaColor.teal.opacity(0.7)
|
||||||
|
}
|
||||||
|
|
||||||
|
return NirvanaColor.dimTeal.opacity(0.2)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CircleGridView_Previews: PreviewProvider {
|
struct CircleGridView_Previews: PreviewProvider {
|
||||||
@@ -309,12 +388,16 @@ struct CircleGridView_Previews: PreviewProvider {
|
|||||||
extension CircleGridView {
|
extension CircleGridView {
|
||||||
// getting the proxy of an individual item
|
// getting the proxy of an individual item
|
||||||
// and decoding into a scale that the item should take
|
// and decoding into a scale that the item should take
|
||||||
private func getScale(proxy: GeometryProxy, itemNumber: Int, userId: String?) -> CGFloat {
|
private func getScale(proxy: GeometryProxy, itemNumber: Int, userId: String? = nil, convoId: String? = nil) -> CGFloat {
|
||||||
// if this user is selected
|
// if this user is selected
|
||||||
if userId != nil && userId == self.selectedFriendIndex {
|
if userId != nil && userId == self.selectedFriendIndex {
|
||||||
return big + 0.2
|
return big + 0.2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if convoId != nil && convoId == self.convoVM.selectedConvoId {
|
||||||
|
return big + 0.2
|
||||||
|
}
|
||||||
|
|
||||||
// if this user that we are rendering
|
// if this user that we are rendering
|
||||||
// has a new message for us
|
// has a new message for us
|
||||||
// TODO: too much memory usage doing this across the board
|
// TODO: too much memory usage doing this across the board
|
||||||
|
|||||||
@@ -88,13 +88,14 @@ struct InnerCircleView: View {
|
|||||||
} else {
|
} else {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
// convos
|
// convos
|
||||||
ConvosView()
|
// ConvosView()
|
||||||
.environmentObject(self.convoViewModel)
|
// .environmentObject(self.convoViewModel)
|
||||||
.padding(.top, 50)
|
// .padding(.top, 50)
|
||||||
|
|
||||||
// inner circle grid
|
// inner circle grid
|
||||||
CircleGridView(selectedFriendIndex: self.$selectedFriendIndex)
|
CircleGridView(selectedFriendIndex: self.$selectedFriendIndex)
|
||||||
.environmentObject(self.innerCircleVM)
|
.environmentObject(self.innerCircleVM)
|
||||||
|
.environmentObject(self.convoViewModel)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user