Merge remote-tracking branch 'origin/master' into ab/self-chat

This commit is contained in:
IC Rainbow 2024-01-09 12:11:51 +02:00
commit e43ed1ca43
49 changed files with 147 additions and 103 deletions

View File

@ -3,11 +3,12 @@ package chat.simplex.app
import android.content.Context import android.content.Context
import android.util.Log import android.util.Log
import androidx.work.* import androidx.work.*
import chat.simplex.app.*
import chat.simplex.app.SimplexService.Companion.showPassphraseNotification import chat.simplex.app.SimplexService.Companion.showPassphraseNotification
import chat.simplex.common.model.ChatController import chat.simplex.common.model.ChatController
import chat.simplex.common.views.helpers.DBMigrationResult import chat.simplex.common.views.helpers.DBMigrationResult
import chat.simplex.app.BuildConfig import chat.simplex.common.platform.chatModel
import chat.simplex.common.platform.initChatControllerAndRunMigrations
import chat.simplex.common.views.helpers.DatabaseUtils
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.util.Date import java.util.Date
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -57,6 +58,10 @@ class MessagesFetcherWork(
val durationSeconds = inputData.getInt(INPUT_DATA_DURATION, 60) val durationSeconds = inputData.getInt(INPUT_DATA_DURATION, 60)
var shouldReschedule = true var shouldReschedule = true
try { try {
// In case of self-destruct is enabled the initialization process will not start in SimplexApp, Let's start it here
if (DatabaseUtils.ksSelfDestructPassword.get() != null && chatModel.chatDbStatus.value == null) {
initChatControllerAndRunMigrations()
}
withTimeout(durationSeconds * 1000L) { withTimeout(durationSeconds * 1000L) {
val chatController = ChatController val chatController = ChatController
SimplexService.waitDbMigrationEnds(chatController) SimplexService.waitDbMigrationEnds(chatController)

View File

@ -26,6 +26,7 @@ import kotlinx.coroutines.sync.withLock
import java.io.* import java.io.*
import java.util.* import java.util.*
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.system.exitProcess
const val TAG = "SIMPLEX" const val TAG = "SIMPLEX"
@ -46,8 +47,8 @@ class SimplexApp: Application(), LifecycleEventObserver {
try { try {
Looper.loop() Looper.loop()
} catch (e: Throwable) { } catch (e: Throwable) {
if (e.message != null && e.message!!.startsWith("Unable to start activity")) { if (e is UnsatisfiedLinkError || e.message?.startsWith("Unable to start activity") == true) {
android.os.Process.killProcess(android.os.Process.myPid()) Process.killProcess(Process.myPid())
break break
} else { } else {
// Send it to our exception handled because it will not get the exception otherwise // Send it to our exception handled because it will not get the exception otherwise
@ -63,7 +64,9 @@ class SimplexApp: Application(), LifecycleEventObserver {
tmpDir.deleteRecursively() tmpDir.deleteRecursively()
tmpDir.mkdir() tmpDir.mkdir()
initChatControllerAndRunMigrations(false) if (DatabaseUtils.ksSelfDestructPassword.get() == null) {
initChatControllerAndRunMigrations()
}
ProcessLifecycleOwner.get().lifecycle.addObserver(this@SimplexApp) ProcessLifecycleOwner.get().lifecycle.addObserver(this@SimplexApp)
} }

View File

@ -72,6 +72,10 @@ class SimplexService: Service() {
stopSelf() stopSelf()
} else { } else {
isServiceStarted = true isServiceStarted = true
// In case of self-destruct is enabled the initialization process will not start in SimplexApp, Let's start it here
if (DatabaseUtils.ksSelfDestructPassword.get() != null && chatModel.chatDbStatus.value == null) {
initChatControllerAndRunMigrations()
}
} }
} }

View File

@ -97,7 +97,8 @@ fun IncomingCallActivityView(m: ChatModel) {
Surface( Surface(
Modifier Modifier
.fillMaxSize(), .fillMaxSize(),
color = MaterialTheme.colors.background color = MaterialTheme.colors.background,
contentColor = LocalContentColor.current
) { ) {
if (showCallView) { if (showCallView) {
Box { Box {
@ -200,7 +201,8 @@ private fun SimpleXLogo() {
private fun LockScreenCallButton(text: String, icon: Painter, color: Color, action: () -> Unit) { private fun LockScreenCallButton(text: String, icon: Painter, color: Color, action: () -> Unit) {
Surface( Surface(
shape = RoundedCornerShape(10.dp), shape = RoundedCornerShape(10.dp),
color = Color.Transparent color = Color.Transparent,
contentColor = LocalContentColor.current
) { ) {
Column( Column(
Modifier Modifier
@ -227,7 +229,8 @@ fun PreviewIncomingCallLockScreenAlert() {
Surface( Surface(
Modifier Modifier
.fillMaxSize(), .fillMaxSize(),
color = MaterialTheme.colors.background color = MaterialTheme.colors.background,
contentColor = LocalContentColor.current
) { ) {
IncomingCallLockScreenAlertLayout( IncomingCallLockScreenAlertLayout(
invitation = RcvCallInvitation( invitation = RcvCallInvitation(

View File

@ -44,7 +44,7 @@ data class SettingsViewState(
fun AppScreen() { fun AppScreen() {
SimpleXTheme { SimpleXTheme {
ProvideWindowInsets(windowInsetsAnimationsEnabled = true) { ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
Surface(color = MaterialTheme.colors.background) { Surface(color = MaterialTheme.colors.background, contentColor = LocalContentColor.current) {
MainScreen() MainScreen()
} }
} }
@ -85,7 +85,7 @@ fun MainScreen() {
@Composable @Composable
fun AuthView() { fun AuthView() {
Surface(color = MaterialTheme.colors.background) { Surface(color = MaterialTheme.colors.background, contentColor = LocalContentColor.current) {
Box( Box(
Modifier.fillMaxSize(), Modifier.fillMaxSize(),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center

View File

@ -1,8 +1,7 @@
package chat.simplex.common package chat.simplex.common
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme import androidx.compose.material.*
import androidx.compose.material.Surface
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import chat.simplex.common.model.* import chat.simplex.common.model.*
@ -107,7 +106,7 @@ object AppLock {
private fun setPasscode() { private fun setPasscode() {
val appPrefs = ChatController.appPrefs val appPrefs = ChatController.appPrefs
ModalManager.fullscreen.showCustomModal { close -> ModalManager.fullscreen.showCustomModal { close ->
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background) { Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background, contentColor = LocalContentColor.current) {
SetAppPasscodeView( SetAppPasscodeView(
submit = { submit = {
ChatModel.performLA.value = true ChatModel.performLA.value = true

View File

@ -41,21 +41,20 @@ val appPreferences: AppPreferences
val chatController: ChatController = ChatController val chatController: ChatController = ChatController
fun initChatControllerAndRunMigrations(ignoreSelfDestruct: Boolean) { fun initChatControllerAndRunMigrations() {
if (ignoreSelfDestruct || DatabaseUtils.ksSelfDestructPassword.get() == null) { withBGApi {
withBGApi { if (appPreferences.chatStopped.get() && appPreferences.storeDBPassphrase.get() && ksDatabasePassword.get() != null) {
if (appPreferences.chatStopped.get() && appPreferences.storeDBPassphrase.get() && ksDatabasePassword.get() != null) { initChatController(startChat = ::showStartChatAfterRestartAlert)
initChatController(startChat = ::showStartChatAfterRestartAlert) } else {
} else { initChatController()
initChatController()
}
runMigrations()
} }
runMigrations()
} }
} }
suspend fun initChatController(useKey: String? = null, confirmMigrations: MigrationConfirmation? = null, startChat: () -> CompletableDeferred<Boolean> = { CompletableDeferred(true) }) { suspend fun initChatController(useKey: String? = null, confirmMigrations: MigrationConfirmation? = null, startChat: () -> CompletableDeferred<Boolean> = { CompletableDeferred(true) }) {
try { try {
if (chatModel.ctrlInitInProgress.value) return
chatModel.ctrlInitInProgress.value = true chatModel.ctrlInitInProgress.value = true
val dbKey = useKey ?: DatabaseUtils.useDatabaseKey() val dbKey = useKey ?: DatabaseUtils.useDatabaseKey()
val confirm = confirmMigrations ?: if (appPreferences.confirmDBUpgrades.get()) MigrationConfirmation.Error else MigrationConfirmation.YesUp val confirm = confirmMigrations ?: if (appPreferences.confirmDBUpgrades.get()) MigrationConfirmation.Error else MigrationConfirmation.YesUp

View File

@ -1,5 +1,7 @@
package chat.simplex.common.ui.theme package chat.simplex.common.ui.theme
import androidx.compose.material.LocalContentColor
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
val Purple200 = Color(0xFFBB86FC) val Purple200 = Color(0xFFBB86FC)
@ -25,4 +27,5 @@ val WarningOrange = Color(255, 127, 0, 255)
val WarningYellow = Color(255, 192, 0, 255) val WarningYellow = Color(255, 192, 0, 255)
val FileLight = Color(183, 190, 199, 255) val FileLight = Color(183, 190, 199, 255)
val FileDark = Color(101, 101, 106, 255) val FileDark = Color(101, 101, 106, 255)
val MenuTextColorDark = Color.White.copy(alpha = 0.8f)
val MenuTextColor: Color @Composable get () = if (isInDarkTheme()) LocalContentColor.current.copy(alpha = 0.8f) else Color.Black

View File

@ -283,27 +283,10 @@ fun SimpleXTheme(darkTheme: Boolean? = null, content: @Composable () -> Unit) {
val theme by CurrentColors.collectAsState() val theme by CurrentColors.collectAsState()
MaterialTheme( MaterialTheme(
colors = theme.colors, colors = theme.colors,
typography = Typography.copy( typography = Typography,
h1 = Typography.h1.copy(color = theme.colors.onBackground),
h2 = Typography.h2.copy(color = theme.colors.onBackground),
h3 = Typography.h3.copy(color = theme.colors.onBackground),
h4 = Typography.h4.copy(color = theme.colors.onBackground),
h5 = Typography.h5.copy(color = theme.colors.onBackground),
h6 = Typography.h6.copy(color = theme.colors.onBackground),
subtitle1 = Typography.subtitle1.copy(color = theme.colors.onBackground),
subtitle2 = Typography.subtitle2.copy(color = theme.colors.onBackground),
body1 = Typography.body1.copy(color = theme.colors.onBackground),
body2 = Typography.body2.copy(color = theme.colors.onBackground),
button = Typography.button.copy(color = theme.colors.onBackground),
caption = Typography.caption.copy(color = theme.colors.onBackground),
overline = Typography.overline.copy(color = theme.colors.onBackground)
),
shapes = Shapes, shapes = Shapes,
content = { content = {
ProvideTextStyle( CompositionLocalProvider(LocalContentColor provides MaterialTheme.colors.onBackground, content = content)
value = TextStyle(color = theme.colors.onBackground),
content = content
)
} }
) )
} }

View File

@ -1,8 +1,7 @@
package chat.simplex.common.views package chat.simplex.common.views
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme import androidx.compose.material.*
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -11,7 +10,8 @@ fun SplashView() {
Surface( Surface(
Modifier Modifier
.fillMaxSize(), .fillMaxSize(),
color = MaterialTheme.colors.background color = MaterialTheme.colors.background,
contentColor = LocalContentColor.current
) { ) {
// Image( // Image(
// painter = painterResource(MR.images.logo), // painter = painterResource(MR.images.logo),

View File

@ -101,13 +101,16 @@ fun TerminalLayout(
) )
} }
}, },
contentColor = LocalContentColor.current,
drawerContentColor = LocalContentColor.current,
modifier = Modifier.navigationBarsWithImePadding() modifier = Modifier.navigationBarsWithImePadding()
) { contentPadding -> ) { contentPadding ->
Surface( Surface(
modifier = Modifier modifier = Modifier
.padding(contentPadding) .padding(contentPadding)
.fillMaxWidth(), .fillMaxWidth(),
color = MaterialTheme.colors.background color = MaterialTheme.colors.background,
contentColor = LocalContentColor.current
) { ) {
TerminalLog() TerminalLog()
} }

View File

@ -239,7 +239,7 @@ fun OnboardingButtons(displayName: MutableState<String>, close: () -> Unit) {
val enabled = canCreateProfile(displayName.value) val enabled = canCreateProfile(displayName.value)
val createModifier: Modifier = Modifier.clickable(enabled) { createProfileOnboarding(chatModel, displayName.value, close) }.padding(8.dp) val createModifier: Modifier = Modifier.clickable(enabled) { createProfileOnboarding(chatModel, displayName.value, close) }.padding(8.dp)
val createColor: Color = if (enabled) MaterialTheme.colors.primary else MaterialTheme.colors.secondary val createColor: Color = if (enabled) MaterialTheme.colors.primary else MaterialTheme.colors.secondary
Surface(shape = RoundedCornerShape(20.dp), color = Color.Transparent) { Surface(shape = RoundedCornerShape(20.dp), color = Color.Transparent, contentColor = LocalContentColor.current) {
Row(verticalAlignment = Alignment.CenterVertically, modifier = createModifier) { Row(verticalAlignment = Alignment.CenterVertically, modifier = createModifier) {
Text(stringResource(MR.strings.create_profile_button), style = MaterialTheme.typography.caption, color = createColor, fontWeight = FontWeight.Medium) Text(stringResource(MR.strings.create_profile_button), style = MaterialTheme.typography.caption, color = createColor, fontWeight = FontWeight.Medium)
Icon(painterResource(MR.images.ic_arrow_forward_ios), stringResource(MR.strings.create_profile_button), tint = createColor) Icon(painterResource(MR.images.ic_arrow_forward_ios), stringResource(MR.strings.create_profile_button), tint = createColor)

View File

@ -85,7 +85,8 @@ fun IncomingCallInfo(invitation: RcvCallInvitation, chatModel: ChatModel) {
private fun CallButton(text: String, icon: Painter, color: Color, action: () -> Unit) { private fun CallButton(text: String, icon: Painter, color: Color, action: () -> Unit) {
Surface( Surface(
shape = RoundedCornerShape(10.dp), shape = RoundedCornerShape(10.dp),
color = Color.Transparent color = Color.Transparent,
contentColor = LocalContentColor.current
) { ) {
Column( Column(
Modifier Modifier

View File

@ -570,6 +570,8 @@ fun ChatLayout(
bottomBar = composeView, bottomBar = composeView,
modifier = Modifier.navigationBarsWithImePadding(), modifier = Modifier.navigationBarsWithImePadding(),
floatingActionButton = { floatingButton.value() }, floatingActionButton = { floatingButton.value() },
contentColor = LocalContentColor.current,
drawerContentColor = LocalContentColor.current,
) { contentPadding -> ) { contentPadding ->
BoxWithConstraints(Modifier BoxWithConstraints(Modifier
.fillMaxHeight() .fillMaxHeight()

View File

@ -258,7 +258,8 @@ private fun CustomDisappearingMessageDialog(
DefaultDialog(onDismissRequest = { setShowDialog(false) }) { DefaultDialog(onDismissRequest = { setShowDialog(false) }) {
Surface( Surface(
shape = RoundedCornerShape(corner = CornerSize(25.dp)) shape = RoundedCornerShape(corner = CornerSize(25.dp)),
contentColor = LocalContentColor.current
) { ) {
Box( Box(
contentAlignment = Alignment.Center contentAlignment = Alignment.Center

View File

@ -131,7 +131,8 @@ fun CIFileView(
Surface( Surface(
Modifier.drawRingModifier(angle, strokeColor, strokeWidth), Modifier.drawRingModifier(angle, strokeColor, strokeWidth),
color = Color.Transparent, color = Color.Transparent,
shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)) shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
contentColor = LocalContentColor.current
) { ) {
Box(Modifier.size(32.dp)) Box(Modifier.size(32.dp))
} }

View File

@ -88,6 +88,7 @@ fun CIGroupInvitationView(
}) else Modifier, }) else Modifier,
shape = RoundedCornerShape(18.dp), shape = RoundedCornerShape(18.dp),
color = if (sent) sentColor else receivedColor, color = if (sent) sentColor else receivedColor,
contentColor = LocalContentColor.current
) { ) {
Box( Box(
Modifier Modifier

View File

@ -142,6 +142,7 @@ fun DecryptionErrorItemFixButton(
Modifier.clickable(onClick = onClick), Modifier.clickable(onClick = onClick),
shape = RoundedCornerShape(18.dp), shape = RoundedCornerShape(18.dp),
color = receivedColor, color = receivedColor,
contentColor = LocalContentColor.current
) { ) {
Box( Box(
Modifier.padding(vertical = 6.dp, horizontal = 12.dp), Modifier.padding(vertical = 6.dp, horizontal = 12.dp),
@ -188,6 +189,7 @@ fun DecryptionErrorItem(
Modifier.clickable(onClick = onClick), Modifier.clickable(onClick = onClick),
shape = RoundedCornerShape(18.dp), shape = RoundedCornerShape(18.dp),
color = receivedColor, color = receivedColor,
contentColor = LocalContentColor.current
) { ) {
Box( Box(
Modifier.padding(vertical = 6.dp, horizontal = 12.dp), Modifier.padding(vertical = 6.dp, horizontal = 12.dp),

View File

@ -153,7 +153,8 @@ private fun BoxScope.PlayButton(error: Boolean = false, onLongClick: () -> Unit,
Surface( Surface(
Modifier.align(Alignment.Center), Modifier.align(Alignment.Center),
color = Color.Black.copy(alpha = 0.25f), color = Color.Black.copy(alpha = 0.25f),
shape = RoundedCornerShape(percent = 50) shape = RoundedCornerShape(percent = 50),
contentColor = LocalContentColor.current
) { ) {
Box( Box(
Modifier Modifier
@ -264,7 +265,8 @@ private fun progressCircle(progress: Long, total: Long) {
Surface( Surface(
Modifier.drawRingModifier(angle, strokeColor, strokeWidth), Modifier.drawRingModifier(angle, strokeColor, strokeWidth),
color = Color.Transparent, color = Color.Transparent,
shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)) shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
contentColor = LocalContentColor.current
) { ) {
Box(Modifier.size(16.dp)) Box(Modifier.size(16.dp))
} }

View File

@ -225,7 +225,8 @@ private fun PlayPauseButton(
Surface( Surface(
Modifier.drawRingModifier(angle, strokeColor, strokeWidth), Modifier.drawRingModifier(angle, strokeColor, strokeWidth),
color = if (sent) sentColor else receivedColor, color = if (sent) sentColor else receivedColor,
shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)) shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
contentColor = LocalContentColor.current
) { ) {
Box( Box(
Modifier Modifier

View File

@ -613,7 +613,7 @@ private fun ShrinkItemAction(revealed: MutableState<Boolean>, showMenu: MutableS
@Composable @Composable
fun ItemAction(text: String, icon: Painter, color: Color = Color.Unspecified, onClick: () -> Unit) { fun ItemAction(text: String, icon: Painter, color: Color = Color.Unspecified, onClick: () -> Unit) {
val finalColor = if (color == Color.Unspecified) { val finalColor = if (color == Color.Unspecified) {
if (isInDarkTheme()) MenuTextColorDark else Color.Black MenuTextColor
} else color } else color
DropdownMenuItem(onClick, contentPadding = PaddingValues(horizontal = DEFAULT_PADDING * 1.5f)) { DropdownMenuItem(onClick, contentPadding = PaddingValues(horizontal = DEFAULT_PADDING * 1.5f)) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
@ -633,7 +633,7 @@ fun ItemAction(text: String, icon: Painter, color: Color = Color.Unspecified, on
@Composable @Composable
fun ItemAction(text: String, icon: ImageVector, onClick: () -> Unit, color: Color = Color.Unspecified) { fun ItemAction(text: String, icon: ImageVector, onClick: () -> Unit, color: Color = Color.Unspecified) {
val finalColor = if (color == Color.Unspecified) { val finalColor = if (color == Color.Unspecified) {
if (isInDarkTheme()) MenuTextColorDark else Color.Black MenuTextColor
} else color } else color
DropdownMenuItem(onClick, contentPadding = PaddingValues(horizontal = DEFAULT_PADDING * 1.5f)) { DropdownMenuItem(onClick, contentPadding = PaddingValues(horizontal = DEFAULT_PADDING * 1.5f)) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {

View File

@ -23,6 +23,7 @@ fun DeletedItemView(ci: ChatItem, timedMessagesTTL: Int?) {
Surface( Surface(
shape = RoundedCornerShape(18.dp), shape = RoundedCornerShape(18.dp),
color = if (sent) sentColor else receivedColor, color = if (sent) sentColor else receivedColor,
contentColor = LocalContentColor.current
) { ) {
Row( Row(
Modifier.padding(horizontal = 12.dp, vertical = 6.dp), Modifier.padding(horizontal = 12.dp, vertical = 6.dp),

View File

@ -56,6 +56,7 @@ fun CIMsgError(ci: ChatItem, timedMessagesTTL: Int?, onClick: () -> Unit) {
Modifier.clickable(onClick = onClick), Modifier.clickable(onClick = onClick),
shape = RoundedCornerShape(18.dp), shape = RoundedCornerShape(18.dp),
color = receivedColor, color = receivedColor,
contentColor = LocalContentColor.current
) { ) {
Row( Row(
Modifier.padding(horizontal = 12.dp, vertical = 6.dp), Modifier.padding(horizontal = 12.dp, vertical = 6.dp),

View File

@ -26,6 +26,7 @@ fun MarkedDeletedItemView(ci: ChatItem, timedMessagesTTL: Int?, revealed: Mutabl
Surface( Surface(
shape = RoundedCornerShape(18.dp), shape = RoundedCornerShape(18.dp),
color = if (ci.chatDir.sent) sentColor else receivedColor, color = if (ci.chatDir.sent) sentColor else receivedColor,
contentColor = LocalContentColor.current
) { ) {
Row( Row(
Modifier.padding(horizontal = 12.dp, vertical = 6.dp), Modifier.padding(horizontal = 12.dp, vertical = 6.dp),

View File

@ -75,6 +75,8 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf
SettingsView(chatModel, setPerformLA, scaffoldState.drawerState) SettingsView(chatModel, setPerformLA, scaffoldState.drawerState)
} }
}, },
contentColor = LocalContentColor.current,
drawerContentColor = LocalContentColor.current,
drawerScrimColor = MaterialTheme.colors.onSurface.copy(alpha = if (isInDarkTheme()) 0.16f else 0.32f), drawerScrimColor = MaterialTheme.colors.onSurface.copy(alpha = if (isInDarkTheme()) 0.16f else 0.32f),
drawerGesturesEnabled = appPlatform.isAndroid, drawerGesturesEnabled = appPlatform.isAndroid,
floatingActionButton = { floatingActionButton = {

View File

@ -30,6 +30,8 @@ fun ShareListView(chatModel: ChatModel, settingsState: SettingsViewState, stoppe
val endPadding = if (appPlatform.isDesktop) 56.dp else 0.dp val endPadding = if (appPlatform.isDesktop) 56.dp else 0.dp
Scaffold( Scaffold(
Modifier.padding(end = endPadding), Modifier.padding(end = endPadding),
contentColor = LocalContentColor.current,
drawerContentColor = LocalContentColor.current,
scaffoldState = scaffoldState, scaffoldState = scaffoldState,
topBar = { Column { ShareListToolbar(chatModel, userPickerState, stopped) { searchInList = it.trim() } } }, topBar = { Column { ShareListToolbar(chatModel, userPickerState, stopped) { searchInList = it.trim() } } },
) { ) {

View File

@ -31,7 +31,6 @@ import chat.simplex.common.views.remote.*
import chat.simplex.common.views.usersettings.doWithAuth import chat.simplex.common.views.usersettings.doWithAuth
import chat.simplex.res.MR import chat.simplex.res.MR
import dev.icerock.moko.resources.compose.stringResource import dev.icerock.moko.resources.compose.stringResource
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -303,7 +302,7 @@ fun UserProfileRow(u: User) {
u.displayName, u.displayName,
modifier = Modifier modifier = Modifier
.padding(start = 10.dp, end = 8.dp), .padding(start = 10.dp, end = 8.dp),
color = if (isInDarkTheme()) MenuTextColorDark else Color.Black, color = MenuTextColor,
fontWeight = if (u.activeUser) FontWeight.Medium else FontWeight.Normal fontWeight = if (u.activeUser) FontWeight.Medium else FontWeight.Normal
) )
} }
@ -346,7 +345,7 @@ fun RemoteHostRow(h: RemoteHostInfo) {
Text( Text(
h.hostDeviceName, h.hostDeviceName,
modifier = Modifier.padding(start = 26.dp, end = 8.dp), modifier = Modifier.padding(start = 26.dp, end = 8.dp),
color = if (h.activeHost) MaterialTheme.colors.onBackground else if (isInDarkTheme()) MenuTextColorDark else Color.Black, color = if (h.activeHost) MaterialTheme.colors.onBackground else MenuTextColor,
fontSize = 14.sp, fontSize = 14.sp,
) )
} }
@ -387,7 +386,7 @@ fun LocalDeviceRow(active: Boolean) {
Text( Text(
stringResource(MR.strings.this_device), stringResource(MR.strings.this_device),
modifier = Modifier.padding(start = 26.dp, end = 8.dp), modifier = Modifier.padding(start = 26.dp, end = 8.dp),
color = if (active) MaterialTheme.colors.onBackground else if (isInDarkTheme()) MenuTextColorDark else Color.Black, color = if (active) MaterialTheme.colors.onBackground else MenuTextColor,
fontSize = 14.sp, fontSize = 14.sp,
) )
} }
@ -399,7 +398,7 @@ private fun UseFromDesktopPickerItem(onClick: () -> Unit) {
val text = generalGetString(MR.strings.settings_section_title_use_from_desktop).lowercase().capitalize(Locale.current) val text = generalGetString(MR.strings.settings_section_title_use_from_desktop).lowercase().capitalize(Locale.current)
Icon(painterResource(MR.images.ic_desktop), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) Icon(painterResource(MR.images.ic_desktop), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground)
Spacer(Modifier.width(DEFAULT_PADDING + 6.dp)) Spacer(Modifier.width(DEFAULT_PADDING + 6.dp))
Text(text, color = if (isInDarkTheme()) MenuTextColorDark else Color.Black) Text(text, color = MenuTextColor)
} }
} }
@ -409,7 +408,7 @@ private fun LinkAMobilePickerItem(onClick: () -> Unit) {
val text = generalGetString(MR.strings.link_a_mobile) val text = generalGetString(MR.strings.link_a_mobile)
Icon(painterResource(MR.images.ic_smartphone_300), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) Icon(painterResource(MR.images.ic_smartphone_300), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground)
Spacer(Modifier.width(DEFAULT_PADDING + 6.dp)) Spacer(Modifier.width(DEFAULT_PADDING + 6.dp))
Text(text, color = if (isInDarkTheme()) MenuTextColorDark else Color.Black) Text(text, color = MenuTextColor)
} }
} }
@ -419,7 +418,7 @@ private fun CreateInitialProfile(onClick: () -> Unit) {
val text = generalGetString(MR.strings.create_chat_profile) val text = generalGetString(MR.strings.create_chat_profile)
Icon(painterResource(MR.images.ic_manage_accounts), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) Icon(painterResource(MR.images.ic_manage_accounts), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground)
Spacer(Modifier.width(DEFAULT_PADDING + 6.dp)) Spacer(Modifier.width(DEFAULT_PADDING + 6.dp))
Text(text, color = if (isInDarkTheme()) MenuTextColorDark else Color.Black) Text(text, color = MenuTextColor)
} }
} }
@ -429,7 +428,7 @@ private fun SettingsPickerItem(onClick: () -> Unit) {
val text = generalGetString(MR.strings.settings_section_title_settings).lowercase().capitalize(Locale.current) val text = generalGetString(MR.strings.settings_section_title_settings).lowercase().capitalize(Locale.current)
Icon(painterResource(MR.images.ic_settings), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) Icon(painterResource(MR.images.ic_settings), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground)
Spacer(Modifier.width(DEFAULT_PADDING + 6.dp)) Spacer(Modifier.width(DEFAULT_PADDING + 6.dp))
Text(text, color = if (isInDarkTheme()) MenuTextColorDark else Color.Black) Text(text, color = MenuTextColor)
} }
} }
@ -439,7 +438,7 @@ private fun CancelPickerItem(onClick: () -> Unit) {
val text = generalGetString(MR.strings.cancel_verb) val text = generalGetString(MR.strings.cancel_verb)
Icon(painterResource(MR.images.ic_close), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) Icon(painterResource(MR.images.ic_close), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground)
Spacer(Modifier.width(DEFAULT_PADDING + 6.dp)) Spacer(Modifier.width(DEFAULT_PADDING + 6.dp))
Text(text, color = if (isInDarkTheme()) MenuTextColorDark else Color.Black) Text(text, color = MenuTextColor)
} }
} }

View File

@ -460,10 +460,10 @@ suspend fun deleteChatAsync(m: ChatModel) {
m.controller.apiDeleteStorage() m.controller.apiDeleteStorage()
DatabaseUtils.ksDatabasePassword.remove() DatabaseUtils.ksDatabasePassword.remove()
m.controller.appPrefs.storeDBPassphrase.set(true) m.controller.appPrefs.storeDBPassphrase.set(true)
deleteChatDatabaseFiles() deleteAppDatabaseAndFiles()
} }
fun deleteChatDatabaseFiles() { fun deleteAppDatabaseAndFiles() {
val chat = File(dataDir, chatDatabaseFileName) val chat = File(dataDir, chatDatabaseFileName)
val chatBak = File(dataDir, "$chatDatabaseFileName.bak") val chatBak = File(dataDir, "$chatDatabaseFileName.bak")
val agent = File(dataDir, agentDatabaseFileName) val agent = File(dataDir, agentDatabaseFileName)
@ -473,6 +473,7 @@ fun deleteChatDatabaseFiles() {
agent.delete() agent.delete()
agentBak.delete() agentBak.delete()
filesDir.deleteRecursively() filesDir.deleteRecursively()
filesDir.mkdir()
remoteHostsDir.deleteRecursively() remoteHostsDir.deleteRecursively()
tmpDir.deleteRecursively() tmpDir.deleteRecursively()
tmpDir.mkdir() tmpDir.mkdir()

View File

@ -152,7 +152,8 @@ fun CustomTimePickerDialog(
) { ) {
DefaultDialog(onDismissRequest = cancel) { DefaultDialog(onDismissRequest = cancel) {
Surface( Surface(
shape = RoundedCornerShape(corner = CornerSize(25.dp)) shape = RoundedCornerShape(corner = CornerSize(25.dp)),
contentColor = LocalContentColor.current
) { ) {
Box( Box(
contentAlignment = Alignment.Center contentAlignment = Alignment.Center

View File

@ -17,7 +17,7 @@ object DatabaseUtils {
val ksAppPassword = KeyStoreItem(APP_PASSWORD_ALIAS, appPreferences.encryptedAppPassphrase, appPreferences.initializationVectorAppPassphrase) val ksAppPassword = KeyStoreItem(APP_PASSWORD_ALIAS, appPreferences.encryptedAppPassphrase, appPreferences.initializationVectorAppPassphrase)
val ksSelfDestructPassword = KeyStoreItem(SELF_DESTRUCT_PASSWORD_ALIAS, appPreferences.encryptedSelfDestructPassphrase, appPreferences.initializationVectorSelfDestructPassphrase) val ksSelfDestructPassword = KeyStoreItem(SELF_DESTRUCT_PASSWORD_ALIAS, appPreferences.encryptedSelfDestructPassphrase, appPreferences.initializationVectorSelfDestructPassphrase)
class KeyStoreItem(val alias: String, val passphrase: SharedPreference<String?>, val initVector: SharedPreference<String?>) { class KeyStoreItem(private val alias: String, val passphrase: SharedPreference<String?>, val initVector: SharedPreference<String?>) {
fun get(): String? { fun get(): String? {
return cryptor.decryptData( return cryptor.decryptData(
passphrase.get()?.toByteArrayFromBase64ForPassphrase() ?: return null, passphrase.get()?.toByteArrayFromBase64ForPassphrase() ?: return null,

View File

@ -70,7 +70,7 @@ fun <T> ExposedDropDownSetting(
selectionOption.second + (if (label != null) " $label" else ""), selectionOption.second + (if (label != null) " $label" else ""),
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
color = if (isInDarkTheme()) MenuTextColorDark else Color.Black, color = MenuTextColor,
fontSize = fontSize, fontSize = fontSize,
) )
} }

View File

@ -1,8 +1,7 @@
package chat.simplex.common.views.helpers package chat.simplex.common.views.helpers
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme import androidx.compose.material.*
import androidx.compose.material.Surface
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import chat.simplex.common.model.ChatController import chat.simplex.common.model.ChatController
import chat.simplex.common.model.ChatModel import chat.simplex.common.model.ChatModel
@ -50,7 +49,7 @@ fun authenticateWithPasscode(
close() close()
completed(LAResult.Error(generalGetString(MR.strings.authentication_cancelled))) completed(LAResult.Error(generalGetString(MR.strings.authentication_cancelled)))
} }
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background) { Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background, contentColor = LocalContentColor.current) {
LocalAuthView(ChatModel, LocalAuthRequest(promptTitle, promptSubtitle, password, selfDestruct && ChatController.appPrefs.selfDestruct.get()) { LocalAuthView(ChatModel, LocalAuthRequest(promptTitle, promptSubtitle, password, selfDestruct && ChatController.appPrefs.selfDestruct.get()) {
close() close()
completed(it) completed(it)

View File

@ -26,7 +26,7 @@ fun ModalView(
if (showClose) { if (showClose) {
BackHandler(onBack = close) BackHandler(onBack = close)
} }
Surface(Modifier.fillMaxSize()) { Surface(Modifier.fillMaxSize(), contentColor = LocalContentColor.current) {
Column(if (background != MaterialTheme.colors.background) Modifier.background(background) else Modifier.themedBackground()) { Column(if (background != MaterialTheme.colors.background) Modifier.background(background) else Modifier.themedBackground()) {
CloseSheetBar(close, showClose, endButtons) CloseSheetBar(close, showClose, endButtons)
Box(modifier) { content() } Box(modifier) { content() }

View File

@ -34,7 +34,7 @@ fun LocalAuthView(m: ChatModel, authRequest: LocalAuthRequest) {
} else { } else {
val r: LAResult = if (passcode.value == authRequest.password) { val r: LAResult = if (passcode.value == authRequest.password) {
if (authRequest.selfDestruct && sdPassword != null && controller.ctrl == -1L) { if (authRequest.selfDestruct && sdPassword != null && controller.ctrl == -1L) {
initChatControllerAndRunMigrations(true) initChatControllerAndRunMigrations()
} }
LAResult.Success LAResult.Success
} else { } else {
@ -67,8 +67,8 @@ private fun deleteStorageAndRestart(m: ChatModel, password: String, completed: (
* */ * */
chatCloseStore(ctrl) chatCloseStore(ctrl)
} }
deleteChatDatabaseFiles() deleteAppDatabaseAndFiles()
// Clear sensitive data on screen just in case ModalManager will fail to prevent hiding its modals while database encrypts itself // Clear sensitive data on screen just in case ModalManager fails to hide its modals while new database is created
m.chatId.value = null m.chatId.value = null
m.chatItems.clear() m.chatItems.clear()
m.chats.clear() m.chats.clear()

View File

@ -12,6 +12,7 @@ import chat.simplex.res.MR
@Composable @Composable
fun SetAppPasscodeView( fun SetAppPasscodeView(
passcodeKeychain: DatabaseUtils.KeyStoreItem = ksAppPassword, passcodeKeychain: DatabaseUtils.KeyStoreItem = ksAppPassword,
prohibitedPasscodeKeychain: DatabaseUtils.KeyStoreItem = ksSelfDestructPassword,
title: String = generalGetString(MR.strings.new_passcode), title: String = generalGetString(MR.strings.new_passcode),
reason: String? = null, reason: String? = null,
submit: () -> Unit, submit: () -> Unit,
@ -51,7 +52,7 @@ fun SetAppPasscodeView(
} else { } else {
SetPasswordView(title, generalGetString(MR.strings.save_verb), SetPasswordView(title, generalGetString(MR.strings.save_verb),
// Do not allow to set app passcode == selfDestruct passcode // Do not allow to set app passcode == selfDestruct passcode
submitEnabled = { pwd -> pwd != (if (passcodeKeychain.alias == ksSelfDestructPassword.alias) ksAppPassword else ksSelfDestructPassword).get() }) { submitEnabled = { pwd -> pwd != prohibitedPasscodeKeychain.get() }) {
enteredPassword = passcode.value enteredPassword = passcode.value
passcode.value = "" passcode.value = ""
confirming = true confirming = true

View File

@ -175,7 +175,7 @@ fun ActionButton(
disabled: Boolean = false, disabled: Boolean = false,
click: () -> Unit = {} click: () -> Unit = {}
) { ) {
Surface(shape = RoundedCornerShape(18.dp), color = Color.Transparent) { Surface(shape = RoundedCornerShape(18.dp), color = Color.Transparent, contentColor = LocalContentColor.current) {
Column( Column(
Modifier Modifier
.clickable(onClick = click) .clickable(onClick = click)
@ -220,7 +220,7 @@ fun ActionButton(
disabled: Boolean = false, disabled: Boolean = false,
click: () -> Unit = {} click: () -> Unit = {}
) { ) {
Surface(modifier, shape = RoundedCornerShape(18.dp)) { Surface(modifier, shape = RoundedCornerShape(18.dp), contentColor = LocalContentColor.current) {
Column( Column(
Modifier Modifier
.fillMaxWidth() .fillMaxWidth()

View File

@ -380,7 +380,8 @@ fun SettingsSectionFooter(revert: () -> Unit, save: () -> Unit, disabled: Boolea
fun FooterButton(icon: Painter, title: String, action: () -> Unit, disabled: Boolean) { fun FooterButton(icon: Painter, title: String, action: () -> Unit, disabled: Boolean) {
Surface( Surface(
shape = RoundedCornerShape(20.dp), shape = RoundedCornerShape(20.dp),
color = Color.Black.copy(alpha = 0f) color = Color.Black.copy(alpha = 0f),
contentColor = LocalContentColor.current
) { ) {
val modifier = if (disabled) Modifier else Modifier.clickable { action() } val modifier = if (disabled) Modifier else Modifier.clickable { action() }
Row( Row(

View File

@ -383,7 +383,7 @@ fun SimplexLockView(
} }
LAMode.PASSCODE -> { LAMode.PASSCODE -> {
ModalManager.fullscreen.showCustomModal { close -> ModalManager.fullscreen.showCustomModal { close ->
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background) { Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background, contentColor = LocalContentColor.current) {
SetAppPasscodeView( SetAppPasscodeView(
submit = { submit = {
laLockDelay.set(30) laLockDelay.set(30)
@ -427,7 +427,7 @@ fun SimplexLockView(
when (laResult) { when (laResult) {
LAResult.Success -> { LAResult.Success -> {
ModalManager.fullscreen.showCustomModal { close -> ModalManager.fullscreen.showCustomModal { close ->
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background) { Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background, contentColor = LocalContentColor.current) {
SetAppPasscodeView( SetAppPasscodeView(
reason = generalGetString(MR.strings.la_app_passcode), reason = generalGetString(MR.strings.la_app_passcode),
submit = { submit = {
@ -451,9 +451,10 @@ fun SimplexLockView(
when (laResult) { when (laResult) {
LAResult.Success -> { LAResult.Success -> {
ModalManager.fullscreen.showCustomModal { close -> ModalManager.fullscreen.showCustomModal { close ->
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background) { Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background, contentColor = LocalContentColor.current) {
SetAppPasscodeView( SetAppPasscodeView(
passcodeKeychain = ksSelfDestructPassword, passcodeKeychain = ksSelfDestructPassword,
prohibitedPasscodeKeychain = ksAppPassword,
reason = generalGetString(MR.strings.self_destruct), reason = generalGetString(MR.strings.self_destruct),
submit = { submit = {
selfDestructPasscodeAlert(generalGetString(MR.strings.self_destruct_passcode_changed)) selfDestructPasscodeAlert(generalGetString(MR.strings.self_destruct_passcode_changed))
@ -487,7 +488,7 @@ fun SimplexLockView(
} }
LAMode.PASSCODE -> { LAMode.PASSCODE -> {
ModalManager.fullscreen.showCustomModal { close -> ModalManager.fullscreen.showCustomModal { close ->
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background) { Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background, contentColor = LocalContentColor.current) {
SetAppPasscodeView( SetAppPasscodeView(
submit = { submit = {
laLockDelay.set(30) laLockDelay.set(30)
@ -598,9 +599,9 @@ private fun EnableSelfDestruct(
selfDestruct: SharedPreference<Boolean>, selfDestruct: SharedPreference<Boolean>,
close: () -> Unit close: () -> Unit
) { ) {
Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background) { Surface(Modifier.fillMaxSize(), color = MaterialTheme.colors.background, contentColor = LocalContentColor.current) {
SetAppPasscodeView( SetAppPasscodeView(
passcodeKeychain = ksSelfDestructPassword, title = generalGetString(MR.strings.set_passcode), reason = generalGetString(MR.strings.enabled_self_destruct_passcode), passcodeKeychain = ksSelfDestructPassword, prohibitedPasscodeKeychain = ksAppPassword, title = generalGetString(MR.strings.set_passcode), reason = generalGetString(MR.strings.enabled_self_destruct_passcode),
submit = { submit = {
selfDestruct.set(true) selfDestruct.set(true)
selfDestructPasscodeAlert(generalGetString(MR.strings.self_destruct_passcode_enabled)) selfDestructPasscodeAlert(generalGetString(MR.strings.self_destruct_passcode_enabled))

View File

@ -155,7 +155,8 @@ fun RTCServersLayout(
.height(160.dp) .height(160.dp)
.fillMaxWidth(), .fillMaxWidth(),
shape = RoundedCornerShape(10.dp), shape = RoundedCornerShape(10.dp),
border = BorderStroke(1.dp, MaterialTheme.colors.secondaryVariant) border = BorderStroke(1.dp, MaterialTheme.colors.secondaryVariant),
contentColor = LocalContentColor.current
) { ) {
SelectionContainer( SelectionContainer(
Modifier.verticalScroll(rememberScrollState()) Modifier.verticalScroll(rememberScrollState())

View File

@ -155,7 +155,7 @@ fun UserAddressView(
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
if (userAddress.value != null) { if (userAddress.value != null) {
Surface(Modifier.size(50.dp), color = MaterialTheme.colors.background.copy(0.9f), shape = RoundedCornerShape(50)){} Surface(Modifier.size(50.dp), color = MaterialTheme.colors.background.copy(0.9f), contentColor = LocalContentColor.current, shape = RoundedCornerShape(50)){}
} }
CircularProgressIndicator( CircularProgressIndicator(
Modifier Modifier

View File

@ -24,7 +24,9 @@ fun initApp() {
override fun cancelAllNotifications() = chat.simplex.common.model.NtfManager.cancelAllNotifications() override fun cancelAllNotifications() = chat.simplex.common.model.NtfManager.cancelAllNotifications()
} }
applyAppLocale() applyAppLocale()
initChatControllerAndRunMigrations(false) if (DatabaseUtils.ksSelfDestructPassword.get() == null) {
initChatControllerAndRunMigrations()
}
// LALAL // LALAL
//testCrypto() //testCrypto()
} }

View File

@ -167,7 +167,8 @@ actual fun PlatformTextField(
decorationBox = { innerTextField -> decorationBox = { innerTextField ->
Surface( Surface(
shape = RoundedCornerShape(18.dp), shape = RoundedCornerShape(18.dp),
border = BorderStroke(1.dp, MaterialTheme.colors.secondary) border = BorderStroke(1.dp, MaterialTheme.colors.secondary),
contentColor = LocalContentColor.current
) { ) {
Row( Row(
Modifier.background(MaterialTheme.colors.background), Modifier.background(MaterialTheme.colors.background),

View File

@ -2,8 +2,7 @@ package chat.simplex.common.views.helpers
import androidx.compose.foundation.* import androidx.compose.foundation.*
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme import androidx.compose.material.*
import androidx.compose.material.Surface
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.* import androidx.compose.ui.input.key.*
@ -39,7 +38,8 @@ actual fun DefaultDialog(
) { ) {
Surface( Surface(
Modifier Modifier
.border(border = BorderStroke(1.dp, MaterialTheme.colors.secondary.copy(alpha = 0.3F)), shape = RoundedCornerShape(8)) .border(border = BorderStroke(1.dp, MaterialTheme.colors.secondary.copy(alpha = 0.3F)), shape = RoundedCornerShape(8)),
contentColor = LocalContentColor.current
) { ) {
content() content()
} }

View File

@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package source-repository-package
type: git type: git
location: https://github.com/simplex-chat/simplexmq.git location: https://github.com/simplex-chat/simplexmq.git
tag: 6d4834f306963e2d3f2f62af212fe855ea9c7595 tag: fa794d7878c82c370f1547f01e76f9691d229b92
source-repository-package source-repository-package
type: git type: git

View File

@ -8,9 +8,9 @@ u="$USER"
tmp="$(mktemp -d -t)" tmp="$(mktemp -d -t)"
folder="$tmp/simplex-chat" folder="$tmp/simplex-chat"
nix_ver="nix-2.15.1" nix_ver="nix-2.19.2"
nix_url="https://releases.nixos.org/nix/$nix_ver/install" nix_url="https://releases.nixos.org/nix/$nix_ver/install"
nix_hash="67aa37f0115195d8ddf32b5d6f471f1e60ecca0fdb3e98bcf54bc147c3078640" nix_hash="435f0d7e11f7c7dffeeab0ec9cc55723f6d3c03352379d785633cf4ddb5caf90"
nix_config="sandbox = true nix_config="sandbox = true
max-jobs = auto max-jobs = auto
experimental-features = nix-command flakes" experimental-features = nix-command flakes"
@ -102,8 +102,19 @@ build() {
sed -i.bak '/android {/a lint {abortOnError = false}' "$folder/apps/multiplatform/android/build.gradle.kts" sed -i.bak '/android {/a lint {abortOnError = false}' "$folder/apps/multiplatform/android/build.gradle.kts"
for arch in $arches; do for arch in $arches; do
android_simplex_lib="${folder}#hydraJobs.${arch}-android:lib:simplex-chat.x86_64-linux"
android_support_lib="${folder}#hydraJobs.${arch}-android:lib:support.x86_64-linux" tag_full="$(git tag --points-at HEAD)"
tag_version="${tag_full%%-*}"
if [ "$arch" = "armv7a" ] && [ -n "$tag_full" ] ; then
git checkout "${tag_version}-armv7a"
android_simplex_lib="${folder}#hydraJobs.${arch}-android:lib:simplex-chat.x86_64-linux"
android_support_lib="${folder}#hydraJobs.${arch}-android:lib:support.x86_64-linux"
else
android_simplex_lib="${folder}#hydraJobs.x86_64-linux.${arch}-android:lib:simplex-chat"
android_support_lib="${folder}#hydraJobs.x86_64-linux.${arch}-android:lib:support"
fi
android_simplex_lib_output="${PWD}/result/pkg-${arch}-android-libsimplex.zip" android_simplex_lib_output="${PWD}/result/pkg-${arch}-android-libsimplex.zip"
android_support_lib_output="${PWD}/result/pkg-${arch}-android-libsupport.zip" android_support_lib_output="${PWD}/result/pkg-${arch}-android-libsupport.zip"
@ -139,6 +150,10 @@ build() {
zipalign -p -f 4 "$tmp/$android_apk_output_final" "$PWD/$android_apk_output_final" zipalign -p -f 4 "$tmp/$android_apk_output_final" "$PWD/$android_apk_output_final"
rm -rf "$libs_folder/$android_arch" rm -rf "$libs_folder/$android_arch"
if [ "$arch" = "armv7a" ] && [ -n "$tag_full" ] ; then
git checkout "${tag_full}"
fi
done done
} }

View File

@ -1,5 +1,5 @@
{ {
"https://github.com/simplex-chat/simplexmq.git"."6d4834f306963e2d3f2f62af212fe855ea9c7595" = "1603nlzkncrl8kg9xb8yi4kjbk8d8gmyw7wzvlni7lgbf0hjrffz"; "https://github.com/simplex-chat/simplexmq.git"."fa794d7878c82c370f1547f01e76f9691d229b92" = "0fmgq7yy42rlpf4a0agz3149iqkw5cri85xppwgicl4i9c7bs9gi";
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38"; "https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d"; "https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl"; "https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";

View File

@ -3,7 +3,7 @@
module Simplex.Chat.Mobile.Shared where module Simplex.Chat.Mobile.Shared where
import qualified Data.ByteString as B import qualified Data.ByteString as B
import Data.ByteString.Internal (ByteString (..), memcpy) import Data.ByteString.Internal (ByteString (..))
import qualified Data.ByteString.Lazy as LB import qualified Data.ByteString.Lazy as LB
import qualified Data.ByteString.Lazy.Internal as LB import qualified Data.ByteString.Lazy.Internal as LB
import Foreign import Foreign
@ -21,7 +21,7 @@ getByteString ptr len = do
putByteString :: Ptr Word8 -> ByteString -> IO () putByteString :: Ptr Word8 -> ByteString -> IO ()
putByteString ptr (PS fp offset len) = putByteString ptr (PS fp offset len) =
withForeignPtr fp $ \p -> memcpy ptr (p `plusPtr` offset) len withForeignPtr fp $ \p -> copyBytes ptr (p `plusPtr` offset) len
{-# INLINE putByteString #-} {-# INLINE putByteString #-}
putLazyByteString :: Ptr Word8 -> LB.ByteString -> IO () putLazyByteString :: Ptr Word8 -> LB.ByteString -> IO ()

View File

@ -415,6 +415,7 @@ xftpServerConfig =
logStatsStartTime = 0, logStatsStartTime = 0,
serverStatsLogFile = "tests/tmp/xftp-server-stats.daily.log", serverStatsLogFile = "tests/tmp/xftp-server-stats.daily.log",
serverStatsBackupFile = Nothing, serverStatsBackupFile = Nothing,
controlPort = Nothing,
transportConfig = defaultTransportServerConfig transportConfig = defaultTransportServerConfig
} }

View File

@ -16,11 +16,12 @@ import qualified Data.Aeson.TH as JQ
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import qualified Data.ByteString as B import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as BS import qualified Data.ByteString.Char8 as BS
import Data.ByteString.Internal (create, memcpy) import Data.ByteString.Internal (create)
import qualified Data.ByteString.Lazy.Char8 as LB import qualified Data.ByteString.Lazy.Char8 as LB
import Data.Word (Word8, Word32) import Data.Word (Word8, Word32)
import Foreign.C import Foreign.C
import Foreign.Marshal.Alloc (mallocBytes) import Foreign.Marshal.Alloc (mallocBytes)
import Foreign.Marshal.Utils (copyBytes)
import Foreign.Ptr import Foreign.Ptr
import Foreign.StablePtr import Foreign.StablePtr
import Foreign.Storable (peek) import Foreign.Storable (peek)
@ -291,7 +292,7 @@ testFileCApi fileName tmp = do
peek ptr' `shouldReturn` (0 :: Word8) peek ptr' `shouldReturn` (0 :: Word8)
sz :: Word32 <- peek (ptr' `plusPtr` 1) sz :: Word32 <- peek (ptr' `plusPtr` 1)
let sz' = fromIntegral sz let sz' = fromIntegral sz
contents <- create sz' $ \toPtr -> memcpy toPtr (ptr' `plusPtr` 5) sz' contents <- create sz' $ \toPtr -> copyBytes toPtr (ptr' `plusPtr` 5) sz'
contents `shouldBe` src contents `shouldBe` src
sz' `shouldBe` fromIntegral len sz' `shouldBe` fromIntegral len