Merge branch 'master' into users
This commit is contained in:
@@ -15,6 +15,7 @@ private let memberImageSize: CGFloat = 34
|
||||
struct ChatView: View {
|
||||
@EnvironmentObject var chatModel: ChatModel
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
@Environment(\.dismiss) var dismiss
|
||||
@State @ObservedObject var chat: Chat
|
||||
@State private var showChatInfoSheet: Bool = false
|
||||
@State private var showAddMembersSheet: Bool = false
|
||||
@@ -70,6 +71,9 @@ struct ChatView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: chatModel.chatId) { _ in
|
||||
if chatModel.chatId == nil { dismiss() }
|
||||
}
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button {
|
||||
|
||||
@@ -18,7 +18,13 @@ struct ChatListView: View {
|
||||
|
||||
var body: some View {
|
||||
ZStack(alignment: .topLeading) {
|
||||
NavigationView {
|
||||
NavStackCompat(
|
||||
isActive: Binding(
|
||||
get: { ChatModel.shared.chatId != nil },
|
||||
set: { _ in }
|
||||
),
|
||||
destination: chatView
|
||||
) {
|
||||
VStack {
|
||||
if chatModel.chats.isEmpty {
|
||||
onboardingButtons()
|
||||
@@ -30,7 +36,6 @@ struct ChatListView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationViewStyle(.stack)
|
||||
if userPickerVisible {
|
||||
Rectangle().fill(.white.opacity(0.001)).onTapGesture {
|
||||
withAnimation {
|
||||
@@ -111,15 +116,6 @@ struct ChatListView: View {
|
||||
.sheet(isPresented: $showSettings) {
|
||||
SettingsView(showSettings: $showSettings)
|
||||
}
|
||||
.background(
|
||||
NavigationLink(
|
||||
destination: chatView(),
|
||||
isActive: Binding(
|
||||
get: { chatModel.chatId != nil },
|
||||
set: { _ in }
|
||||
)
|
||||
) { EmptyView() }
|
||||
)
|
||||
}
|
||||
|
||||
private func unreadBadge(_ text: Text? = Text(" "), size: CGFloat = 18) -> some View {
|
||||
|
||||
43
apps/ios/Shared/Views/Helpers/NavStackCompat.swift
Normal file
43
apps/ios/Shared/Views/Helpers/NavStackCompat.swift
Normal file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// NavStackCompat.swift
|
||||
// SimpleX (iOS)
|
||||
//
|
||||
// Created by Evgeny on 23/01/2023.
|
||||
// Copyright © 2023 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct NavStackCompat <C: View, D: View>: View {
|
||||
let isActive: Binding<Bool>
|
||||
let destination: () -> D
|
||||
let content: () -> C
|
||||
|
||||
var body: some View {
|
||||
if #available(iOS 16, *) {
|
||||
NavigationStack(path: Binding(
|
||||
get: { isActive.wrappedValue ? [true] : [] },
|
||||
set: { _ in }
|
||||
)) {
|
||||
ZStack {
|
||||
NavigationLink(value: true) { EmptyView() }
|
||||
content()
|
||||
}
|
||||
.navigationDestination(for: Bool.self) { show in
|
||||
if show { destination() }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NavigationView {
|
||||
ZStack {
|
||||
NavigationLink(
|
||||
destination: destination(),
|
||||
isActive: isActive
|
||||
) { EmptyView() }
|
||||
content()
|
||||
}
|
||||
}
|
||||
.navigationViewStyle(.stack)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,6 +112,7 @@
|
||||
5CC2C0FC2809BF11000C35E3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5CC2C0FA2809BF11000C35E3 /* Localizable.strings */; };
|
||||
5CC2C0FF2809BF11000C35E3 /* SimpleX--iOS--InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5CC2C0FD2809BF11000C35E3 /* SimpleX--iOS--InfoPlist.strings */; };
|
||||
5CCA7DF32905735700C8FEBA /* AcceptRequestsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCA7DF22905735700C8FEBA /* AcceptRequestsView.swift */; };
|
||||
5CCB939C297EFCB100399E78 /* NavStackCompat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCB939B297EFCB100399E78 /* NavStackCompat.swift */; };
|
||||
5CCD403427A5F6DF00368C90 /* AddContactView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403327A5F6DF00368C90 /* AddContactView.swift */; };
|
||||
5CCD403727A5F9A200368C90 /* ScanToConnectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */; };
|
||||
5CDCAD482818589900503DA2 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CDCAD472818589900503DA2 /* NotificationService.swift */; };
|
||||
@@ -345,6 +346,7 @@
|
||||
5CC2C0FB2809BF11000C35E3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
5CC2C0FE2809BF11000C35E3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "ru.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
5CCA7DF22905735700C8FEBA /* AcceptRequestsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AcceptRequestsView.swift; sourceTree = "<group>"; };
|
||||
5CCB939B297EFCB100399E78 /* NavStackCompat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavStackCompat.swift; sourceTree = "<group>"; };
|
||||
5CCD403327A5F6DF00368C90 /* AddContactView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddContactView.swift; sourceTree = "<group>"; };
|
||||
5CCD403627A5F9A200368C90 /* ScanToConnectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanToConnectView.swift; sourceTree = "<group>"; };
|
||||
5CDCAD452818589900503DA2 /* SimpleX NSE.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "SimpleX NSE.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -543,6 +545,7 @@
|
||||
5C00164328A26FBC0094D739 /* ContextMenu.swift */,
|
||||
5CA7DFC229302AF000F7FDDE /* AppSheet.swift */,
|
||||
18415A7F0F189D87DEFEABCA /* PressedButtonStyle.swift */,
|
||||
5CCB939B297EFCB100399E78 /* NavStackCompat.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
@@ -1057,6 +1060,7 @@
|
||||
5CB346E52868AA7F001FD2EF /* SuspendChat.swift in Sources */,
|
||||
5C9C2DA52894777E00CC63B1 /* GroupProfileView.swift in Sources */,
|
||||
5CEACCED27DEA495000BD591 /* MsgContentView.swift in Sources */,
|
||||
5CCB939C297EFCB100399E78 /* NavStackCompat.swift in Sources */,
|
||||
5C764E89279CBCB3000C6508 /* ChatModel.swift in Sources */,
|
||||
5C971E1D27AEBEF600C8A3CE /* ChatInfoView.swift in Sources */,
|
||||
5CBD285C29575B8E00EC2CF4 /* WhatsNewView.swift in Sources */,
|
||||
|
||||
@@ -2667,7 +2667,7 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do
|
||||
(filePath, fileStatus) <- case inline of
|
||||
Just IFMSent -> do
|
||||
fPath <- getRcvFilePath fileId Nothing fileName
|
||||
withStore' $ \db -> startRcvInlineFT db user ft fPath
|
||||
withStore' $ \db -> startRcvInlineFT db user ft fPath inline
|
||||
pure (Just fPath, CIFSRcvAccepted)
|
||||
_ -> pure (Nothing, CIFSRcvInvitation)
|
||||
pure CIFile {fileId, fileName, fileSize, filePath, fileStatus}
|
||||
@@ -3413,9 +3413,9 @@ cancelRcvFileTransfer user ft@RcvFileTransfer {fileId, fileStatus, rcvFileInline
|
||||
updateRcvFileStatus db ft FSCancelled
|
||||
deleteRcvFileChunks db ft
|
||||
when (isNothing rcvFileInline) $ case fileStatus of
|
||||
RFSAccepted RcvFileInfo {connId, agentConnId} ->
|
||||
RFSAccepted RcvFileInfo {connId = Just connId, agentConnId = Just agentConnId} ->
|
||||
deleteAgentConnectionAsync' user connId agentConnId
|
||||
RFSConnected RcvFileInfo {connId, agentConnId} ->
|
||||
RFSConnected RcvFileInfo {connId = Just connId, agentConnId = Just agentConnId} ->
|
||||
deleteAgentConnectionAsync' user connId agentConnId
|
||||
_ -> pure ()
|
||||
|
||||
@@ -3425,7 +3425,7 @@ cancelSndFile user FileTransferMeta {fileId} fts sendCancel = do
|
||||
forM_ fts $ \ft' -> cancelSndFileTransfer user ft' sendCancel
|
||||
|
||||
cancelSndFileTransfer :: ChatMonad m => User -> SndFileTransfer -> Bool -> m ()
|
||||
cancelSndFileTransfer user ft@SndFileTransfer {connId, agentConnId = agentConnId@(AgentConnId acId), fileStatus} sendCancel =
|
||||
cancelSndFileTransfer user ft@SndFileTransfer {connId, agentConnId = agentConnId@(AgentConnId acId), fileStatus, fileInline} sendCancel =
|
||||
unless (fileStatus == FSCancelled || fileStatus == FSComplete) $ do
|
||||
withStore' $ \db -> do
|
||||
updateSndFileStatus db ft FSCancelled
|
||||
@@ -3433,7 +3433,7 @@ cancelSndFileTransfer user ft@SndFileTransfer {connId, agentConnId = agentConnId
|
||||
when sendCancel $
|
||||
withAgent (\a -> void (sendMessage a acId SMP.noMsgFlags $ smpEncode FileChunkCancel))
|
||||
`catchError` (toView . CRChatError (Just user))
|
||||
deleteAgentConnectionAsync' user connId agentConnId
|
||||
when (isNothing fileInline) $ deleteAgentConnectionAsync' user connId agentConnId
|
||||
|
||||
closeFileHandle :: ChatMonad m => Int64 -> (ChatController -> TVar (Map Int64 Handle)) -> m ()
|
||||
closeFileHandle fileId files = do
|
||||
|
||||
@@ -10,10 +10,10 @@ m20221012_inline_files =
|
||||
[sql|
|
||||
DROP INDEX idx_messages_direct_shared_msg_id;
|
||||
|
||||
ALTER TABLE files ADD COLUMN file_inline TEXT;
|
||||
ALTER TABLE rcv_files ADD COLUMN rcv_file_inline TEXT;
|
||||
ALTER TABLE rcv_files ADD COLUMN file_inline TEXT;
|
||||
ALTER TABLE snd_files ADD COLUMN file_inline TEXT;
|
||||
ALTER TABLE files ADD COLUMN file_inline TEXT; -- based on offer, determined by file sender for both sides
|
||||
ALTER TABLE rcv_files ADD COLUMN rcv_file_inline TEXT; -- actual mode when receiving file, determined when invitation is accepted
|
||||
ALTER TABLE rcv_files ADD COLUMN file_inline TEXT; -- based on offer, determined when invitation is processed
|
||||
ALTER TABLE snd_files ADD COLUMN file_inline TEXT; -- actual mode when sending file, determined when invitation is accepted
|
||||
ALTER TABLE snd_files ADD COLUMN last_inline_msg_delivery_id INTEGER;
|
||||
|
||||
CREATE UNIQUE INDEX idx_snd_files_last_inline_msg_delivery_id ON snd_files(last_inline_msg_delivery_id);
|
||||
|
||||
@@ -2859,14 +2859,14 @@ getRcvFileTransferById db fileId = do
|
||||
(user,) <$> getRcvFileTransfer db user fileId
|
||||
|
||||
getRcvFileTransfer :: DB.Connection -> User -> FileTransferId -> ExceptT StoreError IO RcvFileTransfer
|
||||
getRcvFileTransfer db user@User {userId} fileId = do
|
||||
getRcvFileTransfer db User {userId} fileId = do
|
||||
rftRow <-
|
||||
ExceptT . firstRow id (SERcvFileNotFound fileId) $
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT r.file_status, r.file_queue_info, r.group_member_id, f.file_name,
|
||||
f.file_size, f.chunk_size, f.cancelled, cs.contact_id, cs.local_display_name, m.group_id, m.group_member_id, m.local_display_name,
|
||||
f.file_size, f.chunk_size, f.cancelled, cs.local_display_name, m.local_display_name,
|
||||
f.file_path, r.file_inline, r.rcv_file_inline, c.connection_id, c.agent_conn_id
|
||||
FROM rcv_files r
|
||||
JOIN files f USING (file_id)
|
||||
@@ -2879,11 +2879,11 @@ getRcvFileTransfer db user@User {userId} fileId = do
|
||||
rcvFileTransfer rftRow
|
||||
where
|
||||
rcvFileTransfer ::
|
||||
(FileStatus, Maybe ConnReqInvitation, Maybe Int64, String, Integer, Integer, Maybe Bool) :. (Maybe Int64, Maybe ContactName, Maybe Int64, Maybe Int64, Maybe ContactName, Maybe FilePath, Maybe InlineFileMode, Maybe InlineFileMode) :. (Maybe Int64, Maybe AgentConnId) ->
|
||||
(FileStatus, Maybe ConnReqInvitation, Maybe Int64, String, Integer, Integer, Maybe Bool) :. (Maybe ContactName, Maybe ContactName, Maybe FilePath, Maybe InlineFileMode, Maybe InlineFileMode) :. (Maybe Int64, Maybe AgentConnId) ->
|
||||
ExceptT StoreError IO RcvFileTransfer
|
||||
rcvFileTransfer ((fileStatus', fileConnReq, grpMemberId, fileName, fileSize, chunkSize, cancelled_) :. (contactId_, contactName_, groupId_, groupMemberId_, memberName_, filePath_, fileInline, rcvFileInline) :. (connId_, agentConnId_)) = do
|
||||
rcvFileTransfer ((fileStatus', fileConnReq, grpMemberId, fileName, fileSize, chunkSize, cancelled_) :. (contactName_, memberName_, filePath_, fileInline, rcvFileInline) :. (connId_, agentConnId_)) = do
|
||||
let fileInv = FileInvitation {fileName, fileSize, fileConnReq, fileInline}
|
||||
fileInfo = (filePath_, connId_, agentConnId_, contactId_, groupId_, groupMemberId_, isJust fileInline)
|
||||
fileInfo = (filePath_, connId_, agentConnId_)
|
||||
case contactName_ <|> memberName_ of
|
||||
Nothing -> throwError $ SERcvFileInvalid fileId
|
||||
Just name -> do
|
||||
@@ -2898,22 +2898,14 @@ getRcvFileTransfer db user@User {userId} fileId = do
|
||||
RcvFileTransfer {fileId, fileInvitation, fileStatus, rcvFileInline, senderDisplayName, chunkSize, cancelled, grpMemberId}
|
||||
rfi fileInfo = maybe (throwError $ SERcvFileInvalid fileId) pure =<< rfi_ fileInfo
|
||||
rfi_ = \case
|
||||
(Just filePath, Just connId, Just agentConnId, _, _, _, _) -> pure $ Just RcvFileInfo {filePath, connId, agentConnId}
|
||||
(Just filePath, Nothing, Nothing, Just contactId, _, _, True) -> do
|
||||
Contact {activeConn = Connection {connId, agentConnId}} <- getContact db user contactId
|
||||
pure $ Just RcvFileInfo {filePath, connId, agentConnId}
|
||||
(Just filePath, Nothing, Nothing, _, Just groupId, Just groupMemberId, True) -> do
|
||||
getGroupMember db user groupId groupMemberId >>= \case
|
||||
GroupMember {activeConn = Just Connection {connId, agentConnId}} ->
|
||||
pure $ Just RcvFileInfo {filePath, connId, agentConnId}
|
||||
_ -> pure Nothing
|
||||
(Just filePath, connId, agentConnId) -> pure $ Just RcvFileInfo {filePath, connId, agentConnId}
|
||||
_ -> pure Nothing
|
||||
cancelled = fromMaybe False cancelled_
|
||||
|
||||
acceptRcvFileTransfer :: DB.Connection -> User -> Int64 -> (CommandId, ConnId) -> ConnStatus -> FilePath -> ExceptT StoreError IO AChatItem
|
||||
acceptRcvFileTransfer db user@User {userId} fileId (cmdId, acId) connStatus filePath = ExceptT $ do
|
||||
currentTs <- getCurrentTime
|
||||
acceptRcvFT_ db user fileId filePath currentTs
|
||||
acceptRcvFT_ db user fileId filePath Nothing currentTs
|
||||
DB.execute
|
||||
db
|
||||
"INSERT INTO connections (agent_conn_id, conn_status, conn_type, rcv_file_id, user_id, created_at, updated_at) VALUES (?,?,?,?,?,?,?)"
|
||||
@@ -2933,23 +2925,23 @@ getContactByFileId db user@User {userId} fileId = do
|
||||
|
||||
acceptRcvInlineFT :: DB.Connection -> User -> Int64 -> FilePath -> ExceptT StoreError IO AChatItem
|
||||
acceptRcvInlineFT db user fileId filePath = do
|
||||
liftIO $ acceptRcvFT_ db user fileId filePath =<< getCurrentTime
|
||||
liftIO $ acceptRcvFT_ db user fileId filePath (Just IFMOffer) =<< getCurrentTime
|
||||
getChatItemByFileId db user fileId
|
||||
|
||||
startRcvInlineFT :: DB.Connection -> User -> RcvFileTransfer -> FilePath -> IO ()
|
||||
startRcvInlineFT db user RcvFileTransfer {fileId} filePath =
|
||||
acceptRcvFT_ db user fileId filePath =<< getCurrentTime
|
||||
startRcvInlineFT :: DB.Connection -> User -> RcvFileTransfer -> FilePath -> Maybe InlineFileMode -> IO ()
|
||||
startRcvInlineFT db user RcvFileTransfer {fileId} filePath rcvFileInline =
|
||||
acceptRcvFT_ db user fileId filePath rcvFileInline =<< getCurrentTime
|
||||
|
||||
acceptRcvFT_ :: DB.Connection -> User -> Int64 -> FilePath -> UTCTime -> IO ()
|
||||
acceptRcvFT_ db User {userId} fileId filePath currentTs = do
|
||||
acceptRcvFT_ :: DB.Connection -> User -> Int64 -> FilePath -> Maybe InlineFileMode -> UTCTime -> IO ()
|
||||
acceptRcvFT_ db User {userId} fileId filePath rcvFileInline currentTs = do
|
||||
DB.execute
|
||||
db
|
||||
"UPDATE files SET file_path = ?, ci_file_status = ?, updated_at = ? WHERE user_id = ? AND file_id = ?"
|
||||
(filePath, CIFSRcvAccepted, currentTs, userId, fileId)
|
||||
DB.execute
|
||||
db
|
||||
"UPDATE rcv_files SET file_status = ?, updated_at = ? WHERE file_id = ?"
|
||||
(FSAccepted, currentTs, fileId)
|
||||
"UPDATE rcv_files SET rcv_file_inline = ?, file_status = ?, updated_at = ? WHERE file_id = ?"
|
||||
(rcvFileInline, FSAccepted, currentTs, fileId)
|
||||
|
||||
updateRcvFileStatus :: DB.Connection -> RcvFileTransfer -> FileStatus -> IO ()
|
||||
updateRcvFileStatus db RcvFileTransfer {fileId} status = do
|
||||
|
||||
@@ -1518,8 +1518,8 @@ instance ToJSON RcvFileStatus where
|
||||
|
||||
data RcvFileInfo = RcvFileInfo
|
||||
{ filePath :: FilePath,
|
||||
connId :: Int64,
|
||||
agentConnId :: AgentConnId
|
||||
connId :: Maybe Int64,
|
||||
agentConnId :: Maybe AgentConnId
|
||||
}
|
||||
deriving (Eq, Show, Generic)
|
||||
|
||||
@@ -1531,7 +1531,8 @@ liveRcvFileTransferConnId RcvFileTransfer {fileStatus} = case fileStatus of
|
||||
RFSConnected fi -> acId fi
|
||||
_ -> Nothing
|
||||
where
|
||||
acId RcvFileInfo {agentConnId = AgentConnId cId} = Just cId
|
||||
acId RcvFileInfo {agentConnId = Just (AgentConnId cId)} = Just cId
|
||||
acId _ = Nothing
|
||||
|
||||
newtype AgentConnId = AgentConnId ConnId
|
||||
deriving (Eq, Show)
|
||||
|
||||
Reference in New Issue
Block a user