Skip to content

Commit

Permalink
[Feature] Add Chat Typing Indicator (#399)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpeng-ms authored Oct 25, 2022
1 parent d0c1a9f commit 38ef459
Show file tree
Hide file tree
Showing 30 changed files with 592 additions and 40 deletions.
3 changes: 3 additions & 0 deletions AzureCommunicationUI/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ target 'AzureCommunicationUICalling' do
pod 'MicrosoftFluentUI/Button_ios', '0.3.9'
pod 'MicrosoftFluentUI/PopupMenu_ios', '0.3.9'
pod 'MicrosoftFluentUI/ActivityIndicator_ios', '0.3.9'
pod 'MicrosoftFluentUI/AvatarGroup_ios', '0.3.9'
pod 'SwiftLint', '0.42.0'

target 'AzureCommunicationUICallingTests' do
Expand All @@ -32,6 +33,7 @@ target 'AzureCommunicationUIChat' do
pod 'MicrosoftFluentUI/Button_ios', '0.3.9'
pod 'MicrosoftFluentUI/PopupMenu_ios', '0.3.9'
pod 'MicrosoftFluentUI/ActivityIndicator_ios', '0.3.9'
pod 'MicrosoftFluentUI/AvatarGroup_ios', '0.3.9'
pod 'SwiftLint', '0.42.0'

target 'AzureCommunicationUIChatTests' do
Expand All @@ -50,6 +52,7 @@ target 'AzureCommunicationUIDemoApp' do
pod 'MicrosoftFluentUI/Button_ios', '0.3.9'
pod 'MicrosoftFluentUI/PopupMenu_ios', '0.3.9'
pod 'MicrosoftFluentUI/ActivityIndicator_ios', '0.3.9'
pod 'MicrosoftFluentUI/AvatarGroup_ios', '0.3.9'
pod 'SwiftLint', '0.42.0'
pod 'AppCenter/Crashes', '4.4.1'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@
50F0C59128D38ACA009D7176 /* CompositeViewModelFactoryMocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F0C59028D38ACA009D7176 /* CompositeViewModelFactoryMocking.swift */; };
50F0C59328D38AE3009D7176 /* ChatServiceMocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F0C59228D38AE3009D7176 /* ChatServiceMocking.swift */; };
50F0C59528D38AF5009D7176 /* ChatSDKWrapperMocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F0C59428D38AF5009D7176 /* ChatSDKWrapperMocking.swift */; };
50F0C59728D38B08009D7176 /* ChatSDKEventsHandlerMocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F0C59628D38B08009D7176 /* ChatSDKEventsHandlerMocking.swift */; };
50F0C59928D38B20009D7176 /* ErrorMocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F0C59828D38B20009D7176 /* ErrorMocking.swift */; };
50F0C59B28D38B2B009D7176 /* AccessibilityProviderMocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F0C59A28D38B2B009D7176 /* AccessibilityProviderMocking.swift */; };
50F0C59D28D38B37009D7176 /* LocalizationProviderMocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F0C59C28D38B37009D7176 /* LocalizationProviderMocking.swift */; };
Expand All @@ -143,9 +142,13 @@
50F0C5C628D38CE4009D7176 /* MessageRepositoryManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F0C5C528D38CE4009D7176 /* MessageRepositoryManagerTests.swift */; };
50F0C5C828D38CF1009D7176 /* RemoteOptionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F0C5C728D38CF1009D7176 /* RemoteOptionsTests.swift */; };
50F0C5CA28D38D00009D7176 /* DependencyContainerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F0C5C928D38D00009D7176 /* DependencyContainerTests.swift */; };
521A024028FE1E47002CAD8E /* TypingParticipantAvatarGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 521A023E28FE1E47002CAD8E /* TypingParticipantAvatarGroup.swift */; };
521A024128FE1E47002CAD8E /* TypingParticipantAvatarGroupContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 521A023F28FE1E47002CAD8E /* TypingParticipantAvatarGroupContainer.swift */; };
521A024428FE1E8D002CAD8E /* TypingParticipantsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 521A024228FE1E8C002CAD8E /* TypingParticipantsViewModel.swift */; };
521A024528FE1E8D002CAD8E /* TypingParticipantsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 521A024328FE1E8D002CAD8E /* TypingParticipantsView.swift */; };
521A024729032755002CAD8E /* SystemMessageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 521A024629032755002CAD8E /* SystemMessageViewModel.swift */; };
521A024929032762002CAD8E /* TextMessageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 521A024829032762002CAD8E /* TextMessageViewModel.swift */; };
85D6F5E7707CE2A8E51E5451 /* Pods_AzureCommunicationUIChat_AzureCommunicationUIChatTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1B9C157344D512A9F069F9CC /* Pods_AzureCommunicationUIChat_AzureCommunicationUIChatTests.framework */; };
A812BA6C290093A00096ACF0 /* SystemMessageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A812BA6B290093A00096ACF0 /* SystemMessageViewModel.swift */; };
A812BA6E2900947F0096ACF0 /* TextMessageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A812BA6D2900947F0096ACF0 /* TextMessageViewModel.swift */; };
A8BB978028F770FE008142DB /* SystemMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BB977F28F770FE008142DB /* SystemMessageView.swift */; };
BD1A6A3C28ECDEAE005E0B70 /* MessageListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD1A6A3B28ECDEAE005E0B70 /* MessageListView.swift */; };
BD1A6A3E28ECDFAB005E0B70 /* MessageListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD1A6A3D28ECDFAB005E0B70 /* MessageListViewModel.swift */; };
Expand Down Expand Up @@ -286,7 +289,6 @@
50F0C59028D38ACA009D7176 /* CompositeViewModelFactoryMocking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompositeViewModelFactoryMocking.swift; sourceTree = "<group>"; };
50F0C59228D38AE3009D7176 /* ChatServiceMocking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatServiceMocking.swift; sourceTree = "<group>"; };
50F0C59428D38AF5009D7176 /* ChatSDKWrapperMocking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatSDKWrapperMocking.swift; sourceTree = "<group>"; };
50F0C59628D38B08009D7176 /* ChatSDKEventsHandlerMocking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatSDKEventsHandlerMocking.swift; sourceTree = "<group>"; };
50F0C59828D38B20009D7176 /* ErrorMocking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorMocking.swift; sourceTree = "<group>"; };
50F0C59A28D38B2B009D7176 /* AccessibilityProviderMocking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityProviderMocking.swift; sourceTree = "<group>"; };
50F0C59C28D38B37009D7176 /* LocalizationProviderMocking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationProviderMocking.swift; sourceTree = "<group>"; };
Expand All @@ -312,11 +314,15 @@
50F0C5C528D38CE4009D7176 /* MessageRepositoryManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageRepositoryManagerTests.swift; sourceTree = "<group>"; };
50F0C5C728D38CF1009D7176 /* RemoteOptionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteOptionsTests.swift; sourceTree = "<group>"; };
50F0C5C928D38D00009D7176 /* DependencyContainerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DependencyContainerTests.swift; sourceTree = "<group>"; };
521A023E28FE1E47002CAD8E /* TypingParticipantAvatarGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypingParticipantAvatarGroup.swift; sourceTree = "<group>"; };
521A023F28FE1E47002CAD8E /* TypingParticipantAvatarGroupContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypingParticipantAvatarGroupContainer.swift; sourceTree = "<group>"; };
521A024228FE1E8C002CAD8E /* TypingParticipantsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypingParticipantsViewModel.swift; sourceTree = "<group>"; };
521A024328FE1E8D002CAD8E /* TypingParticipantsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypingParticipantsView.swift; sourceTree = "<group>"; };
521A024629032755002CAD8E /* SystemMessageViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemMessageViewModel.swift; sourceTree = "<group>"; };
521A024829032762002CAD8E /* TextMessageViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextMessageViewModel.swift; sourceTree = "<group>"; };
5BE15140BA042B0F23F23BE3 /* Pods-AzureCommunicationUIChat-AzureCommunicationUIChatTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AzureCommunicationUIChat-AzureCommunicationUIChatTests.release.xcconfig"; path = "Target Support Files/Pods-AzureCommunicationUIChat-AzureCommunicationUIChatTests/Pods-AzureCommunicationUIChat-AzureCommunicationUIChatTests.release.xcconfig"; sourceTree = "<group>"; };
78EED6E1D0BF91A2966AC0C7 /* Pods-AzureCommunicationUIChat.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AzureCommunicationUIChat.debug.xcconfig"; path = "Target Support Files/Pods-AzureCommunicationUIChat/Pods-AzureCommunicationUIChat.debug.xcconfig"; sourceTree = "<group>"; };
A63BF349E7BC31AD5300412A /* Pods_AzureCommunicationUIChat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AzureCommunicationUIChat.framework; sourceTree = BUILT_PRODUCTS_DIR; };
A812BA6B290093A00096ACF0 /* SystemMessageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemMessageViewModel.swift; sourceTree = "<group>"; };
A812BA6D2900947F0096ACF0 /* TextMessageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextMessageViewModel.swift; sourceTree = "<group>"; };
A8BB977F28F770FE008142DB /* SystemMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemMessageView.swift; sourceTree = "<group>"; };
BD1A6A3B28ECDEAE005E0B70 /* MessageListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageListView.swift; sourceTree = "<group>"; };
BD1A6A3D28ECDFAB005E0B70 /* MessageListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageListViewModel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -565,6 +571,8 @@
50CB81F028C2856800680566 /* Wrapper */ = {
isa = PBXGroup;
children = (
521A023E28FE1E47002CAD8E /* TypingParticipantAvatarGroup.swift */,
521A023F28FE1E47002CAD8E /* TypingParticipantAvatarGroupContainer.swift */,
);
path = Wrapper;
sourceTree = "<group>";
Expand Down Expand Up @@ -598,6 +606,8 @@
BD1A6A3D28ECDFAB005E0B70 /* MessageListViewModel.swift */,
BD80293628ECA6C600A55CAC /* TopBarView.swift */,
BD80293A28ECA84200A55CAC /* TopBarViewModel.swift */,
521A024328FE1E8D002CAD8E /* TypingParticipantsView.swift */,
521A024228FE1E8C002CAD8E /* TypingParticipantsViewModel.swift */,
);
path = ChatViewComponents;
sourceTree = "<group>";
Expand Down Expand Up @@ -695,7 +705,6 @@
50370CB828EB5DBE00ACD234 /* LoggerMocking.swift */,
50F0C59228D38AE3009D7176 /* ChatServiceMocking.swift */,
50F0C59428D38AF5009D7176 /* ChatSDKWrapperMocking.swift */,
50F0C59628D38B08009D7176 /* ChatSDKEventsHandlerMocking.swift */,
50F0C59828D38B20009D7176 /* ErrorMocking.swift */,
50370CCC28ECE28D00ACD234 /* MessageRepositoryManagerMocking.swift */,
50F0C59A28D38B2B009D7176 /* AccessibilityProviderMocking.swift */,
Expand Down Expand Up @@ -1025,9 +1034,9 @@
50F0C58428D387E5009D7176 /* MessageView.swift */,
50F0C58628D38812009D7176 /* MessageViewModel.swift */,
A8BB977F28F770FE008142DB /* SystemMessageView.swift */,
A812BA6B290093A00096ACF0 /* SystemMessageViewModel.swift */,
BD80293E28ECCD7800A55CAC /* TextMessageView.swift */,
A812BA6D2900947F0096ACF0 /* TextMessageViewModel.swift */,
521A024629032755002CAD8E /* SystemMessageViewModel.swift */,
521A024829032762002CAD8E /* TextMessageViewModel.swift */,
);
path = Message;
sourceTree = "<group>";
Expand Down Expand Up @@ -1287,7 +1296,6 @@
50CB82BD28C2AD2300680566 /* UIViewControllerExtension.swift in Sources */,
50CB82C228C2AD2300680566 /* Store.swift in Sources */,
50CB81F828C2860200680566 /* ChatCompositeError.swift in Sources */,
A812BA6C290093A00096ACF0 /* SystemMessageViewModel.swift in Sources */,
50CB82D028C2AD9900680566 /* SetParticipantViewDataError.swift in Sources */,
50CB824128C29ADA00680566 /* ParticipantsState.swift in Sources */,
50CB826128C29E0600680566 /* ChatSDKWrapperProtocol.swift in Sources */,
Expand All @@ -1296,6 +1304,7 @@
50CB823728C29A3E00680566 /* ParticipantsAction.swift in Sources */,
BD80293B28ECA84200A55CAC /* TopBarViewModel.swift in Sources */,
50CB82BC28C2AD2300680566 /* CancelBag.swift in Sources */,
521A024128FE1E47002CAD8E /* TypingParticipantAvatarGroupContainer.swift in Sources */,
50CB81FC28C2862000680566 /* LocalizationOptions.swift in Sources */,
50CB824928C29B0100680566 /* LifeCycleReducer.swift in Sources */,
50CB81F428C285E300680566 /* RemoteOptions.swift in Sources */,
Expand All @@ -1316,6 +1325,7 @@
50CB82CD28C2AD2300680566 /* ThemeOptions.swift in Sources */,
50CB826D28C29E8400680566 /* LocalizationKey.swift in Sources */,
50CB82C628C2AD2300680566 /* OrientationManager.swift in Sources */,
521A024929032762002CAD8E /* TextMessageViewModel.swift in Sources */,
50CB82BA28C2AD2300680566 /* DefaultLogger.swift in Sources */,
5085BF1E28F729990057586D /* ChatThreadInfoModel.swift in Sources */,
50CB822928C2996200680566 /* ChatActionHandler.swift in Sources */,
Expand All @@ -1329,6 +1339,7 @@
50CB823128C2999200680566 /* Action.swift in Sources */,
50CB825928C29B7200680566 /* UserEventTimestampModel.swift in Sources */,
50CB82C428C2AD2300680566 /* AppLifeCycleManager.swift in Sources */,
521A024428FE1E8D002CAD8E /* TypingParticipantsViewModel.swift in Sources */,
50CB823328C2999B00680566 /* LifecycleAction.swift in Sources */,
50CB821528C286EA00680566 /* ColorThemeProvider.swift in Sources */,
50CB82C528C2AD2300680566 /* AccessibilityProvider.swift in Sources */,
Expand All @@ -1350,6 +1361,7 @@
50CB82CB28C2AD2300680566 /* ViewModifer.swift in Sources */,
BDB1B8CA28F8A2940000300F /* IconButton.swift in Sources */,
BD80293828ECA7D700A55CAC /* BottomBarView.swift in Sources */,
521A024729032755002CAD8E /* SystemMessageViewModel.swift in Sources */,
50CB824D28C29B1700680566 /* ParticipantsReducer.swift in Sources */,
50CB825D28C29DEF00680566 /* ChatService.swift in Sources */,
50CB824528C29AEB00680566 /* ErrorState.swift in Sources */,
Expand All @@ -1362,6 +1374,7 @@
50CB821328C286DE00680566 /* LocalizationProvider.swift in Sources */,
50CB821728C2870500680566 /* ContainerView.swift in Sources */,
50CB82C328C2AD2300680566 /* StyleProvider.swift in Sources */,
521A024028FE1E47002CAD8E /* TypingParticipantAvatarGroup.swift in Sources */,
50CB821928C2872600680566 /* ContainerUIHostingController.swift in Sources */,
50CB82C028C2AD2300680566 /* Middleware.swift in Sources */,
50CB823D28C29AC900680566 /* AppLifeCycleState.swift in Sources */,
Expand All @@ -1385,8 +1398,8 @@
50CB82C128C2AD2300680566 /* Reducer.swift in Sources */,
5085BF2028F72E0D0057586D /* ParticipantsInfoModel.swift in Sources */,
50F0C58728D38812009D7176 /* MessageViewModel.swift in Sources */,
521A024528FE1E8D002CAD8E /* TypingParticipantsView.swift in Sources */,
50CB820D28C286AA00680566 /* MessageRepositoryManager.swift in Sources */,
A812BA6E2900947F0096ACF0 /* TextMessageViewModel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -1421,7 +1434,6 @@
50F0C5C828D38CF1009D7176 /* RemoteOptionsTests.swift in Sources */,
50F0C5AA28D38BE1009D7176 /* ChatServiceEventHandlerTests.swift in Sources */,
50370CC228EB5E6B00ACD234 /* LocalizationProviderTests.swift in Sources */,
50F0C59728D38B08009D7176 /* ChatSDKEventsHandlerMocking.swift in Sources */,
50370CBD28EB5E0D00ACD234 /* ReducerMocking.swift in Sources */,
50F0C5C628D38CE4009D7176 /* MessageRepositoryManagerTests.swift in Sources */,
50F0C59928D38B20009D7176 /* ErrorMocking.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@
"AzureCommunicationUIChat.ChatView.TopBarView.WaitingForOthersToJoin"="Waiting for others to join";
"AzureCommunicationUIChat.ChatView.TopBarView.ChatWith1Person"="Chat with 1 person";
"AzureCommunicationUIChat.ChatView.TopBarView.ChatWithNPeople"="Chat with %d people"; // %d is for number of people in call
/* TypingParticipantsView */
"AzureCommunicationUIChat.ChatView.TypingParticipantsView.oneParticipantIsTyping"="%@ is typing..."; // %@ is display name
"AzureCommunicationUIChat.ChatView.TypingParticipantsView.twoParticipantsAreTyping"="%@ and %@ are typing...";
"AzureCommunicationUIChat.ChatView.TypingParticipantsView.threeParticipantsAreTyping"="%@, %@ and 1 other are typing...";
"AzureCommunicationUIChat.ChatView.TypingParticipantsView.multipleParticipantsAreTyping"="%@, %@ and %d others are typing..."; // %d is remaining number of participant typing
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ protocol CompositeViewModelFactoryProtocol {
participantsState: ParticipantsState) -> TopBarViewModel
func makeMessageListViewModel(chatState: ChatState) -> MessageListViewModel
func makeBottomBarViewModel(dispatch: @escaping ActionDispatch) -> BottomBarViewModel
func makeTypingParticipantsViewModel() -> TypingParticipantsViewModel
}

class CompositeViewModelFactory: CompositeViewModelFactoryProtocol {
Expand Down Expand Up @@ -89,4 +90,9 @@ class CompositeViewModelFactory: CompositeViewModelFactoryProtocol {
logger: logger,
dispatch: dispatch)
}

func makeTypingParticipantsViewModel() -> TypingParticipantsViewModel {
TypingParticipantsViewModel(logger: logger,
localizationProvider: localizationProvider)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//

import FluentUI
import UIKit

class TypingParticipantAvatarGroup: UIView {

private var group = MSFAvatarGroup(style: .stack, size: .xsmall)

var avatars: [ParticipantInfoModel] = [] {
didSet {
setAvatars(data: avatars)
}
}

private enum Constants {
static let avatarWidth: CGFloat = 16.0
static let maxAvatarAllowed: Int = 2
static let overflowCount: Int = 0
}

override init(frame: CGRect) {
super.init(frame: frame)
initAvatarGroup()
}

required init?(coder: NSCoder) {
super.init(coder: coder)
initAvatarGroup()
}
}

extension TypingParticipantAvatarGroup {
private func initAvatarGroup() {
group.state.overflowCount = Constants.overflowCount
group.state.style = .stack
// Max avatar shown would be 3
group.state.maxDisplayedAvatars = Constants.maxAvatarAllowed
group.isAccessibilityElement = false
addSubview(group.view)
group.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
group.view.leftAnchor.constraint(equalTo: self.leftAnchor),
group.view.rightAnchor.constraint(equalTo: self.rightAnchor),
group.view.topAnchor.constraint(equalTo: self.topAnchor),
group.view.bottomAnchor.constraint(equalTo: self.bottomAnchor)
])
}

private func setAvatars(data: [ParticipantInfoModel]) {
for participant in data {
let newAvatar = group.state.createAvatar()
newAvatar.primaryText = participant.displayName
newAvatar.isTransparent = false
newAvatar.isRingVisible = false
}
}
}
Loading

0 comments on commit 38ef459

Please sign in to comment.