mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
Merge branch 'master' into master-android
This commit is contained in:
@@ -579,7 +579,7 @@ struct ChatInfoView: View {
|
||||
let ct = try await apiSetContactPQ(contact.apiId, true)
|
||||
contact = ct
|
||||
await MainActor.run {
|
||||
chatModel.updateContact(contact)
|
||||
chatModel.updateContact(ct)
|
||||
dismiss()
|
||||
}
|
||||
} catch let error {
|
||||
|
||||
@@ -557,7 +557,12 @@ struct ChatView: View {
|
||||
chatItemView(ci, nil, prev)
|
||||
}
|
||||
} else {
|
||||
chatItemView(chatItem, range, prevItem)
|
||||
// Switch branches just to work around context menu problem when 'revealed' changes but size of item isn't
|
||||
if revealed {
|
||||
chatItemView(chatItem, range, prevItem)
|
||||
} else {
|
||||
chatItemView(chatItem, range, prevItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -974,9 +979,8 @@ struct ChatView: View {
|
||||
title: NSLocalizedString("Hide", comment: "chat item action"),
|
||||
image: UIImage(systemName: "eye.slash")
|
||||
) { _ in
|
||||
withAnimation {
|
||||
revealed = false
|
||||
}
|
||||
// With animation it looks bad because of UIKit context menu involved
|
||||
revealed = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1045,9 +1049,8 @@ struct ChatView: View {
|
||||
title: NSLocalizedString("Reveal", comment: "chat item action"),
|
||||
image: UIImage(systemName: "eye")
|
||||
) { _ in
|
||||
withAnimation {
|
||||
revealed = true
|
||||
}
|
||||
// With animation it looks bad because of UIKit context menu involved
|
||||
revealed = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ struct MigrateFromDevice: View {
|
||||
return Alert(
|
||||
title: Text(title),
|
||||
message: Text(text),
|
||||
primaryButton: .destructive(Text("Delete")) {
|
||||
primaryButton: .default(Text("Delete")) {
|
||||
deleteChatAndDismiss()
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
@@ -333,16 +333,16 @@ struct MigrateFromDevice: View {
|
||||
ZStack {
|
||||
List {
|
||||
Section {
|
||||
Button(action: { alert = .deleteChat() }) {
|
||||
settingsRow("trash.fill") {
|
||||
Text("Delete database from this device").foregroundColor(.accentColor)
|
||||
}
|
||||
}
|
||||
Button(action: { alert = .startChat() }) {
|
||||
settingsRow("play.fill") {
|
||||
Text("Start chat").foregroundColor(.red)
|
||||
}
|
||||
}
|
||||
Button(action: { alert = .deleteChat() }) {
|
||||
settingsRow("trash.fill") {
|
||||
Text("Delete database from this device").foregroundColor(.accentColor)
|
||||
}
|
||||
}
|
||||
} header: {
|
||||
Text("Migration complete")
|
||||
} footer: {
|
||||
|
||||
@@ -276,6 +276,7 @@ struct UserProfilesView: View {
|
||||
// Deleting the last visible user while having hidden one(s)
|
||||
try await deleteUser()
|
||||
try await changeActiveUserAsync_(nil, viewPwd: nil)
|
||||
try? await stopChatAsync()
|
||||
await MainActor.run {
|
||||
onboardingStageDefault.set(.step1_SimpleXInfo)
|
||||
m.onboardingStage = .step1_SimpleXInfo
|
||||
|
||||
@@ -36,6 +36,11 @@
|
||||
5C35CFC827B2782E00FB6C6D /* BGManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C35CFC727B2782E00FB6C6D /* BGManager.swift */; };
|
||||
5C35CFCB27B2E91D00FB6C6D /* NtfManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C35CFCA27B2E91D00FB6C6D /* NtfManager.swift */; };
|
||||
5C36027327F47AD5009F19D9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C36027227F47AD5009F19D9 /* AppDelegate.swift */; };
|
||||
5C371E6A2BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C371E652BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH.a */; };
|
||||
5C371E6B2BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C371E662BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH-ghc9.6.3.a */; };
|
||||
5C371E6C2BA9FDFA00100AD3 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C371E672BA9FDFA00100AD3 /* libgmpxx.a */; };
|
||||
5C371E6D2BA9FDFA00100AD3 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C371E682BA9FDFA00100AD3 /* libffi.a */; };
|
||||
5C371E6E2BA9FDFA00100AD3 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C371E692BA9FDFA00100AD3 /* libgmp.a */; };
|
||||
5C3A88CE27DF50170060F1C2 /* DetermineWidth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3A88CD27DF50170060F1C2 /* DetermineWidth.swift */; };
|
||||
5C3A88D127DF57800060F1C2 /* FramedItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3A88D027DF57800060F1C2 /* FramedItemView.swift */; };
|
||||
5C3CCFCC2AE6BD3100C3F0C3 /* ConnectDesktopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3CCFCB2AE6BD3100C3F0C3 /* ConnectDesktopView.swift */; };
|
||||
@@ -57,11 +62,6 @@
|
||||
5C65F343297D45E100B67AF3 /* VersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C65F341297D3F3600B67AF3 /* VersionView.swift */; };
|
||||
5C6BA667289BD954009B8ECC /* DismissSheets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6BA666289BD954009B8ECC /* DismissSheets.swift */; };
|
||||
5C7031162953C97F00150A12 /* CIFeaturePreferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7031152953C97F00150A12 /* CIFeaturePreferenceView.swift */; };
|
||||
5C746DB82BA0DA920049D734 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C746DB32BA0DA920049D734 /* libffi.a */; };
|
||||
5C746DB92BA0DA920049D734 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C746DB42BA0DA920049D734 /* libgmpxx.a */; };
|
||||
5C746DBA2BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C746DB52BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo.a */; };
|
||||
5C746DBB2BA0DA920049D734 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C746DB62BA0DA920049D734 /* libgmp.a */; };
|
||||
5C746DBC2BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C746DB72BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo-ghc9.6.3.a */; };
|
||||
5C7505A227B65FDB00BE3227 /* CIMetaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A127B65FDB00BE3227 /* CIMetaView.swift */; };
|
||||
5C7505A527B679EE00BE3227 /* NavLinkPlain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A427B679EE00BE3227 /* NavLinkPlain.swift */; };
|
||||
5C7505A827B6D34800BE3227 /* ChatInfoToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A727B6D34800BE3227 /* ChatInfoToolbar.swift */; };
|
||||
@@ -296,6 +296,11 @@
|
||||
5C371E4E2BA9AAA200100AD3 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
5C371E4F2BA9AB6400100AD3 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = "hu.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
5C371E502BA9AB6400100AD3 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
5C371E652BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH.a"; sourceTree = "<group>"; };
|
||||
5C371E662BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
5C371E672BA9FDFA00100AD3 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
5C371E682BA9FDFA00100AD3 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
5C371E692BA9FDFA00100AD3 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
5C3A88CD27DF50170060F1C2 /* DetermineWidth.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetermineWidth.swift; sourceTree = "<group>"; };
|
||||
5C3A88D027DF57800060F1C2 /* FramedItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FramedItemView.swift; sourceTree = "<group>"; };
|
||||
5C3CCFCB2AE6BD3100C3F0C3 /* ConnectDesktopView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectDesktopView.swift; sourceTree = "<group>"; };
|
||||
@@ -332,11 +337,6 @@
|
||||
5C6D183229E93FBA00D430B3 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = "pl.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
5C6D183329E93FBA00D430B3 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
5C7031152953C97F00150A12 /* CIFeaturePreferenceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIFeaturePreferenceView.swift; sourceTree = "<group>"; };
|
||||
5C746DB32BA0DA920049D734 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
5C746DB42BA0DA920049D734 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
5C746DB52BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo.a"; sourceTree = "<group>"; };
|
||||
5C746DB62BA0DA920049D734 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
5C746DB72BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
5C7505A127B65FDB00BE3227 /* CIMetaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIMetaView.swift; sourceTree = "<group>"; };
|
||||
5C7505A427B679EE00BE3227 /* NavLinkPlain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavLinkPlain.swift; sourceTree = "<group>"; };
|
||||
5C7505A727B6D34800BE3227 /* ChatInfoToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInfoToolbar.swift; sourceTree = "<group>"; };
|
||||
@@ -533,12 +533,12 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5C746DB92BA0DA920049D734 /* libgmpxx.a in Frameworks */,
|
||||
5C746DBA2BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo.a in Frameworks */,
|
||||
5C371E6A2BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH.a in Frameworks */,
|
||||
5C371E6E2BA9FDFA00100AD3 /* libgmp.a in Frameworks */,
|
||||
5C371E6D2BA9FDFA00100AD3 /* libffi.a in Frameworks */,
|
||||
5C371E6C2BA9FDFA00100AD3 /* libgmpxx.a in Frameworks */,
|
||||
5C371E6B2BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH-ghc9.6.3.a in Frameworks */,
|
||||
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
|
||||
5C746DB82BA0DA920049D734 /* libffi.a in Frameworks */,
|
||||
5C746DBC2BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo-ghc9.6.3.a in Frameworks */,
|
||||
5C746DBB2BA0DA920049D734 /* libgmp.a in Frameworks */,
|
||||
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -602,11 +602,11 @@
|
||||
5C764E5C279C70B7000C6508 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5C746DB32BA0DA920049D734 /* libffi.a */,
|
||||
5C746DB62BA0DA920049D734 /* libgmp.a */,
|
||||
5C746DB42BA0DA920049D734 /* libgmpxx.a */,
|
||||
5C746DB72BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo-ghc9.6.3.a */,
|
||||
5C746DB52BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo.a */,
|
||||
5C371E682BA9FDFA00100AD3 /* libffi.a */,
|
||||
5C371E692BA9FDFA00100AD3 /* libgmp.a */,
|
||||
5C371E672BA9FDFA00100AD3 /* libgmpxx.a */,
|
||||
5C371E662BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH-ghc9.6.3.a */,
|
||||
5C371E652BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH.a */,
|
||||
);
|
||||
path = Libraries;
|
||||
sourceTree = "<group>";
|
||||
@@ -1546,7 +1546,7 @@
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 202;
|
||||
CURRENT_PROJECT_VERSION = 203;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
@@ -1589,7 +1589,7 @@
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 202;
|
||||
CURRENT_PROJECT_VERSION = 203;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
@@ -1670,7 +1670,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 202;
|
||||
CURRENT_PROJECT_VERSION = 203;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@@ -1702,7 +1702,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 202;
|
||||
CURRENT_PROJECT_VERSION = 203;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
ENABLE_BITCODE = NO;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@@ -1734,7 +1734,7 @@
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 202;
|
||||
CURRENT_PROJECT_VERSION = 203;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@@ -1780,7 +1780,7 @@
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 202;
|
||||
CURRENT_PROJECT_VERSION = 203;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5NN7GUYB6T;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package chat.simplex.common.platform
|
||||
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.gestures.FlingBehavior
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
@Composable
|
||||
actual fun LazyColumnWithScrollBar(
|
||||
modifier: Modifier,
|
||||
state: LazyListState,
|
||||
contentPadding: PaddingValues,
|
||||
reverseLayout: Boolean,
|
||||
verticalArrangement: Arrangement.Vertical,
|
||||
horizontalAlignment: Alignment.Horizontal,
|
||||
flingBehavior: FlingBehavior,
|
||||
userScrollEnabled: Boolean,
|
||||
content: LazyListScope.() -> Unit
|
||||
) {
|
||||
LazyColumn(modifier, state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled, content)
|
||||
}
|
||||
|
||||
@Composable
|
||||
actual fun ColumnWithScrollBar(
|
||||
modifier: Modifier,
|
||||
verticalArrangement: Arrangement.Vertical,
|
||||
horizontalAlignment: Alignment.Horizontal,
|
||||
state: ScrollState,
|
||||
content: @Composable ColumnScope.() -> Unit
|
||||
) {
|
||||
Column(modifier.verticalScroll(rememberScrollState()), verticalArrangement, horizontalAlignment, content)
|
||||
}
|
||||
+1
-1
@@ -154,7 +154,7 @@ actual fun ActiveCallView() {
|
||||
setCallSound(call.soundSpeaker, audioViaBluetooth)
|
||||
}
|
||||
withBGApi { chatModel.controller.apiCallStatus(callRh, call.contact, callStatus) }
|
||||
} catch (e: Error) {
|
||||
} catch (e: Throwable) {
|
||||
Log.d(TAG,"call status ${r.state.connectionState} not used")
|
||||
}
|
||||
is WCallResponse.Connected -> {
|
||||
|
||||
+2
-2
@@ -85,8 +85,8 @@ fun AppearanceScope.AppearanceLayout(
|
||||
showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
|
||||
editColor: (ThemeColor, Color) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.appearance_settings))
|
||||
SectionView(stringResource(MR.strings.settings_section_title_language), padding = PaddingValues()) {
|
||||
|
||||
+15
-15
@@ -75,7 +75,7 @@ class AppPreferences {
|
||||
val value = _callOnLockScreen.get() ?: return CallOnLockScreen.default
|
||||
return try {
|
||||
CallOnLockScreen.valueOf(value)
|
||||
} catch (e: Error) {
|
||||
} catch (e: Throwable) {
|
||||
CallOnLockScreen.default
|
||||
}
|
||||
},
|
||||
@@ -95,7 +95,7 @@ class AppPreferences {
|
||||
val value = _simplexLinkMode.get() ?: return SimplexLinkMode.default
|
||||
return try {
|
||||
SimplexLinkMode.valueOf(value)
|
||||
} catch (e: Error) {
|
||||
} catch (e: Throwable) {
|
||||
SimplexLinkMode.default
|
||||
}
|
||||
},
|
||||
@@ -123,7 +123,7 @@ class AppPreferences {
|
||||
val value = _networkSessionMode.get() ?: return TransportSessionMode.default
|
||||
return try {
|
||||
TransportSessionMode.valueOf(value)
|
||||
} catch (e: Error) {
|
||||
} catch (e: Throwable) {
|
||||
TransportSessionMode.default
|
||||
}
|
||||
},
|
||||
@@ -393,7 +393,7 @@ object ChatController {
|
||||
}
|
||||
Log.d(TAG, "startChat: running")
|
||||
}
|
||||
} catch (e: Error) {
|
||||
} catch (e: Throwable) {
|
||||
Log.e(TAG, "failed starting chat $e")
|
||||
throw e
|
||||
}
|
||||
@@ -411,7 +411,7 @@ object ChatController {
|
||||
startReceiver()
|
||||
setLocalDeviceName(appPrefs.deviceNameForRemoteAccess.get()!!)
|
||||
Log.d(TAG, "startChat: started without user")
|
||||
} catch (e: Error) {
|
||||
} catch (e: Throwable) {
|
||||
Log.e(TAG, "failed starting chat without user $e")
|
||||
throw e
|
||||
}
|
||||
@@ -628,7 +628,7 @@ object ChatController {
|
||||
when (r) {
|
||||
is CR.ChatStarted -> return true
|
||||
is CR.ChatRunning -> return false
|
||||
else -> throw Error("failed starting chat: ${r.responseType} ${r.details}")
|
||||
else -> throw Exception("failed starting chat: ${r.responseType} ${r.details}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,26 +636,26 @@ object ChatController {
|
||||
val r = sendCmd(null, CC.ApiStopChat())
|
||||
when (r) {
|
||||
is CR.ChatStopped -> return true
|
||||
else -> throw Error("failed stopping chat: ${r.responseType} ${r.details}")
|
||||
else -> throw Exception("failed stopping chat: ${r.responseType} ${r.details}")
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun apiSetTempFolder(tempFolder: String, ctrl: ChatCtrl? = null) {
|
||||
val r = sendCmd(null, CC.SetTempFolder(tempFolder), ctrl)
|
||||
if (r is CR.CmdOk) return
|
||||
throw Error("failed to set temp folder: ${r.responseType} ${r.details}")
|
||||
throw Exception("failed to set temp folder: ${r.responseType} ${r.details}")
|
||||
}
|
||||
|
||||
suspend fun apiSetFilesFolder(filesFolder: String, ctrl: ChatCtrl? = null) {
|
||||
val r = sendCmd(null, CC.SetFilesFolder(filesFolder), ctrl)
|
||||
if (r is CR.CmdOk) return
|
||||
throw Error("failed to set files folder: ${r.responseType} ${r.details}")
|
||||
throw Exception("failed to set files folder: ${r.responseType} ${r.details}")
|
||||
}
|
||||
|
||||
suspend fun apiSetRemoteHostsFolder(remoteHostsFolder: String) {
|
||||
val r = sendCmd(null, CC.SetRemoteHostsFolder(remoteHostsFolder))
|
||||
if (r is CR.CmdOk) return
|
||||
throw Error("failed to set remote hosts folder: ${r.responseType} ${r.details}")
|
||||
throw Exception("failed to set remote hosts folder: ${r.responseType} ${r.details}")
|
||||
}
|
||||
|
||||
suspend fun apiSetEncryptLocalFiles(enable: Boolean) = sendCommandOkResp(null, CC.ApiSetEncryptLocalFiles(enable))
|
||||
@@ -663,13 +663,13 @@ object ChatController {
|
||||
suspend fun apiSaveAppSettings(settings: AppSettings) {
|
||||
val r = sendCmd(null, CC.ApiSaveSettings(settings))
|
||||
if (r is CR.CmdOk) return
|
||||
throw Error("failed to set app settings: ${r.responseType} ${r.details}")
|
||||
throw Exception("failed to set app settings: ${r.responseType} ${r.details}")
|
||||
}
|
||||
|
||||
suspend fun apiGetAppSettings(settings: AppSettings): AppSettings {
|
||||
val r = sendCmd(null, CC.ApiGetSettings(settings))
|
||||
if (r is CR.AppSettingsR) return r.appSettings
|
||||
throw Error("failed to get app settings: ${r.responseType} ${r.details}")
|
||||
throw Exception("failed to get app settings: ${r.responseType} ${r.details}")
|
||||
}
|
||||
|
||||
suspend fun apiSetPQEncryption(enable: Boolean) = sendCommandOkResp(null, CC.ApiSetPQEncryption(enable))
|
||||
@@ -684,19 +684,19 @@ object ChatController {
|
||||
suspend fun apiExportArchive(config: ArchiveConfig) {
|
||||
val r = sendCmd(null, CC.ApiExportArchive(config))
|
||||
if (r is CR.CmdOk) return
|
||||
throw Error("failed to export archive: ${r.responseType} ${r.details}")
|
||||
throw Exception("failed to export archive: ${r.responseType} ${r.details}")
|
||||
}
|
||||
|
||||
suspend fun apiImportArchive(config: ArchiveConfig): List<ArchiveError> {
|
||||
val r = sendCmd(null, CC.ApiImportArchive(config))
|
||||
if (r is CR.ArchiveImported) return r.archiveErrors
|
||||
throw Error("failed to import archive: ${r.responseType} ${r.details}")
|
||||
throw Exception("failed to import archive: ${r.responseType} ${r.details}")
|
||||
}
|
||||
|
||||
suspend fun apiDeleteStorage() {
|
||||
val r = sendCmd(null, CC.ApiDeleteStorage())
|
||||
if (r is CR.CmdOk) return
|
||||
throw Error("failed to delete storage: ${r.responseType} ${r.details}")
|
||||
throw Exception("failed to delete storage: ${r.responseType} ${r.details}")
|
||||
}
|
||||
|
||||
suspend fun apiStorageEncryption(currentKey: String = "", newKey: String = ""): CR.ChatCmdError? {
|
||||
|
||||
+2
-2
@@ -42,7 +42,7 @@ fun copyFileToFile(from: File, to: URI, finally: () -> Unit) {
|
||||
}
|
||||
}
|
||||
showToast(generalGetString(MR.strings.file_saved))
|
||||
} catch (e: Error) {
|
||||
} catch (e: Throwable) {
|
||||
showToast(generalGetString(MR.strings.error_saving_file))
|
||||
Log.e(TAG, "copyFileToFile error saving file $e")
|
||||
} finally {
|
||||
@@ -58,7 +58,7 @@ fun copyBytesToFile(bytes: ByteArrayInputStream, to: URI, finally: () -> Unit) {
|
||||
}
|
||||
}
|
||||
showToast(generalGetString(MR.strings.file_saved))
|
||||
} catch (e: Error) {
|
||||
} catch (e: Throwable) {
|
||||
showToast(generalGetString(MR.strings.error_saving_file))
|
||||
Log.e(TAG, "copyBytesToFile error saving file $e")
|
||||
} finally {
|
||||
|
||||
+10
-1
@@ -1,8 +1,14 @@
|
||||
package chat.simplex.common.platform
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.AnimationVector1D
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import chat.simplex.common.model.ChatId
|
||||
import chat.simplex.common.model.NotificationsMode
|
||||
import kotlinx.coroutines.Job
|
||||
|
||||
interface PlatformInterface {
|
||||
suspend fun androidServiceStart() {}
|
||||
@@ -19,6 +25,9 @@ interface PlatformInterface {
|
||||
fun androidCallEnded() {}
|
||||
@Composable fun androidLockPortraitOrientation() {}
|
||||
suspend fun androidAskToAllowBackgroundCalls(): Boolean = true
|
||||
@Composable fun desktopScrollBarComponents(): Triple<Animatable<Float, AnimationVector1D>, Modifier, MutableState<Job>> = remember { Triple(Animatable(0f), Modifier, mutableStateOf(Job())) }
|
||||
@Composable fun desktopScrollBar(state: LazyListState, modifier: Modifier, scrollBarAlpha: Animatable<Float, AnimationVector1D>, scrollJob: MutableState<Job>, reversed: Boolean) {}
|
||||
@Composable fun desktopScrollBar(state: ScrollState, modifier: Modifier, scrollBarAlpha: Animatable<Float, AnimationVector1D>, scrollJob: MutableState<Job>, reversed: Boolean) {}
|
||||
}
|
||||
/**
|
||||
* Multiplatform project has separate directories per platform + common directory that contains directories per platform + common for all of them.
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package chat.simplex.common.platform
|
||||
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.gestures.FlingBehavior
|
||||
import androidx.compose.foundation.gestures.ScrollableDefaults
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
expect fun LazyColumnWithScrollBar(
|
||||
modifier: Modifier = Modifier,
|
||||
state: LazyListState = rememberLazyListState(),
|
||||
contentPadding: PaddingValues = PaddingValues(0.dp),
|
||||
reverseLayout: Boolean = false,
|
||||
verticalArrangement: Arrangement.Vertical =
|
||||
if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
|
||||
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
|
||||
flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
|
||||
userScrollEnabled: Boolean = true,
|
||||
content: LazyListScope.() -> Unit
|
||||
)
|
||||
|
||||
@Composable
|
||||
expect fun ColumnWithScrollBar(
|
||||
modifier: Modifier = Modifier,
|
||||
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
|
||||
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
|
||||
state: ScrollState = rememberScrollState(),
|
||||
content: @Composable ColumnScope.() -> Unit
|
||||
)
|
||||
+1
-1
@@ -130,7 +130,7 @@ fun TerminalLog() {
|
||||
derivedStateOf { chatModel.terminalItems.value.asReversed() }
|
||||
}
|
||||
val clipboard = LocalClipboardManager.current
|
||||
LazyColumn(state = listState, reverseLayout = true) {
|
||||
LazyColumnWithScrollBar(state = listState, reverseLayout = true) {
|
||||
items(reversedTerminalItems) { item ->
|
||||
val rhId = item.remoteHostId
|
||||
val rhIdStr = if (rhId == null) "" else "$rhId "
|
||||
|
||||
+6
-5
@@ -49,8 +49,8 @@ fun CreateProfile(chatModel: ChatModel, close: () -> Unit) {
|
||||
val displayName = rememberSaveable { mutableStateOf("") }
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())
|
||||
ColumnWithScrollBar(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
Column(Modifier.padding(horizontal = DEFAULT_PADDING)) {
|
||||
AppBarTitle(stringResource(MR.strings.create_profile), bottomPadding = DEFAULT_PADDING)
|
||||
@@ -120,8 +120,8 @@ fun CreateFirstProfile(chatModel: ChatModel, close: () -> Unit) {
|
||||
val displayName = rememberSaveable { mutableStateOf("") }
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())
|
||||
ColumnWithScrollBar(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
/*CloseSheetBar(close = {
|
||||
if (chatModel.users.isEmpty()) {
|
||||
@@ -214,7 +214,8 @@ fun createProfileOnboarding(chatModel: ChatModel, displayName: String, close: ()
|
||||
) ?: return@withBGApi
|
||||
chatModel.localUserCreated.value = true
|
||||
val onboardingStage = chatModel.controller.appPrefs.onboardingStage
|
||||
if (chatModel.users.isEmpty()) {
|
||||
// No users or no visible users
|
||||
if (chatModel.users.none { u -> !u.user.hidden }) {
|
||||
onboardingStage.set(if (appPlatform.isDesktop && chatModel.controller.appPrefs.initialRandomDBPassphrase.get() && !chatModel.desktopOnboardingRandomPassword.value) {
|
||||
OnboardingStage.Step2_5_SetupDatabasePassphrase
|
||||
} else {
|
||||
|
||||
+2
-3
@@ -145,7 +145,7 @@ fun ChatInfoView(
|
||||
withBGApi {
|
||||
val ct = chatModel.controller.apiSetContactPQ(chatRh, contact.contactId, true)
|
||||
if (ct != null) {
|
||||
chatModel.updateContact(chatRh, contact)
|
||||
chatModel.updateContact(chatRh, ct)
|
||||
}
|
||||
close.invoke()
|
||||
}
|
||||
@@ -319,10 +319,9 @@ fun ChatInfoLayout(
|
||||
KeyChangeEffect(chat.id) {
|
||||
scope.launch { scrollState.scrollTo(0) }
|
||||
}
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(scrollState)
|
||||
) {
|
||||
Row(
|
||||
Modifier.fillMaxWidth(),
|
||||
|
||||
+7
-5
@@ -24,11 +24,10 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.onRightClick
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.views.chat.item.ItemAction
|
||||
import chat.simplex.common.views.chat.item.MarkdownText
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.platform.shareText
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.res.MR
|
||||
import dev.icerock.moko.resources.ImageResource
|
||||
@@ -186,7 +185,8 @@ fun ChatItemInfoView(chatModel: ChatModel, ci: ChatItem, ciInfo: ChatItemInfo, d
|
||||
|
||||
@Composable
|
||||
fun HistoryTab() {
|
||||
Column(Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) {
|
||||
// LALAL SCROLLBAR DOESN'T WORK
|
||||
ColumnWithScrollBar(Modifier.fillMaxWidth()) {
|
||||
Details()
|
||||
SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = false)
|
||||
val versions = ciInfo.itemVersions
|
||||
@@ -210,7 +210,8 @@ fun ChatItemInfoView(chatModel: ChatModel, ci: ChatItem, ciInfo: ChatItemInfo, d
|
||||
|
||||
@Composable
|
||||
fun QuoteTab(qi: CIQuote) {
|
||||
Column(Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) {
|
||||
// LALAL SCROLLBAR DOESN'T WORK
|
||||
ColumnWithScrollBar(Modifier.fillMaxWidth()) {
|
||||
Details()
|
||||
SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = false)
|
||||
SectionView(padding = PaddingValues(horizontal = DEFAULT_PADDING)) {
|
||||
@@ -267,7 +268,8 @@ fun ChatItemInfoView(chatModel: ChatModel, ci: ChatItem, ciInfo: ChatItemInfo, d
|
||||
|
||||
@Composable
|
||||
fun DeliveryTab(memberDeliveryStatuses: List<MemberDeliveryStatus>) {
|
||||
Column(Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) {
|
||||
// LALAL SCROLLBAR DOESN'T WORK
|
||||
ColumnWithScrollBar(Modifier.fillMaxWidth()) {
|
||||
Details()
|
||||
SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = false)
|
||||
val mss = membersStatuses(chatModel, memberDeliveryStatuses)
|
||||
|
||||
+4
-2
@@ -1,5 +1,6 @@
|
||||
package chat.simplex.common.views.chat
|
||||
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.gestures.*
|
||||
@@ -21,6 +22,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.intl.Locale
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.input.pointer.*
|
||||
import androidx.compose.ui.text.*
|
||||
import androidx.compose.ui.unit.*
|
||||
import chat.simplex.common.model.*
|
||||
@@ -473,7 +475,7 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: suspend (chatId:
|
||||
}
|
||||
is ChatInfo.InvalidJSON -> {
|
||||
val close = { chatModel.chatId.value = null }
|
||||
ModalView(close, showClose = appPlatform.isAndroid, content = {
|
||||
ModalView(close, showClose = appPlatform.isAndroid, endButtons = { ShareButton { clipboard.shareText(chat.chatInfo.json) } }, content = {
|
||||
InvalidJSONView(chat.chatInfo.json)
|
||||
})
|
||||
LaunchedEffect(chat.id) {
|
||||
@@ -907,7 +909,7 @@ fun BoxWithConstraintsScope.ChatItemsList(
|
||||
VideoPlayerHolder.releaseAll()
|
||||
}
|
||||
)
|
||||
LazyColumn(Modifier.align(Alignment.BottomCenter), state = listState, reverseLayout = true) {
|
||||
LazyColumnWithScrollBar(Modifier.align(Alignment.BottomCenter), state = listState, reverseLayout = true) {
|
||||
itemsIndexed(reversedChatItems, key = { _, item -> item.id }) { i, cItem ->
|
||||
CompositionLocalProvider(
|
||||
// Makes horizontal and vertical scrolling to coexist nicely.
|
||||
|
||||
+3
-3
@@ -19,6 +19,7 @@ import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.usersettings.PreferenceToggle
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.res.MR
|
||||
|
||||
@Composable
|
||||
@@ -77,10 +78,9 @@ private fun ContactPreferencesLayout(
|
||||
reset: () -> Unit,
|
||||
savePrefs: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.contact_preferences))
|
||||
val timedMessages: MutableState<Boolean> = remember(featuresAllowed) { mutableStateOf(featuresAllowed.timedMessagesAllowed) }
|
||||
|
||||
+2
-4
@@ -16,8 +16,7 @@ import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.platform.appPlatform
|
||||
import chat.simplex.common.platform.shareText
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.newchat.QRCode
|
||||
@@ -57,10 +56,9 @@ private fun VerifyCodeLayout(
|
||||
connectionVerified: Boolean,
|
||||
verifyCode: (String?, cb: (Boolean) -> Unit) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = DEFAULT_PADDING)
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.security_code), withPadding = false)
|
||||
|
||||
+2
-3
@@ -125,10 +125,9 @@ fun AddGroupMembersLayout(
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.button_add_members))
|
||||
profileText()
|
||||
|
||||
+2
-1
@@ -205,7 +205,8 @@ fun GroupChatInfoLayout(
|
||||
}
|
||||
val searchText = rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue()) }
|
||||
val filteredMembers = remember(members) { derivedStateOf { members.filter { it.chatViewName.lowercase().contains(searchText.value.text.trim()) } } }
|
||||
LazyColumn(
|
||||
// LALAL strange scrolling
|
||||
LazyColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxWidth(),
|
||||
state = listState
|
||||
|
||||
+3
-3
@@ -16,6 +16,7 @@ import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.platform.shareText
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
@@ -118,9 +119,8 @@ fun GroupLinkLayout(
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
Modifier
|
||||
.verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier,
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.group_link))
|
||||
Text(
|
||||
|
||||
+2
-3
@@ -291,10 +291,9 @@ fun GroupMemberInfoLayout(
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
Row(
|
||||
Modifier.fillMaxWidth(),
|
||||
|
||||
+3
-2
@@ -18,6 +18,7 @@ import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.usersettings.PreferenceToggleWithIcon
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.res.MR
|
||||
|
||||
@Composable
|
||||
@@ -72,8 +73,8 @@ private fun GroupPreferencesLayout(
|
||||
reset: () -> Unit,
|
||||
savePrefs: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.group_preferences))
|
||||
val timedMessages = remember(preferences) { mutableStateOf(preferences.timedMessages.enable) }
|
||||
|
||||
+1
-2
@@ -95,9 +95,8 @@ fun GroupProfileLayout(
|
||||
sheetShape = RoundedCornerShape(topStart = 18.dp, topEnd = 18.dp)
|
||||
) {
|
||||
ModalView(close = closeWithAlert) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.verticalScroll(scrollState)
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxWidth()
|
||||
|
||||
+3
-2
@@ -29,6 +29,7 @@ import chat.simplex.common.views.chat.item.MarkdownText
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.model.GroupInfo
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.platform.chatJsonLength
|
||||
import chat.simplex.common.ui.theme.DEFAULT_PADDING_HALF
|
||||
import chat.simplex.res.MR
|
||||
@@ -91,8 +92,8 @@ private fun GroupWelcomeLayout(
|
||||
linkMode: SimplexLinkMode,
|
||||
save: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
val editMode = remember { mutableStateOf(true) }
|
||||
AppBarTitle(stringResource(MR.strings.group_welcome_title))
|
||||
|
||||
+5
-13
@@ -1,6 +1,5 @@
|
||||
package chat.simplex.common.views.chat.item
|
||||
|
||||
import SectionView
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.*
|
||||
@@ -8,23 +7,23 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.platform.shareText
|
||||
import chat.simplex.common.ui.theme.DEFAULT_PADDING
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.usersettings.SettingsActionItem
|
||||
import chat.simplex.res.MR
|
||||
|
||||
@Composable
|
||||
fun CIInvalidJSONView(json: String) {
|
||||
val clipboard = LocalClipboardManager.current
|
||||
Row(Modifier
|
||||
.clickable {
|
||||
ModalManager.center.closeModals()
|
||||
ModalManager.end.closeModals()
|
||||
ModalManager.center.showModal(true) { InvalidJSONView(json) }
|
||||
ModalManager.center.showModal(true, endButtons = { ShareButton { clipboard.shareText(json) } }) { InvalidJSONView(json) }
|
||||
}
|
||||
.padding(horizontal = 10.dp, vertical = 6.dp)
|
||||
) {
|
||||
@@ -34,15 +33,8 @@ fun CIInvalidJSONView(json: String) {
|
||||
|
||||
@Composable
|
||||
fun InvalidJSONView(json: String) {
|
||||
Column {
|
||||
Spacer(Modifier.height(DEFAULT_PADDING))
|
||||
SectionView {
|
||||
val clipboard = LocalClipboardManager.current
|
||||
SettingsActionItem(painterResource(MR.images.ic_share), generalGetString(MR.strings.share_verb), click = {
|
||||
clipboard.shareText(json)
|
||||
})
|
||||
}
|
||||
Column(Modifier.padding(DEFAULT_PADDING).fillMaxWidth().verticalScroll(rememberScrollState())) {
|
||||
ColumnWithScrollBar {
|
||||
Column(Modifier.padding(DEFAULT_PADDING).fillMaxWidth()) {
|
||||
Text(json)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -460,7 +460,7 @@ private fun ChatList(chatModel: ChatModel, searchText: MutableState<TextFieldVal
|
||||
val searchShowingSimplexLink = remember { mutableStateOf(false) }
|
||||
val searchChatFilteredBySimplexLink = remember { mutableStateOf<String?>(null) }
|
||||
val chats = filteredChats(showUnreadAndFavorites, searchShowingSimplexLink, searchChatFilteredBySimplexLink, searchText.value.text, allChats.toList())
|
||||
LazyColumn(
|
||||
LazyColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
listState
|
||||
) {
|
||||
|
||||
+2
-5
@@ -1,7 +1,6 @@
|
||||
package chat.simplex.common.views.chatlist
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
@@ -14,12 +13,10 @@ import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.SettingsViewState
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.model.Chat
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.platform.BackHandler
|
||||
import chat.simplex.common.platform.appPlatform
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.res.MR
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
@@ -146,7 +143,7 @@ private fun ShareList(chatModel: ChatModel, search: String) {
|
||||
if (search.isEmpty()) chatModel.chats.toList().filter { it.chatInfo.ready } else chatModel.chats.toList().filter { it.chatInfo.ready }.filter(filter)
|
||||
}
|
||||
}
|
||||
LazyColumn(
|
||||
LazyColumnWithScrollBar(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
items(chats) { chat ->
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ fun ChatArchiveLayout(
|
||||
saveArchive: () -> Unit,
|
||||
deleteArchiveAlert: () -> Unit
|
||||
) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(title)
|
||||
|
||||
+9
-2
@@ -27,7 +27,7 @@ import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.unit.*
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.appPreferences
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.usersettings.SettingsActionItem
|
||||
@@ -100,8 +100,10 @@ fun DatabaseEncryptionLayout(
|
||||
migration: Boolean,
|
||||
onConfirmEncrypt: () -> Unit,
|
||||
) {
|
||||
val (scrollBarAlpha, scrollModifier, scrollJob) = platform.desktopScrollBarComponents()
|
||||
val scrollState = rememberScrollState()
|
||||
Column(
|
||||
if (!migration) Modifier.fillMaxWidth().verticalScroll(rememberScrollState()) else Modifier.fillMaxWidth(),
|
||||
if (!migration) Modifier.fillMaxWidth().verticalScroll(scrollState).then(if (appPlatform.isDesktop) scrollModifier else Modifier) else Modifier.fillMaxWidth(),
|
||||
) {
|
||||
if (!migration) {
|
||||
AppBarTitle(stringResource(MR.strings.database_passphrase))
|
||||
@@ -190,6 +192,11 @@ fun DatabaseEncryptionLayout(
|
||||
}
|
||||
SectionBottomSpacer()
|
||||
}
|
||||
if (appPlatform.isDesktop && !migration) {
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
platform.desktopScrollBar(scrollState, Modifier.align(Alignment.CenterEnd).fillMaxHeight(), scrollBarAlpha, scrollJob, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expect fun encryptDatabaseSavedAlert(onConfirm: () -> Unit)
|
||||
|
||||
+2
-2
@@ -76,8 +76,8 @@ fun DatabaseErrorView(
|
||||
Text(String.format(generalGetString(MR.strings.database_migrations), ms.joinToString(", ")))
|
||||
}
|
||||
|
||||
Column(
|
||||
Modifier.fillMaxSize().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
val buttonEnabled = validKey(dbKey.value) && !progressIndicator.value
|
||||
|
||||
+3
-6
@@ -7,8 +7,6 @@ import SectionItemView
|
||||
import SectionView
|
||||
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -27,7 +25,6 @@ import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.usersettings.*
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.res.MR
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.datetime.*
|
||||
import java.io.*
|
||||
@@ -158,8 +155,8 @@ fun DatabaseLayout(
|
||||
val stopped = !runChat
|
||||
val operationsDisabled = (!stopped || progressIndicator) && !chatModel.desktopNoUserNoRemote
|
||||
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.your_chat_database))
|
||||
|
||||
@@ -391,7 +388,7 @@ fun startChat(m: ChatModel, chatLastStart: MutableState<Instant?>, chatDbChanged
|
||||
m.controller.appPrefs.chatLastStart.set(ts)
|
||||
chatLastStart.value = ts
|
||||
platform.androidChatStartedAfterBeingOff()
|
||||
} catch (e: Error) {
|
||||
} catch (e: Throwable) {
|
||||
m.chatRunning.value = false
|
||||
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_starting_chat), e.toString())
|
||||
} finally {
|
||||
|
||||
+2
-3
@@ -61,9 +61,8 @@ fun <T> SectionViewSelectable(
|
||||
onSelected: (T) -> Unit,
|
||||
) {
|
||||
SectionView(title) {
|
||||
LazyColumn {
|
||||
items(values.size) { index ->
|
||||
val item = values[index]
|
||||
Column {
|
||||
values.forEach { item ->
|
||||
SectionItemViewSpaceBetween({ onSelected(item.value) }) {
|
||||
Text(item.title)
|
||||
if (currentValue.value == item.value) {
|
||||
|
||||
+25
-17
@@ -145,13 +145,20 @@ private fun MigrateFromDeviceLayout(
|
||||
) {
|
||||
val tempDatabaseFile = rememberSaveable { mutableStateOf(fileForTemporaryDatabase()) }
|
||||
|
||||
val (scrollBarAlpha, scrollModifier, scrollJob) = platform.desktopScrollBarComponents()
|
||||
val scrollState = rememberScrollState()
|
||||
Column(
|
||||
Modifier.fillMaxSize().verticalScroll(rememberScrollState()).height(IntrinsicSize.Max),
|
||||
Modifier.fillMaxSize().verticalScroll(scrollState).then(if (appPlatform.isDesktop) scrollModifier else Modifier).height(IntrinsicSize.Max),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.migrate_from_device_title))
|
||||
SectionByState(migrationState, tempDatabaseFile.value, chatReceiver)
|
||||
SectionBottomSpacer()
|
||||
}
|
||||
if (appPlatform.isDesktop) {
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
platform.desktopScrollBar(scrollState, Modifier.align(Alignment.CenterEnd).fillMaxHeight(), scrollBarAlpha, scrollJob, false)
|
||||
}
|
||||
}
|
||||
platform.androidLockPortraitOrientation()
|
||||
}
|
||||
|
||||
@@ -368,22 +375,6 @@ private fun MutableState<MigrationFromState>.LinkShownView(fileId: Long, link: S
|
||||
private fun MutableState<MigrationFromState>.FinishedView(chatDeletion: Boolean) {
|
||||
Box {
|
||||
SectionView(stringResource(MR.strings.migrate_from_device_migration_complete).uppercase()) {
|
||||
SettingsActionItemWithContent(
|
||||
icon = painterResource(MR.images.ic_delete_forever),
|
||||
text = stringResource(MR.strings.migrate_from_device_delete_database_from_device),
|
||||
textColor = MaterialTheme.colors.primary,
|
||||
click = {
|
||||
AlertManager.shared.showAlertDialog(
|
||||
title = generalGetString(MR.strings.delete_chat_profile_question),
|
||||
text = generalGetString(MR.strings.delete_chat_profile_action_cannot_be_undone_warning),
|
||||
confirmText = generalGetString(MR.strings.delete_verb),
|
||||
onConfirm = {
|
||||
deleteChatAndDismiss()
|
||||
}
|
||||
)
|
||||
}
|
||||
) {}
|
||||
|
||||
SettingsActionItemWithContent(
|
||||
icon = painterResource(MR.images.ic_play_arrow_filled),
|
||||
text = stringResource(MR.strings.migrate_from_device_start_chat),
|
||||
@@ -395,6 +386,23 @@ private fun MutableState<MigrationFromState>.FinishedView(chatDeletion: Boolean)
|
||||
confirmText = generalGetString(MR.strings.migrate_from_device_start_chat),
|
||||
onConfirm = {
|
||||
withLongRunningApi { startChatAndDismiss() }
|
||||
},
|
||||
destructive = true
|
||||
)
|
||||
}
|
||||
) {}
|
||||
|
||||
SettingsActionItemWithContent(
|
||||
icon = painterResource(MR.images.ic_delete_forever),
|
||||
text = stringResource(MR.strings.migrate_from_device_delete_database_from_device),
|
||||
textColor = MaterialTheme.colors.primary,
|
||||
click = {
|
||||
AlertManager.shared.showAlertDialog(
|
||||
title = generalGetString(MR.strings.delete_chat_profile_question),
|
||||
text = generalGetString(MR.strings.delete_chat_profile_action_cannot_be_undone_warning),
|
||||
confirmText = generalGetString(MR.strings.delete_verb),
|
||||
onConfirm = {
|
||||
deleteChatAndDismiss()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
+9
-2
@@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import chat.simplex.common.model.*
|
||||
@@ -154,14 +155,20 @@ private fun ModalData.MigrateToDeviceLayout(
|
||||
close: () -> Unit,
|
||||
) {
|
||||
val tempDatabaseFile = rememberSaveable { mutableStateOf(fileForTemporaryDatabase()) }
|
||||
|
||||
val (scrollBarAlpha, scrollModifier, scrollJob) = platform.desktopScrollBarComponents()
|
||||
val scrollState = rememberScrollState()
|
||||
Column(
|
||||
Modifier.fillMaxSize().verticalScroll(rememberScrollState()).height(IntrinsicSize.Max),
|
||||
Modifier.fillMaxSize().verticalScroll(scrollState).then(if (appPlatform.isDesktop) scrollModifier else Modifier).height(IntrinsicSize.Max),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.migrate_to_device_title))
|
||||
SectionByState(migrationState, tempDatabaseFile.value, chatReceiver, close)
|
||||
SectionBottomSpacer()
|
||||
}
|
||||
if (appPlatform.isDesktop) {
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
platform.desktopScrollBar(scrollState, Modifier.align(Alignment.CenterEnd).fillMaxHeight(), scrollBarAlpha, scrollJob, false)
|
||||
}
|
||||
}
|
||||
platform.androidLockPortraitOrientation()
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -1,10 +1,11 @@
|
||||
package chat.simplex.common.views.newchat
|
||||
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.platform.chatModel
|
||||
import chat.simplex.common.ui.theme.DEFAULT_PADDING
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import chat.simplex.common.views.helpers.AppBarTitle
|
||||
import chat.simplex.common.views.helpers.KeyChangeEffect
|
||||
@@ -14,10 +15,10 @@ import chat.simplex.res.MR
|
||||
|
||||
@Composable
|
||||
fun AddContactLearnMore(close: () -> Unit) {
|
||||
Column(
|
||||
Modifier.verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.padding(horizontal = DEFAULT_PADDING),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.one_time_link))
|
||||
AppBarTitle(stringResource(MR.strings.one_time_link), withPadding = false)
|
||||
ReadableText(MR.strings.scan_qr_to_connect_to_contact)
|
||||
ReadableText(MR.strings.if_you_cant_meet_in_person)
|
||||
ReadableTextWithLink(MR.strings.read_more_in_user_guide_with_link, "https://simplex.chat/docs/guide/readme.html#connect-to-friends")
|
||||
|
||||
+1
-2
@@ -94,10 +94,9 @@ fun AddGroupLayout(
|
||||
sheetShape = RoundedCornerShape(topStart = 18.dp, topEnd = 18.dp)
|
||||
) {
|
||||
ModalView(close = close) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = DEFAULT_PADDING)
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.create_secret_group_title), hostDevice(rhId))
|
||||
|
||||
+3
-11
@@ -65,14 +65,7 @@ fun ContactConnectionInfoView(
|
||||
share = { if (connReqInvitation != null) clipboard.shareText(connReqInvitation) },
|
||||
learnMore = {
|
||||
ModalManager.end.showModalCloseable { close ->
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxHeight()
|
||||
.padding(horizontal = DEFAULT_PADDING),
|
||||
verticalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
AddContactLearnMore(close)
|
||||
}
|
||||
AddContactLearnMore(close)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -111,9 +104,8 @@ private fun ContactConnectionInfoLayout(
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
Modifier
|
||||
.verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier,
|
||||
) {
|
||||
AppBarTitle(
|
||||
stringResource(
|
||||
|
||||
+4
-11
@@ -141,10 +141,10 @@ fun ModalData.NewChatView(rh: RemoteHostInfo?, selection: NewChatOption, showQRC
|
||||
}
|
||||
|
||||
HorizontalPager(state = pagerState, Modifier.fillMaxSize(), verticalAlignment = Alignment.Top) { index ->
|
||||
Column(
|
||||
// LALAL SCROLLBAR DOESN'T WORK
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
.fillMaxSize(),
|
||||
verticalArrangement = if (index == NewChatOption.INVITE.ordinal && connReqInvitation.isEmpty()) Arrangement.Center else Arrangement.Top) {
|
||||
Spacer(Modifier.height(DEFAULT_PADDING))
|
||||
when (index) {
|
||||
@@ -232,14 +232,7 @@ private fun AddContactLearnMoreButton() {
|
||||
{
|
||||
if (appPlatform.isDesktop) ModalManager.end.closeModals()
|
||||
ModalManager.end.showModalCloseable { close ->
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxHeight()
|
||||
.padding(horizontal = DEFAULT_PADDING),
|
||||
verticalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
AddContactLearnMore(close)
|
||||
}
|
||||
AddContactLearnMore(close)
|
||||
}
|
||||
}
|
||||
) {
|
||||
|
||||
+4
-3
@@ -75,8 +75,8 @@ private fun CreateSimpleXAddressLayout(
|
||||
createAddress: () -> Unit,
|
||||
nextStep: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(top = DEFAULT_PADDING),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxSize().padding(top = DEFAULT_PADDING),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.simplex_address))
|
||||
@@ -169,7 +169,8 @@ private fun ProgressIndicator() {
|
||||
}
|
||||
|
||||
private fun prepareChatBeforeAddressCreation(rhId: Long?) {
|
||||
if (chatModel.users.isNotEmpty()) return
|
||||
// No visible users but may have hidden. In this case chat should be started anyway because it's stopped on this stage with hidden users
|
||||
if (chatModel.users.any { u -> !u.user.hidden }) return
|
||||
withBGApi {
|
||||
val user = chatModel.controller.apiGetActiveUser(rhId) ?: return@withBGApi
|
||||
chatModel.currentUser.value = user
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.chat.item.MarkdownText
|
||||
import chat.simplex.common.views.helpers.*
|
||||
@@ -22,7 +23,7 @@ import dev.icerock.moko.resources.StringResource
|
||||
|
||||
@Composable
|
||||
fun HowItWorks(user: User?, onboardingStage: SharedPreference<OnboardingStage>? = null) {
|
||||
Column(Modifier
|
||||
ColumnWithScrollBar(Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = DEFAULT_PADDING),
|
||||
) {
|
||||
|
||||
+2
-2
@@ -15,6 +15,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.model.NotificationsMode
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.usersettings.changeNotificationsMode
|
||||
@@ -23,10 +24,9 @@ import dev.icerock.moko.resources.StringResource
|
||||
|
||||
@Composable
|
||||
fun SetNotificationsMode(m: ChatModel) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(vertical = 14.dp)
|
||||
) {
|
||||
//CloseSheetBar(null)
|
||||
|
||||
+2
-2
@@ -98,8 +98,8 @@ private fun SetupDatabasePassphraseLayout(
|
||||
onConfirmEncrypt: () -> Unit,
|
||||
nextStep: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(top = DEFAULT_PADDING),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxSize().padding(top = DEFAULT_PADDING),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.setup_database_passphrase))
|
||||
|
||||
+2
-2
@@ -16,6 +16,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.*
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.platform.chatModel
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
@@ -39,10 +40,9 @@ fun SimpleXInfoLayout(
|
||||
onboardingStage: SharedPreference<OnboardingStage>?,
|
||||
showModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
|
||||
) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(start = DEFAULT_PADDING , end = DEFAULT_PADDING, top = DEFAULT_PADDING),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
|
||||
+3
-3
@@ -18,6 +18,7 @@ import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.res.MR
|
||||
@@ -105,11 +106,10 @@ fun WhatsNewView(viaSettings: Boolean = false, close: () -> Unit) {
|
||||
val v = versionDescriptions[currentVersion.value]
|
||||
|
||||
ModalView(close = close) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = DEFAULT_PADDING)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
.padding(horizontal = DEFAULT_PADDING),
|
||||
verticalArrangement = Arrangement.spacedBy(DEFAULT_PADDING.times(0.75f))
|
||||
) {
|
||||
AppBarTitle(String.format(generalGetString(MR.strings.new_in_version), v.version), bottomPadding = DEFAULT_PADDING)
|
||||
|
||||
+4
-4
@@ -75,8 +75,8 @@ private fun ConnectDesktopLayout(deviceName: String, close: () -> Unit) {
|
||||
val sessionAddress = remember { mutableStateOf("") }
|
||||
val remoteCtrls = remember { mutableStateListOf<RemoteCtrlInfo>() }
|
||||
val session = remember { chatModel.remoteCtrlSession }.value
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
val discovery = if (session == null) null else session.sessionState is UIRemoteCtrlSessionState.Searching
|
||||
if (discovery == true || (discovery == null && !showConnectScreen.value)) {
|
||||
@@ -391,8 +391,8 @@ private fun DesktopAddressView(sessionAddress: MutableState<String>) {
|
||||
|
||||
@Composable
|
||||
private fun LinkedDesktopsView(remoteCtrls: SnapshotStateList<RemoteCtrlInfo>) {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.linked_desktops))
|
||||
SectionView(stringResource(MR.strings.desktop_devices).uppercase()) {
|
||||
|
||||
+4
-4
@@ -91,8 +91,8 @@ fun ConnectMobileLayout(
|
||||
connectDesktop: () -> Unit,
|
||||
deleteHost: (RemoteHostInfo) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
AppBarTitle(stringResource(if (remember { chatModel.remoteHosts }.isEmpty()) MR.strings.link_a_mobile else MR.strings.linked_mobiles))
|
||||
@@ -181,8 +181,8 @@ private fun ConnectMobileViewLayout(
|
||||
refreshQrCode: () -> Unit = {},
|
||||
UnderQrLayout: @Composable () -> Unit = {},
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
if (title != null) {
|
||||
|
||||
+3
-3
@@ -23,6 +23,7 @@ import chat.simplex.common.model.*
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.res.MR
|
||||
import java.text.DecimalFormat
|
||||
|
||||
@@ -141,10 +142,9 @@ fun AdvancedNetworkSettingsView(chatModel: ChatModel) {
|
||||
) {
|
||||
val secondsLabel = stringResource(MR.strings.network_option_seconds_label)
|
||||
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.network_settings_title))
|
||||
SectionView {
|
||||
|
||||
+2
-2
@@ -57,8 +57,8 @@ object AppearanceScope {
|
||||
|
||||
@Composable
|
||||
fun CustomizeThemeView(editColor: (ThemeColor, Color) -> Unit) {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
val currentTheme by CurrentColors.collectAsState()
|
||||
|
||||
|
||||
+3
-2
@@ -16,6 +16,7 @@ import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.res.MR
|
||||
|
||||
@Composable
|
||||
@@ -35,8 +36,8 @@ fun CallSettingsLayout(
|
||||
callOnLockScreen: SharedPreference<CallOnLockScreen>,
|
||||
editIceServers: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.your_calls))
|
||||
|
||||
+2
-3
@@ -12,10 +12,9 @@ import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.*
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import chat.simplex.common.platform.appPlatform
|
||||
import chat.simplex.common.platform.appPreferences
|
||||
import chat.simplex.common.views.TerminalView
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.res.MR
|
||||
@@ -26,7 +25,7 @@ fun DeveloperView(
|
||||
showCustomModal: (@Composable ModalData.(ChatModel, () -> Unit) -> Unit) -> (() -> Unit),
|
||||
withAuth: (title: String, desc: String, block: () -> Unit) -> Unit
|
||||
) {
|
||||
Column(Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) {
|
||||
ColumnWithScrollBar(Modifier.fillMaxWidth()) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
AppBarTitle(stringResource(MR.strings.settings_developer_tools))
|
||||
val developerTools = m.controller.appPrefs.developerTools
|
||||
|
||||
+2
-2
@@ -7,6 +7,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.ui.theme.DEFAULT_PADDING
|
||||
import chat.simplex.common.ui.theme.SimpleXTheme
|
||||
import chat.simplex.common.views.chatlist.ChatHelpView
|
||||
@@ -20,10 +21,9 @@ fun HelpView(userDisplayName: String) {
|
||||
|
||||
@Composable
|
||||
fun HelpLayout(userDisplayName: String) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = DEFAULT_PADDING),
|
||||
){
|
||||
AppBarTitle(String.format(stringResource(MR.strings.personal_welcome), userDisplayName), withPadding = false)
|
||||
|
||||
+3
-3
@@ -17,6 +17,7 @@ import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.model.User
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.chatlist.UserProfileRow
|
||||
import chat.simplex.common.views.database.PassphraseField
|
||||
@@ -53,10 +54,9 @@ private fun HiddenProfileLayout(
|
||||
user: User,
|
||||
saveProfilePassword: (String) -> Unit
|
||||
) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.hide_profile))
|
||||
SectionView(padding = PaddingValues(start = 8.dp, end = DEFAULT_PADDING)) {
|
||||
|
||||
+2
-3
@@ -1,13 +1,13 @@
|
||||
package chat.simplex.common.views.usersettings
|
||||
|
||||
import SectionBottomSpacer
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.ui.theme.DEFAULT_PADDING
|
||||
import chat.simplex.common.views.helpers.AppBarTitle
|
||||
import chat.simplex.common.views.helpers.generalGetString
|
||||
@@ -21,11 +21,10 @@ fun IncognitoView() {
|
||||
|
||||
@Composable
|
||||
fun IncognitoLayout() {
|
||||
Column {
|
||||
ColumnWithScrollBar {
|
||||
AppBarTitle(stringResource(MR.strings.settings_section_title_incognito))
|
||||
Column(
|
||||
Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = DEFAULT_PADDING),
|
||||
verticalArrangement = Arrangement.spacedBy(20.dp)
|
||||
) {
|
||||
|
||||
+6
-6
@@ -25,6 +25,7 @@ import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.platform.chatModel
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.chat.item.ClickableText
|
||||
@@ -151,8 +152,8 @@ fun NetworkAndServersView() {
|
||||
updateSessionMode: (TransportSessionMode) -> Unit,
|
||||
) {
|
||||
val m = chatModel
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.network_and_servers))
|
||||
@@ -276,10 +277,9 @@ fun SockProxySettings(
|
||||
networkProxyHostPort: SharedPreference<String?> = m.controller.appPrefs.networkProxyHostPort,
|
||||
migration: Boolean,
|
||||
) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
val defaultHostPort = remember { "localhost:9050" }
|
||||
AppBarTitle(generalGetString(MR.strings.network_socks_proxy_settings))
|
||||
@@ -376,7 +376,7 @@ private fun UseOnionHosts(
|
||||
}
|
||||
val onSelected = {
|
||||
showModal {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.network_use_onion_hosts))
|
||||
@@ -430,7 +430,7 @@ private fun SessionModePicker(
|
||||
icon = painterResource(MR.images.ic_safety_divider),
|
||||
onSelected = {
|
||||
showModal {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.network_session_mode_transport_isolation))
|
||||
|
||||
+4
-4
@@ -56,8 +56,8 @@ fun NotificationsSettingsLayout(
|
||||
val modes = remember { notificationModes() }
|
||||
val previewModes = remember { notificationPreviewModes() }
|
||||
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.notifications))
|
||||
SectionView(null) {
|
||||
@@ -90,7 +90,7 @@ fun NotificationsModeView(
|
||||
onNotificationsModeSelected: (NotificationsMode) -> Unit,
|
||||
) {
|
||||
val modes = remember { notificationModes() }
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.settings_notifications_mode_title).lowercase().capitalize(Locale.current))
|
||||
@@ -104,7 +104,7 @@ fun NotificationPreviewView(
|
||||
onNotificationPreviewModeSelected: (NotificationPreviewMode) -> Unit,
|
||||
) {
|
||||
val previewModes = remember { notificationPreviewModes() }
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.settings_notification_preview_title))
|
||||
|
||||
+3
-2
@@ -15,6 +15,7 @@ import androidx.compose.ui.Modifier
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.res.MR
|
||||
|
||||
@Composable
|
||||
@@ -62,8 +63,8 @@ private fun PreferencesLayout(
|
||||
reset: () -> Unit,
|
||||
savePrefs: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.your_preferences))
|
||||
val timedMessages = remember(preferences) { mutableStateOf(preferences.timedMessages.allow) }
|
||||
|
||||
+7
-8
@@ -30,8 +30,7 @@ import chat.simplex.common.views.isValidDisplayName
|
||||
import chat.simplex.common.views.localauth.SetAppPasscodeView
|
||||
import chat.simplex.common.views.onboarding.ReadableText
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.platform.AppPlatform
|
||||
import chat.simplex.common.platform.appPlatform
|
||||
import chat.simplex.common.platform.*
|
||||
|
||||
enum class LAMode {
|
||||
SYSTEM,
|
||||
@@ -55,8 +54,8 @@ fun PrivacySettingsView(
|
||||
showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
|
||||
setPerformLA: (Boolean) -> Unit
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
val simplexLinkMode = chatModel.controller.appPrefs.simplexLinkMode
|
||||
AppBarTitle(stringResource(MR.strings.your_privacy))
|
||||
@@ -473,8 +472,8 @@ fun SimplexLockView(
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.chat_lock))
|
||||
SectionView {
|
||||
@@ -580,8 +579,8 @@ fun SimplexLockView(
|
||||
|
||||
@Composable
|
||||
private fun SelfDestructInfoView() {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()).padding(horizontal = DEFAULT_PADDING),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.self_destruct), withPadding = false)
|
||||
ReadableText(stringResource(MR.strings.if_you_enter_self_destruct_code))
|
||||
|
||||
+2
-4
@@ -5,7 +5,6 @@ import SectionDividerSpaced
|
||||
import SectionItemView
|
||||
import SectionItemViewSpaceBetween
|
||||
import SectionView
|
||||
import chat.simplex.common.platform.Log
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
@@ -20,13 +19,13 @@ import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.platform.TAG
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.model.ServerAddress.Companion.parseServerAddress
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.newchat.QRCode
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.res.MR
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
@@ -76,10 +75,9 @@ private fun ProtocolServerLayout(
|
||||
onUpdate: (ServerCfg) -> Unit,
|
||||
onDelete: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
AppBarTitle(stringResource(if (server.preset) MR.strings.smp_servers_preset_server else MR.strings.smp_servers_your_server))
|
||||
|
||||
|
||||
+2
-2
@@ -22,6 +22,7 @@ import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.model.ServerAddress.Companion.parseServerAddress
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.platform.appPlatform
|
||||
import chat.simplex.res.MR
|
||||
|
||||
@@ -191,10 +192,9 @@ private fun ProtocolServersLayout(
|
||||
saveSMPServers: () -> Unit,
|
||||
showServer: (ServerCfg) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
AppBarTitle(stringResource(if (serverProtocol == ServerProtocol.SMP) MR.strings.your_SMP_servers else MR.strings.your_XFTP_servers))
|
||||
|
||||
|
||||
+2
-2
@@ -19,6 +19,7 @@ import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.call.parseRTCIceServers
|
||||
import chat.simplex.common.views.helpers.*
|
||||
@@ -98,12 +99,11 @@ fun RTCServersLayout(
|
||||
saveRTCServers: () -> Unit,
|
||||
editOn: () -> Unit,
|
||||
) {
|
||||
Column {
|
||||
ColumnWithScrollBar {
|
||||
AppBarTitle(stringResource(MR.strings.your_ICE_servers))
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = DEFAULT_PADDING),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
|
||||
+8
-1
@@ -74,8 +74,10 @@ private fun SetDeliveryReceiptsLayout(
|
||||
userCount: Int,
|
||||
) {
|
||||
val endPadding = if (appPlatform.isDesktop) 56.dp else 0.dp
|
||||
val (scrollBarAlpha, scrollModifier, scrollJob) = platform.desktopScrollBarComponents()
|
||||
val scrollState = rememberScrollState()
|
||||
Column(
|
||||
Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(top = DEFAULT_PADDING, end = endPadding),
|
||||
Modifier.fillMaxSize().verticalScroll(scrollState).then(if (appPlatform.isDesktop) scrollModifier else Modifier).padding(top = DEFAULT_PADDING, end = endPadding),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.delivery_receipts_title))
|
||||
@@ -95,6 +97,11 @@ private fun SetDeliveryReceiptsLayout(
|
||||
|
||||
SectionBottomSpacer()
|
||||
}
|
||||
if (appPlatform.isDesktop) {
|
||||
Box(Modifier.fillMaxSize().padding(end = endPadding)) {
|
||||
platform.desktopScrollBar(scrollState, Modifier.align(Alignment.CenterEnd).fillMaxHeight(), scrollBarAlpha, scrollJob, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
+1
-2
@@ -105,10 +105,9 @@ fun SettingsLayout(
|
||||
val theme = CurrentColors.collectAsState()
|
||||
val uriHandler = LocalUriHandler.current
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.themedBackground(theme.value.base)
|
||||
.padding(top = if (appPlatform.isAndroid) DEFAULT_PADDING else DEFAULT_PADDING * 3)
|
||||
) {
|
||||
|
||||
+5
-3
@@ -1,9 +1,10 @@
|
||||
package chat.simplex.common.views.usersettings
|
||||
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.ui.theme.DEFAULT_PADDING
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.onboarding.ReadableText
|
||||
@@ -12,8 +13,9 @@ import chat.simplex.res.MR
|
||||
|
||||
@Composable
|
||||
fun UserAddressLearnMore() {
|
||||
Column(
|
||||
Modifier.verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(Modifier
|
||||
.fillMaxHeight()
|
||||
.padding(horizontal = DEFAULT_PADDING)
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.simplex_address))
|
||||
ReadableText(MR.strings.you_can_share_your_address)
|
||||
|
||||
+2
-13
@@ -7,9 +7,7 @@ import SectionTextFooter
|
||||
import SectionView
|
||||
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
@@ -91,14 +89,7 @@ fun UserAddressView(
|
||||
},
|
||||
learnMore = {
|
||||
ModalManager.start.showModal {
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxHeight()
|
||||
.padding(horizontal = DEFAULT_PADDING),
|
||||
verticalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
UserAddressLearnMore()
|
||||
}
|
||||
UserAddressLearnMore()
|
||||
}
|
||||
},
|
||||
share = { userAddress: String -> clipboard.shareText(userAddress) },
|
||||
@@ -182,9 +173,7 @@ private fun UserAddressLayout(
|
||||
deleteAddress: () -> Unit,
|
||||
saveAas: (AutoAcceptState, MutableState<AutoAcceptState>) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
Modifier.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
ColumnWithScrollBar {
|
||||
AppBarTitle(stringResource(MR.strings.simplex_address), hostDevice(user?.remoteHostId), withPadding = false)
|
||||
Column(
|
||||
Modifier.fillMaxWidth().padding(bottom = DEFAULT_PADDING_HALF),
|
||||
|
||||
+1
-2
@@ -98,9 +98,8 @@ fun UserProfileLayout(
|
||||
}
|
||||
}
|
||||
ModalView(close = closeWithAlert) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.verticalScroll(scrollState)
|
||||
.padding(horizontal = DEFAULT_PADDING),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.your_current_profile))
|
||||
|
||||
+3
-4
@@ -158,10 +158,9 @@ private fun UserProfilesLayout(
|
||||
unmuteUser: (User) -> Unit,
|
||||
showHiddenProfile: (User) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
if (profileHidden.value) {
|
||||
SectionView {
|
||||
@@ -260,10 +259,9 @@ enum class UserProfileAction {
|
||||
|
||||
@Composable
|
||||
private fun ProfileActionView(action: UserProfileAction, user: User, doAction: (String) -> Unit) {
|
||||
Column(
|
||||
ColumnWithScrollBar(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
val actionPassword = rememberSaveable { mutableStateOf("") }
|
||||
val passwordValid by remember { derivedStateOf { actionPassword.value == actionPassword.value.trim() } }
|
||||
@@ -358,6 +356,7 @@ private suspend fun doRemoveUser(m: ChatModel, user: User, users: List<User>, de
|
||||
m.controller.apiDeleteUser(user, delSMPQueues, viewPwd)
|
||||
m.controller.changeActiveUser_(user.remoteHostId, null, null)
|
||||
if (appPlatform.isAndroid) {
|
||||
m.controller.apiStopChat()
|
||||
controller.appPrefs.onboardingStage.set(OnboardingStage.Step1_SimpleXInfo)
|
||||
ModalManager.closeAllModalsEverywhere()
|
||||
}
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
package chat.simplex.common.platform
|
||||
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.AnimationVector1D
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.gestures.FlingBehavior
|
||||
import androidx.compose.foundation.interaction.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.input.pointer.*
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.views.helpers.detectCursorMove
|
||||
import chat.simplex.common.views.helpers.mixWith
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
@Composable
|
||||
actual fun LazyColumnWithScrollBar(
|
||||
modifier: Modifier,
|
||||
state: LazyListState,
|
||||
contentPadding: PaddingValues,
|
||||
reverseLayout: Boolean,
|
||||
verticalArrangement: Arrangement.Vertical,
|
||||
horizontalAlignment: Alignment.Horizontal,
|
||||
flingBehavior: FlingBehavior,
|
||||
userScrollEnabled: Boolean,
|
||||
content: LazyListScope.() -> Unit
|
||||
) {
|
||||
if (appPlatform.isAndroid) {
|
||||
LazyColumn(modifier, state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled, content)
|
||||
} else {
|
||||
val scope = rememberCoroutineScope()
|
||||
val scrollBarAlpha = remember { Animatable(0f) }
|
||||
val scrollJob: MutableState<Job> = remember { mutableStateOf(Job()) }
|
||||
val scrollModifier = remember {
|
||||
Modifier
|
||||
.pointerInput(Unit) {
|
||||
detectCursorMove {
|
||||
scope.launch {
|
||||
scrollBarAlpha.animateTo(1f)
|
||||
}
|
||||
scrollJob.value.cancel()
|
||||
scrollJob.value = scope.launch {
|
||||
delay(1000L)
|
||||
scrollBarAlpha.animateTo(0f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LazyColumn(modifier.then(if (appPlatform.isDesktop) scrollModifier else Modifier), state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled, content)
|
||||
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.CenterEnd) {
|
||||
DesktopScrollBar(rememberScrollbarAdapter(state), Modifier.align(Alignment.CenterEnd).fillMaxHeight(), scrollBarAlpha, scrollJob, reverseLayout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
actual fun ColumnWithScrollBar(
|
||||
modifier: Modifier,
|
||||
verticalArrangement: Arrangement.Vertical,
|
||||
horizontalAlignment: Alignment.Horizontal,
|
||||
state: ScrollState,
|
||||
content: @Composable ColumnScope.() -> Unit
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val scrollBarAlpha = remember { Animatable(0f) }
|
||||
val scrollJob: MutableState<Job> = remember { mutableStateOf(Job()) }
|
||||
val scrollModifier = remember {
|
||||
Modifier
|
||||
.pointerInput(Unit) {
|
||||
detectCursorMove {
|
||||
scope.launch {
|
||||
scrollBarAlpha.animateTo(1f)
|
||||
}
|
||||
scrollJob.value.cancel()
|
||||
scrollJob.value = scope.launch {
|
||||
delay(1000L)
|
||||
scrollBarAlpha.animateTo(0f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Column(modifier.verticalScroll(state).then(scrollModifier), verticalArrangement, horizontalAlignment, content)
|
||||
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.CenterEnd) {
|
||||
DesktopScrollBar(rememberScrollbarAdapter(state), Modifier.align(Alignment.CenterEnd).fillMaxHeight(), scrollBarAlpha, scrollJob, false)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DesktopScrollBar(adapter: androidx.compose.foundation.v2.ScrollbarAdapter, modifier: Modifier, scrollBarAlpha: Animatable<Float, AnimationVector1D>, scrollJob: MutableState<Job>, reversed: Boolean) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
val isHovered by interactionSource.collectIsHoveredAsState()
|
||||
val isDragged by interactionSource.collectIsDraggedAsState()
|
||||
LaunchedEffect(isHovered, isDragged) {
|
||||
scrollJob.value.cancel()
|
||||
if (isHovered || isDragged) {
|
||||
scrollBarAlpha.animateTo(1f)
|
||||
} else {
|
||||
scrollJob.value = scope.launch {
|
||||
delay(1000L)
|
||||
scrollBarAlpha.animateTo(0f)
|
||||
}
|
||||
}
|
||||
}
|
||||
VerticalScrollbar(
|
||||
modifier = modifier.graphicsLayer { alpha = scrollBarAlpha.value }
|
||||
.onPointerEvent(PointerEventType.Enter) {
|
||||
scrollJob.value.cancel()
|
||||
scope.launch {
|
||||
scrollBarAlpha.animateTo(1f)
|
||||
}
|
||||
},
|
||||
reverseLayout = reversed,
|
||||
style = LocalScrollbarStyle.current.copy(
|
||||
thickness = if (isHovered || isDragged) 10.dp else 6.dp,
|
||||
shape = RoundedCornerShape(if (isHovered || isDragged) 5.dp else 3.dp),
|
||||
unhoverColor = if (MaterialTheme.colors.isLight) MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, 0.7f) else MaterialTheme.colors.onBackground.mixWith(MaterialTheme.colors.background, 0.3f),
|
||||
hoverColor = if (MaterialTheme.colors.isLight) MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, 0.6f) else MaterialTheme.colors.onBackground.mixWith(MaterialTheme.colors.background, 0.4f)
|
||||
),
|
||||
adapter = adapter,
|
||||
interactionSource = interactionSource
|
||||
)
|
||||
}
|
||||
+1
-1
@@ -75,7 +75,7 @@ actual fun ActiveCallView() {
|
||||
chatModel.activeCall.value = call.copy(callState = CallState.Connected, connectedAt = Clock.System.now())
|
||||
}
|
||||
withBGApi { chatModel.controller.apiCallStatus(callRh, call.contact, callStatus) }
|
||||
} catch (e: Error) {
|
||||
} catch (e: Throwable) {
|
||||
Log.d(TAG, "call status ${r.state.connectionState} not used")
|
||||
}
|
||||
is WCallResponse.Connected -> {
|
||||
|
||||
+3
-4
@@ -4,8 +4,6 @@ import SectionBottomSpacer
|
||||
import SectionDividerSpaced
|
||||
import SectionView
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
@@ -13,6 +11,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.model.SharedPreference
|
||||
import chat.simplex.common.platform.ColumnWithScrollBar
|
||||
import chat.simplex.common.platform.defaultLocale
|
||||
import chat.simplex.common.ui.theme.ThemeColor
|
||||
import chat.simplex.common.views.helpers.*
|
||||
@@ -43,8 +42,8 @@ fun AppearanceScope.AppearanceLayout(
|
||||
showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit),
|
||||
editColor: (ThemeColor, Color) -> Unit,
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().verticalScroll(rememberScrollState()),
|
||||
ColumnWithScrollBar(
|
||||
Modifier.fillMaxWidth(),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.appearance_settings))
|
||||
SectionView(stringResource(MR.strings.settings_section_title_language), padding = PaddingValues()) {
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
package chat.simplex.desktop
|
||||
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.AnimationVector1D
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.interaction.*
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.pointer.*
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.platform.DesktopPlatform
|
||||
import chat.simplex.common.showApp
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import kotlinx.coroutines.*
|
||||
import java.io.File
|
||||
|
||||
fun main() {
|
||||
@@ -12,6 +24,7 @@ fun main() {
|
||||
return showApp()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
@Suppress("UnsafeDynamicallyLoadedCode")
|
||||
private fun initHaskell() {
|
||||
val resourcesDir = File(System.getProperty("compose.application.resources.dir"))
|
||||
@@ -27,6 +40,40 @@ private fun initHaskell() {
|
||||
System.setProperty("jna.library.path", vlcDir.absolutePath)
|
||||
//discoverVlcLibs(File(File(vlcDir, "vlc"), "plugins").absolutePath)
|
||||
initHS()
|
||||
|
||||
platform = object: PlatformInterface {
|
||||
@Composable
|
||||
override fun desktopScrollBarComponents(): Triple<Animatable<Float, AnimationVector1D>, Modifier, MutableState<Job>> {
|
||||
val scope = rememberCoroutineScope()
|
||||
val scrollBarAlpha = remember { Animatable(0f) }
|
||||
val scrollJob: MutableState<Job> = remember { mutableStateOf(Job()) }
|
||||
val modifier = remember {
|
||||
Modifier.pointerInput(Unit) {
|
||||
detectCursorMove {
|
||||
scope.launch {
|
||||
scrollBarAlpha.animateTo(1f)
|
||||
}
|
||||
scrollJob.value.cancel()
|
||||
scrollJob.value = scope.launch {
|
||||
delay(1000L)
|
||||
scrollBarAlpha.animateTo(0f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Triple(scrollBarAlpha, modifier, scrollJob)
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun desktopScrollBar(state: LazyListState, modifier: Modifier, scrollBarAlpha: Animatable<Float, AnimationVector1D>, scrollJob: MutableState<Job>, reversed: Boolean) {
|
||||
DesktopScrollBar(rememberScrollbarAdapter(scrollState = state), modifier, scrollBarAlpha, scrollJob, reversed)
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun desktopScrollBar(state: ScrollState, modifier: Modifier, scrollBarAlpha: Animatable<Float, AnimationVector1D>, scrollJob: MutableState<Job>, reversed: Boolean) {
|
||||
DesktopScrollBar(rememberScrollbarAdapter(scrollState = state), modifier, scrollBarAlpha, scrollJob, reversed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun windowsLoadRequiredLibs(libsTmpDir: File, vlcDir: File) {
|
||||
|
||||
@@ -25,11 +25,11 @@ android.nonTransitiveRClass=true
|
||||
android.enableJetifier=true
|
||||
kotlin.mpp.androidSourceSetLayoutVersion=2
|
||||
|
||||
android.version_name=5.6-beta.0
|
||||
android.version_code=189
|
||||
android.version_name=5.6-beta.1
|
||||
android.version_code=190
|
||||
|
||||
desktop.version_name=5.6-beta.0
|
||||
desktop.version_code=33
|
||||
desktop.version_name=5.6-beta.1
|
||||
desktop.version_code=34
|
||||
|
||||
kotlin.version=1.8.20
|
||||
gradle.plugin.version=7.4.2
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/simplex-chat/simplexmq.git
|
||||
tag: 7b6b80cea21c7fbafffa118f1ed268411fcb79ca
|
||||
tag: 8496884b42d76bd0d934e5ae481846d9c324d3c7
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
name: simplex-chat
|
||||
version: 5.6.0.3
|
||||
version: 5.6.0.4
|
||||
#synopsis:
|
||||
#description:
|
||||
homepage: https://github.com/simplex-chat/simplex-chat#readme
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"https://github.com/simplex-chat/simplexmq.git"."7b6b80cea21c7fbafffa118f1ed268411fcb79ca" = "0a665v4v1ilm2j9cxkiwqq2xlp2732h95mqaywf7qrlk03qkasfi";
|
||||
"https://github.com/simplex-chat/simplexmq.git"."8496884b42d76bd0d934e5ae481846d9c324d3c7" = "0c040s00zc1qg0ilsvpv54f01xz7flh8rsar2nplcs4a4gnp78qs";
|
||||
"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/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ cabal-version: 1.12
|
||||
-- see: https://github.com/sol/hpack
|
||||
|
||||
name: simplex-chat
|
||||
version: 5.6.0.3
|
||||
version: 5.6.0.4
|
||||
category: Web, System, Services, Cryptography
|
||||
homepage: https://github.com/simplex-chat/simplex-chat#readme
|
||||
author: simplex.chat
|
||||
|
||||
+5
-2
@@ -37,10 +37,11 @@ import Simplex.Chat.Types
|
||||
import Simplex.FileTransfer.Description (kb, mb)
|
||||
import Simplex.FileTransfer.Server (runXFTPServerBlocking)
|
||||
import Simplex.FileTransfer.Server.Env (XFTPServerConfig (..), defaultFileExpiration)
|
||||
import Simplex.Messaging.Agent (disposeAgentClient)
|
||||
import Simplex.Messaging.Agent.Env.SQLite
|
||||
import Simplex.Messaging.Agent.Protocol (currentSMPAgentVersion, duplexHandshakeSMPAgentVersion, pqdrSMPAgentVersion, supportedSMPAgentVRange)
|
||||
import Simplex.Messaging.Agent.RetryInterval
|
||||
import Simplex.Messaging.Agent.Store.SQLite (MigrationConfirmation (..))
|
||||
import Simplex.Messaging.Agent.Store.SQLite (MigrationConfirmation (..), closeSQLiteStore)
|
||||
import qualified Simplex.Messaging.Agent.Store.SQLite.DB as DB
|
||||
import Simplex.Messaging.Client (ProtocolClientConfig (..), defaultNetworkConfig)
|
||||
import Simplex.Messaging.Crypto.Ratchet (supportedE2EEncryptVRange, pattern PQSupportOff)
|
||||
@@ -250,10 +251,12 @@ startTestChat_ db cfg opts user = do
|
||||
pure TestCC {chatController = cc, virtualTerminal = t, chatAsync, termAsync, termQ, printOutput = False}
|
||||
|
||||
stopTestChat :: TestCC -> IO ()
|
||||
stopTestChat TestCC {chatController = cc, chatAsync, termAsync} = do
|
||||
stopTestChat TestCC {chatController = cc@ChatController {smpAgent, chatStore}, chatAsync, termAsync} = do
|
||||
stopChatController cc
|
||||
uninterruptibleCancel termAsync
|
||||
uninterruptibleCancel chatAsync
|
||||
liftIO $ disposeAgentClient smpAgent
|
||||
closeSQLiteStore chatStore
|
||||
threadDelay 200000
|
||||
|
||||
withNewTestChat :: HasCallStack => FilePath -> String -> Profile -> (HasCallStack => TestCC -> IO a) -> IO a
|
||||
|
||||
+26
-6
@@ -37,10 +37,10 @@
|
||||
"hero-overlay-1-title": "Jak funguje SimpleX?",
|
||||
"hero-overlay-2-title": "Proč jsou uživatelská ID špatná pro soukromí?",
|
||||
"feature-1-title": "E2E šifrované zprávy s Markdown a editací",
|
||||
"feature-3-title": "Decentralizované tajné skupiny —<br>pouze uživatelé vědí, že existují",
|
||||
"feature-3-title": "E2E-šifrované decentralizované skupiny — pouze uživatelé vědí, že existují",
|
||||
"feature-4-title": "Hlasové zprávy šifrované E2E",
|
||||
"feature-6-title": "E2E šifrované<br>hlasové a videohovory",
|
||||
"feature-7-title": "Přenosná šifrovaná databáze— přeneste svůj profil do jiného zařízení",
|
||||
"feature-7-title": "Přenosné šifrované ůložiště aplikace — přeneste profil do jiného zařízení",
|
||||
"feature-8-title": "režim Inkognito —<br>Unikátní pro SimpleX Chat",
|
||||
"simplex-network-overlay-1-title": "Srovnání s protokoly zpráv P2P",
|
||||
"simplex-private-2-title": "Další vrstva<br>šifrování serveru",
|
||||
@@ -170,8 +170,8 @@
|
||||
"comparison-section-list-point-1": "Založeném obvykle na telefonním čísle a v některých případech uživatelském jménu",
|
||||
"comparison-section-list-point-2": "Adresy založené na DNS",
|
||||
"comparison-section-list-point-3": "Veřejný klíč nebo jiné globálně jedinečné ID",
|
||||
"comparison-section-list-point-4": "Pokud jsou servery operátora ohroženy",
|
||||
"comparison-section-list-point-5": "Nechrání metadata uživatelů",
|
||||
"comparison-section-list-point-4": "Pokud jsou servery operátora kompromitovány. Ověřte bezpečnostní kód v Signálu a nějaké jiné aplikaci ke zmírnění",
|
||||
"comparison-section-list-point-5": "Nechrání soukromí metadat uživatelů",
|
||||
"comparison-section-list-point-6": "Zatímco P2P jsou distribuovány, nejsou federované – fungují jako jediná síť",
|
||||
"comparison-section-list-point-7": "P2P sítě mají buď centrální autoritu, nebo může být ohrožena celá síť",
|
||||
"see-here": "viz zde",
|
||||
@@ -195,7 +195,7 @@
|
||||
"simplex-explained-tab-3-p-2": "Uživatelé mohou dále zlepšit soukromí metadat pomocí Tor pro přístup k serverům, což zabraňuje korelaci podle IP adresy.",
|
||||
"hero-p-1": "Jiné aplikace mají uživatelská ID: Signal, Matrix, Session, Briar, Jami, Cwtch atd.<br> SimpleX ne, <strong>ani náhodná čísla</strong>.<br> To radikálně zlepšuje vaše soukromí.",
|
||||
"hero-2-header-desc": "Video ukazuje, jak se spojit se svým přítelem prostřednictvím jeho jednorázového QR kódu, osobně nebo prostřednictvím QR kódu ve videu. Můžete se také připojit sdílením pozvánky.",
|
||||
"feature-2-title": "Obrázky a soubory šifrované E2E<br>",
|
||||
"feature-2-title": "E2E šifrované<br>obrázky, videa a soubory",
|
||||
"feature-5-title": "Mizící tajné konverzace",
|
||||
"simplex-private-1-title": "2-vrstvé<br>end-to-end šifrování",
|
||||
"simplex-private-8-title": "Smíchání zpráv<br>ke snížení korelace",
|
||||
@@ -232,5 +232,25 @@
|
||||
"on-this-page": "Na této stránce",
|
||||
"back-to-top": "Zpět nahoru",
|
||||
"newer-version-of-eng-msg": "V angličtině je novější verze této stránky.",
|
||||
"glossary": "Rejstřík"
|
||||
"glossary": "Rejstřík",
|
||||
"hero-overlay-3-title": "Posouzení bezpečnosti",
|
||||
"hero-overlay-3-textlink": "Posouzení bezpečnosti",
|
||||
"hero-overlay-card-3-p-1": "<a href=\"https://www.trailofbits.com/about/\">Trail of Bits</a> je přední bezpečnostní a technologické poradenství, jejichž klienti zahrnují velké technologické firmy, vládní agentury a významné blockchainové projekty.",
|
||||
"f-droid-page-simplex-chat-repo-section-text": "Chcete-li jej přidat do vašeho F-Droid clienta, <span class='hide-on-mobile'> naskenujte QR kód nebo</span> použijte tuto adresu URL:",
|
||||
"f-droid-page-f-droid-org-repo-section-text": "SimpleX Chat a F-Droid.org repozitáře jsou podepsané různými klíči. Chcete-li přepnout, prosím <a href='/docs/guide/chat-profiles.html#move-your-chat-profiles-to-another-device'>exportujte</a> chat databázi a přeinstalujte aplikaci.",
|
||||
"comparison-section-list-point-4a": "SimpleX relé nemůže ohrozit šifrování e2e. Ověřte bezpečnostní kód, který zmírňuje mimo pásmový útok na kanál",
|
||||
"docs-dropdown-8": "Služba SimpleX Directory",
|
||||
"please-enable-javascript": "Prosím, povolte JavaScript k zobrazení QR kódu.",
|
||||
"please-use-link-in-mobile-app": "Prosím použijte odkaz v mobilní aplikaci",
|
||||
"simplex-chat-via-f-droid": "SimpleX Chat přes F-Droid",
|
||||
"simplex-chat-repo": "SimpleX Chat repozitář",
|
||||
"stable-and-beta-versions-built-by-developers": "Stabilní a beta verze vytvořené vývojáři",
|
||||
"signing-key-fingerprint": "Otisk podpisového klíče (SHA-256)",
|
||||
"f-droid-org-repo": "F-Droid.org repozitář",
|
||||
"stable-versions-built-by-f-droid-org": "Stabilní verze vytvořené F-Droid.org",
|
||||
"releases-to-this-repo-are-done-1-2-days-later": "Vydání v tomto repozitáři se provádí o 1-2 dny později",
|
||||
"jobs": "Připojit k týmu",
|
||||
"hero-overlay-card-3-p-2": "Trail of Bits přezkoumala kryptografii a síťové komponenty SimpleX platformy v listopadu 2022.",
|
||||
"hero-overlay-card-3-p-3": "Přečtěte si více v <a href=\"/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html\">ohlášení</a>.",
|
||||
"docs-dropdown-9": "Ke stažení"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user