make chat model not nullable (#328)

* make chat model not nullable

* parse datetimes

* smart constructors for TerminalItem
This commit is contained in:
Evgeny Poberezkin
2022-02-17 21:52:37 +00:00
committed by GitHub
parent 290a88fd90
commit 52f758c6e1
4 changed files with 35 additions and 39 deletions

View File

@@ -67,6 +67,7 @@ dependencies {
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.activity:activity-compose:1.3.1'
implementation 'org.jetbrains.kotlinx:kotlinx-datetime:0.3.2'
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'

View File

@@ -30,10 +30,12 @@ external fun chatRecvMsg(ctrl: ChatCtrl) : String
class SimplexApp: Application() {
private lateinit var controller: ChatController
lateinit var chatModel: ChatModel
override fun onCreate() {
super.onCreate()
controller = ChatController(chatInit(applicationContext.filesDir.toString()))
chatModel = controller.chatModel
GlobalScope.launch {
withContext(Dispatchers.Main) {
var user = controller.apiGetActiveUser()
@@ -42,13 +44,6 @@ class SimplexApp: Application() {
}
}
val chatModel by lazy {
val m = ChatModel(controller)
controller.setModel(m)
controller.startReceiver()
m
}
companion object {
lateinit var weakActivity: WeakReference<MainActivity>
init {

View File

@@ -1,8 +1,8 @@
package chat.simplex.app.model
import androidx.compose.runtime.*
import kotlinx.datetime.*
import kotlinx.serialization.*
import java.util.*
class ChatModel(val controller: ChatController) {
var currentUser = mutableStateOf<User?>(null)
@@ -155,8 +155,7 @@ class Contact(
val profile: Profile,
val activeConn: Connection,
val viaGroup: Long? = null,
// no serializer for type Date?
// val createdAt: Date
val createdAt: Instant
): SomeChat, NamedChat {
override val chatType get() = ChatType.Direct
override val id get() = "@$contactId"
@@ -170,8 +169,8 @@ class Contact(
contactId = 1,
localDisplayName = "alice",
profile = Profile.sampleData,
activeConn = Connection.sampleData
// createdAt = Date()
activeConn = Connection.sampleData,
createdAt = Clock.System.now()
)
}
}
@@ -201,7 +200,7 @@ class GroupInfo (
val groupId: Long,
override val localDisplayName: String,
val groupProfile: GroupProfile,
// var createdAt: Date
val createdAt: Instant
): SomeChat, NamedChat {
override val chatType get() = ChatType.Group
override val id get() = "#$groupId"
@@ -215,7 +214,7 @@ class GroupInfo (
groupId = 1,
localDisplayName = "team",
groupProfile = GroupProfile.sampleData,
// createdAt: Date()
createdAt = Clock.System.now()
)
}
}
@@ -261,8 +260,8 @@ class GroupMember (
class UserContactRequest (
val contactRequestId: Long,
override val localDisplayName: String,
val profile: Profile
// val createdAt: Date
val profile: Profile,
val createdAt: Instant
): SomeChat, NamedChat {
override val chatType get() = ChatType.ContactRequest
override val id get() = "<@$contactRequestId"
@@ -276,7 +275,7 @@ class UserContactRequest (
contactRequestId = 1,
localDisplayName = "alice",
profile = Profile.sampleData,
// createdAt: Date()
createdAt = Clock.System.now()
)
}
}
@@ -298,7 +297,7 @@ class ChatItem (
val isRcvNew: Boolean get() = meta.itemStatus is CIStatus.RcvNew
companion object {
fun getSampleData(id: Long, dir: CIDirection, ts: Date, text: String,status: CIStatus = CIStatus.SndNew()) =
fun getSampleData(id: Long, dir: CIDirection, ts: Instant, text: String,status: CIStatus = CIStatus.SndNew()) =
ChatItem(
chatDir = dir,
meta = CIMeta.getSample(id, ts, text, status),
@@ -335,27 +334,27 @@ sealed class CIDirection {
@Serializable
class CIMeta (
val itemId: Long,
// val itemTs: Date,
val itemTs: Instant,
val itemText: String,
val itemStatus: CIStatus,
// val createdAt: Date
val createdAt: Instant
) {
// val timestampText: String get() = getTimestampText(itemTs)
companion object {
fun getSample(id: Long, ts: Date, text: String, status: CIStatus = CIStatus.SndNew()): CIMeta =
fun getSample(id: Long, ts: Instant, text: String, status: CIStatus = CIStatus.SndNew()): CIMeta =
CIMeta(
itemId = id,
// itemTs = ts,
itemTs = ts,
itemText = text,
itemStatus = status,
// createdAt = ts
createdAt = ts
)
}
}
// TODO
fun getTimestampText(d: Date): String = ""
fun getTimestampText(d: Instant): String = ""
@Serializable
sealed class CIStatus {

View File

@@ -18,20 +18,20 @@ import kotlin.concurrent.thread
typealias ChatCtrl = Long
open class ChatController(val ctrl: ChatCtrl) {
private var chatModel: ChatModel? = null
private val callbacks = mutableMapOf<String, (Error?, CR?) -> Unit>()
var chatModel: ChatModel
fun setModel(m: ChatModel) {
chatModel = m
init {
chatModel = ChatModel(this)
}
suspend fun startChat(u: User) {
chatModel!!.currentUser = mutableStateOf(u)
chatModel.currentUser = mutableStateOf(u)
Log.d("SIMPLEX (user)", u.toString())
apiStartChat()
try {
apiStartChat()
chatModel.chats.addAll(apiGetChats())
startReceiver()
Log.d("SIMPLEX", "started chat")
chatModel!!.chats = apiGetChats().toMutableStateList()
} catch(e: Error) {
Log.d("SIMPLEX", "failed starting chat $e")
throw e
@@ -45,11 +45,7 @@ open class ChatController(val ctrl: ChatCtrl) {
val json = chatRecvMsg(ctrl)
Log.d("SIMPLEX chatRecvMsg: ", json)
val r = APIResponse.decodeStr(json)
if (r.corr != null) {
val cb = callbacks[r.corr]
if (cb != null) cb(null, r.resp)
}
chatModel?.terminalItems?.add(TerminalItem.Resp(System.currentTimeMillis(), r.resp))
chatModel.terminalItems.add(TerminalItem.resp(r.resp))
}
}
}
@@ -57,13 +53,15 @@ open class ChatController(val ctrl: ChatCtrl) {
suspend fun sendCmd(cmd: CC): CR {
return withContext(Dispatchers.IO) {
val c = cmd.cmdString
chatModel?.terminalItems?.add(TerminalItem.Cmd(System.currentTimeMillis(), cmd))
chatModel.terminalItems.add(TerminalItem.cmd(cmd))
val json = chatSendCmd(ctrl, c)
Log.d("SIMPLEX", "sendCmd: ${cmd.cmdType}")
Log.d("SIMPLEX", "sendCmd response json $json")
val r = APIResponse.decodeStr(json)
Log.d("SIMPLEX", "sendCmd response type ${r.resp.responseType}")
chatModel?.terminalItems?.add(TerminalItem.Resp(System.currentTimeMillis(), r.resp))
if (r.resp is CR.Response || r.resp is CR.Invalid) {
Log.d("SIMPLEX", "sendCmd response json $json")
}
chatModel.terminalItems.add(TerminalItem.resp(r.resp))
r.resp
}
}
@@ -276,5 +274,8 @@ abstract class TerminalItem {
TerminalItem.Cmd(0, CC.ShowActiveUser()),
TerminalItem.Resp(1, CR.ActiveUser(User.sampleData))
)
fun cmd(c: CC) = TerminalItem.Cmd(System.currentTimeMillis(), c)
fun resp(r: CR) = TerminalItem.Resp(System.currentTimeMillis(), r)
}
}