Skip to content

Commit

Permalink
Add text chat to the iOS app (#148)
Browse files Browse the repository at this point in the history
* Update player SDK

* Integrate conversations SDK

* Small changes

* Improve stubs for UI previews

* Improve chat UI

* Refactor

* Use LazyVStack

* Create ChatInputBar

* Refactor ChatView

* Refactor to more views

* Smal improvements

* Reorganize files

* Adjust layout

* Improve spacing at the end of the list

* Remove unnecessary weak self

* Make unread dot work and fix a couple bugs

* Get room SID from backend

* Fix chat not working after user changes role

* Add chat feature flag

* Update version to 1.1.0 and regenerate Package.resolved for new Xcode version

* Update CI to use new Xcode version that can read new Package.resolved file
  • Loading branch information
timrozum committed Jul 11, 2022
1 parent ac978a8 commit 601675f
Show file tree
Hide file tree
Showing 21 changed files with 614 additions and 94 deletions.
2 changes: 1 addition & 1 deletion .circleci/continue_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ parameters:
executors:
macos_executor:
macos:
xcode: "13.1.0"
xcode: "13.3.1"

jobs:
build-and-test-ios-app:
Expand Down
61 changes: 61 additions & 0 deletions apps/ios/LiveVideo/LiveVideo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
objects = {

/* Begin PBXBuildFile section */
DC0A95F62819DB7500E7678C /* TwilioConversationsClient in Frameworks */ = {isa = PBXBuildFile; productRef = DC0A95F52819DB7500E7678C /* TwilioConversationsClient */; };
DC0A95F92819E1C800E7678C /* ChatManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC0A95F82819E1C800E7678C /* ChatManager.swift */; };
DC0A96052819E2C600E7678C /* ChatMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC0A96042819E2C600E7678C /* ChatMessage.swift */; };
DC0A9607281B2F0F00E7678C /* ChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC0A9606281B2F0F00E7678C /* ChatView.swift */; };
DC175F2D270E232F00D9D1FE /* SyncManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC175F2C270E232F00D9D1FE /* SyncManager.swift */; };
DC175F30270E238F00D9D1FE /* TwilioSyncClient in Frameworks */ = {isa = PBXBuildFile; productRef = DC175F2F270E238F00D9D1FE /* TwilioSyncClient */; };
DC175F32270E23F900D9D1FE /* SyncUserDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC175F31270E23F900D9D1FE /* SyncUserDocument.swift */; };
Expand Down Expand Up @@ -74,6 +78,10 @@
DCB1BE052756D954006CE9D1 /* EnterPasscodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB1BE042756D954006CE9D1 /* EnterPasscodeView.swift */; };
DCB1BE0827581BC6006CE9D1 /* Quick in Frameworks */ = {isa = PBXBuildFile; productRef = DCB1BE0727581BC6006CE9D1 /* Quick */; };
DCB1BE0B27581C11006CE9D1 /* Nimble in Frameworks */ = {isa = PBXBuildFile; productRef = DCB1BE0A27581C11006CE9D1 /* Nimble */; };
DCB3DA34282193210020DE6C /* ChatBubbleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB3DA33282193210020DE6C /* ChatBubbleView.swift */; };
DCB3DA36282195FC0020DE6C /* ChatHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB3DA35282195FC0020DE6C /* ChatHeaderView.swift */; };
DCB3DA382821BBDC0020DE6C /* ChatInputBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB3DA372821BBDC0020DE6C /* ChatInputBar.swift */; };
DCB3DA3A2821BE270020DE6C /* ChatMessageList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB3DA392821BE270020DE6C /* ChatMessageList.swift */; };
DCB4497426F5496400B52774 /* SpeakerSettingsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB4497326F5496400B52774 /* SpeakerSettingsManager.swift */; };
DCB4497626F65A7000B52774 /* SpeakerVideoViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB4497526F65A7000B52774 /* SpeakerVideoViewModel.swift */; };
DCC1D62626D9396400892038 /* StreamManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCC1D62526D9396400892038 /* StreamManager.swift */; };
Expand Down Expand Up @@ -115,6 +123,9 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
DC0A95F82819E1C800E7678C /* ChatManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatManager.swift; sourceTree = "<group>"; };
DC0A96042819E2C600E7678C /* ChatMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessage.swift; sourceTree = "<group>"; };
DC0A9606281B2F0F00E7678C /* ChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatView.swift; sourceTree = "<group>"; };
DC175F2C270E232F00D9D1FE /* SyncManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncManager.swift; sourceTree = "<group>"; };
DC175F31270E23F900D9D1FE /* SyncUserDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncUserDocument.swift; sourceTree = "<group>"; };
DC175F33270E3FD200D9D1FE /* SyncUsersMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncUsersMap.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -182,6 +193,10 @@
DCB1BDFD27568D70006CE9D1 /* VerifyPasscodeRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifyPasscodeRequest.swift; sourceTree = "<group>"; };
DCB1BDFF27568F5B006CE9D1 /* PasscodeComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasscodeComponents.swift; sourceTree = "<group>"; };
DCB1BE042756D954006CE9D1 /* EnterPasscodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnterPasscodeView.swift; sourceTree = "<group>"; };
DCB3DA33282193210020DE6C /* ChatBubbleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatBubbleView.swift; sourceTree = "<group>"; };
DCB3DA35282195FC0020DE6C /* ChatHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatHeaderView.swift; sourceTree = "<group>"; };
DCB3DA372821BBDC0020DE6C /* ChatInputBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInputBar.swift; sourceTree = "<group>"; };
DCB3DA392821BE270020DE6C /* ChatMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageList.swift; sourceTree = "<group>"; };
DCB4497326F5496400B52774 /* SpeakerSettingsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpeakerSettingsManager.swift; sourceTree = "<group>"; };
DCB4497526F65A7000B52774 /* SpeakerVideoViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpeakerVideoViewModel.swift; sourceTree = "<group>"; };
DCC1D62526D9396400892038 /* StreamManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamManager.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -209,6 +224,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DC0A95F62819DB7500E7678C /* TwilioConversationsClient in Frameworks */,
DCC48F9826D828E500EE49EF /* Alamofire in Frameworks */,
DC4F45E7271F5A3700BE730B /* TwilioLivePlayer in Frameworks */,
DCB1BE032756A288006CE9D1 /* KeychainAccess in Frameworks */,
Expand Down Expand Up @@ -236,6 +252,15 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
DC0A95F72819E19100E7678C /* Chat */ = {
isa = PBXGroup;
children = (
DC0A95F82819E1C800E7678C /* ChatManager.swift */,
DC0A96042819E2C600E7678C /* ChatMessage.swift */,
);
path = Chat;
sourceTree = "<group>";
};
DC14B78626FA385E003BDABC /* SpeakerSettings */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -280,6 +305,7 @@
DC4AA65226D0118200E677D5 /* Views */ = {
isa = PBXGroup;
children = (
DCB3DA3B2822F8820020DE6C /* Chat */,
DC175F35270E5B5700D9D1FE /* Participants */,
DC4AA65E26D03E0600E677D5 /* Home */,
DC4AA65C26D03DDF00E677D5 /* Settings */,
Expand Down Expand Up @@ -445,6 +471,18 @@
path = HostControls;
sourceTree = "<group>";
};
DCB3DA3B2822F8820020DE6C /* Chat */ = {
isa = PBXGroup;
children = (
DCB3DA33282193210020DE6C /* ChatBubbleView.swift */,
DCB3DA35282195FC0020DE6C /* ChatHeaderView.swift */,
DCB3DA372821BBDC0020DE6C /* ChatInputBar.swift */,
DCB3DA392821BE270020DE6C /* ChatMessageList.swift */,
DC0A9606281B2F0F00E7678C /* ChatView.swift */,
);
path = Chat;
sourceTree = "<group>";
};
DCC1D62426D9393900892038 /* Stream */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -517,6 +555,7 @@
DCC48F9E26D830D300EE49EF /* Twilio */ = {
isa = PBXGroup;
children = (
DC0A95F72819E19100E7678C /* Chat */,
DCC48F9F26D830E300EE49EF /* Player */,
DC1ED0FE26E92D7C00FFA769 /* Room */,
DCC1D62426D9393900892038 /* Stream */,
Expand Down Expand Up @@ -575,6 +614,7 @@
DC175F2F270E238F00D9D1FE /* TwilioSyncClient */,
DC4F45E6271F5A3700BE730B /* TwilioLivePlayer */,
DCB1BE022756A288006CE9D1 /* KeychainAccess */,
DC0A95F52819DB7500E7678C /* TwilioConversationsClient */,
);
productName = LiveVideo;
productReference = DC5F453526CC061A009C5C79 /* LiveVideo.app */;
Expand Down Expand Up @@ -659,6 +699,7 @@
DCB1BE012756A288006CE9D1 /* XCRemoteSwiftPackageReference "KeychainAccess" */,
DCB1BE0627581BC6006CE9D1 /* XCRemoteSwiftPackageReference "Quick" */,
DCB1BE0927581C11006CE9D1 /* XCRemoteSwiftPackageReference "Nimble" */,
DC0A95F42819DB7500E7678C /* XCRemoteSwiftPackageReference "conversations-ios" */,
);
productRefGroup = DC5F453626CC061A009C5C79 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -709,6 +750,7 @@
DC5F458326CDBA0B009C5C79 /* EnterUserIdentityView.swift in Sources */,
DC44BB412703C8DD00DB656D /* SceneDelegate.swift in Sources */,
DCADF35027FE264E0093A9FE /* EnvironmentBadge.swift in Sources */,
DCB3DA36282195FC0020DE6C /* ChatHeaderView.swift in Sources */,
DC9E18392729DC740070F53F /* OffscreenSpeakersView.swift in Sources */,
DCADF34227FCF4950093A9FE /* SignInSettingsView.swift in Sources */,
DC50A57B273DBB2700E29580 /* JSONEncoderExtension.swift in Sources */,
Expand All @@ -718,6 +760,7 @@
DC6404D8271B68D4004730C6 /* ParticipantsViewModel.swift in Sources */,
DCB1BE0027568F5B006CE9D1 /* PasscodeComponents.swift in Sources */,
DC1ED0FD26E14D0B00FFA769 /* StreamToolbar.swift in Sources */,
DC0A96052819E2C600E7678C /* ChatMessage.swift in Sources */,
DC1ED0F926E1440200FFA769 /* StreamStatusView.swift in Sources */,
DC504A7726F1468E00C37EC9 /* SpeakerVideoView.swift in Sources */,
DC175F34270E3FD200D9D1FE /* SyncUsersMap.swift in Sources */,
Expand Down Expand Up @@ -753,15 +796,19 @@
DCCA727327B5C142006B0441 /* PresentationVideoView.swift in Sources */,
DCADF33727FC95DF0093A9FE /* GeneralSettingsView.swift in Sources */,
DC4AA65926D0133600E677D5 /* Color.swift in Sources */,
DCB3DA382821BBDC0020DE6C /* ChatInputBar.swift in Sources */,
DC0A9607281B2F0F00E7678C /* ChatView.swift in Sources */,
DCCA726D27B5890E006B0441 /* SpeakerVideoViewModelFactory.swift in Sources */,
DC3BB82527445F9A005D0327 /* ParticipantsHeader.swift in Sources */,
DCB3DA34282193210020DE6C /* ChatBubbleView.swift in Sources */,
DCC1D62826D9568700892038 /* StreamConfig.swift in Sources */,
DC1ED11C26E92DEA00FFA769 /* RemoteParticipantManager.swift in Sources */,
DC5F453B26CC061A009C5C79 /* HomeView.swift in Sources */,
DCC1D62A26D9643400892038 /* FormStack.swift in Sources */,
DC6404D4271B3BF8004730C6 /* StreamViewModel.swift in Sources */,
DCB4497426F5496400B52774 /* SpeakerSettingsManager.swift in Sources */,
DC1ED0FB26E144AE00FFA769 /* StreamToolbarButton.swift in Sources */,
DC0A95F92819E1C800E7678C /* ChatManager.swift in Sources */,
DC5F453926CC061A009C5C79 /* LiveVideoApp.swift in Sources */,
DC175F37270E5B6F00D9D1FE /* ParticipantsView.swift in Sources */,
DC3BB82727480A9E005D0327 /* RemoveSpeakerRequest.swift in Sources */,
Expand All @@ -776,6 +823,7 @@
DC175F402718852B00D9D1FE /* DeleteStreamRequest.swift in Sources */,
DC1ED0F026DFCD3C00FFA769 /* LiveBadge.swift in Sources */,
DC50A57D273DBD6D00E29580 /* JSONDecoderExtension.swift in Sources */,
DCB3DA3A2821BE270020DE6C /* ChatMessageList.swift in Sources */,
DC4F45ED2728591900BE730B /* StreamConfigFlowModel.swift in Sources */,
DCC48FA126D8311700EE49EF /* PlayerManager.swift in Sources */,
DC4AA66026D047DD00E677D5 /* FormTextFieldStyle.swift in Sources */,
Expand Down Expand Up @@ -1120,6 +1168,14 @@
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
DC0A95F42819DB7500E7678C /* XCRemoteSwiftPackageReference "conversations-ios" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/twilio/conversations-ios";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.2.0;
};
};
DC175F2E270E238F00D9D1FE /* XCRemoteSwiftPackageReference "twilio-sync-ios" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/twilio/twilio-sync-ios";
Expand Down Expand Up @@ -1179,6 +1235,11 @@
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
DC0A95F52819DB7500E7678C /* TwilioConversationsClient */ = {
isa = XCSwiftPackageProductDependency;
package = DC0A95F42819DB7500E7678C /* XCRemoteSwiftPackageReference "conversations-ios" */;
productName = TwilioConversationsClient;
};
DC175F2F270E238F00D9D1FE /* TwilioSyncClient */ = {
isa = XCSwiftPackageProductDependency;
package = DC175F2E270E238F00D9D1FE /* XCRemoteSwiftPackageReference "twilio-sync-ios" */;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,88 +1,95 @@
{
"object": {
"pins": [
{
"package": "Alamofire",
"repositoryURL": "https://github.com/Alamofire/Alamofire",
"state": {
"branch": null,
"revision": "f82c23a8a7ef8dc1a49a8bfc6a96883e79121864",
"version": "5.5.0"
}
},
{
"package": "CwlCatchException",
"repositoryURL": "https://github.com/mattgallagher/CwlCatchException.git",
"state": {
"branch": null,
"revision": "35f9e770f54ce62dd8526470f14c6e137cef3eea",
"version": "2.1.1"
}
},
{
"package": "CwlPreconditionTesting",
"repositoryURL": "https://github.com/mattgallagher/CwlPreconditionTesting.git",
"state": {
"branch": null,
"revision": "c21f7bab5ca8eee0a9998bbd17ca1d0eb45d4688",
"version": "2.1.0"
}
},
{
"package": "KeychainAccess",
"repositoryURL": "https://github.com/kishikawakatsumi/KeychainAccess",
"state": {
"branch": null,
"revision": "84e546727d66f1adc5439debad16270d0fdd04e7",
"version": "4.2.2"
}
},
{
"package": "Nimble",
"repositoryURL": "https://github.com/Quick/Nimble",
"state": {
"branch": null,
"revision": "c93f16c25af5770f0d3e6af27c9634640946b068",
"version": "9.2.1"
}
},
{
"package": "Quick",
"repositoryURL": "https://github.com/Quick/Quick",
"state": {
"branch": null,
"revision": "bd86ca0141e3cfb333546de5a11ede63f0c4a0e6",
"version": "4.0.0"
}
},
{
"package": "TwilioLivePlayer",
"repositoryURL": "https://github.com/twilio/twilio-live-player-ios",
"state": {
"branch": null,
"revision": "7c4827e0bdb3b935aecdce9fa3c1b3c42ba60dd5",
"version": "1.0.1"
}
},
{
"package": "TwilioSyncClient",
"repositoryURL": "https://github.com/twilio/twilio-sync-ios",
"state": {
"branch": null,
"revision": "dd300a5841544afc145feec90800ced480b7cfd2",
"version": "1.1.0"
}
},
{
"package": "TwilioVideo",
"repositoryURL": "https://github.com/twilio/twilio-video-ios",
"state": {
"branch": null,
"revision": "e028f87d5425316c39723c7bc2508f5349e36482",
"version": "4.6.3"
}
"pins" : [
{
"identity" : "alamofire",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Alamofire/Alamofire",
"state" : {
"revision" : "f82c23a8a7ef8dc1a49a8bfc6a96883e79121864",
"version" : "5.5.0"
}
]
},
"version": 1
},
{
"identity" : "conversations-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/twilio/conversations-ios",
"state" : {
"revision" : "df44d958cdc810d343b06e555107d1ab0f66b491",
"version" : "2.2.2"
}
},
{
"identity" : "cwlcatchexception",
"kind" : "remoteSourceControl",
"location" : "https://github.com/mattgallagher/CwlCatchException.git",
"state" : {
"revision" : "35f9e770f54ce62dd8526470f14c6e137cef3eea",
"version" : "2.1.1"
}
},
{
"identity" : "cwlpreconditiontesting",
"kind" : "remoteSourceControl",
"location" : "https://github.com/mattgallagher/CwlPreconditionTesting.git",
"state" : {
"revision" : "c21f7bab5ca8eee0a9998bbd17ca1d0eb45d4688",
"version" : "2.1.0"
}
},
{
"identity" : "keychainaccess",
"kind" : "remoteSourceControl",
"location" : "https://github.com/kishikawakatsumi/KeychainAccess",
"state" : {
"revision" : "84e546727d66f1adc5439debad16270d0fdd04e7",
"version" : "4.2.2"
}
},
{
"identity" : "nimble",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Quick/Nimble",
"state" : {
"revision" : "c93f16c25af5770f0d3e6af27c9634640946b068",
"version" : "9.2.1"
}
},
{
"identity" : "quick",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Quick/Quick",
"state" : {
"revision" : "bd86ca0141e3cfb333546de5a11ede63f0c4a0e6",
"version" : "4.0.0"
}
},
{
"identity" : "twilio-live-player-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/twilio/twilio-live-player-ios",
"state" : {
"revision" : "97dff98041229cfe90c9d2e5b930c836279a9a48",
"version" : "1.1.0"
}
},
{
"identity" : "twilio-sync-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/twilio/twilio-sync-ios",
"state" : {
"revision" : "dd300a5841544afc145feec90800ced480b7cfd2",
"version" : "1.1.0"
}
},
{
"identity" : "twilio-video-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/twilio/twilio-video-ios",
"state" : {
"revision" : "e028f87d5425316c39723c7bc2508f5349e36482",
"version" : "4.6.3"
}
}
],
"version" : 2
}
Loading

0 comments on commit 601675f

Please sign in to comment.