Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
elixxir
xx messenger iOS
Commits
f3d76668
Commit
f3d76668
authored
Jul 05, 2022
by
Ahmed Shehata
Browse files
Merge branch 'development' into 'master'
v1.1.2b166 See merge request
!40
parents
8afb182c
d72d804a
Changes
109
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
f3d76668
.build
.DS_Store
*.xcuserstate
xcuserdata/
...
...
App/client-ios.xcodeproj/project.pbxproj
View file @
f3d76668
...
...
@@ -448,7 +448,7 @@
CODE_SIGN_ENTITLEMENTS
=
"client-ios/Resources/client-ios.entitlements"
;
CODE_SIGN_IDENTITY
=
"Apple Development"
;
CODE_SIGN_STYLE
=
Automatic
;
CURRENT_PROJECT_VERSION
=
1
29
;
CURRENT_PROJECT_VERSION
=
1
67
;
DEBUG_INFORMATION_FORMAT
=
"dwarf-with-dsym"
;
DEVELOPMENT_TEAM
=
S6JDM2WW29
;
ENABLE_BITCODE
=
NO
;
...
...
@@ -463,7 +463,7 @@
"$(inherited)"
,
"@executable_path/Frameworks"
,
);
MARKETING_VERSION
=
1.1.
1
;
MARKETING_VERSION
=
1.1.
2
;
OTHER_SWIFT_FLAGS
=
"$(inherited)"
;
PRODUCT_BUNDLE_IDENTIFIER
=
xx.messenger.mock
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
...
...
@@ -487,7 +487,7 @@
CODE_SIGN_ENTITLEMENTS
=
"client-ios/Resources/client-ios.entitlements"
;
CODE_SIGN_IDENTITY
=
"Apple Development"
;
CODE_SIGN_STYLE
=
Automatic
;
CURRENT_PROJECT_VERSION
=
1
29
;
CURRENT_PROJECT_VERSION
=
1
67
;
DEBUG_INFORMATION_FORMAT
=
"dwarf-with-dsym"
;
DEVELOPMENT_TEAM
=
S6JDM2WW29
;
ENABLE_BITCODE
=
NO
;
...
...
@@ -503,7 +503,7 @@
"$(inherited)"
,
"@executable_path/Frameworks"
,
);
MARKETING_VERSION
=
1.1.
1
;
MARKETING_VERSION
=
1.1.
2
;
OTHER_SWIFT_FLAGS
=
""
;
PRODUCT_BUNDLE_IDENTIFIER
=
xx.messenger
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
...
...
@@ -522,7 +522,7 @@
CODE_SIGN_ENTITLEMENTS
=
NotificationExtension/NotificationExtension.entitlements
;
CODE_SIGN_IDENTITY
=
"Apple Development"
;
CODE_SIGN_STYLE
=
Automatic
;
CURRENT_PROJECT_VERSION
=
1
29
;
CURRENT_PROJECT_VERSION
=
1
67
;
DEVELOPMENT_TEAM
=
S6JDM2WW29
;
ENABLE_BITCODE
=
NO
;
FRAMEWORK_SEARCH_PATHS
=
(
...
...
@@ -536,7 +536,7 @@
"@executable_path/Frameworks"
,
"@executable_path/../../Frameworks"
,
);
MARKETING_VERSION
=
1.1.
1
;
MARKETING_VERSION
=
1.1.
3
;
PRODUCT_BUNDLE_IDENTIFIER
=
xx.messenger.mock.notifications
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PROVISIONING_PROFILE_SPECIFIER
=
""
;
...
...
@@ -553,7 +553,7 @@
CODE_SIGN_ENTITLEMENTS
=
NotificationExtension/NotificationExtension.entitlements
;
CODE_SIGN_IDENTITY
=
"Apple Development"
;
CODE_SIGN_STYLE
=
Automatic
;
CURRENT_PROJECT_VERSION
=
1
29
;
CURRENT_PROJECT_VERSION
=
1
67
;
DEVELOPMENT_TEAM
=
S6JDM2WW29
;
ENABLE_BITCODE
=
NO
;
FRAMEWORK_SEARCH_PATHS
=
(
...
...
@@ -567,7 +567,7 @@
"@executable_path/Frameworks"
,
"@executable_path/../../Frameworks"
,
);
MARKETING_VERSION
=
1.1.
1
;
MARKETING_VERSION
=
1.1.
3
;
PRODUCT_BUNDLE_IDENTIFIER
=
xx.messenger.notifications
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PROVISIONING_PROFILE_SPECIFIER
=
""
;
...
...
Package.swift
View file @
f3d76668
// swift-tools-version:5.
3
// swift-tools-version:5.
6
import
PackageDescription
let
package
=
Package
(
...
...
@@ -14,7 +14,6 @@ let package = Package(
.
library
(
name
:
"Shared"
,
targets
:
[
"Shared"
]),
.
library
(
name
:
"Models"
,
targets
:
[
"Models"
]),
.
library
(
name
:
"XXLogger"
,
targets
:
[
"XXLogger"
]),
.
library
(
name
:
"Database"
,
targets
:
[
"Database"
]),
.
library
(
name
:
"Defaults"
,
targets
:
[
"Defaults"
]),
.
library
(
name
:
"Bindings"
,
targets
:
[
"Bindings"
]),
.
library
(
name
:
"Keychain"
,
targets
:
[
"Keychain"
]),
...
...
@@ -52,96 +51,24 @@ let package = Package(
.
library
(
name
:
"DependencyInjection"
,
targets
:
[
"DependencyInjection"
])
],
dependencies
:
[
.
package
(
name
:
"Quick"
,
url
:
"https://github.com/Quick/Quick"
,
from
:
"3.0.0"
),
.
package
(
name
:
"DifferenceKit"
,
url
:
"https://github.com/ra1028/DifferenceKit"
,
from
:
"1.2.0"
),
.
package
(
name
:
"Nimble"
,
url
:
"https://github.com/Quick/Nimble"
,
from
:
"9.0.0"
),
.
package
(
name
:
"FilesProvider"
,
url
:
"https://github.com/amosavian/FileProvider.git"
,
from
:
"0.26.0"
),
.
package
(
name
:
"GRDB"
,
url
:
"https://github.com/groue/GRDB.swift"
,
from
:
"5.3.0"
),
.
package
(
name
:
"GoogleSignIn"
,
url
:
"https://github.com/google/GoogleSignIn-iOS"
,
from
:
"6.1.0"
),
.
package
(
name
:
"GoogleAPIClientForREST"
,
url
:
"https://github.com/google/google-api-objectivec-client-for-rest"
,
from
:
"1.6.0"
),
.
package
(
name
:
"SnapKit"
,
url
:
"https://github.com/SnapKit/SnapKit"
,
from
:
"5.0.1"
),
.
package
(
name
:
"Firebase"
,
url
:
"https://github.com/firebase/firebase-ios-sdk.git"
,
.
upToNextMajor
(
from
:
"8.10.0"
)
),
.
package
(
name
:
"SwiftProtobuf"
,
url
:
"https://github.com/apple/swift-protobuf"
,
from
:
"1.14.0"
),
.
package
(
name
:
"SwiftyDropbox"
,
url
:
"https://github.com/dropbox/SwiftyDropbox.git"
,
from
:
"8.2.1"
),
.
package
(
name
:
"KeychainAccess"
,
url
:
"https://github.com/kishikawakatsumi/KeychainAccess"
,
from
:
"4.2.1"
),
.
package
(
name
:
"Retry"
,
url
:
"https://github.com/icanzilb/Retry.git"
,
from
:
"0.6.3"
),
.
package
(
name
:
"ChatLayout"
,
url
:
"https://github.com/ekazaev/ChatLayout"
,
from
:
"1.1.14"
),
.
package
(
name
:
"SwiftyBeaver"
,
url
:
"https://github.com/SwiftyBeaver/SwiftyBeaver.git"
,
from
:
"1.9.5"
),
.
package
(
name
:
"swift-composable-architecture"
,
url
:
"https://github.com/pointfreeco/swift-composable-architecture.git"
,
.
upToNextMajor
(
from
:
"0.32.0"
)
),
.
package
(
name
:
"ScrollViewController"
,
url
:
"https://github.com/darrarski/ScrollViewController"
,
from
:
"1.2.0"
),
.
package
(
name
:
"combine-schedulers"
,
url
:
"https://github.com/pointfreeco/combine-schedulers"
,
from
:
"0.5.0"
)
.
package
(
url
:
"https://github.com/Quick/Quick"
,
from
:
"3.0.0"
),
.
package
(
url
:
"https://github.com/Quick/Nimble"
,
from
:
"9.0.0"
),
.
package
(
url
:
"https://github.com/SnapKit/SnapKit"
,
from
:
"5.0.1"
),
.
package
(
url
:
"https://github.com/icanzilb/Retry.git"
,
from
:
"0.6.3"
),
.
package
(
url
:
"https://github.com/ekazaev/ChatLayout"
,
from
:
"1.1.14"
),
.
package
(
url
:
"https://github.com/ra1028/DifferenceKit"
,
from
:
"1.2.0"
),
.
package
(
url
:
"https://github.com/apple/swift-protobuf"
,
from
:
"1.14.0"
),
.
package
(
url
:
"https://github.com/google/GoogleSignIn-iOS"
,
from
:
"6.1.0"
),
.
package
(
url
:
"https://github.com/dropbox/SwiftyDropbox.git"
,
from
:
"8.2.1"
),
.
package
(
url
:
"https://github.com/amosavian/FileProvider.git"
,
from
:
"0.26.0"
),
.
package
(
url
:
"https://github.com/SwiftyBeaver/SwiftyBeaver.git"
,
from
:
"1.9.5"
),
.
package
(
url
:
"https://github.com/darrarski/ScrollViewController"
,
from
:
"1.2.0"
),
.
package
(
url
:
"https://github.com/pointfreeco/combine-schedulers"
,
from
:
"0.5.0"
),
.
package
(
url
:
"https://github.com/kishikawakatsumi/KeychainAccess"
,
from
:
"4.2.1"
),
.
package
(
url
:
"https://github.com/google/google-api-objectivec-client-for-rest"
,
from
:
"1.6.0"
),
.
package
(
url
:
"https://git.xx.network/elixxir/client-ios-db.git"
,
.
upToNextMajor
(
from
:
"1.0.5"
)),
.
package
(
url
:
"https://github.com/firebase/firebase-ios-sdk.git"
,
.
upToNextMajor
(
from
:
"8.10.0"
)),
.
package
(
url
:
"https://github.com/pointfreeco/swift-composable-architecture.git"
,
.
upToNextMajor
(
from
:
"0.32.0"
))
],
targets
:
[
.
target
(
...
...
@@ -197,7 +124,6 @@ let package = Package(
name
:
"PushFeature"
,
dependencies
:
[
"Models"
,
"Database"
,
"Defaults"
,
"Integration"
,
"DependencyInjection"
...
...
@@ -246,7 +172,7 @@ let package = Package(
),
.
product
(
name
:
"SwiftProtobuf"
,
package
:
"
S
wift
P
rotobuf"
package
:
"
s
wift
-p
rotobuf"
)
]
),
...
...
@@ -277,7 +203,7 @@ let package = Package(
"CrashReporting"
,
.
product
(
name
:
"FirebaseCrashlytics"
,
package
:
"
F
irebase"
package
:
"
f
irebase
-ios-sdk
"
)
]
),
...
...
@@ -289,11 +215,11 @@ let package = Package(
dependencies
:
[
.
product
(
name
:
"GoogleSignIn"
,
package
:
"GoogleSignIn"
package
:
"GoogleSignIn
-iOS
"
),
.
product
(
name
:
"GoogleAPIClientForREST_Drive"
,
package
:
"
G
oogle
APIClientForREST
"
package
:
"
g
oogle
-api-objectivec-client-for-rest
"
)
],
resources
:
[
.
process
(
"Resources"
)]
...
...
@@ -306,7 +232,7 @@ let package = Package(
dependencies
:
[
.
product
(
name
:
"FilesProvider"
,
package
:
"File
s
Provider"
package
:
"FileProvider"
)
]
),
...
...
@@ -386,40 +312,22 @@ let package = Package(
]
),
// MARK: - Database
.
target
(
name
:
"Database"
,
dependencies
:
[
"Models"
,
"XXLogger"
,
.
product
(
name
:
"GRDB"
,
package
:
"GRDB"
),
.
product
(
name
:
"DifferenceKit"
,
package
:
"DifferenceKit"
)
]
),
// MARK: - Shared
.
target
(
name
:
"Shared"
,
dependencies
:
[
.
product
(
name
:
"
Difference
Kit"
,
package
:
"
Difference
Kit"
name
:
"
Snap
Kit"
,
package
:
"
Snap
Kit"
),
.
product
(
name
:
"ChatLayout"
,
package
:
"ChatLayout"
),
.
product
(
name
:
"
Snap
Kit"
,
package
:
"
Snap
Kit"
name
:
"
Difference
Kit"
,
package
:
"
Difference
Kit"
)
],
exclude
:
[
"swiftgen.yml"
],
...
...
@@ -431,10 +339,10 @@ let package = Package(
.
target
(
name
:
"Integration"
,
dependencies
:
[
"XXLogger"
,
"Shared"
,
"Database"
,
"Bindings"
,
"XXLogger"
,
"Keychain"
,
"ToastFeature"
,
"BackupFeature"
,
"CrashReporting"
,
...
...
@@ -443,6 +351,14 @@ let package = Package(
.
product
(
name
:
"Retry"
,
package
:
"Retry"
),
.
product
(
name
:
"XXDatabase"
,
package
:
"client-ios-db"
),
.
product
(
name
:
"XXLegacyDatabaseMigrator"
,
package
:
"client-ios-db"
)
],
resources
:
[
.
process
(
"Resources"
)]
...
...
@@ -500,13 +416,13 @@ let package = Package(
"InputField"
,
"ChatFeature"
,
"Presentation"
,
.
product
(
name
:
"ScrollViewController"
,
package
:
"ScrollViewController"
),
.
product
(
name
:
"CombineSchedulers"
,
package
:
"combine-schedulers"
),
.
product
(
name
:
"ScrollViewController"
,
package
:
"ScrollViewController"
)
]
),
...
...
@@ -528,14 +444,14 @@ let package = Package(
"DrawerFeature"
,
"ChatInputFeature"
,
"DependencyInjection"
,
.
product
(
name
:
"DifferenceKit"
,
package
:
"DifferenceKit"
),
.
product
(
name
:
"ChatLayout"
,
package
:
"ChatLayout"
),
.
product
(
name
:
"DifferenceKit"
,
package
:
"DifferenceKit"
),
.
product
(
name
:
"ScrollViewController"
,
package
:
"ScrollViewController"
...
...
@@ -612,13 +528,13 @@ let package = Package(
"Presentation"
,
"DrawerFeature"
,
"DependencyInjection"
,
.
product
(
name
:
"ScrollViewController"
,
package
:
"ScrollViewController"
),
.
product
(
name
:
"CombineSchedulers"
,
package
:
"combine-schedulers"
),
.
product
(
name
:
"ScrollViewController"
,
package
:
"ScrollViewController"
)
]
),
...
...
@@ -662,13 +578,13 @@ let package = Package(
"DrawerFeature"
,
"VersionChecking"
,
"DependencyInjection"
,
.
product
(
name
:
"ScrollViewController"
,
package
:
"ScrollViewController"
),
.
product
(
name
:
"CombineSchedulers"
,
package
:
"combine-schedulers"
),
.
product
(
name
:
"ScrollViewController"
,
package
:
"ScrollViewController"
)
]
),
...
...
@@ -697,9 +613,10 @@ let package = Package(
"Models"
,
"InputField"
,
"Presentation"
,
"GoogleDriveFeature"
,
"iCloudFeature"
,
"DrawerFeature"
,
"DropboxFeature"
,
"GoogleDriveFeature"
,
"DependencyInjection"
]
),
...
...
@@ -760,13 +677,13 @@ let package = Package(
"Presentation"
,
"DrawerFeature"
,
"DependencyInjection"
,
.
product
(
name
:
"ScrollViewController"
,
package
:
"ScrollViewController"
),
.
product
(
name
:
"CombineSchedulers"
,
package
:
"combine-schedulers"
),
.
product
(
name
:
"ScrollViewController"
,
package
:
"ScrollViewController"
)
]
),
...
...
Sources/App/AppDelegate.swift
View file @
f3d76668
import
UIKit
import
BackgroundTasks
import
XXModels
import
Theme
import
XXLogger
import
Defaults
...
...
@@ -91,7 +92,10 @@ public class AppDelegate: UIResponder, UIApplicationDelegate {
guard
UIApplication
.
shared
.
backgroundTimeRemaining
>
9
else
{
if
!
self
.
forceFailedPendingMessages
{
self
.
forceFailedPendingMessages
=
true
session
.
forceFailMessages
()
let
query
=
Message
.
Query
(
status
:
[
.
sending
])
let
assignment
=
Message
.
Assignments
(
status
:
.
sendingFailed
)
_
=
try
?
session
.
dbManager
.
bulkUpdateMessages
(
query
,
assignment
)
}
return
...
...
Sources/App/DependencyRegistrator.swift
View file @
f3d76668
...
...
@@ -259,7 +259,7 @@ extension PushRouter {
}
case
.
contactChat
(
id
:
let
id
):
if
let
session
=
try
?
DependencyInjection
.
Container
.
shared
.
resolve
()
as
SessionType
,
let
contact
=
session
.
getContactWith
(
userI
d
:
id
)
{
let
contact
=
try
?
session
.
dbManager
.
fetchContacts
(
.
init
(
i
d
:
[
id
]))
.
first
{
navigationController
.
setViewControllers
([
ChatListController
(),
SingleChatController
(
contact
)
...
...
@@ -267,7 +267,7 @@ extension PushRouter {
}
case
.
groupChat
(
id
:
let
id
):
if
let
session
=
try
?
DependencyInjection
.
Container
.
shared
.
resolve
()
as
SessionType
,
let
info
=
session
.
getGroupChatInfoW
it
h
(
groupId
:
id
)
{
let
info
=
try
?
session
.
dbManager
.
fetchGroupInfos
(
.
in
it
(
groupId
:
id
)
)
.
first
{
navigationController
.
setViewControllers
([
ChatListController
(),
GroupChatController
(
info
)
...
...
Sources/ChatFeature/Controllers/GroupChatController.swift
View file @
f3d76668
...
...
@@ -3,6 +3,7 @@ import Theme
import
Models
import
Shared
import
Combine
import
XXModels
import
Voxophone
import
ChatLayout
import
DrawerFeature
...
...
@@ -32,13 +33,13 @@ public final class GroupChatController: UIViewController {
private
let
layoutDelegate
=
LayoutDelegate
()
private
var
cancellables
=
Set
<
AnyCancellable
>
()
private
var
drawerCancellables
=
Set
<
AnyCancellable
>
()
private
var
sections
=
[
ArraySection
<
ChatSection
,
GroupChatItem
>
]()
private
var
sections
=
[
ArraySection
<
ChatSection
,
Message
>
]()
private
var
currentInterfaceActions
=
SetActor
<
Set
<
InterfaceActions
>
,
ReactionTypes
>
()
public
override
var
canBecomeFirstResponder
:
Bool
{
true
}
public
override
var
inputAccessoryView
:
UIView
?
{
inputComponent
}
public
init
(
_
info
:
Group
Chat
Info
)
{
public
init
(
_
info
:
GroupInfo
)
{
let
viewModel
=
GroupChatViewModel
(
info
)
self
.
viewModel
=
viewModel
self
.
members
=
.
init
(
with
:
info
.
members
)
...
...
@@ -59,7 +60,14 @@ public final class GroupChatController: UIViewController {
super
.
init
(
nibName
:
nil
,
bundle
:
nil
)
header
.
setup
(
title
:
info
.
group
.
name
,
memberList
:
info
.
members
.
map
{
(
$0
.
username
,
$0
.
photo
)
})
let
memberList
=
info
.
members
.
map
{
Member
(
title
:
(
$0
.
nickname
??
$0
.
username
)
??
"Fetching username..."
,
photo
:
$0
.
photo
)
}
header
.
setup
(
title
:
info
.
group
.
name
,
memberList
:
memberList
)
}
public
required
init
?(
coder
:
NSCoder
)
{
nil
}
...
...
@@ -154,7 +162,9 @@ public final class GroupChatController: UIViewController {
viewModel
.
replyPublisher
.
receive
(
on
:
DispatchQueue
.
main
)
.
sink
{
[
unowned
self
]
in
inputComponent
.
setupReply
(
message
:
$0
.
text
,
sender
:
$0
.
sender
)
}
.
sink
{
[
unowned
self
]
senderTitle
,
messageText
in
inputComponent
.
setupReply
(
message
:
messageText
,
sender
:
senderTitle
)
}
.
store
(
in
:
&
cancellables
)
}
...
...
@@ -317,9 +327,7 @@ extension GroupChatController: UICollectionViewDataSource {
let
item
=
sections
[
indexPath
.
section
]
.
elements
[
indexPath
.
item
]
let
canReply
:
()
->
Bool
=
{
item
.
status
==
.
sent
||
item
.
status
==
.
received
||
item
.
status
==
.
read
(
item
.
status
==
.
sent
||
item
.
status
==
.
received
)
&&
item
.
networkId
!=
nil
}
let
performReply
:
()
->
Void
=
{
[
weak
self
]
in
...
...
@@ -327,21 +335,18 @@ extension GroupChatController: UICollectionViewDataSource {
}
let
name
:
(
Data
)
->
String
=
viewModel
.
getName
(
from
:)
let
text
:
(
Data
)
->
String
=
viewModel
.
getText
(
from
:)
let
showRound
:
(
String
?)
->
Void
=
viewModel
.
showRoundFrom
(
_
:)
let
replyContent
:
(
Data
)
->
(
String
,
String
)
=
viewModel
.
getReplyContent
(
for
:)
if
item
.
status
==
.
received
{
if
item
.
payload
.
reply
!=
nil
{
if
let
replyMessageId
=
item
.
replyMessageId
{
let
cell
:
IncomingGroupReplyCell
=
collectionView
.
dequeueReusableCell
(
forIndexPath
:
indexPath
)
Bubbler
.
buildReplyGroup
(
bubble
:
cell
.
leftView
,
with
:
item
,
reply
:
.
init
(
text
:
text
(
item
.
payload
.
reply
!.
messageId
),
sender
:
name
(
item
.
payload
.
reply
!.
senderId
)
),
sender
:
name
(
item
.
sender
)
reply
:
replyContent
(
replyMessageId
),
sender
:
name
(
item
.
senderId
)
)
cell
.
canReply
=
canReply
()
...
...
@@ -351,25 +356,27 @@ extension GroupChatController: UICollectionViewDataSource {
return
cell
}
else
{
let
cell
:
IncomingGroupTextCell
=
collectionView
.
dequeueReusableCell
(
forIndexPath
:
indexPath
)
Bubbler
.
buildGroup
(
bubble
:
cell
.
leftView
,
with
:
item
,
with
:
name
(
item
.
sender
))
Bubbler
.
buildGroup
(
bubble
:
cell
.
leftView
,
with
:
item
,
with
:
name
(
item
.
senderId
)
)
cell
.
canReply
=
canReply
()
cell
.
performReply
=
performReply
cell
.
leftView
.
didTapShowRound
=
{
showRound
(
item
.
roundURL
)
}
return
cell
}
}
else
if
item
.
status
==
.
f
ailed
{
if
item
.
payload
.
reply
!=
nil
{
}
else
if
item
.
status
==
.
sendingF
ailed
{
if
let
replyMessageId
=
item
.
replyMessageId
{
let
cell
:
OutgoingFailedGroupReplyCell
=
collectionView
.
dequeueReusableCell
(
forIndexPath
:
indexPath
)
Bubbler
.
buildReplyGroup
(
bubble
:
cell
.
rightView
,
with
:
item
,
reply
:
.
init
(
text
:
text
(
item
.
payload
.
reply
!.
messageId
),
sender
:
name
(
item
.
payload
.
reply
!.
senderId
)
),
sender
:
name
(
item
.
sender
)
reply
:
replyContent
(
replyMessageId
),
sender
:
name
(
item
.
senderId
)
)
cell
.
canReply
=
canReply
()
...
...
@@ -379,24 +386,26 @@ extension GroupChatController: UICollectionViewDataSource {
}
else
{
let
cell
:
OutgoingFailedGroupTextCell
=
collectionView
.
dequeueReusableCell
(
forIndexPath
:
indexPath
)
Bubbler
.
buildGroup
(
bubble
:
cell
.
rightView
,
with
:
item
,
with
:
name
(
item
.
sender
))
Bubbler
.
buildGroup
(
bubble
:
cell
.
rightView
,
with
:
item
,
with
:
name
(
item
.
senderId
)
)
cell
.
canReply
=
canReply
()
cell
.
performReply
=
performReply
return
cell
}
}
else
{
if
item
.
payload
.
reply
!=
nil
{
if
let
replyMessageId
=
item
.
replyMessageId
{
let
cell
:
OutgoingGroupReplyCell
=
collectionView
.
dequeueReusableCell
(
forIndexPath
:
indexPath
)
Bubbler
.
buildReplyGroup
(
bubble
:
cell
.
rightView
,
with
:
item
,
reply
:
.
init
(
text
:
text
(
item
.
payload
.
reply
!.
messageId
),
sender
:
name
(
item
.
payload
.
reply
!.
senderId
)
),
sender
:
name
(
item
.
sender
)
reply
:
replyContent
(
replyMessageId
),
sender
:
name
(
item
.
senderId
)
)
cell
.
canReply
=
canReply
()
...
...
@@ -407,7 +416,12 @@ extension GroupChatController: UICollectionViewDataSource {
}
else
{
let
cell
:
OutgoingGroupTextCell
=
collectionView
.
dequeueReusableCell
(
forIndexPath
:
indexPath
)