Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
E
Elixxir dApps SDK Swift
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
mobile
iOS
Elixxir dApps SDK Swift
Merge requests
!87
Messenger example - chat
Code
Review changes
Check out branch
Download
Patches
Plain diff
Expand sidebar
Merged
Messenger example - chat
feature/messenger-example-chat
into
development
Overview
0
Commits
17
Pipelines
0
Changes
2
Merged
Messenger example - chat
Dariusz Rybicki
requested to merge
feature/messenger-example-chat
into
development
Sep 13, 2022
Overview
0
Commits
17
Pipelines
0
Changes
2
0
0
Merge request reports
Viewing commit
dd53d9f1
Prev
Next
Show latest version
2 files
+
52
−
2
Side-by-side
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
Files
2
dd53d9f1
Handle send errors in ChatFeature
· dd53d9f1
Dariusz Rybicki
authored
Sep 14, 2022
Examples/xx-messenger/Sources/ChatFeature/ChatFeature.swift
0 → 100644
+
185
−
0
View file @ 4379c8ae
Edit in single-file editor
Open in Web IDE
import
AppCore
import
Combine
import
ComposableArchitecture
import
Foundation
import
XCTestDynamicOverlay
import
XXClient
import
XXMessengerClient
import
XXModels
public
struct
ChatState
:
Equatable
,
Identifiable
{
public
enum
ID
:
Equatable
,
Hashable
{
case
contact
(
Data
)
}
public
struct
Message
:
Equatable
,
Identifiable
{
public
init
(
id
:
Int64
,
date
:
Date
,
senderId
:
Data
,
text
:
String
,
status
:
XXModels
.
Message
.
Status
)
{
self
.
id
=
id
self
.
date
=
date
self
.
senderId
=
senderId
self
.
text
=
text
self
.
status
=
status
}
public
var
id
:
Int64
public
var
date
:
Date
public
var
senderId
:
Data
public
var
text
:
String
public
var
status
:
XXModels
.
Message
.
Status
}
public
init
(
id
:
ID
,
myContactId
:
Data
?
=
nil
,
messages
:
IdentifiedArrayOf
<
Message
>
=
[],
failure
:
String
?
=
nil
,
sendFailure
:
String
?
=
nil
,
text
:
String
=
""
)
{
self
.
id
=
id
self
.
myContactId
=
myContactId
self
.
messages
=
messages
self
.
failure
=
failure
self
.
sendFailure
=
sendFailure
self
.
text
=
text
}
public
var
id
:
ID
public
var
myContactId
:
Data
?
public
var
messages
:
IdentifiedArrayOf
<
Message
>
public
var
failure
:
String
?
public
var
sendFailure
:
String
?
@BindableState
public
var
text
:
String
}
public
enum
ChatAction
:
Equatable
,
BindableAction
{
case
start
case
didFetchMessages
(
IdentifiedArrayOf
<
ChatState
.
Message
>
)
case
sendTapped
case
sendFailed
(
String
)
case
dismissSendFailureTapped
case
binding
(
BindingAction
<
ChatState
>
)
}
public
struct
ChatEnvironment
{
public
init
(
messenger
:
Messenger
,
db
:
DBManagerGetDB
,
sendMessage
:
SendMessage
,
mainQueue
:
AnySchedulerOf
<
DispatchQueue
>
,
bgQueue
:
AnySchedulerOf
<
DispatchQueue
>
)
{
self
.
messenger
=
messenger
self
.
db
=
db
self
.
sendMessage
=
sendMessage
self
.
mainQueue
=
mainQueue
self
.
bgQueue
=
bgQueue
}
public
var
messenger
:
Messenger
public
var
db
:
DBManagerGetDB
public
var
sendMessage
:
SendMessage
public
var
mainQueue
:
AnySchedulerOf
<
DispatchQueue
>
public
var
bgQueue
:
AnySchedulerOf
<
DispatchQueue
>
}
#if DEBUG
extension
ChatEnvironment
{
public
static
let
unimplemented
=
ChatEnvironment
(
messenger
:
.
unimplemented
,
db
:
.
unimplemented
,
sendMessage
:
.
unimplemented
,
mainQueue
:
.
unimplemented
,
bgQueue
:
.
unimplemented
)
}
#endif
public
let
chatReducer
=
Reducer
<
ChatState
,
ChatAction
,
ChatEnvironment
>
{
state
,
action
,
env
in
enum
FetchEffectId
{}
switch
action
{
case
.
start
:
state
.
failure
=
nil
do
{
let
myContactId
=
try
env
.
messenger
.
e2e
.
tryGet
()
.
getContact
()
.
getId
()
state
.
myContactId
=
myContactId
let
queryChat
:
XXModels
.
Message
.
Query
.
Chat
switch
state
.
id
{
case
.
contact
(
let
contactId
):
queryChat
=
.
direct
(
myContactId
,
contactId
)
}
let
query
=
XXModels
.
Message
.
Query
(
chat
:
queryChat
)
return
try
env
.
db
()
.
fetchMessagesPublisher
(
query
)
.
assertNoFailure
()
.
map
{
messages
in
messages
.
compactMap
{
message
in
guard
let
id
=
message
.
id
else
{
return
nil
}
return
ChatState
.
Message
(
id
:
id
,
date
:
message
.
date
,
senderId
:
message
.
senderId
,
text
:
message
.
text
,
status
:
message
.
status
)
}
}
.
map
{
IdentifiedArrayOf
<
ChatState
.
Message
>
(
uniqueElements
:
$0
)
}
.
map
(
ChatAction
.
didFetchMessages
)
.
subscribe
(
on
:
env
.
bgQueue
)
.
receive
(
on
:
env
.
mainQueue
)
.
eraseToEffect
()
.
cancellable
(
id
:
FetchEffectId
.
self
,
cancelInFlight
:
true
)
}
catch
{
state
.
failure
=
error
.
localizedDescription
return
.
none
}
case
.
didFetchMessages
(
let
messages
):
state
.
messages
=
messages
return
.
none
case
.
sendTapped
:
let
text
=
state
.
text
let
chatId
=
state
.
id
state
.
text
=
""
return
Effect
.
run
{
subscriber
in
switch
chatId
{
case
.
contact
(
let
recipientId
):
env
.
sendMessage
(
text
:
text
,
to
:
recipientId
,
onError
:
{
error
in
subscriber
.
send
(
.
sendFailed
(
error
.
localizedDescription
))
},
completion
:
{
subscriber
.
send
(
completion
:
.
finished
)
}
)
}
return
AnyCancellable
{}
}
.
subscribe
(
on
:
env
.
bgQueue
)
.
receive
(
on
:
env
.
mainQueue
)
.
eraseToEffect
()
case
.
sendFailed
(
let
failure
):
state
.
sendFailure
=
failure
return
.
none
case
.
dismissSendFailureTapped
:
state
.
sendFailure
=
nil
return
.
none
case
.
binding
(
_
):
return
.
none
}
}
.
binding
()
Loading