mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-09-16 17:03:29 +00:00
core: send badge ZK-proofs to XFTP servers, add file expiry time (#7430)
* core: send badge ZK-proofs to XFTP servers * update simplexmq, use keys and header from simplexmq * core: add file expiry time * refactor * remove posix module * rename migrations * bot api * update UI * import * show item from loaded information * ios: update core library * text * send entitlements in handshake * simplexmq * query plans * update simplexmq --------- Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
co-authored by
Evgeny @ SimpleX Chat
parent
f71b132536
commit
f99c474ca6
+5
-2
@@ -4252,8 +4252,11 @@ data class CIFile(
|
||||
val fileSize: Long,
|
||||
val fileSource: CryptoFile? = null,
|
||||
val fileStatus: CIFileStatus,
|
||||
val fileProtocol: FileProtocol
|
||||
val fileProtocol: FileProtocol,
|
||||
val fileExpires: Instant? = null
|
||||
) {
|
||||
val expired: Boolean = fileExpires != null && fileExpires < Clock.System.now()
|
||||
|
||||
val loaded: Boolean = when (fileStatus) {
|
||||
is CIFileStatus.SndStored -> true
|
||||
is CIFileStatus.SndTransfer -> true
|
||||
@@ -4303,7 +4306,7 @@ data class CIFile(
|
||||
is CIFileStatus.SndCancelled -> true
|
||||
is CIFileStatus.SndError -> true
|
||||
is CIFileStatus.SndWarning -> true
|
||||
is CIFileStatus.RcvInvitation -> false
|
||||
is CIFileStatus.RcvInvitation -> expired
|
||||
is CIFileStatus.RcvAccepted -> true
|
||||
is CIFileStatus.RcvTransfer -> true
|
||||
is CIFileStatus.RcvAborted -> true
|
||||
|
||||
+2
-2
@@ -1161,9 +1161,9 @@ object ChatController {
|
||||
return null
|
||||
}
|
||||
|
||||
suspend fun apiGetChatItemInfo(rh: Long?, type: ChatType, id: Long, scope: GroupChatScope?, itemId: Long): ChatItemInfo? {
|
||||
suspend fun apiGetChatItemInfo(rh: Long?, type: ChatType, id: Long, scope: GroupChatScope?, itemId: Long): Pair<ChatItem, ChatItemInfo>? {
|
||||
val r = sendCmd(rh, CC.ApiGetChatItemInfo(type, id, scope, itemId))
|
||||
if (r is API.Result && r.res is CR.ApiChatItemInfo) return r.res.chatItemInfo
|
||||
if (r is API.Result && r.res is CR.ApiChatItemInfo) return r.res.chatItem.chatItem to r.res.chatItemInfo
|
||||
apiErrorAlert("apiGetChatItemInfo", generalGetString(MR.strings.error_loading_details), r)
|
||||
return null
|
||||
}
|
||||
|
||||
+5
@@ -273,6 +273,11 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools
|
||||
if (deleteAt != null) {
|
||||
InfoRow(stringResource(MR.strings.info_row_disappears_at), localTimestamp(deleteAt))
|
||||
}
|
||||
val file = ci.file
|
||||
if (file?.fileExpires != null) {
|
||||
val expiresRes = if (file.expired) MR.strings.info_row_file_expired else MR.strings.info_row_file_expires
|
||||
InfoRow(stringResource(expiresRes), localTimestamp(file.fileExpires))
|
||||
}
|
||||
if (ci.meta.msgVerified?.verified == true) {
|
||||
val signedRes = if (sent) MR.strings.info_row_signed else MR.strings.info_row_signed_verified
|
||||
InfoRow(stringResource(signedRes), "", icon = painterResource(MR.images.ic_verified))
|
||||
|
||||
+4
-3
@@ -699,7 +699,7 @@ fun ChatView(
|
||||
}
|
||||
},
|
||||
showItemDetails = { cInfo, cItem ->
|
||||
suspend fun loadChatItemInfo(): ChatItemInfo? = coroutineScope {
|
||||
suspend fun loadChatItemInfo(): Pair<ChatItem, ChatItemInfo>? = coroutineScope {
|
||||
val ciInfo = chatModel.controller.apiGetChatItemInfo(chatRh, cInfo.chatType, cInfo.apiId, cInfo.groupChatScope(), cItem.id)
|
||||
if (ciInfo != null) {
|
||||
if (chatInfo is ChatInfo.Group) {
|
||||
@@ -717,11 +717,12 @@ fun ChatView(
|
||||
}
|
||||
ModalManager.end.showModalCloseable(endButtons = {
|
||||
ShareButton {
|
||||
clipboard.shareText(itemInfoShareText(chatModel, cItem, initialCiInfo, chatModel.controller.appPrefs.developerTools.get()))
|
||||
clipboard.shareText(itemInfoShareText(chatModel, initialCiInfo.first, initialCiInfo.second, chatModel.controller.appPrefs.developerTools.get()))
|
||||
}
|
||||
}) { close ->
|
||||
var ciInfo by remember(cItem.id) { mutableStateOf(initialCiInfo) }
|
||||
ChatItemInfoView(chatRh, cItem, ciInfo, devTools = chatModel.controller.appPrefs.developerTools.get(), chatInfo)
|
||||
val (item, info) = ciInfo
|
||||
ChatItemInfoView(chatRh, item, info, devTools = chatModel.controller.appPrefs.developerTools.get(), chatInfo)
|
||||
LaunchedEffect(cItem.id) {
|
||||
withContext(Dispatchers.Default) {
|
||||
for (msg in controller.messagesChannel) {
|
||||
|
||||
+15
-5
@@ -101,7 +101,7 @@ fun CIFileView(
|
||||
FileProtocol.LOCAL -> {}
|
||||
}
|
||||
file.fileStatus is CIFileStatus.RcvError ->
|
||||
showFileErrorAlert(file.fileStatus.rcvFileError)
|
||||
showFileErrorAlert(file.fileStatus.rcvFileError, file)
|
||||
file.fileStatus is CIFileStatus.RcvWarning ->
|
||||
showFileErrorAlert(file.fileStatus.rcvFileError, temporary = true)
|
||||
file.fileStatus is CIFileStatus.SndError ->
|
||||
@@ -157,10 +157,12 @@ fun CIFileView(
|
||||
is CIFileStatus.SndError -> fileIcon(innerIcon = painterResource(MR.images.ic_close))
|
||||
is CIFileStatus.SndWarning -> fileIcon(innerIcon = painterResource(MR.images.ic_warning_filled))
|
||||
is CIFileStatus.RcvInvitation ->
|
||||
if (fileSizeValid(file, senderProfile))
|
||||
fileIcon(innerIcon = painterResource(MR.images.ic_arrow_downward), color = MaterialTheme.colors.primary, topPadding = 10.sp.toDp())
|
||||
else
|
||||
if (!fileSizeValid(file, senderProfile))
|
||||
fileIcon(innerIcon = painterResource(MR.images.ic_priority_high), color = WarningOrange)
|
||||
else if (file.expired)
|
||||
fileIcon(innerIcon = painterResource(MR.images.ic_close))
|
||||
else
|
||||
fileIcon(innerIcon = painterResource(MR.images.ic_arrow_downward), color = MaterialTheme.colors.primary, topPadding = 10.sp.toDp())
|
||||
is CIFileStatus.RcvAccepted -> fileIcon(innerIcon = painterResource(MR.images.ic_more_horiz))
|
||||
is CIFileStatus.RcvTransfer ->
|
||||
if (file.fileProtocol == FileProtocol.XFTP && file.fileStatus.rcvProgress < file.fileStatus.rcvTotal) {
|
||||
@@ -241,7 +243,15 @@ fun CIFileView(
|
||||
fun fileSizeValid(file: CIFile, senderProfile: LocalProfile?): Boolean =
|
||||
file.fileSize <= getMaxFileSize(file.fileProtocol, senderProfile)
|
||||
|
||||
fun showFileErrorAlert(err: FileError, temporary: Boolean = false) {
|
||||
fun showFileErrorAlert(err: FileError, file: CIFile? = null, temporary: Boolean = false) {
|
||||
val fileExpires = file?.fileExpires
|
||||
if (file != null && fileExpires != null && file.expired && (err is FileError.Auth || err is FileError.NoFile)) {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.file_expired),
|
||||
String.format(generalGetString(MR.strings.file_error_expired), localTimestamp(fileExpires))
|
||||
)
|
||||
return
|
||||
}
|
||||
val title: String = generalGetString(if (temporary) MR.strings.temporary_file_error else MR.strings.file_error)
|
||||
val btn = err.moreInfoButton
|
||||
if (btn != null) {
|
||||
|
||||
+6
-2
@@ -83,7 +83,11 @@ fun CIImageView(
|
||||
is CIFileStatus.SndCancelled -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file)
|
||||
is CIFileStatus.SndError -> fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file)
|
||||
is CIFileStatus.SndWarning -> fileIcon(painterResource(MR.images.ic_warning_filled), MR.strings.icon_descr_file)
|
||||
is CIFileStatus.RcvInvitation -> fileIcon(painterResource(MR.images.ic_arrow_downward), MR.strings.icon_descr_asked_to_receive)
|
||||
is CIFileStatus.RcvInvitation ->
|
||||
if (file.expired && fileSizeValid(file, senderProfile))
|
||||
fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file)
|
||||
else
|
||||
fileIcon(painterResource(MR.images.ic_arrow_downward), MR.strings.icon_descr_asked_to_receive)
|
||||
is CIFileStatus.RcvAccepted -> fileIcon(painterResource(MR.images.ic_more_horiz), MR.strings.icon_descr_waiting_for_image)
|
||||
is CIFileStatus.RcvTransfer -> progressIndicator()
|
||||
is CIFileStatus.RcvComplete -> {}
|
||||
@@ -239,7 +243,7 @@ fun CIImageView(
|
||||
FileProtocol.LOCAL -> {}
|
||||
}
|
||||
file.fileStatus is CIFileStatus.RcvError ->
|
||||
showFileErrorAlert(file.fileStatus.rcvFileError)
|
||||
showFileErrorAlert(file.fileStatus.rcvFileError, file)
|
||||
file.fileStatus is CIFileStatus.RcvWarning ->
|
||||
showFileErrorAlert(file.fileStatus.rcvFileError, temporary = true)
|
||||
file.fileStatus is CIFileStatus.SndError ->
|
||||
|
||||
+9
-5
@@ -135,10 +135,10 @@ fun CIVideoView(
|
||||
}
|
||||
// Do not show download icon when the view is blurred
|
||||
if (!smallView && (!showDownloadButton(file?.fileStatus) || !blurred.value)) {
|
||||
fileStatusIcon(file, false)
|
||||
fileStatusIcon(file, false, senderProfile)
|
||||
} else if (smallView && file?.showStatusIconInSmallView == true) {
|
||||
Box(Modifier.align(Alignment.Center)) {
|
||||
fileStatusIcon(file, true)
|
||||
fileStatusIcon(file, true, senderProfile)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -486,7 +486,7 @@ private fun progressCircle(progress: Long, total: Long) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun fileStatusIcon(file: CIFile?, smallView: Boolean) {
|
||||
private fun fileStatusIcon(file: CIFile?, smallView: Boolean, senderProfile: LocalProfile?) {
|
||||
if (file != null) {
|
||||
Box(
|
||||
Modifier
|
||||
@@ -525,7 +525,11 @@ private fun fileStatusIcon(file: CIFile?, smallView: Boolean) {
|
||||
showFileErrorAlert(file.fileStatus.sndFileError, temporary = true)
|
||||
}
|
||||
)
|
||||
is CIFileStatus.RcvInvitation -> fileIcon(painterResource(MR.images.ic_arrow_downward), MR.strings.icon_descr_video_asked_to_receive)
|
||||
is CIFileStatus.RcvInvitation ->
|
||||
if (file.expired && fileSizeValid(file, senderProfile))
|
||||
fileIcon(painterResource(MR.images.ic_close), MR.strings.icon_descr_file)
|
||||
else
|
||||
fileIcon(painterResource(MR.images.ic_arrow_downward), MR.strings.icon_descr_video_asked_to_receive)
|
||||
is CIFileStatus.RcvAccepted -> fileIcon(painterResource(MR.images.ic_more_horiz), MR.strings.icon_descr_waiting_for_video)
|
||||
is CIFileStatus.RcvTransfer ->
|
||||
if (file.fileProtocol == FileProtocol.XFTP && file.fileStatus.rcvProgress < file.fileStatus.rcvTotal) {
|
||||
@@ -541,7 +545,7 @@ private fun fileStatusIcon(file: CIFile?, smallView: Boolean) {
|
||||
painterResource(MR.images.ic_close),
|
||||
MR.strings.icon_descr_file,
|
||||
onClick = {
|
||||
showFileErrorAlert(file.fileStatus.rcvFileError)
|
||||
showFileErrorAlert(file.fileStatus.rcvFileError, file)
|
||||
}
|
||||
)
|
||||
is CIFileStatus.RcvWarning ->
|
||||
|
||||
+2
-2
@@ -412,7 +412,7 @@ private fun VoiceMsgIndicator(
|
||||
}
|
||||
)
|
||||
file?.fileStatus is CIFileStatus.RcvInvitation ->
|
||||
PlayPauseButton(audioPlaying, sent, 0f, strokeWidth, strokeColor, true, error, sizeMultiplier, { receiveFile(file.fileId) }, {}, longClick = longClick)
|
||||
PlayPauseButton(audioPlaying, sent, 0f, strokeWidth, strokeColor, true, error, sizeMultiplier, { receiveFile(file.fileId) }, {}, longClick = longClick, icon = if (file.expired) MR.images.ic_close else MR.images.ic_play_arrow_filled)
|
||||
file?.fileStatus is CIFileStatus.RcvTransfer || file?.fileStatus is CIFileStatus.RcvAccepted ->
|
||||
VoiceMsgLoadingProgressIndicator(sizeMultiplier)
|
||||
file?.fileStatus is CIFileStatus.RcvAborted ->
|
||||
@@ -424,7 +424,7 @@ private fun VoiceMsgIndicator(
|
||||
sizeMultiplier,
|
||||
longClick,
|
||||
onClick = {
|
||||
showFileErrorAlert(file.fileStatus.rcvFileError)
|
||||
showFileErrorAlert(file.fileStatus.rcvFileError, file)
|
||||
}
|
||||
)
|
||||
file != null && file.fileStatus is CIFileStatus.RcvWarning ->
|
||||
|
||||
@@ -697,6 +697,8 @@
|
||||
<string name="loading_remote_file_title">Loading the file </string>
|
||||
<string name="loading_remote_file_desc">Please, wait while the file is being loaded from the linked mobile</string>
|
||||
<string name="file_error">File error</string>
|
||||
<string name="file_expired">File expired</string>
|
||||
<string name="file_error_expired">File was available until %1$s.</string>
|
||||
<string name="temporary_file_error">Temporary file error</string>
|
||||
<string name="open_with_app">Open with %s</string>
|
||||
|
||||
@@ -2044,6 +2046,8 @@
|
||||
<string name="info_row_deleted_at">Deleted at</string>
|
||||
<string name="info_row_moderated_at">Moderated at</string>
|
||||
<string name="info_row_disappears_at">Disappears at</string>
|
||||
<string name="info_row_file_expires">File available until</string>
|
||||
<string name="info_row_file_expired">File was available until</string>
|
||||
<string name="share_text_database_id">Database ID: %d</string>
|
||||
<string name="share_text_updated_at">Record updated at: %s</string>
|
||||
<string name="share_text_message_status">Message status: %s</string>
|
||||
|
||||
Reference in New Issue
Block a user