From 1af513c548bb874ee7e195d851b753254f1b2fe7 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Sun, 23 Jun 2024 23:36:25 +0400 Subject: [PATCH 01/43] docs: update chat protocol (#4344) --- docs/protocol/simplex-chat.md | 45 ++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/docs/protocol/simplex-chat.md b/docs/protocol/simplex-chat.md index e3d8e88ae0..efa4edb959 100644 --- a/docs/protocol/simplex-chat.md +++ b/docs/protocol/simplex-chat.md @@ -17,18 +17,23 @@ SimpleX Chat Protocol is a protocol used by SimpleX Chat clients to exchange mes The scope of SimpleX Chat Protocol is application level messages, both for chat functionality, related to the conversations between the clients, and extensible for any other application functions. Currently supported chat functions: - direct and group messages, -- message replies (quoting), forwarded messages and message deletions, -- message attachments: images and files, +- message replies (quoting), message editing, forwarded messages and message deletions, +- message attachments: images, videos, voice messages and files, - creating and managing chat groups, - invitation and signalling for audio/video WebRTC calls. ## General message format -SimpleX Chat protocol supports two message formats: +SimpleX Chat protocol supports these message formats: - JSON-based format for chat and application messages. +- compressed format for adapting larger messages to reduced size of message envelope, caused by addition of PQ encryption keys to SMP agent message envelope. - binary format for sending files or any other binary data. +JSON-based message format supports batching inside a single container message, by encoding list of messages as JSON array. + +Current implementation of chat protocol in SimpleX Chat uses SimpleX File Transfer Protocol (XFTP) for file transfer, with passing file description as chat protocol messages, instead passing files in binary format via SMP connections. + ### JSON format for chat and application messages This document uses JTD schemas [RFC 8927](https://www.rfc-editor.org/rfc/rfc8927.html) to define the properties of chat messages, with some additional restrictions on message properties included in metadata member of JTD schemas. In case of any contradiction between JSON examples and JTD schema the latter MUST be considered correct. @@ -77,8 +82,22 @@ For example, this message defines a simple text message `"hello!"`: `params` property includes message data, depending on `event`, as defined below and in [JTD schema](./simplex-chat.schema.json). +### Compressed format + +The syntax of compressed message is defined by the following ABNF notation: + +```abnf +compressedMessage = %s"X" 1*15780 OCTET; compressed message data +``` + +Compressed message is required to fit into 13388 bytes, accounting for agent overhead (see Protocol's maxCompressedMsgLength). + +The actual JSON message is required to fit into 15610 bytes, accounting for group message forwarding (x.grp.msg.forward) overhead (see Protocol's maxEncodedMsgLength). + ### Binary format for sending files +> Note: Planned to be deprecated. No longer used for file transfer in SimpleX Chat implementation of chat protocol. + SimpleX Chat clients use separate connections to send files using a binary format. File chunk size send in each message MUST NOT be bigger than 15,780 bytes to fit into 16kb (16384 bytes) transport block. The syntax of each message used to send files is defined by the following ABNF notation: @@ -117,7 +136,9 @@ SimpleX Chat Protocol supports the following message types passed in `event` pro - `x.contact` - contact profile and additional data sent as part of contact request to a long-term contact address. - `x.info*` - messages to send, update and de-duplicate contact profiles. - `x.msg.*` - messages to create, update and delete content chat items. +- `x.msg.file.descr` - message to transfer XFTP file description. - `x.file.*` - messages to accept and cancel sending files (see files sub-protocol). +- `x.direct.del` - message to notify about contact deletion. - `x.grp.*` - messages used to manage groups and group members (see group sub-protocol). - `x.call.*` - messages to invite to WebRTC calls and send signalling messages. - `x.ok` - message sent during connection handshake. @@ -155,6 +176,8 @@ Message content can be one of four types: - `text` - no file attachment is expected for this format, `text` property MUST be non-empty. - `file` - attached file is required, `text` property MAY be empty. - `image` - attached file is required, `text` property MAY be empty. +- `video` - attached file is required, `text` property MAY be empty. +- `voice` - attached file is required, `text` property MAY be empty. - `link` - no file attachment is expected, `text` property MUST be non-empty. `preview` property contains information about link preview. See `/definition/msgContent` in [JTD schema](./simplex-chat.schema.json) for message container format. @@ -181,6 +204,8 @@ File attachment can optionally include connection address to receive the file - `x.file.cancel` message is sent to notify the recipient that sending of the file was cancelled. It is sent in response to accepting the file with `x.file.acpt.inv` message. It is sent in the same connection where the file was offered. +`x.msg.file.descr` message is used to send XFTP file description. File descriptions that don't fit into a single chat protocol message are sent in parts, with messages including part number (`fileDescrPartNo`) and description completion marker (`fileDescrComplete`). Recipient client accumulates description parts and starts file download upon completing file description. + ## Sub-protocol for chat groups ### Decentralized design for chat groups @@ -197,6 +222,8 @@ The diagram below shows the sequence of messages sent between the users' clients ![Adding member to the group](./diagrams/group.svg) +While introduced members establish connection inside group, inviting member forwards messages between them by sending `x.grp.msg.forward` messages. When introduced members finalize connection, they notify inviting member to stop forwarding via `x.grp.mem.con` message. + ### Member roles Currently members can have one of three roles - `owner`, `admin` and `member`. The user that created the group is self-assigned owner role, the new members are assigned role by the member who adds them - only `owner` and `admin` members can add new members; only `owner` members can add members with `owner` role. @@ -207,6 +234,10 @@ Currently members can have one of three roles - `owner`, `admin` and `member`. T `x.grp.acpt` message is sent as part of group member connection handshake, only to the inviting user. +`x.grp.link.inv` message is sent as part of connection handshake to member joining via group link, and contains group profile and initial information about inviting and joining member. + +`x.grp.link.mem` message is sent as part of connection handshake to member joining via group link, and contains remaining information about inviting member. + `x.grp.mem.new` message is sent by the inviting user to all connected members (and scheduled as pending to all announced but not yet connected members) to announce a new member to the existing members. This message MUST only be sent by members with `admin` or `owner` role. Receiving clients MUST ignore this message if it is received from member with `member` role. `x.grp.mem.intro` messages are sent by the inviting user to the invited member, via their group member connection, one message for each existing member. When this message is sent by any other member than the one who invited the recipient it MUST be ignored. @@ -219,6 +250,10 @@ Currently members can have one of three roles - `owner`, `admin` and `member`. T `x.grp.mem.role` message is sent to update group member role - it is sent to all members by the member who updated the role of the member referenced in this message. This message MUST only be sent by members with `admin` or `owner` role. Receiving clients MUST ignore this message if it is received from member with role less than `admin`. +`x.grp.mem.restrict` message is sent to group members to communicate group member restrictions, such as member being blocked for sending messages. + +`x.grp.mem.con` message is sent by members connecting inside group to inviting member, to notify the inviting member they have completed the connection and no longer require forwarding messages between them. + `x.grp.mem.del` message is sent to delete a member - it is sent to all members by the member who deletes the member referenced in this message. This message MUST only be sent by members with `admin` or `owner` role. Receiving clients MUST ignore this message if it is received from member with `member` role. `x.grp.leave` message is sent to all members by the member leaving the group. If the only group `owner` leaves the group, it will not be possible to delete it with `x.grp.del` message - but all members can still leave the group with `x.grp.leave` message and then delete a local copy of the group. @@ -227,6 +262,10 @@ Currently members can have one of three roles - `owner`, `admin` and `member`. T `x.grp.info` message is sent to all members by the member who updated group profile. Only group owners can update group profiles. Clients MAY implement some conflict resolution strategy - it is currently not implemented by SimpleX Chat client. This message MUST only be sent by members with `owner` role. Receiving clients MUST ignore this message if it is received from member other than with `owner` role. +`x.grp.direct.inv` message is sent to a group member to propose establishing a direct connection between members, thus creating a contact with another member. + +`x.grp.msg.forward` message is sent by inviting member to forward messages between introduced members, while they are connecting. + ## Sub-protocol for WebRTC audio/video calls This sub-protocol is used to send call invitations and to negotiate end-to-end encryption keys and pass WebRTC signalling information. From d9510031917bed8aa8caa6c428d4385c3bd790ba Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:51:55 +0400 Subject: [PATCH 02/43] core: servers summary api (#4319) * core: servers summary api * rework * server known types * set stats file path * rename * local simplexmq * update * rfc * update * update * get servers * compile summary * remove sort * rename * rename, refactor * refactor attempt * refactor attempt 2 * refactor * fix * fix2 * remove space * refactor xftp * update --------- Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> --- cabal.project | 2 +- .../2024-06-17-agent-stats-persistence.md | 87 ++++++ scripts/nix/sha256map.nix | 2 +- simplex-chat.cabal | 1 + src/Simplex/Chat.hs | 26 +- src/Simplex/Chat/Call.hs | 2 +- src/Simplex/Chat/Controller.hs | 5 +- src/Simplex/Chat/Markdown.hs | 5 +- src/Simplex/Chat/Messages/CIContent.hs | 5 +- src/Simplex/Chat/Protocol.hs | 3 +- src/Simplex/Chat/Stats.hs | 268 ++++++++++++++++++ src/Simplex/Chat/Store/Profiles.hs | 7 +- src/Simplex/Chat/Types.hs | 36 ++- src/Simplex/Chat/Types/Preferences.hs | 2 +- src/Simplex/Chat/Types/UITheme.hs | 1 + src/Simplex/Chat/Types/Util.hs | 11 - src/Simplex/Chat/View.hs | 2 +- tests/ChatTests/Profiles.hs | 2 +- 18 files changed, 432 insertions(+), 35 deletions(-) create mode 100644 docs/rfcs/2024-06-17-agent-stats-persistence.md create mode 100644 src/Simplex/Chat/Stats.hs diff --git a/cabal.project b/cabal.project index 5a607b257d..be95820371 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: 8a3b72458f917e9867f4e3640dda0fa1827ff6cf + tag: c7886926870e97fa592d51fa36a2cdec49296388 source-repository-package type: git diff --git a/docs/rfcs/2024-06-17-agent-stats-persistence.md b/docs/rfcs/2024-06-17-agent-stats-persistence.md new file mode 100644 index 0000000000..2f5d641769 --- /dev/null +++ b/docs/rfcs/2024-06-17-agent-stats-persistence.md @@ -0,0 +1,87 @@ +# Agent stats persistence + +## Problem + +State/state tracked in agent are lost on app restart, which makes it difficult to debug user bugs. + +## Solution + +Persist stats between sessions. + +App terminal signals may vary per platform / be absent (?) -> persist stats periodically. + +Stats would have `` key, so we don't want to store them in a plaintext file to not leak used servers locally -> persist in encrypted db. + +There's couple of orthogonal design decision to be made: +- persist in chat or in agent db + - pros for chat: + - possibly less contention for db than agent + - pros for agent: + - no unnecessary back and forth, especially if agent starts accumulating from past sessions and has to be parameterized with past stats (see below) +- agent to start accumulating from past sessions stats, or keep past separately and only accumulate for current session from zeros + - pros for accumulating from past sessions: + - easier to maintain stats - e.g. user deletion has to remove keys, which is more convoluted if past stats are not stored in memory + - simpler UI - overall stats, no differentiation for past/current session (or less logic in backend preparing presentation data) + - pros for accumulating from zeros: + - simpler start logic - no need to restore stats from agent db / pass initial stats from chat db + - can differentiate between past sessions and current session stats in UI + +### Option 1 - Persist in chat db, agent to track only current session + +- Chat stores stats in such table: + +```sql +CREATE TABLE agent_stats( + agent_stats_id INTEGER PRIMARY KEY, -- dummy id, there will only be one record + past_stats TEXT, -- accumulated from previous sessions + session_stats TEXT, -- current session + past_started_at TEXT NOT NULL DEFAULT(datetime('now')), -- starting point of tracking stats, reset on stats reset + session_started_at TEXT NOT NULL DEFAULT(datetime('now')), -- starting point of current session + session_updated_at TEXT NOT NULL DEFAULT(datetime('now')) -- last update of current session stats (periodic, frequent updates) +); +``` + +- Chat periodically calls getAgentServersStats api and updates `session_stats`. + - interval? should be short to not lose too much data, 5-30 seconds? +- On start `session_stats` are accumulated into `past_stats` and set to null. +- On user deletion, agent updates current session stats in memory (removes keys), chat has to do same for both stats fields in db. + - other cases where stats have to be manipulated in similar way? + +### Option 2 - Persist in chat db, agent to accumulate stats from past sessions + +- Table is only used for persistence of overall stats: + +```sql +CREATE TABLE agent_stats( + agent_stats_id INTEGER PRIMARY KEY, -- dummy id, there will only be one record + agent_stats TEXT, -- overall stats - past and session + started_tracking_at TEXT NOT NULL DEFAULT(datetime('now')), -- starting point of tracking stats, reset on stats reset + updated_at TEXT NOT NULL DEFAULT(datetime('now')) +); +``` + +- Chat to parameterize creation of agent client with initial stats. + +### Option 3 - Persist in agent db, agent to differentiate past stats and session stats + +- Table in agent db similar to option 1. +- Agent is responsible for periodic updates in session, as well as accumulating into "past" and resetting session stats on start. +- Agent only communicates stats to chat on request. +- On user deletion agent is fully responsible for maintaining both in-memory session stats, and updating db records. + +### Option 4 - Persist in agent db, agent to accumulate stats from past sessions + +- Table in agent db similar to option 2. +- On start agent restores initial stats into memory by itself. +- Since all stats are in memory, on user deletion it's enough to update in memory without updating db. + - there is a race possible where agent crashes after updating stats (removing user keys) in memory before database stats have been overwritten by a periodic update, so it may be better to immediately overwrite and not wait for periodic update. + - still at least there's at least no additional logic to update past stats. + +### Other considerations + +Why is it important to timely remove user keys from past stats? +- stats not being saved for past users: + - important both privacy-wise and to not cause confusion when showing "All" stats (e.g. user summing up across users stats would have smaller total than total stats). + - to avoid accidentally mixing up with newer users. + - though we do have an AUTOINCREMENT user_id in agent so probably it wouldn't be a problem. +- on the other hand maybe we don't want to "forget" stats on user deletion so that stats would reflect networking more accurately? diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index fc8833ee31..3a8284a74b 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."8a3b72458f917e9867f4e3640dda0fa1827ff6cf" = "1mmxdaj563kjmlkacxdnq62n6mzw9khampzaqghnk6iiwzdig0qy"; + "https://github.com/simplex-chat/simplexmq.git"."c7886926870e97fa592d51fa36a2cdec49296388" = "1r3nibcgw3whl0q3ssyr1606x4ilqphhzqyihi3aw4nw5fmz226h"; "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"; diff --git a/simplex-chat.cabal b/simplex-chat.cabal index f8ab75568b..3b9d2681d9 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -160,6 +160,7 @@ library Simplex.Chat.Remote.RevHTTP Simplex.Chat.Remote.Transport Simplex.Chat.Remote.Types + Simplex.Chat.Stats Simplex.Chat.Store Simplex.Chat.Store.AppSettings Simplex.Chat.Store.Connections diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index c46eed70e1..539ad003ba 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -20,6 +20,7 @@ import Control.Applicative (optional, (<|>)) import Control.Concurrent.STM (retry) import Control.Logger.Simple import Control.Monad +import Simplex.Chat.Stats import Control.Monad.Except import Control.Monad.IO.Unlift import Control.Monad.Reader @@ -84,7 +85,6 @@ import Simplex.Chat.Store.Shared import Simplex.Chat.Types import Simplex.Chat.Types.Preferences import Simplex.Chat.Types.Shared -import Simplex.Chat.Types.Util import Simplex.Chat.Util (encryptFile, liftIOEither, shuffle) import qualified Simplex.Chat.Util as U import Simplex.FileTransfer.Client.Main (maxFileSize, maxFileSizeHard) @@ -113,7 +113,7 @@ import qualified Simplex.Messaging.Crypto.Ratchet as CR import Simplex.Messaging.Encoding import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (base64P) -import Simplex.Messaging.Protocol (AProtoServerWithAuth (..), AProtocolType (..), EntityId, ErrorType (..), MsgBody, MsgFlags (..), NtfServer, ProtoServerWithAuth (..), ProtocolTypeI, SProtocolType (..), SubscriptionMode (..), UserProtocol, XFTPServer, userProtocol) +import Simplex.Messaging.Protocol (AProtoServerWithAuth (..), AProtocolType (..), EntityId, ErrorType (..), MsgBody, MsgFlags (..), NtfServer, ProtoServerWithAuth (..), ProtocolTypeI, SProtocolType (..), SubscriptionMode (..), UserProtocol, XFTPServer, userProtocol, ProtocolServer) import qualified Simplex.Messaging.Protocol as SMP import Simplex.Messaging.ServiceScheme (ServiceScheme (..)) import qualified Simplex.Messaging.TMap as TM @@ -369,7 +369,7 @@ activeAgentServers ChatConfig {defaultServers} p = fromMaybe (cfgServers p defaultServers) . nonEmpty . map (\ServerCfg {server} -> server) - . filter (\ServerCfg {enabled} -> enabled) + . filter (\ServerCfg {enabled} -> enabled == SEEnabled) cfgServers :: UserProtocol p => SProtocolType p -> (DefaultAgentServers -> NonEmpty (ProtoServerWithAuth p)) cfgServers p DefaultAgentServers {smp, xftp} = case p of @@ -1315,7 +1315,7 @@ processChatCommand' vr = \case servers' = fromMaybe (L.map toServerCfg defServers) $ nonEmpty servers pure $ CRUserProtoServers user $ AUPS $ UserProtoServers p servers' defServers where - toServerCfg server = ServerCfg {server, preset = True, tested = Nothing, enabled = True} + toServerCfg server = ServerCfg {server, preset = True, tested = Nothing, enabled = SEEnabled} GetUserProtoServers aProtocol -> withUser $ \User {userId} -> processChatCommand $ APIGetUserProtoServers userId aProtocol APISetUserProtoServers userId (APSC p (ProtoServersConfig servers)) -> withUserId userId $ \user -> withServerProtocol p $ do @@ -2253,6 +2253,21 @@ processChatCommand' vr = \case CLUserContact ucId -> "UserContact " <> show ucId CLFile fId -> "File " <> show fId DebugEvent event -> toView event >> ok_ + GetAgentServersSummary userId -> withUserId userId $ \user -> do + agentServersSummary <- lift $ withAgent' getAgentServersSummary + users <- withStore' getUsers + smpServers <- getUserServers user SPSMP + xftpServers <- getUserServers user SPXFTP + let presentedServersSummary = toPresentedServersSummary agentServersSummary users user smpServers xftpServers + pure $ CRAgentServersSummary user presentedServersSummary + where + getUserServers :: forall p. (ProtocolTypeI p, UserProtocol p) => User -> SProtocolType p -> CM [ProtocolServer p] + getUserServers users protocol = do + ChatConfig {defaultServers} <- asks config + let defServers = cfgServers protocol defaultServers + servers <- map (\ServerCfg {server} -> server) <$> withStore' (`getProtocolServers` users) + let srvs = if null servers then L.toList defServers else servers + pure $ map protoServer srvs GetAgentWorkers -> lift $ CRAgentWorkersSummary <$> withAgent' getAgentWorkersSummary GetAgentWorkersDetails -> lift $ CRAgentWorkersDetails <$> withAgent' getAgentWorkersDetails GetAgentStats -> lift $ CRAgentStats . map stat <$> withAgent' getAgentStats @@ -7611,6 +7626,7 @@ chatCommandP = ("/version" <|> "/v") $> ShowVersion, "/debug locks" $> DebugLocks, "/debug event " *> (DebugEvent <$> jsonP), + "/get servers summary " *> (GetAgentServersSummary <$> A.decimal), "/get stats" $> GetAgentStats, "/reset stats" $> ResetAgentStats, "/get subs" $> GetAgentSubs, @@ -7755,7 +7771,7 @@ chatCommandP = (Just <$> (AutoAccept <$> (" incognito=" *> onOffP <|> pure False) <*> optional (A.space *> msgContentP))) (pure Nothing) srvCfgP = strP >>= \case AProtocolType p -> APSC p <$> (A.space *> jsonP) - toServerCfg server = ServerCfg {server, preset = False, tested = Nothing, enabled = True} + toServerCfg server = ServerCfg {server, preset = False, tested = Nothing, enabled = SEEnabled} rcCtrlAddressP = RCCtrlAddress <$> ("addr=" *> strP) <*> (" iface=" *> (jsonP <|> text1P)) text1P = safeDecodeUtf8 <$> A.takeTill (== ' ') char_ = optional . A.char diff --git a/src/Simplex/Chat/Call.hs b/src/Simplex/Chat/Call.hs index 115cd839e4..9968d170aa 100644 --- a/src/Simplex/Chat/Call.hs +++ b/src/Simplex/Chat/Call.hs @@ -21,10 +21,10 @@ import Data.Time.Clock (UTCTime) import Database.SQLite.Simple.FromField (FromField (..)) import Database.SQLite.Simple.ToField (ToField (..)) import Simplex.Chat.Types (Contact, ContactId, User) -import Simplex.Chat.Types.Util (decodeJSON, encodeJSON) import qualified Simplex.Messaging.Crypto as C import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, fromTextField_, fstToLower, singleFieldJSON) +import Simplex.Messaging.Util (decodeJSON, encodeJSON) data Call = Call { contactId :: ContactId, diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index 04f360cc3e..4404360c2a 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -60,6 +60,7 @@ import Simplex.Chat.Messages.CIContent import Simplex.Chat.Protocol import Simplex.Chat.Remote.AppVersion import Simplex.Chat.Remote.Types +import Simplex.Chat.Stats (PresentedServersSummary) import Simplex.Chat.Store (AutoAccept, ChatLockEntity, StoreError (..), UserContactLink, UserMsgReceiptSettings) import Simplex.Chat.Types import Simplex.Chat.Types.Preferences @@ -75,7 +76,7 @@ import Simplex.Messaging.Agent.Protocol import Simplex.Messaging.Agent.Store.SQLite (MigrationConfirmation, SQLiteStore, UpMigration, withTransaction) import Simplex.Messaging.Agent.Store.SQLite.DB (SlowQueryStats (..)) import qualified Simplex.Messaging.Agent.Store.SQLite.DB as DB -import Simplex.Messaging.Client (SMPProxyMode (..), SMPProxyFallback (..)) +import Simplex.Messaging.Client (SMPProxyFallback (..), SMPProxyMode (..)) import qualified Simplex.Messaging.Crypto as C import Simplex.Messaging.Crypto.File (CryptoFile (..)) import qualified Simplex.Messaging.Crypto.File as CF @@ -505,6 +506,7 @@ data ChatCommand | ShowVersion | DebugLocks | DebugEvent ChatResponse + | GetAgentServersSummary UserId | GetAgentStats | ResetAgentStats | GetAgentSubs @@ -756,6 +758,7 @@ data ChatResponse | CRSQLResult {rows :: [Text]} | CRSlowSQLQueries {chatQueries :: [SlowSQLQuery], agentQueries :: [SlowSQLQuery]} | CRDebugLocks {chatLockName :: Maybe String, chatEntityLocks :: Map String String, agentLocks :: AgentLocks} + | CRAgentServersSummary {user :: User, serversSummary :: PresentedServersSummary} | CRAgentStats {agentStats :: [[String]]} | CRAgentWorkersDetails {agentWorkersDetails :: AgentWorkersDetails} | CRAgentWorkersSummary {agentWorkersSummary :: AgentWorkersSummary} diff --git a/src/Simplex/Chat/Markdown.hs b/src/Simplex/Chat/Markdown.hs index d7c6d31fc8..688ffa6b1d 100644 --- a/src/Simplex/Chat/Markdown.hs +++ b/src/Simplex/Chat/Markdown.hs @@ -29,13 +29,12 @@ import Data.Text (Text) import qualified Data.Text as T import Data.Text.Encoding (encodeUtf8) import Simplex.Chat.Types -import Simplex.Chat.Types.Util import Simplex.Messaging.Agent.Protocol (AConnectionRequestUri (..), ConnReqUriData (..), ConnectionRequestUri (..), SMPQueue (..)) import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, fstToLower, sumTypeJSON) import Simplex.Messaging.Protocol (ProtocolServer (..)) import Simplex.Messaging.ServiceScheme (ServiceScheme (..)) -import Simplex.Messaging.Util (safeDecodeUtf8) +import Simplex.Messaging.Util (decodeJSON, safeDecodeUtf8) import System.Console.ANSI.Types import qualified Text.Email.Validate as Email @@ -146,7 +145,7 @@ parseMarkdown s = fromRight (unmarked s) $ A.parseOnly (markdownP <* A.endOfInpu isSimplexLink :: Format -> Bool isSimplexLink = \case - SimplexLink {} -> True; + SimplexLink {} -> True _ -> False markdownP :: Parser Markdown diff --git a/src/Simplex/Chat/Messages/CIContent.hs b/src/Simplex/Chat/Messages/CIContent.hs index 3d71047d57..e198183b06 100644 --- a/src/Simplex/Chat/Messages/CIContent.hs +++ b/src/Simplex/Chat/Messages/CIContent.hs @@ -29,12 +29,11 @@ import Simplex.Chat.Protocol import Simplex.Chat.Types import Simplex.Chat.Types.Preferences import Simplex.Chat.Types.Shared -import Simplex.Chat.Types.Util import Simplex.Messaging.Agent.Protocol (MsgErrorType (..), RatchetSyncState (..), SwitchPhase (..)) -import Simplex.Messaging.Crypto.Ratchet (PQEncryption, pattern PQEncOn, pattern PQEncOff) +import Simplex.Messaging.Crypto.Ratchet (PQEncryption, pattern PQEncOff, pattern PQEncOn) import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, fstToLower, singleFieldJSON, sumTypeJSON) -import Simplex.Messaging.Util (safeDecodeUtf8, tshow, (<$?>)) +import Simplex.Messaging.Util (encodeJSON, safeDecodeUtf8, tshow, (<$?>)) data MsgDirection = MDRcv | MDSnd deriving (Eq, Show) diff --git a/src/Simplex/Chat/Protocol.hs b/src/Simplex/Chat/Protocol.hs index 8c5a9e1905..d611760fbf 100644 --- a/src/Simplex/Chat/Protocol.hs +++ b/src/Simplex/Chat/Protocol.hs @@ -46,14 +46,13 @@ import Database.SQLite.Simple.ToField (ToField (..)) import Simplex.Chat.Call import Simplex.Chat.Types import Simplex.Chat.Types.Shared -import Simplex.Chat.Types.Util import Simplex.Messaging.Agent.Protocol (VersionSMPA, pqdrSMPAgentVersion) import Simplex.Messaging.Compression (Compressed, compress1, decompress1) import Simplex.Messaging.Encoding import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, fromTextField_, fstToLower, parseAll, sumTypeJSON, taggedObjectJSON) import Simplex.Messaging.Protocol (MsgBody) -import Simplex.Messaging.Util (eitherToMaybe, safeDecodeUtf8, (<$?>)) +import Simplex.Messaging.Util (decodeJSON, eitherToMaybe, encodeJSON, safeDecodeUtf8, (<$?>)) import Simplex.Messaging.Version hiding (version) -- Chat version history: diff --git a/src/Simplex/Chat/Stats.hs b/src/Simplex/Chat/Stats.hs new file mode 100644 index 0000000000..f6ea195e1c --- /dev/null +++ b/src/Simplex/Chat/Stats.hs @@ -0,0 +1,268 @@ +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE TemplateHaskell #-} +{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} + +module Simplex.Chat.Stats where + +import Control.Applicative ((<|>)) +import qualified Data.Aeson.TH as J +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as M +import Data.Maybe (fromMaybe, isJust) +import Data.Time.Clock (UTCTime) +import Simplex.Chat.Types +import Simplex.Messaging.Agent.Client +import Simplex.Messaging.Agent.Protocol (UserId) +import Simplex.Messaging.Agent.Stats +import Simplex.Messaging.Parsers (defaultJSON) +import Simplex.Messaging.Protocol + +data PresentedServersSummary = PresentedServersSummary + { statsStartedAt :: UTCTime, + currentUserServers :: ServersSummary, + allUsersServers :: ServersSummary + } + deriving (Show) + +-- Presentation of servers will be split into separate categories, +-- so users can differentiate currently used (connected) servers, +-- previously connected servers that were in use in previous sessions, +-- and servers that are only proxied (not connected directly). +data ServersSummary = ServersSummary + { -- currently used SMP servers are those with Just in sessions and/or subs in SMPServerSummary; + -- all other servers would fall either into previously used or only proxied servers category + currentlyUsedSMPServers :: [SMPServerSummary], + -- previously used SMP servers are those with Nothing in sessions and subs, + -- and have any of sentDirect, sentProxied, recvMsgs, etc. > 0 in server stats (see toPresentedServersSummary); + -- remaining servers would fall into only proxied servers category + previouslyUsedSMPServers :: [SMPServerSummary], + -- only proxied SMP servers are those that aren't (according to current state - sessions and subs) + -- and weren't (according to stats) connected directly; they would have Nothing in sessions and subs, + -- and have all of sentDirect, sentProxied, recvMsgs, etc. = 0 in server stats + onlyProxiedSMPServers :: [SMPServerSummary], + -- currently used XFTP servers are those with Just in sessions in XFTPServerSummary, + -- and/or have upload/download/deletion in progress; + -- all other servers would fall into previously used servers category + currentlyUsedXFTPServers :: [XFTPServerSummary], + -- previously used XFTP servers are those with Nothing in sessions and don't have any process in progress + previouslyUsedXFTPServers :: [XFTPServerSummary] + } + deriving (Show) + +data SMPServerSummary = SMPServerSummary + { smpServer :: SMPServer, + -- known: + -- for simplicity always Nothing in totalServersSummary - allows us to load configured servers only for current user, + -- and also unnecessary unless we want to add navigation to other users servers settings; + -- always Just in currentUserServers - True if server is in list of user servers, otherwise False; + -- True - allows to navigate to server settings, False - allows to add server to configured as known (SEKnown) + known :: Maybe Bool, + sessions :: Maybe ServerSessions, + subs :: Maybe SMPServerSubs, + -- stats: + -- even if sessions and subs are Nothing, stats can be Just - server could be used earlier in session, + -- or in previous sessions and stats for it were restored; server would fall into a category of + -- previously used or only proxied servers - see ServersSummary above + stats :: Maybe AgentSMPServerStatsData + } + deriving (Show) + +data XFTPServerSummary = XFTPServerSummary + { xftpServer :: XFTPServer, + known :: Maybe Bool, -- same as for SMPServerSummary + sessions :: Maybe ServerSessions, + stats :: Maybe AgentXFTPServerStatsData, + rcvInProgress :: Bool, + sndInProgress :: Bool, + delInProgress :: Bool + } + deriving (Show) + +-- Maps AgentServersSummary to PresentedServersSummary: +-- - currentUserServers is for currentUser; +-- - users are passed to exclude hidden users from totalServersSummary; +-- - if currentUser is hidden, it should be accounted in totalServersSummary; +-- - known is set only in user level summaries based on passed userSMPSrvs and userXFTPSrvs +toPresentedServersSummary :: AgentServersSummary -> [User] -> User -> [SMPServer] -> [XFTPServer] -> PresentedServersSummary +toPresentedServersSummary agentSummary users currentUser userSMPSrvs userXFTPSrvs = do + let (userSMPSrvsSumms, allSMPSrvsSumms) = accSMPSrvsSummaries + (userSMPCurr, userSMPPrev, userSMPProx) = smpSummsIntoCategories userSMPSrvsSumms + (allSMPCurr, allSMPPrev, allSMPProx) = smpSummsIntoCategories allSMPSrvsSumms + (userXFTPSrvsSumms, allXFTPSrvsSumms) = accXFTPSrvsSummaries + (userXFTPCurr, userXFTPPrev) = xftpSummsIntoCategories userXFTPSrvsSumms + (allXFTPCurr, allXFTPPrev) = xftpSummsIntoCategories allXFTPSrvsSumms + PresentedServersSummary + { statsStartedAt, + currentUserServers = + ServersSummary + { currentlyUsedSMPServers = userSMPCurr, + previouslyUsedSMPServers = userSMPPrev, + onlyProxiedSMPServers = userSMPProx, + currentlyUsedXFTPServers = userXFTPCurr, + previouslyUsedXFTPServers = userXFTPPrev + }, + allUsersServers = + ServersSummary + { currentlyUsedSMPServers = allSMPCurr, + previouslyUsedSMPServers = allSMPPrev, + onlyProxiedSMPServers = allSMPProx, + currentlyUsedXFTPServers = allXFTPCurr, + previouslyUsedXFTPServers = allXFTPPrev + } + } + where + AgentServersSummary {statsStartedAt, smpServersSessions, smpServersSubs, smpServersStats, xftpServersSessions, xftpServersStats, xftpRcvInProgress, xftpSndInProgress, xftpDelInProgress} = agentSummary + countUserInAll auId = auId == aUserId currentUser || auId `notElem` hiddenUserIds + hiddenUserIds = map aUserId $ filter (isJust . viewPwdHash) users + smpSummsIntoCategories :: Map SMPServer SMPServerSummary -> ([SMPServerSummary], [SMPServerSummary], [SMPServerSummary]) + smpSummsIntoCategories = foldr partitionSummary ([], [], []) + where + partitionSummary srvSumm (curr, prev, prox) + | isCurrentlyUsed srvSumm = (srvSumm : curr, prev, prox) + | isPreviouslyUsed srvSumm = (curr, srvSumm : prev, prox) + | otherwise = (curr, prev, srvSumm : prox) + isCurrentlyUsed SMPServerSummary {sessions, subs} = isJust sessions || isJust subs + isPreviouslyUsed SMPServerSummary {stats} = case stats of + Nothing -> False + -- add connCompleted, connDeleted? + -- check: should connCompleted be counted for proxy? is it? + Just AgentSMPServerStatsData {_sentDirect, _sentProxied, _sentDirectAttempts, _sentProxiedAttempts, _recvMsgs, _connCreated, _connSecured, _connSubscribed, _connSubAttempts} -> + _sentDirect > 0 || _sentProxied > 0 || _sentDirectAttempts > 0 || _sentProxiedAttempts > 0 || _recvMsgs > 0 || _connCreated > 0 || _connSecured > 0 || _connSubscribed > 0 || _connSubAttempts > 0 + xftpSummsIntoCategories :: Map XFTPServer XFTPServerSummary -> ([XFTPServerSummary], [XFTPServerSummary]) + xftpSummsIntoCategories = foldr partitionSummary ([], []) + where + partitionSummary srvSumm (curr, prev) + | isCurrentlyUsed srvSumm = (srvSumm : curr, prev) + | otherwise = (curr, srvSumm : prev) + isCurrentlyUsed XFTPServerSummary {sessions, rcvInProgress, sndInProgress, delInProgress} = + isJust sessions || rcvInProgress || sndInProgress || delInProgress + accSMPSrvsSummaries :: (Map SMPServer SMPServerSummary, Map SMPServer SMPServerSummary) + accSMPSrvsSummaries = M.foldrWithKey' (addServerData addStats) summs2 smpServersStats + where + summs1 = M.foldrWithKey' (addServerData addSessions) (M.empty, M.empty) smpServersSessions + summs2 = M.foldrWithKey' (addServerData addSubs) summs1 smpServersSubs + addServerData :: + (a -> SMPServerSummary -> SMPServerSummary) -> + (UserId, SMPServer) -> + a -> + (Map SMPServer SMPServerSummary, Map SMPServer SMPServerSummary) -> + (Map SMPServer SMPServerSummary, Map SMPServer SMPServerSummary) + addServerData addData (userId, srv) d (userSumms, allUsersSumms) = (userSumms', allUsersSumms') + where + userSumms' + | userId == aUserId currentUser = alterSumms newUserSummary userSumms + | otherwise = userSumms + allUsersSumms' + | countUserInAll userId = alterSumms newSummary allUsersSumms + | otherwise = allUsersSumms + alterSumms n = M.alter (Just . addData d . fromMaybe n) srv + newUserSummary = (newSummary :: SMPServerSummary) {known = Just $ srv `elem` userSMPSrvs} + newSummary = + SMPServerSummary + { smpServer = srv, + known = Nothing, + sessions = Nothing, + subs = Nothing, + stats = Nothing + } + addSessions :: ServerSessions -> SMPServerSummary -> SMPServerSummary + addSessions s summ@SMPServerSummary {sessions} = summ {sessions = Just $ maybe s (s `addServerSessions`) sessions} + addSubs :: SMPServerSubs -> SMPServerSummary -> SMPServerSummary + addSubs s summ@SMPServerSummary {subs} = summ {subs = Just $ maybe s (s `addSMPSubs`) subs} + addStats :: AgentSMPServerStatsData -> SMPServerSummary -> SMPServerSummary + addStats s summ@SMPServerSummary {stats} = summ {stats = Just $ maybe s (s `addSMPStats`) stats} + accXFTPSrvsSummaries :: (Map XFTPServer XFTPServerSummary, Map XFTPServer XFTPServerSummary) + accXFTPSrvsSummaries = M.foldrWithKey' (addServerData addStats) summs1 xftpServersStats + where + summs1 = M.foldrWithKey' (addServerData addSessions) (M.empty, M.empty) xftpServersSessions + addServerData :: + (a -> XFTPServerSummary -> XFTPServerSummary) -> + (UserId, XFTPServer) -> + a -> + (Map XFTPServer XFTPServerSummary, Map XFTPServer XFTPServerSummary) -> + (Map XFTPServer XFTPServerSummary, Map XFTPServer XFTPServerSummary) + addServerData addData (userId, srv) d (userSumms, allUsersSumms) = (userSumms', allUsersSumms') + where + userSumms' + | userId == aUserId currentUser = alterSumms newUserSummary userSumms + | otherwise = userSumms + allUsersSumms' + | countUserInAll userId = alterSumms newSummary allUsersSumms + | otherwise = allUsersSumms + alterSumms n = M.alter (Just . addData d . fromMaybe n) srv + newUserSummary = (newSummary :: XFTPServerSummary) {known = Just $ srv `elem` userXFTPSrvs} + newSummary = + XFTPServerSummary + { xftpServer = srv, + known = Nothing, + sessions = Nothing, + stats = Nothing, + rcvInProgress = srv `elem` xftpRcvInProgress, + sndInProgress = srv `elem` xftpSndInProgress, + delInProgress = srv `elem` xftpDelInProgress + } + addSessions :: ServerSessions -> XFTPServerSummary -> XFTPServerSummary + addSessions s summ@XFTPServerSummary {sessions} = summ {sessions = Just $ maybe s (s `addServerSessions`) sessions} + addStats :: AgentXFTPServerStatsData -> XFTPServerSummary -> XFTPServerSummary + addStats s summ@XFTPServerSummary {stats} = summ {stats = Just $ maybe s (s `addXFTPStats`) stats} + addServerSessions :: ServerSessions -> ServerSessions -> ServerSessions + addServerSessions ss1 ss2 = + ServerSessions + { ssConnected = ssConnected ss1 + ssConnected ss2, + ssErrors = ssErrors ss1 + ssErrors ss2, + ssConnecting = ssConnecting ss1 + ssConnecting ss2 + } + addSMPSubs :: SMPServerSubs -> SMPServerSubs -> SMPServerSubs + addSMPSubs ss1 ss2 = + SMPServerSubs + { ssActive = ssActive ss1 + ssActive ss2, + ssPending = ssPending ss1 + ssPending ss2 + } + addSMPStats :: AgentSMPServerStatsData -> AgentSMPServerStatsData -> AgentSMPServerStatsData + addSMPStats sd1 sd2 = + AgentSMPServerStatsData + { _sentDirect = _sentDirect sd1 + _sentDirect sd2, + _sentViaProxy = _sentViaProxy sd1 + _sentViaProxy sd2, + _sentProxied = _sentProxied sd1 + _sentProxied sd2, + _sentDirectAttempts = _sentDirectAttempts sd1 + _sentDirectAttempts sd2, + _sentViaProxyAttempts = _sentViaProxyAttempts sd1 + _sentViaProxyAttempts sd2, + _sentProxiedAttempts = _sentProxiedAttempts sd1 + _sentProxiedAttempts sd2, + _sentAuthErrs = _sentAuthErrs sd1 + _sentAuthErrs sd2, + _sentQuotaErrs = _sentQuotaErrs sd1 + _sentQuotaErrs sd2, + _sentExpiredErrs = _sentExpiredErrs sd1 + _sentExpiredErrs sd2, + _sentOtherErrs = _sentOtherErrs sd1 + _sentOtherErrs sd2, + _recvMsgs = _recvMsgs sd1 + _recvMsgs sd2, + _recvDuplicates = _recvDuplicates sd1 + _recvDuplicates sd2, + _recvCryptoErrs = _recvCryptoErrs sd1 + _recvCryptoErrs sd2, + _recvErrs = _recvErrs sd1 + _recvErrs sd2, + _connCreated = _connCreated sd1 + _connCreated sd2, + _connSecured = _connSecured sd1 + _connSecured sd2, + _connCompleted = _connCompleted sd1 + _connCompleted sd2, + _connDeleted = _connDeleted sd1 + _connDeleted sd2, + _connSubscribed = _connSubscribed sd1 + _connSubscribed sd2, + _connSubAttempts = _connSubAttempts sd1 + _connSubAttempts sd2, + _connSubErrs = _connSubErrs sd1 + _connSubErrs sd2 + } + addXFTPStats :: AgentXFTPServerStatsData -> AgentXFTPServerStatsData -> AgentXFTPServerStatsData + addXFTPStats sd1 sd2 = + AgentXFTPServerStatsData + { _uploads = _uploads sd1 + _uploads sd2, + _uploadAttempts = _uploadAttempts sd1 + _uploadAttempts sd2, + _uploadErrs = _uploadErrs sd1 + _uploadErrs sd2, + _downloads = _downloads sd1 + _downloads sd2, + _downloadAttempts = _downloadAttempts sd1 + _downloadAttempts sd2, + _downloadAuthErrs = _downloadAuthErrs sd1 + _downloadAuthErrs sd2, + _downloadErrs = _downloadErrs sd1 + _downloadErrs sd2, + _deletions = _deletions sd1 + _deletions sd2, + _deleteAttempts = _deleteAttempts sd1 + _deleteAttempts sd2, + _deleteErrs = _deleteErrs sd1 + _deleteErrs sd2 + } + +$(J.deriveJSON defaultJSON ''SMPServerSummary) + +$(J.deriveJSON defaultJSON ''XFTPServerSummary) + +$(J.deriveJSON defaultJSON ''ServersSummary) + +$(J.deriveJSON defaultJSON ''PresentedServersSummary) diff --git a/src/Simplex/Chat/Store/Profiles.hs b/src/Simplex/Chat/Store/Profiles.hs index be06ea8878..a740389c6a 100644 --- a/src/Simplex/Chat/Store/Profiles.hs +++ b/src/Simplex/Chat/Store/Profiles.hs @@ -523,9 +523,10 @@ getProtocolServers db User {userId} = (userId, decodeLatin1 $ strEncode protocol) where protocol = protocolTypeI @p - toServerCfg :: (NonEmpty TransportHost, String, C.KeyHash, Maybe Text, Bool, Maybe Bool, Bool) -> ServerCfg p - toServerCfg (host, port, keyHash, auth_, preset, tested, enabled) = + toServerCfg :: (NonEmpty TransportHost, String, C.KeyHash, Maybe Text, Bool, Maybe Bool, Int) -> ServerCfg p + toServerCfg (host, port, keyHash, auth_, preset, tested, enabledInt) = let server = ProtoServerWithAuth (ProtocolServer protocol host port keyHash) (BasicAuth . encodeUtf8 <$> auth_) + enabled = toServerEnabled enabledInt in ServerCfg {server, preset, tested, enabled} overwriteProtocolServers :: forall p. ProtocolTypeI p => DB.Connection -> User -> [ServerCfg p] -> ExceptT StoreError IO () @@ -542,7 +543,7 @@ overwriteProtocolServers db User {userId} servers = (protocol, host, port, key_hash, basic_auth, preset, tested, enabled, user_id, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?) |] - ((protocol, host, port, keyHash, safeDecodeUtf8 . unBasicAuth <$> auth_) :. (preset, tested, enabled, userId, currentTs, currentTs)) + ((protocol, host, port, keyHash, safeDecodeUtf8 . unBasicAuth <$> auth_) :. (preset, tested, fromServerEnabled enabled, userId, currentTs, currentTs)) pure $ Right () where protocol = decodeLatin1 $ strEncode $ protocolTypeI @p diff --git a/src/Simplex/Chat/Types.hs b/src/Simplex/Chat/Types.hs index 106c4b3373..07c9afa2e2 100644 --- a/src/Simplex/Chat/Types.hs +++ b/src/Simplex/Chat/Types.hs @@ -1632,10 +1632,42 @@ data ServerCfg p = ServerCfg { server :: ProtoServerWithAuth p, preset :: Bool, tested :: Maybe Bool, - enabled :: Bool + enabled :: ServerEnabled } deriving (Show) +data ServerEnabled + = SEDisabled + | SEEnabled + | -- server is marked as known, but it's not in the list of configured servers; + -- e.g., it may be added via an unknown server dialogue and user didn't manually configure it, + -- meaning server wasn't tested (or at least such option wasn't presented in UI) + -- and it may be inoperable for user due to server password + SEKnown + deriving (Eq, Show) + +pattern DBSEDisabled :: Int +pattern DBSEDisabled = 0 + +pattern DBSEEnabled :: Int +pattern DBSEEnabled = 1 + +pattern DBSEKnown :: Int +pattern DBSEKnown = 2 + +toServerEnabled :: Int -> ServerEnabled +toServerEnabled = \case + DBSEDisabled -> SEDisabled + DBSEEnabled -> SEEnabled + DBSEKnown -> SEKnown + _ -> SEDisabled + +fromServerEnabled :: ServerEnabled -> Int +fromServerEnabled = \case + SEDisabled -> DBSEDisabled + SEEnabled -> DBSEEnabled + SEKnown -> DBSEKnown + data ChatVersion instance VersionScope ChatVersion @@ -1764,6 +1796,8 @@ $(JQ.deriveJSON defaultJSON ''ContactRef) $(JQ.deriveJSON defaultJSON ''NoteFolder) +$(JQ.deriveJSON (enumJSON $ dropPrefix "SE") ''ServerEnabled) + instance ProtocolTypeI p => ToJSON (ServerCfg p) where toEncoding = $(JQ.mkToEncoding defaultJSON ''ServerCfg) toJSON = $(JQ.mkToJSON defaultJSON ''ServerCfg) diff --git a/src/Simplex/Chat/Types/Preferences.hs b/src/Simplex/Chat/Types/Preferences.hs index 4cf9f862d2..bccfd4bdce 100644 --- a/src/Simplex/Chat/Types/Preferences.hs +++ b/src/Simplex/Chat/Types/Preferences.hs @@ -36,7 +36,7 @@ import Simplex.Chat.Types.Shared import Simplex.Chat.Types.Util import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, fromTextField_, sumTypeJSON) -import Simplex.Messaging.Util (safeDecodeUtf8, (<$?>)) +import Simplex.Messaging.Util (decodeJSON, encodeJSON, safeDecodeUtf8, (<$?>)) data ChatFeature = CFTimedMessages diff --git a/src/Simplex/Chat/Types/UITheme.hs b/src/Simplex/Chat/Types/UITheme.hs index ef445c5a7c..cc5290aa69 100644 --- a/src/Simplex/Chat/Types/UITheme.hs +++ b/src/Simplex/Chat/Types/UITheme.hs @@ -18,6 +18,7 @@ import Database.SQLite.Simple.ToField (ToField (..)) import Simplex.Chat.Types.Util import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, fromTextField_) +import Simplex.Messaging.Util (decodeJSON, encodeJSON) data UITheme = UITheme { themeId :: Text, diff --git a/src/Simplex/Chat/Types/Util.hs b/src/Simplex/Chat/Types/Util.hs index e19d48caba..47edf8eaf8 100644 --- a/src/Simplex/Chat/Types/Util.hs +++ b/src/Simplex/Chat/Types/Util.hs @@ -2,26 +2,15 @@ module Simplex.Chat.Types.Util where -import Data.Aeson (FromJSON, ToJSON) import qualified Data.Aeson as J import qualified Data.Aeson.Types as JT import Data.ByteString (ByteString) -import qualified Data.ByteString.Lazy.Char8 as LB -import Data.Text (Text) -import Data.Text.Encoding (encodeUtf8) import Data.Typeable import Database.SQLite.Simple (ResultError (..), SQLData (..)) import Database.SQLite.Simple.FromField (FieldParser, returnError) import Database.SQLite.Simple.Internal (Field (..)) import Database.SQLite.Simple.Ok (Ok (Ok)) import Simplex.Messaging.Encoding.String -import Simplex.Messaging.Util (safeDecodeUtf8) - -encodeJSON :: ToJSON a => a -> Text -encodeJSON = safeDecodeUtf8 . LB.toStrict . J.encode - -decodeJSON :: FromJSON a => Text -> Maybe a -decodeJSON = J.decode . LB.fromStrict . encodeUtf8 textParseJSON :: TextEncoding a => String -> J.Value -> JT.Parser a textParseJSON name = J.withText name $ maybe (fail $ "bad " <> name) pure . textDecode diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index d1f3625e18..5b14084552 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -54,7 +54,6 @@ import qualified Simplex.FileTransfer.Transport as XFTP import Simplex.Messaging.Agent.Client (ProtocolTestFailure (..), ProtocolTestStep (..), SubscriptionsInfo (..)) import Simplex.Messaging.Agent.Env.SQLite (NetworkConfig (..)) import Simplex.Messaging.Agent.Protocol -import Simplex.Messaging.Agent.Protocol (AgentErrorType (RCP)) import Simplex.Messaging.Agent.Store.SQLite.DB (SlowQueryStats (..)) import Simplex.Messaging.Client (SMPProxyFallback, SMPProxyMode (..)) import qualified Simplex.Messaging.Crypto as C @@ -366,6 +365,7 @@ responseToView hu@(currentRH, user_) ChatConfig {logLevel, showReactions, showRe "chat entity locks: " <> viewJSON chatEntityLocks, "agent locks: " <> viewJSON agentLocks ] + CRAgentServersSummary u serversSummary -> ttyUser u ["agent servers summary: " <> viewJSON serversSummary] CRAgentStats stats -> map (plain . intercalate ",") stats CRAgentSubs {activeSubs, pendingSubs, removedSubs} -> [plain $ "Subscriptions: active = " <> show (sum activeSubs) <> ", pending = " <> show (sum pendingSubs) <> ", removed = " <> show (sum $ M.map length removedSubs)] diff --git a/tests/ChatTests/Profiles.hs b/tests/ChatTests/Profiles.hs index c1388072ab..f29d6d848a 100644 --- a/tests/ChatTests/Profiles.hs +++ b/tests/ChatTests/Profiles.hs @@ -17,7 +17,7 @@ import Simplex.Chat.Store.Shared (createContact) import Simplex.Chat.Types (ConnStatus (..), Profile (..)) import Simplex.Chat.Types.Shared (GroupMemberRole (..)) import Simplex.Chat.Types.UITheme -import Simplex.Chat.Types.Util (encodeJSON) +import Simplex.Messaging.Util (encodeJSON) import Simplex.Messaging.Encoding.String (StrEncoding (..)) import System.Directory (copyFile, createDirectoryIfMissing) import Test.Hspec hiding (it) From fba0478e509cf56851cef44dc0543a0531bec32b Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Tue, 25 Jun 2024 11:37:54 +0400 Subject: [PATCH 03/43] docs: more additions to chat protocol (#4355) * docs: more additions to chat protocol * schema wip * schema * update diagram * remove comments * punctuation * diagram text * update threat model --------- Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> --- docs/protocol/diagrams/group.mmd | 26 ++- docs/protocol/diagrams/group.svg | 4 +- docs/protocol/simplex-chat.md | 77 ++++++- docs/protocol/simplex-chat.schema.json | 281 +++++++++++++++++++++++-- 4 files changed, 364 insertions(+), 24 deletions(-) diff --git a/docs/protocol/diagrams/group.mmd b/docs/protocol/diagrams/group.mmd index 18d392caa5..6a9bd0c786 100644 --- a/docs/protocol/diagrams/group.mmd +++ b/docs/protocol/diagrams/group.mmd @@ -4,9 +4,16 @@ sequenceDiagram participant B as Bob participant C as Existing
contact - note over A, B: 1. send and accept group invitation - A ->> B: x.grp.inv
invite Bob to group
(via contact connection) - B ->> A: x.grp.acpt
accept invitation
(via member connection)
establish group member connection + alt invite contact + note over A, B: 1a. send and accept group invitation + A ->> B: x.grp.inv
invite Bob to group
(via contact connection) + B ->> A: x.grp.acpt
accept invitation
(via member connection)
establish group member connection + else join via group link + note over A, B: 1b. join via group link and accept request + B ->> A: join via group link
SimpleX contact address + A ->> B: x.grp.link.inv in SMP confirmation
accept joining member request,
sending group profile, etc.
establish group member connection + A ->> B: x.grp.link.mem
send inviting member profile + end note over M, B: 2. introduce new member Bob to all existing members A ->> M: x.grp.mem.new
"announce" Bob
to existing members
(via member connections) @@ -20,14 +27,25 @@ sequenceDiagram end A ->> M: x.grp.mem.fwd
forward "invitations" and
Bob's chat protocol version
to all members
(via member connections) + note over M, B: group message forwarding
(while connections between members are being established) + M -->> B: messages between members and Bob are forwarded by Alice + B -->> M: + note over M, B: 3. establish direct and group member connections M ->> B: establish group member connection opt chat protocol compatible version < 2 M ->> B: establish direct connection - note over M, C: 4. deduplicate new contact + note over M, C: 3*. deduplicate new contact B ->> M: x.info.probe
"probe" is sent to all new members B ->> C: x.info.probe.check
"probe" hash,
in case contact and
member profiles match C ->> B: x.info.probe.ok
original "probe",
in case contact and member
are the same user note over B: merge existing and new contacts if received and sent probe hashes match end + + note over M, B: 4. notify inviting member that connection is established + M ->> A: x.grp.mem.con + B ->> A: x.grp.mem.con + note over A: stops forwarding messages + M -->> B: messages are sent via group connection without forwarding + B -->> M: diff --git a/docs/protocol/diagrams/group.svg b/docs/protocol/diagrams/group.svg index 8c1b65dee2..f3c9aa8a26 100644 --- a/docs/protocol/diagrams/group.svg +++ b/docs/protocol/diagrams/group.svg @@ -1 +1,3 @@ -ExistingcontactBobAliceN existingmembersExistingcontactBobAliceN existingmembers1. send and accept group invitation2. introduce new member Bob to all existing membersprepare group member connectionsprepare direct connectionsopt[chat protocolcompatible version< 2]loop[batched]3. establish direct and group member connections4. deduplicate new contactmerge existing and new contacts if received and sent probe hashes matchopt[chat protocol compatible version < 2]x.grp.invinvite Bob to group(via contact connection)x.grp.acptaccept invitation(via member connection)establish group member connectionx.grp.mem.new"announce" Bobto existing members(via member connections)x.grp.mem.intro * N"introduce" members andtheir chat protocol versions(via member connection)x.grp.mem.inv * N"invitations" to connectfor all members(via member connection)x.grp.mem.fwdforward "invitations" andBob's chat protocol versionto all members(via member connections)establish group member connectionestablish direct connectionx.info.probe"probe" is sent to all new membersx.info.probe.check"probe" hash,in case contact andmember profiles matchx.info.probe.ok original "probe", in case contact and memberare the same user \ No newline at end of file + + +ExistingcontactBobAliceN existingmembersExistingcontactBobAliceN existingmembers1a. send and accept group invitation1b. join via group link and accept requestalt[invite contact][join via group link]2. introduce new member Bob to all existing membersprepare group member connectionsprepare direct connectionsopt[chat protocolcompatible version< 2]loop[batched]group message forwarding(while connections between members are being established)3. establish direct and group member connections3*. deduplicate new contactmerge existing and new contacts if received and sent probe hashes matchopt[chat protocol compatible version < 2]4. notify inviting member that connection is establishedstops forwarding messagesx.grp.invinvite Bob to group(via contact connection)x.grp.acptaccept invitation(via member connection)establish group member connectionjoin via group linkSimpleX contact addressx.grp.link.inv in SMP confirmationaccept joining member request,sending group profile, etc.establish group member connectionx.grp.link.memsend inviting member profilex.grp.mem.new"announce" Bobto existing members(via member connections)x.grp.mem.intro * N"introduce" members andtheir chat protocol versions(via member connection)x.grp.mem.inv * N"invitations" to connectfor all members(via member connection)x.grp.mem.fwdforward "invitations" andBob's chat protocol versionto all members(via member connections)messages between members and Bob are forwarded by Aliceestablish group member connectionestablish direct connectionx.info.probe"probe" is sent to all new membersx.info.probe.check"probe" hash,in case contact andmember profiles matchx.info.probe.ok original "probe", in case contact and memberare the same userx.grp.mem.conx.grp.mem.conmessages are sent via group connection without forwarding \ No newline at end of file diff --git a/docs/protocol/simplex-chat.md b/docs/protocol/simplex-chat.md index efa4edb959..4b5f87821b 100644 --- a/docs/protocol/simplex-chat.md +++ b/docs/protocol/simplex-chat.md @@ -2,7 +2,7 @@ title: SimpleX Chat Protocol revision: 08.08.2022 --- -DRAFT Revision 0.1, 2022-08-08 +Revision 2, 2024-06-24 Evgeny Poberezkin @@ -157,7 +157,7 @@ This message is sent by both sides of the connection during the connection hands ### Probing for duplicate contacts -As there are no globally unique user identitifiers, when the contact a user is already connected to is added to the group by some other group member, this contact will be added to user's list of contacts as a new contact. To allow merging such contacts, "a probe" (random base64url-encoded 32 bytes) SHOULD be sent to all new members as part of `x.info.probe` message and, in case there is a contact with the same profile, the hash of the probe MAY be sent to it as part of `x.info.probe.check` message. In case both the new member and the existing contact are the same user (they would receive both the probe and its hash), the contact would send back the original probe as part of `x.info.probe.ok` message via the previously existing contact connection – proving to the sender that this new member and the existing contact are the same user, in which case the sender SHOULD merge these two contacts. +As there are no globally unique user identifiers, when the contact a user is already connected to is added to the group by some other group member, this contact will be added to user's list of contacts as a new contact. To allow merging such contacts, "a probe" (random base64url-encoded 32 bytes) SHOULD be sent to all new members as part of `x.info.probe` message and, in case there is a contact with the same profile, the hash of the probe MAY be sent to it as part of `x.info.probe.check` message. In case both the new member and the existing contact are the same user (they would receive both the probe and its hash), the contact would send back the original probe as part of `x.info.probe.ok` message via the previously existing contact connection – proving to the sender that this new member and the existing contact are the same user, in which case the sender SHOULD merge these two contacts. Sending clients MAY disable this functionality, and receiving clients MAY ignore probe messages. @@ -210,23 +210,23 @@ File attachment can optionally include connection address to receive the file - ### Decentralized design for chat groups -SimpleX Chat groups are fully decentralized and do not have any globally unique group identifiers - they are only defined on client devices as a group profile and a set of bi-directional SimpleX connections with other group members. When a new member accepts group invitation, the inviting member introduces a new member to all existing members and forwards the connection addresses so that they can establish direct and group member connections. +SimpleX Chat groups are fully decentralized and do not have any globally unique group identifiers - they are only defined on client devices as a group profile and a set of bi-directional SimpleX connections with other group members. When a new member accepts group invitation or joins via group link, the inviting member introduces a new member to all existing members and forwards the connection addresses so that they can establish direct and group member connections. There is a possibility of the attack here: as the introducing member forwards the addresses, they can substitute them with other addresses, performing MITM attack on the communication between existing and introduced members - this is similar to the communication operator being able to perform MITM on any connection between the users. To mitigate this attack this group sub-protocol will be extended to allow validating security of the connection by sending connection verification out-of-band. -Clients are RECOMMENDED to indicate in the UI whether the connection to a group member or contact was made directly or via annother user. +Clients are RECOMMENDED to indicate in the UI whether the connection to a group member or contact was made directly or via another user. Each member in the group is identified by a group-wide unique identifier used by all members in the group. This is to allow referencing members in the messages and to allow group message integrity validation. The diagram below shows the sequence of messages sent between the users' clients to add the new member to the group. -![Adding member to the group](./diagrams/group.svg) - While introduced members establish connection inside group, inviting member forwards messages between them by sending `x.grp.msg.forward` messages. When introduced members finalize connection, they notify inviting member to stop forwarding via `x.grp.mem.con` message. +![Adding member to the group](./diagrams/group.svg) + ### Member roles -Currently members can have one of three roles - `owner`, `admin` and `member`. The user that created the group is self-assigned owner role, the new members are assigned role by the member who adds them - only `owner` and `admin` members can add new members; only `owner` members can add members with `owner` role. +Currently members can have one of three roles - `owner`, `admin`, `member` and `observer`. The user that created the group is self-assigned owner role, the new members are assigned role by the member who adds them - only `owner` and `admin` members can add new members; only `owner` members can add members with `owner` role. `Observer` members only receive messages and aren't allowed to send messages. ### Messages to manage groups and add members @@ -279,3 +279,66 @@ These message are used for WebRTC calls: 3. `x.call.answer`: to continue with call connection the initiating clients must reply with `x.call.answer` message. This message contains WebRTC answer and collected ICE candidates. Additional ICE candidates can be sent in `x.call.extra` message. 4. `x.call.end` message is sent to notify the other party that the call is terminated. + +## Threat model + +This threat model compliments SMP, XFTP, push notifications and XRCP protocols threat models: + +- [SimpleX Messaging Protocol threat model](https://github.com/simplex-chat/simplexmq/blob/master/protocol/overview-tjr.md#threat-model); +- [SimpleX File Transfer Protocol threat model](https://github.com/simplex-chat/simplexmq/blob/master/protocol/xftp.md#threat-model); +- [Push notifications threat model](https://github.com/simplex-chat/simplexmq/blob/master/protocol/push-notifications.md#threat-model); +- [SimpleX Remote Control Protocol threat model](https://github.com/simplex-chat/simplexmq/blob/master/protocol/xrcp.md#threat-model). + +#### A user's contact + +*can:* + +- send messages prohibited by user's preferences or otherwise act non-compliantly with user's preferences (for example, if message with updated preferences was lost or failed to be processed, or with modified client), in which case user client should treat such messages and actions as prohibited. + +- by exchanging special messages with user's client, match user's contact with existing group members and/or contacts that have identical user profile (see [Probing for duplicate contacts](#probing-for-duplicate-contacts)). + +- identify that and when a user is using SimpleX, in case user has delivery receipts enabled, or based on other automated client responses. + +*cannot:* + +- match user's contact with existing group members and/or contacts with different or with incognito profiles. + +- match user's contact without communicating with the user's client. + +#### A group member + +*can:* + +- send messages prohibited by group's preferences and member restrictions or otherwise act non-compliantly with preferences and restrictions (for example, if decentralized group state diverged, or with modified client), in which case user client should treat such messages and actions as prohibited. + +- create a direct contact with a user if group permissions allow it. + +- by exchanging special messages with user's client, match user's group member record with the existing group members and/or contacts that have identical user profile. + +- undetectably send different messages to different group members, or selectively send messages to some members and not send to others. + +- identify that and when a user is using SimpleX, in case user has delivery receipts enabled, or based on other automated client responses. + +- join the same group several times, from the same or from different user profile, and pretend to be different members. + +*cannot:* + +- match user's contact with existing group members and/or contacts with different or with incognito profiles. + +- match user's group member record with existing group members and/or contacts without communication of user's client. + +- determine whether two group members with different or with incognito profiles are the same user. + +#### A group admin + +*can:* + +- carry out MITM attack between user and other group member(s) when forwarding invitations for group connections (user can detect such attack by verifying connection security codes out-of-band). + +- undetectably forward different messages to different group members, selectively adding, modifying, and dropping forwarded messages. + +- disrupt decentralized group state by sending different messages that change group state (such as adding or removing members, member role changes, etc.) to different group members, or sending such messages selectively. + +*cannot:* + +- prove that two group members with incognito profiles is the same user. diff --git a/docs/protocol/simplex-chat.schema.json b/docs/protocol/simplex-chat.schema.json index a9738190bd..2e94a4f2c2 100644 --- a/docs/protocol/simplex-chat.schema.json +++ b/docs/protocol/simplex-chat.schema.json @@ -8,7 +8,7 @@ "displayName": { "type": "string", "metadata": { - "format": "non-empty string without spaces, the first character must not be # or @" + "format": "non-empty string, the first character must not be # or @" } }, "fullName": {"type": "string"} @@ -19,6 +19,39 @@ "metadata": { "format": "data URI format for base64 encoded image" } + }, + "contactLink": {"ref": "connReqUri"}, + "preferences": { + "type": "string", + "metadata": { + "format": "JSON encoded user preferences" + } + } + }, + "additionalProperties": true + }, + "groupProfile": { + "properties": { + "displayName": { + "type": "string", + "metadata": { + "format": "non-empty string, the first character must not be # or @" + } + }, + "fullName": {"type": "string"} + }, + "optionalProperties": { + "image": { + "type": "string", + "metadata": { + "format": "data URI format for base64 encoded image" + } + }, + "groupPreferences": { + "type": "string", + "metadata": { + "format": "JSON encoded user preferences" + } } }, "additionalProperties": true @@ -29,6 +62,8 @@ }, "optionalProperties": { "file": {"ref": "fileInvitation"}, + "ttl": {"type": "integer"}, + "live": {"type": "boolean"}, "quote": { "properties": { "msgRef": {"ref": "msgRef"}, @@ -56,17 +91,47 @@ } }, "image": { - "text": {"type": "string", "metadata": {"comment": "can be empty"}}, - "image": {"ref": "base64url"} + "properties": { + "text": {"type": "string", "metadata": {"comment": "can be empty"}}, + "image": {"ref": "base64url"} + } + }, + "video": { + "properties": { + "text": {"type": "string", "metadata": {"comment": "can be empty"}}, + "image": {"ref": "base64url"}, + "duration": {"type": "integer"} + } + }, + "voice": { + "properties": { + "text": {"type": "string", "metadata": {"comment": "can be empty"}}, + "duration": {"type": "integer"} + } }, "file": { - "text": {"type": "string", "metadata": {"comment": "can be empty"}} + "properties": { + "text": {"type": "string", "metadata": {"comment": "can be empty"}} + } } }, "metadata": { "comment": "it is RECOMMENDED that the clients support other values in `type` properties showing them as text messages in case `text` property is present" } }, + "msgReaction" : { + "discriminator": "type", + "mapping": { + "emoji": { + "properties": { + "emoji": { + "type": "string", + "metadata": {"comment": "emoji character"} + } + } + } + } + }, "msgRef": { "properties": { "msgId": {"ref": "base64url"}, @@ -91,7 +156,31 @@ "fileSize": {"type": "uint32"} }, "optionalProperties": { - "fileConnReq": {"ref": "connReqUri"} + "fileDigest": {"ref": "base64url"}, + "fileConnReq": {"ref": "connReqUri"}, + "fileDescr": {"ref": "fileDescription"} + } + }, + "fileDescription": { + "properties": { + "fileDescrText": { + "type": "string", + "metadata": { + "format": "XFTP file description part text" + } + }, + "fileDescrPartNo": { + "type": "integer", + "metadata": { + "format": "XFTP file description part number" + } + }, + "fileDescrComplete": { + "type": "boolean", + "metadata": { + "format": "XFTP file description completion marker" + } + } } }, "linkPreview": { @@ -100,6 +189,21 @@ "title": {"type": "string"}, "description": {"type": "string"}, "image": {"ref": "base64url"} + }, + "optionalProperties": { + "content": {"ref": "linkContent"} + } + }, + "linkContent": { + "discriminator": "type", + "mapping": { + "page": {}, + "image": {}, + "video": { + "optionalProperties": { + "duration": {"type": "integer"} + } + } } }, "groupInvitation": { @@ -107,15 +211,27 @@ "fromMember": {"ref": "memberIdRole"}, "invitedMember": {"ref": "memberIdRole"}, "connRequest": {"ref": "connReqUri"}, - "groupProfile": {"ref": "profile"} + "groupProfile": {"ref": "groupProfile"} }, "optionalProperties": { "groupLinkId": {"ref": "base64url"}, + "groupSize": {"type": "integer"}, "metadata": { - "comment": "used to identify invitation via group link" + "comment": "groupLinkId is used to identify invitation via group link" } } }, + "groupLinkInvitation": { + "properties": { + "fromMember": {"ref": "memberIdRole"}, + "fromMemberName": {"type": "string"}, + "invitedMember": {"ref": "memberIdRole"}, + "groupProfile": {"ref": "groupProfile"} + }, + "optionalProperties": { + "groupSize": {"type": "integer"} + } + }, "memberIdRole": { "properties": { "memberId": {"ref": "base64url"}, @@ -127,16 +243,35 @@ "memberId": {"ref": "base64url"}, "memberRole": {"ref": "groupMemberRole"}, "profile": {"ref": "profile"} + }, + "optionalProperties": { + "v": {"ref": "chatVersionRange"} + } + }, + "memberRestrictions": { + "properties": { + "restriction": {"ref": "memberRestrictionStatus"} + } + }, + "memberRestrictionStatus": { + "enum": ["blocked", "unrestricted"] + }, + "chatVersionRange": { + "type": "string", + "metadata": { + "format": "chat version range string encoded as `-`, or as `` if min = max" } }, "introInvitation": { "properties": { - "groupConnReq": {"ref": "connReqUri"}, + "groupConnReq": {"ref": "connReqUri"} + }, + "optionalProperties": { "directConnReq": {"ref": "connReqUri"} } }, "groupMemberRole": { - "enum": ["author", "member", "admin", "owner"] + "enum": ["observer", "author", "member", "admin", "owner"] }, "callInvitation": { "properties": { @@ -257,6 +392,17 @@ "params": {"ref": "msgContainer"} } }, + "x.msg.file.descr": { + "properties": { + "msgId": {"ref": "base64url"}, + "params": { + "properties": { + "msgId": {"ref": "base64url"}, + "fileDescr": {"ref": "fileDescription"} + } + } + } + }, "x.msg.update": { "properties": { "msgId": {"ref": "base64url"}, @@ -264,6 +410,10 @@ "properties": { "msgId": {"ref": "base64url"}, "content": {"ref": "msgContent"} + }, + "optionalProperties": { + "ttl": {"type": "integer"}, + "live": {"type": "boolean"} } } } @@ -274,6 +424,24 @@ "params": { "properties": { "msgId": {"ref": "base64url"} + }, + "optionalProperties": { + "memberId": {"ref": "base64url"} + } + } + } + }, + "x.msg.react": { + "properties": { + "msgId": {"ref": "base64url"}, + "params": { + "properties": { + "msgId": {"ref": "base64url"}, + "reaction": {"ref": "msgReaction"}, + "add": {"type": "boolean"} + }, + "optionalProperties": { + "memberId": {"ref": "base64url"} } } } @@ -294,8 +462,10 @@ "params": { "properties": { "msgId": {"ref": "base64url"}, - "fileConnReq": {"ref": "connReqUri"}, "fileName": {"type": "string"} + }, + "optionalProperties": { + "fileConnReq": {"ref": "connReqUri"} } } } @@ -310,6 +480,14 @@ } } }, + "x.direct.del": { + "properties": { + "msgId": {"ref": "base64url"}, + "params": { + "properties": {} + } + } + }, "x.grp.inv": { "properties": { "msgId": {"ref": "base64url"}, @@ -330,6 +508,26 @@ } } }, + "x.grp.link.inv": { + "properties": { + "msgId": {"ref": "base64url"}, + "params": { + "properties": { + "groupLinkInvitation": {"ref": "groupLinkInvitation"} + } + } + } + }, + "x.grp.link.mem": { + "properties": { + "msgId": {"ref": "base64url"}, + "params": { + "properties": { + "profile": {"ref": "profile"} + } + } + } + }, "x.grp.mem.new": { "properties": { "msgId": {"ref": "base64url"}, @@ -346,6 +544,9 @@ "params": { "properties": { "memberInfo": {"ref": "memberInfo"} + }, + "optionalProperties": { + "memberRestrictions": {"ref": "memberRestrictions"} } } } @@ -394,6 +595,27 @@ } } }, + "x.grp.mem.restrict": { + "properties": { + "msgId": {"ref": "base64url"}, + "params": { + "properties": { + "memberId": {"ref": "base64url"}, + "memberRestrictions": {"ref": "memberRestrictions"} + } + } + } + }, + "x.grp.mem.con": { + "properties": { + "msgId": {"ref": "base64url"}, + "params": { + "properties": { + "memberId": {"ref": "base64url"} + } + } + } + }, "x.grp.mem.del": { "properties": { "msgId": {"ref": "base64url"}, @@ -425,7 +647,42 @@ "msgId": {"ref": "base64url"}, "params": { "properties": { - "groupProfile": {"ref": "profile"} + "groupProfile": {"ref": "groupProfile"} + } + } + } + }, + "x.grp.direct.inv": { + "properties": { + "msgId": {"ref": "base64url"}, + "params": { + "properties": { + "connReq": {"ref": "connReqUri"} + }, + "optionalProperties": { + "content": {"ref": "msgContent"} + } + } + } + }, + "x.grp.msg.forward": { + "properties": { + "msgId": {"ref": "base64url"}, + "params": { + "properties": { + "memberId": {"ref": "base64url"}, + "msg": { + "type": "string", + "metadata": { + "format": "JSON encoded chat message" + } + }, + "msgTs": { + "type": "string", + "metadata": { + "format": "ISO8601 UTC time of the message" + } + } } } } @@ -436,7 +693,7 @@ "params": { "properties": { "callId": {"ref": "base64url"}, - "invitation": {} + "invitation": {"ref": "callInvitation"} } } } From fca098f53509950281ac52d51c7894a18d6025d8 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Fri, 28 Jun 2024 00:10:51 +0100 Subject: [PATCH 04/43] docs: update donation addresses --- README.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 4e74bbc866..29ee7e189e 100644 --- a/README.md +++ b/README.md @@ -158,20 +158,19 @@ We are prioritizing users privacy and security - it would be impossible without Our pledge to our users is that SimpleX protocols are and will remain open, and in public domain, - so anybody can build the future implementations of the clients and the servers. We are building SimpleX platform based on the same principles as email and web, but much more private and secure. -Your donations help us raise more funds – any amount, even the price of the cup of coffee, would make a big difference for us. +Your donations help us raise more funds - any amount, even the price of the cup of coffee, would make a big difference for us. It is possible to donate via: -- [GitHub](https://github.com/sponsors/simplex-chat) - it is commission-free for us. -- [OpenCollective](https://opencollective.com/simplex-chat) - it charges a commission, and also accepts donations in crypto-currencies. +- [GitHub](https://github.com/sponsors/simplex-chat) (commission-free) or [OpenCollective](https://opencollective.com/simplex-chat) (~10% commission). +- Bitcoin: bc1qd74rc032ek2knhhr3yjq2ajzc5enz3h4qwnxad - Monero: 8568eeVjaJ1RQ65ZUn9PRQ8ENtqeX9VVhcCYYhnVLxhV4JtBqw42so2VEUDQZNkFfsH5sXCuV7FN8VhRQ21DkNibTZP57Qt -- Bitcoin: 1bpefFkzuRoMY3ZuBbZNZxycbg7NYPYTG -- BCH: 1bpefFkzuRoMY3ZuBbZNZxycbg7NYPYTG +- BCH: bitcoincash:qq6c8vfvxqrk6rhdysgvkhqc24sggkfsx5nqvdlqcg +- Ethereum: 0xD9ee7Db0AD0dc1Dfa7eD53290199ED06beA04692 - USDT: - - BNB Smart Chain: 0x83fd788f7241a2be61780ea9dc72d2151e6843e2 - - Tron: TNnTrKLBmdy2Wn3cAQR98dAVvWhLskQGfW -- Ethereum: 0x83fd788f7241a2be61780ea9dc72d2151e6843e2 -- Solana: 43tWFWDczgAcn4Rzwkpqg2mqwnQETSiTwznmCgA2tf1L + - Ethereum: 0xD9ee7Db0AD0dc1Dfa7eD53290199ED06beA04692 +- Solana: 7JCf5m3TiHmYKZVr6jCu1KeZVtb9Y1jRMQDU69p5ARnu +- please ask if you want to donate any other coins. Thank you, From 5baf8789d675dc7ad45ed225141c33522e5e7cfe Mon Sep 17 00:00:00 2001 From: sh <37271604+shumvgolove@users.noreply.github.com> Date: Fri, 28 Jun 2024 09:09:34 +0000 Subject: [PATCH 05/43] flatpak: add desktop and metainfo (#4366) * flatpak: add desktop and metainfo * metainfo: update * corrections * ampersand * shorter --------- Co-authored-by: Evgeny Poberezkin --- scripts/flatpak/chat.simplex.simplex.desktop | 10 +++ .../flatpak/chat.simplex.simplex.metainfo.xml | 81 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 scripts/flatpak/chat.simplex.simplex.desktop create mode 100644 scripts/flatpak/chat.simplex.simplex.metainfo.xml diff --git a/scripts/flatpak/chat.simplex.simplex.desktop b/scripts/flatpak/chat.simplex.simplex.desktop new file mode 100644 index 0000000000..4f4cd4eece --- /dev/null +++ b/scripts/flatpak/chat.simplex.simplex.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Type=Application +Terminal=false +Name=SimpleX Chat +Comment=A private & encrypted open-source messenger without any user IDs (not even random ones)! +Keywords=chat;message;private;secure;simplex; +Categories=Utility;Chat;InstantMessaging; +Exec=simplex %U +Icon=chat.simplex.simplex +StartupWMClass=simplex-chat diff --git a/scripts/flatpak/chat.simplex.simplex.metainfo.xml b/scripts/flatpak/chat.simplex.simplex.metainfo.xml new file mode 100644 index 0000000000..dd3f1143b5 --- /dev/null +++ b/scripts/flatpak/chat.simplex.simplex.metainfo.xml @@ -0,0 +1,81 @@ + + + chat.simplex.simplex + + SimpleX Chat + A private & encrypted open-source messenger without any user IDs (not even random)! + + + SimpleX Chat + + + MIT + AGPL-3.0-or-later + + +

SimpleX - the first messaging platform that has no user identifiers, not even random numbers!

+

Security assessment was done by Trail of Bits in November 2022.

+

SimpleX Chat features:

+
    +
  1. end-to-end encrypted messages, with editing, replies and deletion of messages.
  2. +
  3. sending end-to-end encrypted images and files.
  4. +
  5. single-use and long-term user addresses.
  6. +
  7. secret chat groups - only group members know it exists and who is the member.
  8. +
  9. end-to-end encrypted audio and video calls.
  10. +
  11. private instant notifications.
  12. +
  13. portable chat profile - you can transfer your chat contacts and history to another device (terminal or mobile).
  14. +
+

SimpleX Chat advantages:

+
    +
  1. Full privacy of your identity, profile, contacts and metadata: unlike any other existing messaging platform, SimpleX uses no phone numbers or any other identifiers assigned to the users - not even random numbers. This protects the privacy of who you are communicating with, hiding it from SimpleX platform servers and from any observers.
  2. +
  3. Complete protection against spam and abuse: as you have no identifier on SimpleX platform, you cannot be contacted unless you share a one-time invitation link or an optional temporary user address.
  4. +
  5. Full ownership, control and security of your data: SimpleX stores all user data on client devices, the messages are only held temporarily on SimpleX relay servers until they are received.
  6. +
  7. Decentralized network: you can use SimpleX with your own servers and still communicate with people using the servers that are pre-configured in the apps or any other SimpleX servers.
  8. +
+

You can connect to anybody you know via link or scan QR code (in the video call or in person) and start sending messages instantly - no emails, phone numbers or passwords needed.

+

Your profile and contacts are only stored in the app on your device - our servers do not have access to this information.

+

All messages are end-to-end encrypted using open-source double-ratchet protocol; the messages are routed via our servers using open-source SimpleX Messaging Protocol.

+
+ + + + +

General:

+
    +
  1. fixes in sending/receiving files.
  2. +
  3. better error reporting when connecting to desktop app.
  4. +
  5. prevent forwarding to conversations where conversation preferences do not allow message.
  6. +
+

Android and desktop apps:

+
    +
  1. support transparent theme colors for chat message bubbles.
  2. +
  3. do not reset changed network settings when switching SOCKS proxy on/off
  4. +
  5. fix swipe to reply when animation is disabled.
  6. +
  7. fix bug when duplicate group shown in the UI.
  8. +
+
+
+
+ + + + https://simplex.chat/ + https://github.com/simplex-chat/simplex-chat/issues + https://opencollective.com/simplex-chat + https://simplex.chat/docs/translations + https://simplex.chat/faq + https://github.com/simplex-chat/simplex-chat + + chat.simplex.simplex.desktop + + + #a5f0ff + #110e26 + + + + + https://simplex.chat/blog/images/simplex-desktop-light.png + + +
From d8126e0cd067cbf53db9edc31ec7fd1dbfb91025 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Fri, 28 Jun 2024 19:09:01 +0100 Subject: [PATCH 06/43] website: update join team --- docs/JOIN_TEAM.md | 55 +++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/docs/JOIN_TEAM.md b/docs/JOIN_TEAM.md index 3379f9ae04..26502a05af 100644 --- a/docs/JOIN_TEAM.md +++ b/docs/JOIN_TEAM.md @@ -15,29 +15,32 @@ We want to add up to 3 people to the team. ## Who we are looking for +### Product/UI designer + +You will be designing the user experience and the interface of both the app and the website in collaboration with the team. + +The current focus of the app is privacy and security, but we hope to have the design that would support the feeling of psychological safety, enabling people to achieve the results in the smallest amount of time. + +You are an experienced and innovative product designer with: +- 8+ years of user experience and visual design. +- Expertise in typography and high sensitivity to colors. +- Exceptional precision and attention to details. +- Strong opinions (weakly held). +- A strong empathy. + ### Application Haskell engineer +You will work with the Haskell core of the client applications and with the network servers. + You are an expert in language models, databases and Haskell: - expert knowledge of SQL. -- exception handling, concurrency, STM. -- type systems - we use ad hoc dependent types a lot. -- experience integrating open-source language models. -- experience developing community-centric applications. -- interested to build the next generation of messaging network. - -You will be focussed mostly on our client applications, and will also contribute to the servers also written in Haskell. - -### iOS / Mac engineer - -You are an expert in Apple platforms, including: -- iOS and Mac platform architecture. -- Swift and Objective-C. -- SwiftUI and UIKit. -- extensions, including notification service extension and sharing extension. -- low level inter-process communication primitives for concurrency. -- interested about creating the next generation of UX for a communication/social network. - -Knowledge of Android and Kotlin Multiplatform would be a bonus - we use Kotlin Jetpack Compose for our Android and desktop apps. +- Haskell exception handling, concurrency, STM, type systems. +- 8y+ of software engineering experience in complex projects, +- deep understanding of the common programming principles: + - data structures, bits and bytes, text encoding. + - software design and algorithms. + - concurrency. + - networking. ## About you @@ -53,20 +56,10 @@ Knowledge of Android and Kotlin Multiplatform would be a bonus - we use Kotlin J - focus on solving only today's problems and resist engineering for the future (aka over-engineering) – see [The Duct Tape Programmer](https://www.joelonsoftware.com/2009/09/23/the-duct-tape-programmer/) and [Why I Hate Frameworks](https://medium.com/@johnfliu/why-i-hate-frameworks-6af8cbadba42). - do not suffer from "not invented here" syndrome, at the same time interested to design and implement protocols and systems from the ground up when appropriate. -- **Love software engineering**: - - have 5y+ of software engineering experience in complex projects, - - great understanding of the common principles: - - data structures, bits and byte manipulation - - text encoding and manipulation - - software design and algorithms - - concurrency - - networking - - **Want to join a very early stage startup**: - high pace and intensity, longer hours. - a substantial part of the compensation is stock options. - - full transparency – we believe that too much [autonomy](https://twitter.com/KentBeck/status/851459129830850561) hurts learning and slows down progress. - + - full transparency - we believe that too much [autonomy](https://twitter.com/KentBeck/status/851459129830850561) hurts learning and slows down progress. ## How to join the team @@ -75,3 +68,5 @@ Knowledge of Android and Kotlin Multiplatform would be a bonus - we use Kotlin J 2. Also look through [GitHub issues](https://github.com/simplex-chat/simplex-chat/issues) submitted by the users to see what would you want to contribute as a test. 3. [Connect to us](https://simplex.chat/contact#/?v=1&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FKBCmxJ3-lEjpWLPPkI6OWPk-YJneU5uY%23%2F%3Fv%3D1%26dh%3DMCowBQYDK2VuAyEAtixHJWDXvYWcoe-77vIfjvI6XWEuzUsapMS9nVHP_Go%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) via SimpleX Chat to chat about what you want to contribute and about joining the team. + +4. You can also email [jobs@simplex.chat](mailto:jobs@simplex.chat?subject=Join%20SimpleX%20Chat%20team) From fab38276970021af3c0b0a45fb18753bbad257f8 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Sat, 29 Jun 2024 08:41:21 +0100 Subject: [PATCH 07/43] core: fix markdown for trailing / and ) characters in the links (#4357) --- src/Simplex/Chat/Markdown.hs | 8 ++++++-- tests/MarkdownTests.hs | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Simplex/Chat/Markdown.hs b/src/Simplex/Chat/Markdown.hs index 688ffa6b1d..8e82bfe727 100644 --- a/src/Simplex/Chat/Markdown.hs +++ b/src/Simplex/Chat/Markdown.hs @@ -222,11 +222,15 @@ markdownP = mconcat <$> A.many' fragmentP wordMD s | T.null s = unmarked s | isUri s = - let t = T.takeWhileEnd isPunctuation s - uri = uriMarkdown $ T.dropWhileEnd isPunctuation s + let t = T.takeWhileEnd isPunctuation' s + uri = uriMarkdown $ T.dropWhileEnd isPunctuation' s in if T.null t then uri else uri :|: unmarked t | isEmail s = markdown Email s | otherwise = unmarked s + isPunctuation' = \case + '/' -> False + ')' -> False + c -> isPunctuation c uriMarkdown s = case strDecode $ encodeUtf8 s of Right cReq -> markdown (simplexUriFormat cReq) s _ -> markdown Uri s diff --git a/tests/MarkdownTests.hs b/tests/MarkdownTests.hs index a279201bea..615edc02c4 100644 --- a/tests/MarkdownTests.hs +++ b/tests/MarkdownTests.hs @@ -149,6 +149,11 @@ textWithUri = describe "text with Uri" do parseMarkdown "http://simplex.chat" `shouldBe` uri "http://simplex.chat" parseMarkdown "this is https://simplex.chat" `shouldBe` "this is " <> uri "https://simplex.chat" parseMarkdown "https://simplex.chat site" `shouldBe` uri "https://simplex.chat" <> " site" + parseMarkdown "SimpleX on GitHub: https://github.com/simplex-chat/" `shouldBe` "SimpleX on GitHub: " <> uri "https://github.com/simplex-chat/" + parseMarkdown "SimpleX on GitHub: https://github.com/simplex-chat." `shouldBe` "SimpleX on GitHub: " <> uri "https://github.com/simplex-chat" <> "." + parseMarkdown "https://github.com/simplex-chat/ - SimpleX on GitHub" `shouldBe` uri "https://github.com/simplex-chat/" <> " - SimpleX on GitHub" + -- parseMarkdown "SimpleX on GitHub (https://github.com/simplex-chat/)" `shouldBe` "SimpleX on GitHub (" <> uri "https://github.com/simplex-chat/" <> ")" + parseMarkdown "https://en.m.wikipedia.org/wiki/Servo_(software)" `shouldBe` uri "https://en.m.wikipedia.org/wiki/Servo_(software)" it "ignored as markdown" do parseMarkdown "_https://simplex.chat" `shouldBe` "_https://simplex.chat" parseMarkdown "this is _https://simplex.chat" `shouldBe` "this is _https://simplex.chat" From d066c662820f1fdb01835fe89326e3f8360e3d7c Mon Sep 17 00:00:00 2001 From: sergeyshadok <41486169+sergeyshadok@users.noreply.github.com> Date: Sat, 29 Jun 2024 15:50:28 +0000 Subject: [PATCH 08/43] Update XFTP-SERVER.md (#4184) Systemd itself uses % tokens so %% needs to be used for specifiers (https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html) --- docs/XFTP-SERVER.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/XFTP-SERVER.md b/docs/XFTP-SERVER.md index a0ad0e0cf7..a2eb9816e5 100644 --- a/docs/XFTP-SERVER.md +++ b/docs/XFTP-SERVER.md @@ -75,7 +75,7 @@ Manual installation requires some preliminary actions: Group=xftp Type=simple ExecStart=/usr/local/bin/xftp-server start +RTS -N -RTS - ExecStopPost=/usr/bin/env sh -c '[ -e "/var/opt/simplex-xftp/file-server-store.log" ] && cp "/var/opt/simplex-xftp/file-server-store.log" "/var/opt/simplex-xftp/file-server-store.log.$(date +'%FT%T')"' + ExecStopPost=/usr/bin/env sh -c '[ -e "/var/opt/simplex-xftp/file-server-store.log" ] && cp "/var/opt/simplex-xftp/file-server-store.log" "/var/opt/simplex-xftp/file-server-store.log.$(date +'%%FT%%T')"' LimitNOFILE=65535 KillSignal=SIGINT TimeoutStopSec=infinity From 231082860e65c51dca61700c35021e11607ae529 Mon Sep 17 00:00:00 2001 From: sh <37271604+shumvgolove@users.noreply.github.com> Date: Mon, 1 Jul 2024 08:34:38 +0000 Subject: [PATCH 09/43] flatpak: verify app (#4379) --- website/src/.well-known/org.flathub.VerifiedApps.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 website/src/.well-known/org.flathub.VerifiedApps.txt diff --git a/website/src/.well-known/org.flathub.VerifiedApps.txt b/website/src/.well-known/org.flathub.VerifiedApps.txt new file mode 100644 index 0000000000..3a9a2d04de --- /dev/null +++ b/website/src/.well-known/org.flathub.VerifiedApps.txt @@ -0,0 +1 @@ +ae8b5b2e-76c9-4a31-a044-bcbda1cdf264 From 5907d8bd0c58a57ba7c96fea7ad912e792856718 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Mon, 1 Jul 2024 11:25:27 +0100 Subject: [PATCH 10/43] core: remove legacy agent stats (#4375) --- cabal.project | 2 +- scripts/nix/sha256map.nix | 2 +- src/Simplex/Chat.hs | 18 +++--------------- src/Simplex/Chat/Controller.hs | 5 ----- src/Simplex/Chat/View.hs | 2 -- 5 files changed, 5 insertions(+), 24 deletions(-) diff --git a/cabal.project b/cabal.project index be95820371..2177a5a130 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: c7886926870e97fa592d51fa36a2cdec49296388 + tag: 6a54a58a0d47aeca9d5482b0d27e451731b692f1 source-repository-package type: git diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index 3a8284a74b..beb33a733a 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."c7886926870e97fa592d51fa36a2cdec49296388" = "1r3nibcgw3whl0q3ssyr1606x4ilqphhzqyihi3aw4nw5fmz226h"; + "https://github.com/simplex-chat/simplexmq.git"."6a54a58a0d47aeca9d5482b0d27e451731b692f1" = "1hfbzcirncmmzag2c3gbxnpxl1dwy9gy42d78a5zzf1979rp3yjq"; "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"; diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index 539ad003ba..5e288f886c 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -20,7 +20,6 @@ import Control.Applicative (optional, (<|>)) import Control.Concurrent.STM (retry) import Control.Logger.Simple import Control.Monad -import Simplex.Chat.Stats import Control.Monad.Except import Control.Monad.IO.Unlift import Control.Monad.Reader @@ -72,6 +71,7 @@ import Simplex.Chat.ProfileGenerator (generateRandomProfile) import Simplex.Chat.Protocol import Simplex.Chat.Remote import Simplex.Chat.Remote.Types +import Simplex.Chat.Stats import Simplex.Chat.Store import Simplex.Chat.Store.AppSettings import Simplex.Chat.Store.Connections @@ -95,7 +95,7 @@ import Simplex.FileTransfer.Protocol (FileParty (..), FilePartyI) import qualified Simplex.FileTransfer.Transport as XFTP import Simplex.FileTransfer.Types (FileErrorType (..), RcvFileId, SndFileId) import Simplex.Messaging.Agent as Agent -import Simplex.Messaging.Agent.Client (AgentStatsKey (..), SubInfo (..), agentClientStore, getAgentQueuesInfo, getAgentWorkersDetails, getAgentWorkersSummary, getNetworkConfig', ipAddressProtected, withLockMap) +import Simplex.Messaging.Agent.Client (SubInfo (..), agentClientStore, getAgentQueuesInfo, getAgentWorkersDetails, getAgentWorkersSummary, getNetworkConfig', ipAddressProtected, withLockMap) import Simplex.Messaging.Agent.Env.SQLite (AgentConfig (..), InitialAgentServers (..), createAgentStore, defaultAgentConfig) import Simplex.Messaging.Agent.Lock (withLock) import Simplex.Messaging.Agent.Protocol @@ -113,7 +113,7 @@ import qualified Simplex.Messaging.Crypto.Ratchet as CR import Simplex.Messaging.Encoding import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (base64P) -import Simplex.Messaging.Protocol (AProtoServerWithAuth (..), AProtocolType (..), EntityId, ErrorType (..), MsgBody, MsgFlags (..), NtfServer, ProtoServerWithAuth (..), ProtocolTypeI, SProtocolType (..), SubscriptionMode (..), UserProtocol, XFTPServer, userProtocol, ProtocolServer) +import Simplex.Messaging.Protocol (AProtoServerWithAuth (..), AProtocolType (..), EntityId, ErrorType (..), MsgBody, MsgFlags (..), NtfServer, ProtoServerWithAuth (..), ProtocolServer, ProtocolTypeI, SProtocolType (..), SubscriptionMode (..), UserProtocol, XFTPServer, userProtocol) import qualified Simplex.Messaging.Protocol as SMP import Simplex.Messaging.ServiceScheme (ServiceScheme (..)) import qualified Simplex.Messaging.TMap as TM @@ -2270,15 +2270,6 @@ processChatCommand' vr = \case pure $ map protoServer srvs GetAgentWorkers -> lift $ CRAgentWorkersSummary <$> withAgent' getAgentWorkersSummary GetAgentWorkersDetails -> lift $ CRAgentWorkersDetails <$> withAgent' getAgentWorkersDetails - GetAgentStats -> lift $ CRAgentStats . map stat <$> withAgent' getAgentStats - where - stat (AgentStatsKey {host, clientTs, cmd, res}, count) = - map B.unpack [host, clientTs, cmd, res, bshow count] - ResetAgentStats -> lift (withAgent' resetAgentStats) >> ok_ - GetAgentMsgCounts -> lift $ do - counts <- map (first decodeLatin1) <$> withAgent' getMsgCounts - let allMsgs = foldl' (\(ts, ds) (_, (t, d)) -> (ts + t, ds + d)) (0, 0) counts - pure CRAgentMsgCounts {msgCounts = ("all", allMsgs) : sortOn (Down . snd) (filter (\(_, (_, d)) -> d /= 0) counts)} GetAgentSubs -> lift $ summary <$> withAgent' getAgentSubscriptions where summary SubscriptionsInfo {activeSubscriptions, pendingSubscriptions, removedSubscriptions} = @@ -7627,13 +7618,10 @@ chatCommandP = "/debug locks" $> DebugLocks, "/debug event " *> (DebugEvent <$> jsonP), "/get servers summary " *> (GetAgentServersSummary <$> A.decimal), - "/get stats" $> GetAgentStats, - "/reset stats" $> ResetAgentStats, "/get subs" $> GetAgentSubs, "/get subs details" $> GetAgentSubsDetails, "/get workers" $> GetAgentWorkers, "/get workers details" $> GetAgentWorkersDetails, - "/get msgs" $> GetAgentMsgCounts, "/get queues" $> GetAgentQueuesInfo, "//" *> (CustomChatCommand <$> A.takeByteString) ] diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index 4404360c2a..366e767154 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -507,13 +507,10 @@ data ChatCommand | DebugLocks | DebugEvent ChatResponse | GetAgentServersSummary UserId - | GetAgentStats - | ResetAgentStats | GetAgentSubs | GetAgentSubsDetails | GetAgentWorkers | GetAgentWorkersDetails - | GetAgentMsgCounts | GetAgentQueuesInfo | -- The parser will return this command for strings that start from "//". -- This command should be processed in preCmdHook @@ -759,12 +756,10 @@ data ChatResponse | CRSlowSQLQueries {chatQueries :: [SlowSQLQuery], agentQueries :: [SlowSQLQuery]} | CRDebugLocks {chatLockName :: Maybe String, chatEntityLocks :: Map String String, agentLocks :: AgentLocks} | CRAgentServersSummary {user :: User, serversSummary :: PresentedServersSummary} - | CRAgentStats {agentStats :: [[String]]} | CRAgentWorkersDetails {agentWorkersDetails :: AgentWorkersDetails} | CRAgentWorkersSummary {agentWorkersSummary :: AgentWorkersSummary} | CRAgentSubs {activeSubs :: Map Text Int, pendingSubs :: Map Text Int, removedSubs :: Map Text [String]} | CRAgentSubsDetails {agentSubs :: SubscriptionsInfo} - | CRAgentMsgCounts {msgCounts :: [(Text, (Int, Int))]} | CRAgentQueuesInfo {agentQueuesInfo :: AgentQueuesInfo} | CRContactDisabled {user :: User, contact :: Contact} | CRConnectionDisabled {connectionEntity :: ConnectionEntity} diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 5b14084552..04c06103ea 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -366,7 +366,6 @@ responseToView hu@(currentRH, user_) ChatConfig {logLevel, showReactions, showRe "agent locks: " <> viewJSON agentLocks ] CRAgentServersSummary u serversSummary -> ttyUser u ["agent servers summary: " <> viewJSON serversSummary] - CRAgentStats stats -> map (plain . intercalate ",") stats CRAgentSubs {activeSubs, pendingSubs, removedSubs} -> [plain $ "Subscriptions: active = " <> show (sum activeSubs) <> ", pending = " <> show (sum pendingSubs) <> ", removed = " <> show (sum $ M.map length removedSubs)] <> ("active subscriptions:" : listSubs activeSubs) @@ -384,7 +383,6 @@ responseToView hu@(currentRH, user_) ChatConfig {logLevel, showReactions, showRe [ "agent workers details:", viewJSON agentWorkersDetails -- this would be huge, but copypastable when has its own line ] - CRAgentMsgCounts {msgCounts} -> ["received messages (total, duplicates):", viewJSON msgCounts] CRAgentQueuesInfo {agentQueuesInfo} -> [ "agent queues info:", plain . LB.unpack $ J.encode agentQueuesInfo From 593c7d247c2acd557987d6ae6bb60c7a5326a1d8 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:10:22 +0400 Subject: [PATCH 11/43] ui: add ServerEnabled type (#4381) --- .../UserSettings/ProtocolServerView.swift | 9 +++++++-- .../UserSettings/ProtocolServersView.swift | 15 ++++++++------- .../UserSettings/ScanProtocolServer.swift | 2 +- apps/ios/SimpleXChat/APITypes.swift | 18 ++++++++++++------ .../chat/simplex/common/model/SimpleXAPI.kt | 17 ++++++++++++----- .../views/usersettings/ProtocolServerView.kt | 6 ++++-- .../views/usersettings/ProtocolServersView.kt | 12 ++++++------ .../views/usersettings/ScanProtocolServer.kt | 3 ++- 8 files changed, 52 insertions(+), 30 deletions(-) diff --git a/apps/ios/Shared/Views/UserSettings/ProtocolServerView.swift b/apps/ios/Shared/Views/UserSettings/ProtocolServerView.swift index 6702ab7ce8..8926ee09fa 100644 --- a/apps/ios/Shared/Views/UserSettings/ProtocolServerView.swift +++ b/apps/ios/Shared/Views/UserSettings/ProtocolServerView.swift @@ -14,6 +14,7 @@ struct ProtocolServerView: View { let serverProtocol: ServerProtocol @Binding var server: ServerCfg @State var serverToEdit: ServerCfg + @State var serverEnabled: Bool @State private var showTestFailure = false @State private var testing = false @State private var testFailure: ProtocolTestFailure? @@ -110,7 +111,10 @@ struct ProtocolServerView: View { Spacer() showTestStatus(server: serverToEdit) } - Toggle("Use for new connections", isOn: $serverToEdit.enabled) + Toggle("Use for new connections", isOn: $serverEnabled) + .onChange(of: serverEnabled) { enabled in + serverToEdit.enabled = enabled ? .enabled : .disabled + } } } } @@ -179,7 +183,8 @@ struct ProtocolServerView_Previews: PreviewProvider { ProtocolServerView( serverProtocol: .smp, server: Binding.constant(ServerCfg.sampleData.custom), - serverToEdit: ServerCfg.sampleData.custom + serverToEdit: ServerCfg.sampleData.custom, + serverEnabled: true ) } } diff --git a/apps/ios/Shared/Views/UserSettings/ProtocolServersView.swift b/apps/ios/Shared/Views/UserSettings/ProtocolServersView.swift index b9163d4bad..db82008182 100644 --- a/apps/ios/Shared/Views/UserSettings/ProtocolServersView.swift +++ b/apps/ios/Shared/Views/UserSettings/ProtocolServersView.swift @@ -159,7 +159,7 @@ struct ProtocolServersView: View { } private var allServersDisabled: Bool { - servers.allSatisfy { !$0.enabled } + servers.allSatisfy { $0.enabled != .enabled } } private func protocolServerView(_ server: Binding) -> some View { @@ -168,7 +168,8 @@ struct ProtocolServersView: View { ProtocolServerView( serverProtocol: serverProtocol, server: server, - serverToEdit: srv + serverToEdit: srv, + serverEnabled: srv.enabled == .enabled ) .navigationBarTitle(srv.preset ? "Preset server" : "Your server") .navigationBarTitleDisplayMode(.large) @@ -181,7 +182,7 @@ struct ProtocolServersView: View { invalidServer() } else if !uniqueAddress(srv, address) { Image(systemName: "exclamationmark.circle").foregroundColor(.red) - } else if !srv.enabled { + } else if srv.enabled != .enabled { Image(systemName: "slash.circle").foregroundColor(.secondary) } else { showTestStatus(server: srv) @@ -194,7 +195,7 @@ struct ProtocolServersView: View { .padding(.trailing, 4) let v = Text(address?.hostnames.first ?? srv.server).lineLimit(1) - if srv.enabled { + if srv.enabled == .enabled { v } else { v.foregroundColor(.secondary) @@ -235,7 +236,7 @@ struct ProtocolServersView: View { private func addAllPresets() { for srv in presetServers { if !hasPreset(srv) { - servers.append(ServerCfg(server: srv, preset: true, tested: nil, enabled: true)) + servers.append(ServerCfg(server: srv, preset: true, tested: nil, enabled: .enabled)) } } } @@ -260,7 +261,7 @@ struct ProtocolServersView: View { private func resetTestStatus() { for i in 0.. [String: ProtocolTestFailure] { var fs: [String: ProtocolTestFailure] = [:] for i in 0.. + onUpdate(server.copy(enabled = if (enable) ServerEnabled.Enabled else ServerEnabled.Disabled)) + } SectionItemView(onDelete, disabled = testing) { Text(stringResource(MR.strings.smp_servers_delete_server), color = if (testing) MaterialTheme.colors.secondary else MaterialTheme.colors.error) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ProtocolServersView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ProtocolServersView.kt index fe847432fb..bbf3e07c93 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ProtocolServersView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ProtocolServersView.kt @@ -34,7 +34,7 @@ fun ModalData.ProtocolServersView(m: ChatModel, rhId: Long?, serverProtocol: Ser val currServers = remember(rhId) { mutableStateOf(servers) } val testing = rememberSaveable(rhId) { mutableStateOf(false) } val serversUnchanged = remember(servers) { derivedStateOf { servers == currServers.value || testing.value } } - val allServersDisabled = remember { derivedStateOf { servers.none { it.enabled } } } + val allServersDisabled = remember { derivedStateOf { servers.none { it.enabled == ServerEnabled.Enabled } } } val saveDisabled = remember(servers) { derivedStateOf { servers.isEmpty() || @@ -250,12 +250,12 @@ private fun ProtocolServerView(serverProtocol: ServerProtocol, srv: ServerCfg, s val address = parseServerAddress(srv.server) when { address == null || !address.valid || address.serverProtocol != serverProtocol || !uniqueAddress(srv, address, servers) -> InvalidServer() - !srv.enabled -> Icon(painterResource(MR.images.ic_do_not_disturb_on), null, tint = MaterialTheme.colors.secondary) + srv.enabled != ServerEnabled.Enabled -> Icon(painterResource(MR.images.ic_do_not_disturb_on), null, tint = MaterialTheme.colors.secondary) else -> ShowTestStatus(srv) } Spacer(Modifier.padding(horizontal = 4.dp)) val text = address?.hostnames?.firstOrNull() ?: srv.server - if (srv.enabled) { + if (srv.enabled == ServerEnabled.Enabled) { Text(text, color = if (disabled) MaterialTheme.colors.secondary else MaterialTheme.colors.onBackground, maxLines = 1) } else { Text(text, maxLines = 1, color = MaterialTheme.colors.secondary) @@ -292,7 +292,7 @@ private fun addAllPresets(rhId: Long?, presetServers: List, servers: Lis val toAdd = ArrayList() for (srv in presetServers) { if (!hasPreset(srv, servers)) { - toAdd.add(ServerCfg(remoteHostId = rhId, srv, preset = true, tested = null, enabled = true)) + toAdd.add(ServerCfg(remoteHostId = rhId, srv, preset = true, tested = null, enabled = ServerEnabled.Enabled)) } } return toAdd @@ -319,7 +319,7 @@ private suspend fun testServers(testing: MutableState, servers: List): List { val copy = ArrayList(servers) for ((index, server) in servers.withIndex()) { - if (server.enabled) { + if (server.enabled == ServerEnabled.Enabled) { copy.removeAt(index) copy.add(index, server.copy(tested = null)) } @@ -331,7 +331,7 @@ private suspend fun runServersTest(servers: List, m: ChatModel, onUpd val fs: MutableMap = mutableMapOf() val updatedServers = ArrayList(servers) for ((index, server) in servers.withIndex()) { - if (server.enabled) { + if (server.enabled == ServerEnabled.Enabled) { interruptIfCancelled() val (updatedServer, f) = testServerConnection(server, m) updatedServers.removeAt(index) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ScanProtocolServer.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ScanProtocolServer.kt index 502b579d64..c1951341a4 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ScanProtocolServer.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ScanProtocolServer.kt @@ -7,6 +7,7 @@ import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import chat.simplex.common.model.ServerAddress.Companion.parseServerAddress import chat.simplex.common.model.ServerCfg +import chat.simplex.common.model.ServerEnabled import chat.simplex.common.ui.theme.DEFAULT_PADDING import chat.simplex.common.views.helpers.* import chat.simplex.common.views.newchat.QRCodeScanner @@ -25,7 +26,7 @@ fun ScanProtocolServerLayout(rhId: Long?, onNext: (ServerCfg) -> Unit) { QRCodeScanner { text -> val res = parseServerAddress(text) if (res != null) { - onNext(ServerCfg(remoteHostId = rhId, text, false, null, true)) + onNext(ServerCfg(remoteHostId = rhId, text, false, null, ServerEnabled.Enabled)) } else { AlertManager.shared.showAlertMsg( title = generalGetString(MR.strings.smp_servers_invalid_address), From 00ba46889867a56cd5089ebb9e0091605ee17f3a Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Tue, 2 Jul 2024 14:35:47 +0100 Subject: [PATCH 12/43] core: update simplexmq (disable fast handshake) (#4388) * core: update simplexmq (disable fast handshake) * fix encoding tests * fix * update simplexmq --- cabal.project | 2 +- scripts/nix/sha256map.nix | 2 +- src/Simplex/Chat.hs | 1 - tests/ProtocolTests.hs | 23 ++++++++++++----------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cabal.project b/cabal.project index 2177a5a130..49e35a6e48 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: 6a54a58a0d47aeca9d5482b0d27e451731b692f1 + tag: aa1d8d6c8bcff82f02aa580b1b729fc4b1396fd9 source-repository-package type: git diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index beb33a733a..fab7a3de0e 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."6a54a58a0d47aeca9d5482b0d27e451731b692f1" = "1hfbzcirncmmzag2c3gbxnpxl1dwy9gy42d78a5zzf1979rp3yjq"; + "https://github.com/simplex-chat/simplexmq.git"."aa1d8d6c8bcff82f02aa580b1b729fc4b1396fd9" = "01walrsa69n4f01bs5w4sj7svsah483dxmg88a0si7qh5ylay0r0"; "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"; diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index 5e288f886c..2a7c0ec83e 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -47,7 +47,6 @@ import qualified Data.List.NonEmpty as L import Data.Map.Strict (Map) import qualified Data.Map.Strict as M import Data.Maybe (catMaybes, fromMaybe, isJust, isNothing, listToMaybe, mapMaybe, maybeToList) -import Data.Ord (Down (..)) import qualified Data.Set as S import Data.Text (Text) import qualified Data.Text as T diff --git a/tests/ProtocolTests.hs b/tests/ProtocolTests.hs index c4dfa7da25..0bc801e824 100644 --- a/tests/ProtocolTests.hs +++ b/tests/ProtocolTests.hs @@ -34,7 +34,8 @@ queue = SMPQueueAddress { smpServer = srv, senderId = "\223\142z\251", - dhPublicKey = "MCowBQYDK2VuAyEAjiswwI3O/NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o=" + dhPublicKey = "MCowBQYDK2VuAyEAjiswwI3O/NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o=", + sndSecure = False } connReqData :: ConnReqUriData @@ -194,7 +195,7 @@ decodeChatMessageTest = describe "Chat message encoding/decoding" $ do "{\"v\":\"1\",\"event\":\"x.msg.deleted\",\"params\":{}}" #==# XMsgDeleted it "x.file" $ - "{\"v\":\"1\",\"event\":\"x.file\",\"params\":{\"file\":{\"fileConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"fileSize\":12345,\"fileName\":\"photo.jpg\"}}}" + "{\"v\":\"1\",\"event\":\"x.file\",\"params\":{\"file\":{\"fileConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"fileSize\":12345,\"fileName\":\"photo.jpg\"}}}" #==# XFile FileInvitation {fileName = "photo.jpg", fileSize = 12345, fileDigest = Nothing, fileConnReq = Just testConnReq, fileInline = Nothing, fileDescr = Nothing} it "x.file without file invitation" $ "{\"v\":\"1\",\"event\":\"x.file\",\"params\":{\"file\":{\"fileSize\":12345,\"fileName\":\"photo.jpg\"}}}" @@ -203,7 +204,7 @@ decodeChatMessageTest = describe "Chat message encoding/decoding" $ do "{\"v\":\"1\",\"event\":\"x.file.acpt\",\"params\":{\"fileName\":\"photo.jpg\"}}" #==# XFileAcpt "photo.jpg" it "x.file.acpt.inv" $ - "{\"v\":\"1\",\"event\":\"x.file.acpt.inv\",\"params\":{\"msgId\":\"AQIDBA==\",\"fileName\":\"photo.jpg\",\"fileConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}" + "{\"v\":\"1\",\"event\":\"x.file.acpt.inv\",\"params\":{\"msgId\":\"AQIDBA==\",\"fileName\":\"photo.jpg\",\"fileConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}" #==# XFileAcptInv (SharedMsgId "\1\2\3\4") (Just testConnReq) "photo.jpg" it "x.file.acpt.inv" $ "{\"v\":\"1\",\"event\":\"x.file.acpt.inv\",\"params\":{\"msgId\":\"AQIDBA==\",\"fileName\":\"photo.jpg\"}}" @@ -230,10 +231,10 @@ decodeChatMessageTest = describe "Chat message encoding/decoding" $ do "{\"v\":\"1\",\"event\":\"x.contact\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"},\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}" ==# XContact testProfile Nothing it "x.grp.inv" $ - "{\"v\":\"1\",\"event\":\"x.grp.inv\",\"params\":{\"groupInvitation\":{\"connRequest\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"invitedMember\":{\"memberRole\":\"member\",\"memberId\":\"BQYHCA==\"},\"groupProfile\":{\"fullName\":\"Team\",\"displayName\":\"team\",\"groupPreferences\":{\"reactions\":{\"enable\":\"on\"},\"voice\":{\"enable\":\"on\"}}},\"fromMember\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\"}}}}" + "{\"v\":\"1\",\"event\":\"x.grp.inv\",\"params\":{\"groupInvitation\":{\"connRequest\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"invitedMember\":{\"memberRole\":\"member\",\"memberId\":\"BQYHCA==\"},\"groupProfile\":{\"fullName\":\"Team\",\"displayName\":\"team\",\"groupPreferences\":{\"reactions\":{\"enable\":\"on\"},\"voice\":{\"enable\":\"on\"}}},\"fromMember\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\"}}}}" #==# XGrpInv GroupInvitation {fromMember = MemberIdRole (MemberId "\1\2\3\4") GRAdmin, invitedMember = MemberIdRole (MemberId "\5\6\7\8") GRMember, connRequest = testConnReq, groupProfile = testGroupProfile, groupLinkId = Nothing, groupSize = Nothing} it "x.grp.inv with group link id" $ - "{\"v\":\"1\",\"event\":\"x.grp.inv\",\"params\":{\"groupInvitation\":{\"connRequest\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"invitedMember\":{\"memberRole\":\"member\",\"memberId\":\"BQYHCA==\"},\"groupProfile\":{\"fullName\":\"Team\",\"displayName\":\"team\",\"groupPreferences\":{\"reactions\":{\"enable\":\"on\"},\"voice\":{\"enable\":\"on\"}}},\"fromMember\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\"}, \"groupLinkId\":\"AQIDBA==\"}}}" + "{\"v\":\"1\",\"event\":\"x.grp.inv\",\"params\":{\"groupInvitation\":{\"connRequest\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"invitedMember\":{\"memberRole\":\"member\",\"memberId\":\"BQYHCA==\"},\"groupProfile\":{\"fullName\":\"Team\",\"displayName\":\"team\",\"groupPreferences\":{\"reactions\":{\"enable\":\"on\"},\"voice\":{\"enable\":\"on\"}}},\"fromMember\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\"}, \"groupLinkId\":\"AQIDBA==\"}}}" #==# XGrpInv GroupInvitation {fromMember = MemberIdRole (MemberId "\1\2\3\4") GRAdmin, invitedMember = MemberIdRole (MemberId "\5\6\7\8") GRMember, connRequest = testConnReq, groupProfile = testGroupProfile, groupLinkId = Just $ GroupLinkId "\1\2\3\4", groupSize = Nothing} it "x.grp.acpt without incognito profile" $ "{\"v\":\"1\",\"event\":\"x.grp.acpt\",\"params\":{\"memberId\":\"AQIDBA==\"}}" @@ -254,16 +255,16 @@ decodeChatMessageTest = describe "Chat message encoding/decoding" $ do "{\"v\":\"1\",\"event\":\"x.grp.mem.intro\",\"params\":{\"memberRestrictions\":{\"restriction\":\"blocked\"},\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}" #==# XGrpMemIntro MemberInfo {memberId = MemberId "\1\2\3\4", memberRole = GRAdmin, v = Nothing, profile = testProfile} (Just MemberRestrictions {restriction = MRSBlocked}) it "x.grp.mem.inv" $ - "{\"v\":\"1\",\"event\":\"x.grp.mem.inv\",\"params\":{\"memberId\":\"AQIDBA==\",\"memberIntro\":{\"directConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}}" + "{\"v\":\"1\",\"event\":\"x.grp.mem.inv\",\"params\":{\"memberId\":\"AQIDBA==\",\"memberIntro\":{\"directConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}}" #==# XGrpMemInv (MemberId "\1\2\3\4") IntroInvitation {groupConnReq = testConnReq, directConnReq = Just testConnReq} it "x.grp.mem.inv w/t directConnReq" $ - "{\"v\":\"1\",\"event\":\"x.grp.mem.inv\",\"params\":{\"memberId\":\"AQIDBA==\",\"memberIntro\":{\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}}" + "{\"v\":\"1\",\"event\":\"x.grp.mem.inv\",\"params\":{\"memberId\":\"AQIDBA==\",\"memberIntro\":{\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}}" #==# XGrpMemInv (MemberId "\1\2\3\4") IntroInvitation {groupConnReq = testConnReq, directConnReq = Nothing} it "x.grp.mem.fwd" $ - "{\"v\":\"1\",\"event\":\"x.grp.mem.fwd\",\"params\":{\"memberIntro\":{\"directConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"},\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}" + "{\"v\":\"1\",\"event\":\"x.grp.mem.fwd\",\"params\":{\"memberIntro\":{\"directConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"},\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}" #==# XGrpMemFwd MemberInfo {memberId = MemberId "\1\2\3\4", memberRole = GRAdmin, v = Nothing, profile = testProfile} IntroInvitation {groupConnReq = testConnReq, directConnReq = Just testConnReq} it "x.grp.mem.fwd with member chat version range and w/t directConnReq" $ - "{\"v\":\"1\",\"event\":\"x.grp.mem.fwd\",\"params\":{\"memberIntro\":{\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"},\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"v\":\"1-8\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}" + "{\"v\":\"1\",\"event\":\"x.grp.mem.fwd\",\"params\":{\"memberIntro\":{\"groupConnReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"},\"memberInfo\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\",\"v\":\"1-8\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}}" #==# XGrpMemFwd MemberInfo {memberId = MemberId "\1\2\3\4", memberRole = GRAdmin, v = Just $ ChatVersionRange supportedChatVRange, profile = testProfile} IntroInvitation {groupConnReq = testConnReq, directConnReq = Nothing} it "x.grp.mem.info" $ "{\"v\":\"1\",\"event\":\"x.grp.mem.info\",\"params\":{\"memberId\":\"AQIDBA==\",\"profile\":{\"fullName\":\"Alice\",\"displayName\":\"alice\",\"image\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII=\",\"preferences\":{\"reactions\":{\"allow\":\"yes\"},\"voice\":{\"allow\":\"yes\"}}}}}" @@ -284,10 +285,10 @@ decodeChatMessageTest = describe "Chat message encoding/decoding" $ do "{\"v\":\"1\",\"event\":\"x.grp.del\",\"params\":{}}" ==# XGrpDel it "x.grp.direct.inv" $ - "{\"v\":\"1\",\"event\":\"x.grp.direct.inv\",\"params\":{\"connReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\", \"content\":{\"text\":\"hello\",\"type\":\"text\"}}}" + "{\"v\":\"1\",\"event\":\"x.grp.direct.inv\",\"params\":{\"connReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\", \"content\":{\"text\":\"hello\",\"type\":\"text\"}}}" #==# XGrpDirectInv testConnReq (Just $ MCText "hello") it "x.grp.direct.inv without content" $ - "{\"v\":\"1\",\"event\":\"x.grp.direct.inv\",\"params\":{\"connReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}" + "{\"v\":\"1\",\"event\":\"x.grp.direct.inv\",\"params\":{\"connReq\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-3%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D2-3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\"}}" #==# XGrpDirectInv testConnReq Nothing -- it "x.grp.msg.forward" -- $ "{\"v\":\"1\",\"event\":\"x.grp.msg.forward\",\"params\":{\"msgForward\":{\"memberId\":\"AQIDBA==\",\"msg\":\"{\"v\":\"1\",\"event\":\"x.msg.new\",\"params\":{\"content\":{\"text\":\"hello\",\"type\":\"text\"}}}\",\"msgTs\":\"1970-01-01T00:00:01.000000001Z\"}}}" From ddeaa1c7c342d1cd11f3445eb3899449ee359ec0 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Tue, 2 Jul 2024 14:50:10 +0100 Subject: [PATCH 13/43] core: servers --- src/Simplex/Chat.hs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index 2a7c0ec83e..cc829eaa16 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -175,12 +175,11 @@ defaultChatConfig = _defaultSMPServers :: NonEmpty SMPServerWithAuth _defaultSMPServers = L.fromList - [ "smp://0YuTwO05YJWS8rkjn9eLJDjQhFKvIYd8d4xG8X1blIU=@smp8.simplex.im,beccx4yfxxbvyhqypaavemqurytl6hozr47wfc7uuecacjqdvwpw2xid.onion", - "smp://SkIkI6EPd2D63F4xFKfHk7I1UGZVNn6k1QWZ5rcyr6w=@smp9.simplex.im,jssqzccmrcws6bhmn77vgmhfjmhwlyr3u7puw4erkyoosywgl67slqqd.onion", - "smp://6iIcWT_dF2zN_w5xzZEY7HI2Prbh3ldP07YTyDexPjE=@smp10.simplex.im,rb2pbttocvnbrngnwziclp2f4ckjq65kebafws6g4hy22cdaiv5dwjqd.onion", - "smp://1OwYGt-yqOfe2IyVHhxz3ohqo3aCCMjtB-8wn4X_aoY=@smp11.simplex.im,6ioorbm6i3yxmuoezrhjk6f6qgkc4syabh7m3so74xunb5nzr4pwgfqd.onion", - "smp://UkMFNAXLXeAAe0beCa4w6X_zp18PwxSaSjY17BKUGXQ=@smp12.simplex.im,ie42b5weq7zdkghocs3mgxdjeuycheeqqmksntj57rmejagmg4eor5yd.onion", - "smp://enEkec4hlR3UtKx2NMpOUK_K4ZuDxjWBO1d9Y4YXVaA=@smp14.simplex.im,aspkyu2sopsnizbyfabtsicikr2s4r3ti35jogbcekhm3fsoeyjvgrid.onion" + [ "smp://h--vW7ZSkXPeOUpfxlFGgauQmXNFOzGoizak7Ult7cw=@smp15.simplex.im,oauu4bgijybyhczbnxtlggo6hiubahmeutaqineuyy23aojpih3dajad.onion", + "smp://hejn2gVIqNU6xjtGM3OwQeuk8ZEbDXVJXAlnSBJBWUA=@smp16.simplex.im,p3ktngodzi6qrf7w64mmde3syuzrv57y55hxabqcq3l5p6oi7yzze6qd.onion", + "smp://ZKe4uxF4Z_aLJJOEsC-Y6hSkXgQS5-oc442JQGkyP8M=@smp17.simplex.im,ogtwfxyi3h2h5weftjjpjmxclhb5ugufa5rcyrmg7j4xlch7qsr5nuqd.onion", + "smp://PtsqghzQKU83kYTlQ1VKg996dW4Cw4x_bvpKmiv8uns=@smp18.simplex.im,lyqpnwbs2zqfr45jqkncwpywpbtq7jrhxnib5qddtr6npjyezuwd3nqd.onion", + "smp://N_McQS3F9TGoh4ER0QstUf55kGnNSd-wXfNPZ7HukcM=@smp19.simplex.im,i53bbtoqhlc365k6kxzwdp5w3cdt433s7bwh3y32rcbml2vztiyyz5id.onion" ] _defaultNtfServers :: [NtfServer] From 0d3928bd5179eb4e29cb78dad08b12c91a49405f Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Tue, 2 Jul 2024 21:02:36 +0700 Subject: [PATCH 14/43] android, desktop: handle situation when not all databases created before shut down (#4294) * android, desktop: handle situation when not all databases created before shut down * more logic of choosing whether to delete databases or not * comment * rename * refactoring --- .../chat/simplex/common/model/ChatModel.kt | 1 + .../chat/simplex/common/model/SimpleXAPI.kt | 7 +++ .../chat/simplex/common/platform/Core.kt | 15 +++++++ .../views/database/DatabaseErrorView.kt | 43 ++++++++++++++++--- .../common/views/database/DatabaseView.kt | 2 + .../common/views/helpers/DatabaseUtils.kt | 11 +++-- 6 files changed, 68 insertions(+), 11 deletions(-) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index 0ebe77e524..c155010a28 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -52,6 +52,7 @@ object ChatModel { val chatDbStatus = mutableStateOf(null) val ctrlInitInProgress = mutableStateOf(false) val dbMigrationInProgress = mutableStateOf(false) + val incompleteInitializedDbRemoved = mutableStateOf(false) val chats = mutableStateListOf() // map of connections network statuses, key is agent connection id val networkStatuses = mutableStateMapOf() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index 795a4d50e1..60957d0f41 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -176,6 +176,12 @@ class AppPreferences { val selfDestruct = mkBoolPreference(SHARED_PREFS_SELF_DESTRUCT, false) val selfDestructDisplayName = mkStrPreference(SHARED_PREFS_SELF_DESTRUCT_DISPLAY_NAME, null) + // This flag is set when database is first initialized and resets only when the database is removed. + // This is needed for recover from incomplete initialization when only one database file is created. + // If false - the app will clear database folder on missing file and re-initialize. + // Note that this situation can only happen if passphrase for the first database is incorrect because, otherwise, backend will re-create second database automatically + val newDatabaseInitialized = mkBoolPreference(SHARED_PREFS_NEW_DATABASE_INITIALIZED, false) + val currentTheme = mkStrPreference(SHARED_PREFS_CURRENT_THEME, DefaultTheme.SYSTEM_THEME_NAME) val systemDarkTheme = mkStrPreference(SHARED_PREFS_SYSTEM_DARK_THEME, DefaultTheme.SIMPLEX.themeName) val currentThemeIds = mkMapPreference(SHARED_PREFS_CURRENT_THEME_IDs, mapOf(), encode = { @@ -361,6 +367,7 @@ class AppPreferences { private const val SHARED_PREFS_ENCRYPTED_SELF_DESTRUCT_PASSPHRASE = "EncryptedSelfDestructPassphrase" private const val SHARED_PREFS_INITIALIZATION_VECTOR_SELF_DESTRUCT_PASSPHRASE = "InitializationVectorSelfDestructPassphrase" private const val SHARED_PREFS_ENCRYPTION_STARTED_AT = "EncryptionStartedAt" + private const val SHARED_PREFS_NEW_DATABASE_INITIALIZED = "NewDatabaseInitialized" private const val SHARED_PREFS_CONFIRM_DB_UPGRADES = "ConfirmDBUpgrades" private const val SHARED_PREFS_SELF_DESTRUCT = "LocalAuthenticationSelfDestruct" private const val SHARED_PREFS_SELF_DESTRUCT_DISPLAY_NAME = "LocalAuthenticationSelfDestructDisplayName" diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt index d6b8901042..57b93d4d6e 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt @@ -88,8 +88,23 @@ suspend fun initChatController(useKey: String? = null, confirmMigrations: Migrat chatModel.chatDbStatus.value = res if (res != DBMigrationResult.OK) { Log.d(TAG, "Unable to migrate successfully: $res") + if (!appPrefs.newDatabaseInitialized.get() && DatabaseUtils.hasOnlyOneDatabase(dataDir.absolutePath)) { + if (chatModel.incompleteInitializedDbRemoved.value) { + Log.d(TAG, "Incomplete initialized databases were removed but after repeated migration only one database exists again, not trying to remove again") + } else { + val dbPath = dbAbsolutePrefixPath + File(dbPath + "_chat.db").delete() + File(dbPath + "_agent.db").delete() + chatModel.incompleteInitializedDbRemoved.value = true + Log.d(TAG, "Incomplete initialized databases were removed for the first time, repeating migration") + chatModel.ctrlInitInProgress.value = false + initChatController(useKey, confirmMigrations, startChat) + } + } return } + appPrefs.newDatabaseInitialized.set(true) + chatModel.incompleteInitializedDbRemoved.value = false platform.androidRestartNetworkObserver() controller.apiSetAppFilePaths( appFilesDir.absolutePath, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseErrorView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseErrorView.kt index 5f0356bb2d..109e5bc737 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseErrorView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseErrorView.kt @@ -22,8 +22,11 @@ import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* import chat.simplex.common.views.usersettings.AppVersionText +import chat.simplex.common.views.usersettings.SettingsActionItem import chat.simplex.res.MR import dev.icerock.moko.resources.StringResource +import dev.icerock.moko.resources.compose.painterResource +import dev.icerock.moko.resources.compose.stringResource import kotlinx.coroutines.* import kotlinx.datetime.Clock import java.io.File @@ -106,7 +109,7 @@ fun DatabaseErrorView( } } is DBMigrationResult.ErrorMigration -> when (val err = status.migrationError) { - is MigrationError.Upgrade -> + is MigrationError.Upgrade -> { DatabaseErrorDetails(MR.strings.database_upgrade) { TextButton({ callRunChat(confirmMigrations = MigrationConfirmation.YesUp) }, Modifier.align(Alignment.CenterHorizontally), enabled = !progressIndicator.value) { Text(generalGetString(MR.strings.upgrade_and_open_chat)) @@ -116,7 +119,9 @@ fun DatabaseErrorView( MigrationsText(err.upMigrations.map { it.upName }) AppVersionText() } - is MigrationError.Downgrade -> + OpenDatabaseDirectoryButton() + } + is MigrationError.Downgrade -> { DatabaseErrorDetails(MR.strings.database_downgrade) { TextButton({ callRunChat(confirmMigrations = MigrationConfirmation.YesUpDown) }, Modifier.align(Alignment.CenterHorizontally), enabled = !progressIndicator.value) { Text(generalGetString(MR.strings.downgrade_and_open_chat)) @@ -127,29 +132,41 @@ fun DatabaseErrorView( MigrationsText(err.downMigrations) AppVersionText() } - is MigrationError.Error -> + OpenDatabaseDirectoryButton() + } + is MigrationError.Error -> { DatabaseErrorDetails(MR.strings.incompatible_database_version) { FileNameText(status.dbFile) Text(String.format(generalGetString(MR.strings.error_with_info), mtrErrorDescription(err.mtrError))) } + OpenDatabaseDirectoryButton() + } } - is DBMigrationResult.ErrorSQL -> + is DBMigrationResult.ErrorSQL -> { DatabaseErrorDetails(MR.strings.database_error) { FileNameText(status.dbFile) Text(String.format(generalGetString(MR.strings.error_with_info), status.migrationSQLError)) } - is DBMigrationResult.ErrorKeychain -> + OpenDatabaseDirectoryButton() + } + is DBMigrationResult.ErrorKeychain -> { DatabaseErrorDetails(MR.strings.keychain_error) { Text(generalGetString(MR.strings.cannot_access_keychain)) } - is DBMigrationResult.InvalidConfirmation -> + OpenDatabaseDirectoryButton() + } + is DBMigrationResult.InvalidConfirmation -> { DatabaseErrorDetails(MR.strings.invalid_migration_confirmation) { // this can only happen if incorrect parameter is passed } - is DBMigrationResult.Unknown -> + OpenDatabaseDirectoryButton() + } + is DBMigrationResult.Unknown -> { DatabaseErrorDetails(MR.strings.database_error) { Text(String.format(generalGetString(MR.strings.unknown_database_error_with_info), status.json)) } + OpenDatabaseDirectoryButton() + } is DBMigrationResult.OK -> {} null -> {} } @@ -294,6 +311,18 @@ private fun ColumnScope.SaveAndOpenButton(enabled: Boolean, onClick: () -> Unit) } } +@Composable +private fun OpenDatabaseDirectoryButton() { + if (appPlatform.isDesktop) { + Spacer(Modifier.padding(top = DEFAULT_PADDING)) + SettingsActionItem( + painterResource(MR.images.ic_folder_open), + stringResource(MR.strings.open_database_folder), + ::desktopOpenDatabaseDir + ) + } +} + @Composable private fun ColumnScope.OpenChatButton(enabled: Boolean, onClick: () -> Unit) { TextButton(onClick, Modifier.align(Alignment.CenterHorizontally), enabled = enabled) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt index ca0a6f2f93..6c51f778d6 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt @@ -18,6 +18,7 @@ import androidx.compose.ui.text.* import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.model.ChatModel.controller import chat.simplex.common.model.ChatModel.updatingChatsMutex import chat.simplex.common.ui.theme.* @@ -492,6 +493,7 @@ fun deleteChatDatabaseFilesAndState() { wallpapersDir.deleteRecursively() wallpapersDir.mkdirs() DatabaseUtils.ksDatabasePassword.remove() + appPrefs.newDatabaseInitialized.set(false) controller.appPrefs.storeDBPassphrase.set(true) controller.ctrl = null diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/DatabaseUtils.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/DatabaseUtils.kt index 0ad7af439f..c621f186cd 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/DatabaseUtils.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/DatabaseUtils.kt @@ -39,22 +39,25 @@ object DatabaseUtils { } } - private fun hasDatabase(rootDir: String): Boolean = - File(rootDir + File.separator + chatDatabaseFileName).exists() && File(rootDir + File.separator + agentDatabaseFileName).exists() + private fun hasAtLeastOneDatabase(rootDir: String): Boolean = + File(rootDir + File.separator + chatDatabaseFileName).exists() || File(rootDir + File.separator + agentDatabaseFileName).exists() + + fun hasOnlyOneDatabase(rootDir: String): Boolean = + File(rootDir + File.separator + chatDatabaseFileName).exists() != File(rootDir + File.separator + agentDatabaseFileName).exists() fun useDatabaseKey(): String { Log.d(TAG, "useDatabaseKey ${appPreferences.storeDBPassphrase.get()}") var dbKey = "" val useKeychain = appPreferences.storeDBPassphrase.get() if (useKeychain) { - if (!hasDatabase(dataDir.absolutePath)) { + if (!hasAtLeastOneDatabase(dataDir.absolutePath)) { dbKey = randomDatabasePassword() ksDatabasePassword.set(dbKey) appPreferences.initialRandomDBPassphrase.set(true) } else { dbKey = ksDatabasePassword.get() ?: "" } - } else if (appPlatform.isDesktop && !hasDatabase(dataDir.absolutePath)) { + } else if (appPlatform.isDesktop && !hasAtLeastOneDatabase(dataDir.absolutePath)) { // In case of database was deleted by hand dbKey = randomDatabasePassword() ksDatabasePassword.set(dbKey) From 85af368371378d35878f4554958dd29967893540 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Tue, 2 Jul 2024 15:07:46 +0100 Subject: [PATCH 15/43] core: 5.8.2.0, simplexmq: 5.8.2.0 --- cabal.project | 2 +- package.yaml | 2 +- scripts/nix/sha256map.nix | 2 +- simplex-chat.cabal | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cabal.project b/cabal.project index 49e35a6e48..3f05fb8561 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: aa1d8d6c8bcff82f02aa580b1b729fc4b1396fd9 + tag: f392ce0a9355cd3883400906ae6c361b77ca46ea source-repository-package type: git diff --git a/package.yaml b/package.yaml index 15f9c5bfa1..0bf1c1e858 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: simplex-chat -version: 5.8.1.0 +version: 5.8.2.0 #synopsis: #description: homepage: https://github.com/simplex-chat/simplex-chat#readme diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index fab7a3de0e..d046469ea8 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."aa1d8d6c8bcff82f02aa580b1b729fc4b1396fd9" = "01walrsa69n4f01bs5w4sj7svsah483dxmg88a0si7qh5ylay0r0"; + "https://github.com/simplex-chat/simplexmq.git"."f392ce0a9355cd3883400906ae6c361b77ca46ea" = "0id9mg30kmhlfcpnn2np3f0a4bb4smdzvhrbw6km8vv26si1js60"; "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"; diff --git a/simplex-chat.cabal b/simplex-chat.cabal index 3b9d2681d9..48cd8a67d4 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: simplex-chat -version: 5.8.1.0 +version: 5.8.2.0 category: Web, System, Services, Cryptography homepage: https://github.com/simplex-chat/simplex-chat#readme author: simplex.chat From ecff3c6ee51b47a363327da159f682ed18bccad9 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:19:43 +0700 Subject: [PATCH 16/43] android, desktop: notifications improvement (missed call, hidden user) (#4389) * android, desktop: notifications improvement (missed call, hidden user) * change * change --- .../main/java/chat/simplex/app/SimplexApp.kt | 1 + .../simplex/app/model/NtfManager.android.kt | 24 +++++++++++++++---- .../chat/simplex/common/model/SimpleXAPI.kt | 6 +++++ .../simplex/common/platform/NtfManager.kt | 1 + .../common/views/database/DatabaseView.kt | 1 + .../views/usersettings/HiddenProfileView.kt | 4 ++++ .../views/usersettings/UserProfilesView.kt | 1 + .../common/model/NtfManager.desktop.kt | 23 +++++++++++++----- .../common/platform/AppCommon.desktop.kt | 1 + 9 files changed, 52 insertions(+), 10 deletions(-) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt index 95bba8e8a2..7d0312a43a 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt @@ -179,6 +179,7 @@ class SimplexApp: Application(), LifecycleEventObserver { override fun notifyCallInvitation(invitation: RcvCallInvitation): Boolean = NtfManager.notifyCallInvitation(invitation) override fun hasNotificationsForChat(chatId: String): Boolean = NtfManager.hasNotificationsForChat(chatId) override fun cancelNotificationsForChat(chatId: String) = NtfManager.cancelNotificationsForChat(chatId) + override fun cancelNotificationsForUser(userId: Long) = NtfManager.cancelNotificationsForUser(userId) override fun displayNotification(user: UserLike, chatId: String, displayName: String, msgText: String, image: String?, actions: List Unit>>) = NtfManager.displayNotification(user, chatId, displayName, msgText, image, actions.map { it.first }) override fun androidCreateNtfChannelsMaybeShowAlert() = NtfManager.createNtfChannelsMaybeShowAlert() override fun cancelCallNotification() = NtfManager.cancelCallNotification() diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/model/NtfManager.android.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/model/NtfManager.android.kt index 69ad8defbf..417a81a953 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/model/NtfManager.android.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/model/NtfManager.android.kt @@ -48,7 +48,8 @@ object NtfManager { } private val manager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - private var prevNtfTime = mutableMapOf() + // (UserId, ChatId) -> Time + private var prevNtfTime = mutableMapOf, Long>() private val msgNtfTimeoutMs = 30000L init { @@ -72,7 +73,8 @@ object NtfManager { } fun cancelNotificationsForChat(chatId: String) { - prevNtfTime.remove(chatId) + val key = prevNtfTime.keys.firstOrNull { it.second == chatId } + prevNtfTime.remove(key) manager.cancel(chatId.hashCode()) val msgNtfs = manager.activeNotifications.filter { ntf -> ntf.notification.channelId == MessageChannel @@ -83,12 +85,26 @@ object NtfManager { } } + fun cancelNotificationsForUser(userId: Long) { + prevNtfTime.keys.filter { it.first == userId }.forEach { + prevNtfTime.remove(it) + manager.cancel(it.second.hashCode()) + } + val msgNtfs = manager.activeNotifications.filter { ntf -> + ntf.notification.channelId == MessageChannel + } + if (msgNtfs.size <= 1) { + // Have a group notification with no children so cancel it + manager.cancel(0) + } + } + fun displayNotification(user: UserLike, chatId: String, displayName: String, msgText: String, image: String? = null, actions: List = emptyList()) { if (!user.showNotifications) return Log.d(TAG, "notifyMessageReceived $chatId") val now = Clock.System.now().toEpochMilliseconds() - val recentNotification = (now - prevNtfTime.getOrDefault(chatId, 0) < msgNtfTimeoutMs) - prevNtfTime[chatId] = now + val recentNotification = (now - prevNtfTime.getOrDefault(user.userId to chatId, 0) < msgNtfTimeoutMs) + prevNtfTime[user.userId to chatId] = now val previewMode = appPreferences.notificationPreviewMode.get() val title = if (previewMode == NotificationPreviewMode.HIDDEN.name) generalGetString(MR.strings.notification_preview_somebody) else displayName val content = if (previewMode != NotificationPreviewMode.MESSAGE.name) generalGetString(MR.strings.notification_preview_new_message) else msgText diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index 60957d0f41..9367fe5f71 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -498,11 +498,15 @@ object ChatController { } suspend fun changeActiveUser_(rhId: Long?, toUserId: Long?, viewPwd: String?) { + val prevActiveUser = chatModel.currentUser.value val currentUser = changingActiveUserMutex.withLock { (if (toUserId != null) apiSetActiveUser(rhId, toUserId, viewPwd) else apiGetActiveUser(rhId)).also { chatModel.currentUser.value = it } } + if (prevActiveUser?.hidden == true) { + ntfManager.cancelNotificationsForUser(prevActiveUser.userId) + } val users = listUsers(rhId) chatModel.users.clear() chatModel.users.addAll(users) @@ -2354,6 +2358,8 @@ object ChatController { notify() } else if (chatModel.upsertChatItem(rh, cInfo, cItem)) { notify() + } else if (cItem.content is CIContent.RcvCall && cItem.content.status == CICallStatus.Missed) { + notify() } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/NtfManager.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/NtfManager.kt index 57c1e578ae..e7c653e1b9 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/NtfManager.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/NtfManager.kt @@ -96,6 +96,7 @@ abstract class NtfManager { abstract fun notifyCallInvitation(invitation: RcvCallInvitation): Boolean abstract fun hasNotificationsForChat(chatId: String): Boolean abstract fun cancelNotificationsForChat(chatId: String) + abstract fun cancelNotificationsForUser(userId: Long) abstract fun displayNotification(user: UserLike, chatId: String, displayName: String, msgText: String, image: String? = null, actions: List Unit>> = emptyList()) abstract fun cancelCallNotification() abstract fun cancelAllNotifications() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt index 6c51f778d6..a80b519973 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt @@ -502,6 +502,7 @@ fun deleteChatDatabaseFilesAndState() { chatModel.chatItems.clear() chatModel.chats.clear() chatModel.users.clear() + ntfManager.cancelAllNotifications() } private fun exportArchive( diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/HiddenProfileView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/HiddenProfileView.kt index 4dd406c398..c60e8e6bf4 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/HiddenProfileView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/HiddenProfileView.kt @@ -18,6 +18,7 @@ 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.platform.ntfManager import chat.simplex.common.ui.theme.* import chat.simplex.common.views.chatlist.UserProfileRow import chat.simplex.common.views.database.PassphraseField @@ -36,6 +37,9 @@ fun HiddenProfileView( withBGApi { try { val u = m.controller.apiHideUser(user, hidePassword) + if (!u.activeUser) { + ntfManager.cancelNotificationsForUser(u.userId) + } m.updateUser(u) close() } catch (e: Exception) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt index b40cc7db92..862fb052e1 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt @@ -367,6 +367,7 @@ private suspend fun doRemoveUser(m: ChatModel, user: User, users: List, de } } m.removeUser(user) + ntfManager.cancelNotificationsForUser(user.userId) } catch (e: Exception) { AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_deleting_user), e.stackTraceToString()) } diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/model/NtfManager.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/model/NtfManager.desktop.kt index 3913c0dc9b..3bd1506b4f 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/model/NtfManager.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/model/NtfManager.desktop.kt @@ -16,7 +16,7 @@ import java.io.File import javax.imageio.ImageIO object NtfManager { - private val prevNtfs = arrayListOf>() + private val prevNtfs = arrayListOf, Slice>>() private val prevNtfsMutex: Mutex = Mutex() fun notifyCallInvitation(invitation: RcvCallInvitation): Boolean { @@ -45,14 +45,14 @@ object NtfManager { generalGetString(MR.strings.accept) to { ntfManager.acceptCallAction(invitation.contact.id) }, generalGetString(MR.strings.reject) to { ChatModel.callManager.endCall(invitation = invitation) } ) - displayNotificationViaLib(contactId, title, text, prepareIconPath(largeIcon), actions) { + displayNotificationViaLib(invitation.user.userId, contactId, title, text, prepareIconPath(largeIcon), actions) { ntfManager.openChatAction(invitation.user.userId, contactId) } return true } fun showMessage(title: String, text: String) { - displayNotificationViaLib("MESSAGE", title, text, null, emptyList()) {} + displayNotificationViaLib(-1, "MESSAGE", title, text, null, emptyList()) {} } fun hasNotificationsForChat(chatId: ChatId) = false//prevNtfs.any { it.first == chatId } @@ -60,7 +60,7 @@ object NtfManager { fun cancelNotificationsForChat(chatId: ChatId) { withBGApi { prevNtfsMutex.withLock { - val ntf = prevNtfs.firstOrNull { it.first == chatId } + val ntf = prevNtfs.firstOrNull { (userChat) -> userChat.second == chatId } if (ntf != null) { prevNtfs.remove(ntf) /*try { @@ -74,6 +74,16 @@ object NtfManager { } } + fun cancelNotificationsForUser(userId: Long) { + withBGApi { + prevNtfsMutex.withLock { + prevNtfs.filter { (userChat) -> userChat.first == userId }.forEach { + prevNtfs.remove(it) + } + } + } + } + fun cancelAllNotifications() { // prevNtfs.forEach { try { it.second.close() } catch (e: Exception) { println("Failed to close notification: ${e.stackTraceToString()}") } } withBGApi { @@ -95,12 +105,13 @@ object NtfManager { else -> base64ToBitmap(image) } - displayNotificationViaLib(chatId, title, content, prepareIconPath(largeIcon), actions.map { it.first.name to it.second }) { + displayNotificationViaLib(user.userId, chatId, title, content, prepareIconPath(largeIcon), actions.map { it.first.name to it.second }) { ntfManager.openChatAction(user.userId, chatId) } } private fun displayNotificationViaLib( + userId: Long, chatId: String, title: String, text: String, @@ -123,7 +134,7 @@ object NtfManager { try { withBGApi { prevNtfsMutex.withLock { - prevNtfs.add(chatId to builder.toast()) + prevNtfs.add(Pair(userId, chatId) to builder.toast()) } } } catch (e: Throwable) { diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt index 33a3ae2578..905e25566b 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/AppCommon.desktop.kt @@ -18,6 +18,7 @@ fun initApp() { override fun notifyCallInvitation(invitation: RcvCallInvitation): Boolean = chat.simplex.common.model.NtfManager.notifyCallInvitation(invitation) override fun hasNotificationsForChat(chatId: String): Boolean = chat.simplex.common.model.NtfManager.hasNotificationsForChat(chatId) override fun cancelNotificationsForChat(chatId: String) = chat.simplex.common.model.NtfManager.cancelNotificationsForChat(chatId) + override fun cancelNotificationsForUser(userId: Long) = chat.simplex.common.model.NtfManager.cancelNotificationsForUser(userId) override fun displayNotification(user: UserLike, chatId: String, displayName: String, msgText: String, image: String?, actions: List Unit>>) = chat.simplex.common.model.NtfManager.displayNotification(user, chatId, displayName, msgText, image, actions) override fun androidCreateNtfChannelsMaybeShowAlert() {} override fun cancelCallNotification() {} From 8e4299afb61ca1bd4d915c438b36466ff24bde56 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:26:23 +0700 Subject: [PATCH 17/43] android, desktop: close modals only for desktop (#4390) --- .../kotlin/chat/simplex/common/views/database/DatabaseView.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt index a80b519973..fa43048e9e 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt @@ -451,7 +451,9 @@ private fun stopChat(m: ChatModel, progressIndicator: MutableState? = n platform.androidChatStopped() // close chat view for desktop chatModel.chatId.value = null - ModalManager.end.closeModals() + if (appPlatform.isDesktop) { + ModalManager.end.closeModals() + } onStop?.invoke() } catch (e: Error) { m.chatRunning.value = true From e22e01acd232afb73572ab4b3119ea6c1ef55ba9 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Tue, 2 Jul 2024 21:28:34 +0100 Subject: [PATCH 18/43] 5.8.2: ios 226, android 223, desktop 55 --- apps/ios/SimpleX.xcodeproj/project.pbxproj | 64 +++++++++++----------- apps/multiplatform/gradle.properties | 8 +-- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 8907938f52..43aa79e0a9 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -192,11 +192,11 @@ D741547A29AF90B00022400A /* PushKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D741547929AF90B00022400A /* PushKit.framework */; }; D77B92DC2952372200A5A1CC /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = D77B92DB2952372200A5A1CC /* SwiftyGif */; }; D7F0E33929964E7E0068AF69 /* LZString in Frameworks */ = {isa = PBXBuildFile; productRef = D7F0E33829964E7E0068AF69 /* LZString */; }; - E5D68D3F2C22D78C00CBA347 /* libHSsimplex-chat-5.8.1.0-GEbUSGuGADZH0bnStuks0c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5D68D3A2C22D78C00CBA347 /* libHSsimplex-chat-5.8.1.0-GEbUSGuGADZH0bnStuks0c.a */; }; - E5D68D402C22D78C00CBA347 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5D68D3B2C22D78C00CBA347 /* libffi.a */; }; - E5D68D412C22D78C00CBA347 /* libHSsimplex-chat-5.8.1.0-GEbUSGuGADZH0bnStuks0c-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5D68D3C2C22D78C00CBA347 /* libHSsimplex-chat-5.8.1.0-GEbUSGuGADZH0bnStuks0c-ghc9.6.3.a */; }; - E5D68D422C22D78C00CBA347 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5D68D3D2C22D78C00CBA347 /* libgmp.a */; }; - E5D68D432C22D78C00CBA347 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5D68D3E2C22D78C00CBA347 /* libgmpxx.a */; }; + E52FF8DA2C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D52C34676600BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a */; }; + E52FF8DB2C34676700BF81EB /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D62C34676600BF81EB /* libgmpxx.a */; }; + E52FF8DC2C34676700BF81EB /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D72C34676700BF81EB /* libffi.a */; }; + E52FF8DD2C34676700BF81EB /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D82C34676700BF81EB /* libgmp.a */; }; + E52FF8DE2C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D92C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -487,11 +487,11 @@ D741547729AF89AF0022400A /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/StoreKit.framework; sourceTree = DEVELOPER_DIR; }; D741547929AF90B00022400A /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/PushKit.framework; sourceTree = DEVELOPER_DIR; }; D7AA2C3429A936B400737B40 /* MediaEncryption.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; name = MediaEncryption.playground; path = Shared/MediaEncryption.playground; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - E5D68D3A2C22D78C00CBA347 /* libHSsimplex-chat-5.8.1.0-GEbUSGuGADZH0bnStuks0c.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.1.0-GEbUSGuGADZH0bnStuks0c.a"; sourceTree = ""; }; - E5D68D3B2C22D78C00CBA347 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; - E5D68D3C2C22D78C00CBA347 /* libHSsimplex-chat-5.8.1.0-GEbUSGuGADZH0bnStuks0c-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.1.0-GEbUSGuGADZH0bnStuks0c-ghc9.6.3.a"; sourceTree = ""; }; - E5D68D3D2C22D78C00CBA347 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; - E5D68D3E2C22D78C00CBA347 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; + E52FF8D52C34676600BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a"; sourceTree = ""; }; + E52FF8D62C34676600BF81EB /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; + E52FF8D72C34676700BF81EB /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; + E52FF8D82C34676700BF81EB /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; + E52FF8D92C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -529,13 +529,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E5D68D412C22D78C00CBA347 /* libHSsimplex-chat-5.8.1.0-GEbUSGuGADZH0bnStuks0c-ghc9.6.3.a in Frameworks */, + E52FF8DE2C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a in Frameworks */, + E52FF8DB2C34676700BF81EB /* libgmpxx.a in Frameworks */, 5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */, 5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */, - E5D68D3F2C22D78C00CBA347 /* libHSsimplex-chat-5.8.1.0-GEbUSGuGADZH0bnStuks0c.a in Frameworks */, - E5D68D422C22D78C00CBA347 /* libgmp.a in Frameworks */, - E5D68D402C22D78C00CBA347 /* libffi.a in Frameworks */, - E5D68D432C22D78C00CBA347 /* libgmpxx.a in Frameworks */, + E52FF8DC2C34676700BF81EB /* libffi.a in Frameworks */, + E52FF8DD2C34676700BF81EB /* libgmp.a in Frameworks */, + E52FF8DA2C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -601,11 +601,11 @@ 5C764E5C279C70B7000C6508 /* Libraries */ = { isa = PBXGroup; children = ( - E5D68D3B2C22D78C00CBA347 /* libffi.a */, - E5D68D3D2C22D78C00CBA347 /* libgmp.a */, - E5D68D3E2C22D78C00CBA347 /* libgmpxx.a */, - E5D68D3C2C22D78C00CBA347 /* libHSsimplex-chat-5.8.1.0-GEbUSGuGADZH0bnStuks0c-ghc9.6.3.a */, - E5D68D3A2C22D78C00CBA347 /* libHSsimplex-chat-5.8.1.0-GEbUSGuGADZH0bnStuks0c.a */, + E52FF8D72C34676700BF81EB /* libffi.a */, + E52FF8D82C34676700BF81EB /* libgmp.a */, + E52FF8D62C34676600BF81EB /* libgmpxx.a */, + E52FF8D52C34676600BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a */, + E52FF8D92C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a */, ); path = Libraries; sourceTree = ""; @@ -1552,7 +1552,7 @@ CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 225; + CURRENT_PROJECT_VERSION = 226; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; @@ -1577,7 +1577,7 @@ "@executable_path/Frameworks", ); LLVM_LTO = YES_THIN; - MARKETING_VERSION = 5.8.1; + MARKETING_VERSION = 5.8.2; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_NAME = SimpleX; SDKROOT = iphoneos; @@ -1601,7 +1601,7 @@ CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 225; + CURRENT_PROJECT_VERSION = 226; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; @@ -1626,7 +1626,7 @@ "@executable_path/Frameworks", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.8.1; + MARKETING_VERSION = 5.8.2; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_NAME = SimpleX; SDKROOT = iphoneos; @@ -1687,7 +1687,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 225; + CURRENT_PROJECT_VERSION = 226; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; GCC_OPTIMIZATION_LEVEL = s; @@ -1702,7 +1702,7 @@ "@executable_path/../../Frameworks", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.8.1; + MARKETING_VERSION = 5.8.2; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1724,7 +1724,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 225; + CURRENT_PROJECT_VERSION = 226; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; ENABLE_CODE_COVERAGE = NO; @@ -1739,7 +1739,7 @@ "@executable_path/../../Frameworks", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.8.1; + MARKETING_VERSION = 5.8.2; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1761,7 +1761,7 @@ CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 225; + CURRENT_PROJECT_VERSION = 226; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1787,7 +1787,7 @@ "$(PROJECT_DIR)/Libraries/sim", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.8.1; + MARKETING_VERSION = 5.8.2; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; @@ -1812,7 +1812,7 @@ CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 225; + CURRENT_PROJECT_VERSION = 226; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1838,7 +1838,7 @@ "$(PROJECT_DIR)/Libraries/sim", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.8.1; + MARKETING_VERSION = 5.8.2; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; diff --git a/apps/multiplatform/gradle.properties b/apps/multiplatform/gradle.properties index ecf038c8a5..d87b70cc56 100644 --- a/apps/multiplatform/gradle.properties +++ b/apps/multiplatform/gradle.properties @@ -26,11 +26,11 @@ android.enableJetifier=true kotlin.mpp.androidSourceSetLayoutVersion=2 kotlin.jvm.target=11 -android.version_name=5.8.1 -android.version_code=221 +android.version_name=5.8.2 +android.version_code=223 -desktop.version_name=5.8.1 -desktop.version_code=54 +desktop.version_name=5.8.2 +desktop.version_code=55 kotlin.version=1.9.23 gradle.plugin.version=8.2.0 From 2585f4ecfd8c7a2e5ab0dba304507c6b8d414718 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Wed, 3 Jul 2024 10:24:26 +0100 Subject: [PATCH 19/43] ios: ChatView performance improvements (#4353) * feat: Add synthesized hashable conformance to chat and API types (#4348) * UIKit ReverseList * ReverseList - manual layout updates for external state * Propagate ScrollModel; Disable async media width * Filter chat items * Remove UIKit menu wrapper * Make chat item width calculation synchronous (#4371) * Fix floating button regression * Improve filter performance * Fix page load the merged items exceed full page * Resolve iOS15 compabibility * Restore build config * Add page-up scroll; Fix same item decrementing unread counter multiple times * Fix: Chat not loading additional pages, if newest items are all merged and exceed page size * Minor * Fix item loading regression * Fix item loading regression 2 * Fix unread regression * refactor --------- Co-authored-by: Arturs Krumins Co-authored-by: Levitating Pineapple Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> --- apps/ios/Shared/Model/ChatModel.swift | 18 +- apps/ios/Shared/Model/SimpleXAPI.swift | 4 +- .../Views/Chat/ChatItem/CIImageView.swift | 13 +- .../Views/Chat/ChatItem/CIVideoView.swift | 24 +- .../Views/Chat/ChatItem/FramedItemView.swift | 22 +- .../Chat/ChatItem/FullScreenMediaView.swift | 6 +- apps/ios/Shared/Views/Chat/ChatItemView.swift | 35 +- apps/ios/Shared/Views/Chat/ChatView.swift | 673 ++++++++++-------- apps/ios/Shared/Views/Chat/ReverseList.swift | 270 +++++++ .../Shared/Views/ChatList/ChatListView.swift | 4 +- .../Shared/Views/Helpers/ContextMenu.swift | 112 --- apps/ios/SimpleX.xcodeproj/project.pbxproj | 8 +- apps/ios/SimpleXChat/APITypes.swift | 136 ++-- apps/ios/SimpleXChat/ChatTypes.swift | 245 ++++--- 14 files changed, 921 insertions(+), 649 deletions(-) create mode 100644 apps/ios/Shared/Views/Chat/ReverseList.swift delete mode 100644 apps/ios/Shared/Views/Helpers/ContextMenu.swift diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index a4651e1d42..542c7974e2 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -332,12 +332,12 @@ final class ChatModel: ObservableObject { private func _upsertChatItem(_ cInfo: ChatInfo, _ cItem: ChatItem) -> Bool { if let i = getChatItemIndex(cItem) { - withAnimation { + withConditionalAnimation { _updateChatItem(at: i, with: cItem) } return false } else { - withAnimation(itemAnimation()) { + withConditionalAnimation(itemAnimation()) { var ci = cItem if let status = chatItemStatuses.removeValue(forKey: ci.id), case .sndNew = ci.meta.itemStatus { ci.meta.itemStatus = status @@ -357,7 +357,7 @@ final class ChatModel: ObservableObject { func updateChatItem(_ cInfo: ChatInfo, _ cItem: ChatItem, status: CIStatus? = nil) { if chatId == cInfo.id, let i = getChatItemIndex(cItem) { - withAnimation { + withConditionalAnimation { _updateChatItem(at: i, with: cItem) } } else if let status = status { @@ -512,11 +512,13 @@ final class ChatModel: ObservableObject { } func markChatItemRead(_ cInfo: ChatInfo, _ cItem: ChatItem) { - // update preview - decreaseUnreadCounter(cInfo) - // update current chat if chatId == cInfo.id, let i = getChatItemIndex(cItem) { - markChatItemRead_(i) + if reversedChatItems[i].isRcvNew { + // update current chat + markChatItemRead_(i) + // update preview + decreaseUnreadCounter(cInfo) + } } } @@ -723,7 +725,7 @@ struct NTFContactRequest { var chatId: String } -struct UnreadChatItemCounts { +struct UnreadChatItemCounts: Equatable { var totalBelow: Int var unreadBelow: Int } diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index 49152283ee..eb66071ef8 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -309,8 +309,10 @@ private func apiChatsResponse(_ r: ChatResponse) throws -> [ChatData] { throw r } +let loadItemsPerPage = 50 + func apiGetChat(type: ChatType, id: Int64, search: String = "") throws -> Chat { - let r = chatSendCmdSync(.apiGetChat(type: type, id: id, pagination: .last(count: 50), search: search)) + let r = chatSendCmdSync(.apiGetChat(type: type, id: id, pagination: .last(count: loadItemsPerPage), search: search)) if case let .apiChat(_, chat) = r { return Chat.init(chat) } throw r } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift index cfead635fe..5aacc335ab 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift @@ -13,10 +13,9 @@ struct CIImageView: View { @EnvironmentObject var m: ChatModel @Environment(\.colorScheme) var colorScheme let chatItem: ChatItem - let image: String + var preview: UIImage? let maxWidth: CGFloat - @Binding var imgWidth: CGFloat? - @State var scrollProxy: ScrollViewProxy? + var imgWidth: CGFloat? @State private var showFullScreenImage = false var body: some View { @@ -25,15 +24,14 @@ struct CIImageView: View { if let uiImage = getLoadedImage(file) { imageView(uiImage) .fullScreenCover(isPresented: $showFullScreenImage) { - FullScreenMediaView(chatItem: chatItem, image: uiImage, showView: $showFullScreenImage, scrollProxy: scrollProxy) + FullScreenMediaView(chatItem: chatItem, image: uiImage, showView: $showFullScreenImage) } .onTapGesture { showFullScreenImage = true } .onChange(of: m.activeCallViewIsCollapsed) { _ in showFullScreenImage = false } - } else if let data = Data(base64Encoded: dropImagePrefix(image)), - let uiImage = UIImage(data: data) { - imageView(uiImage) + } else if let preview { + imageView(preview) .onTapGesture { if let file = file { switch file.fileStatus { @@ -90,7 +88,6 @@ struct CIImageView: View { private func imageView(_ img: UIImage) -> some View { let w = img.size.width <= img.size.height ? maxWidth * 0.75 : maxWidth - DispatchQueue.main.async { imgWidth = w } return ZStack(alignment: .topTrailing) { if img.imageData == nil { Image(uiImage: img) diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIVideoView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIVideoView.swift index d84ad8f5fc..055a235970 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIVideoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIVideoView.swift @@ -15,14 +15,12 @@ struct CIVideoView: View { @EnvironmentObject var m: ChatModel @Environment(\.colorScheme) var colorScheme private let chatItem: ChatItem - private let image: String + private let preview: UIImage? @State private var duration: Int @State private var progress: Int = 0 @State private var videoPlaying: Bool = false private let maxWidth: CGFloat - @Binding private var videoWidth: CGFloat? - @State private var scrollProxy: ScrollViewProxy? - @State private var preview: UIImage? = nil + private var videoWidth: CGFloat? @State private var player: AVPlayer? @State private var fullPlayer: AVPlayer? @State private var url: URL? @@ -33,13 +31,12 @@ struct CIVideoView: View { @State private var fullScreenTimeObserver: Any? = nil @State private var publisher: AnyCancellable? = nil - init(chatItem: ChatItem, image: String, duration: Int, maxWidth: CGFloat, videoWidth: Binding, scrollProxy: ScrollViewProxy?) { + init(chatItem: ChatItem, preview: UIImage?, duration: Int, maxWidth: CGFloat, videoWidth: CGFloat?) { self.chatItem = chatItem - self.image = image + self.preview = preview self._duration = State(initialValue: duration) self.maxWidth = maxWidth - self._videoWidth = videoWidth - self.scrollProxy = scrollProxy + self.videoWidth = videoWidth if let url = getLoadedVideo(chatItem.file) { let decrypted = chatItem.file?.fileSource?.cryptoArgs == nil ? url : chatItem.file?.fileSource?.decryptedGet() self._urlDecrypted = State(initialValue: decrypted) @@ -49,10 +46,6 @@ struct CIVideoView: View { } self._url = State(initialValue: url) } - if let data = Data(base64Encoded: dropImagePrefix(image)), - let uiImage = UIImage(data: data) { - self._preview = State(initialValue: uiImage) - } } var body: some View { @@ -63,9 +56,8 @@ struct CIVideoView: View { videoView(player, decrypted, file, preview, duration) } else if let file = file, let defaultPreview = preview, file.loaded && urlDecrypted == nil { videoViewEncrypted(file, defaultPreview, duration) - } else if let data = Data(base64Encoded: dropImagePrefix(image)), - let uiImage = UIImage(data: data) { - imageView(uiImage) + } else if let preview { + imageView(preview) .onTapGesture { if let file = file { switch file.fileStatus { @@ -152,7 +144,6 @@ struct CIVideoView: View { private func videoView(_ player: AVPlayer, _ url: URL, _ file: CIFile, _ preview: UIImage, _ duration: Int) -> some View { let w = preview.size.width <= preview.size.height ? maxWidth * 0.75 : maxWidth - DispatchQueue.main.async { videoWidth = w } return ZStack(alignment: .topTrailing) { ZStack(alignment: .center) { let canBePlayed = !chatItem.chatDir.sent || file.fileStatus == CIFileStatus.sndComplete || (file.fileStatus == .sndStored && file.fileProtocol == .local) @@ -252,7 +243,6 @@ struct CIVideoView: View { private func imageView(_ img: UIImage) -> some View { let w = img.size.width <= img.size.height ? maxWidth * 0.75 : maxWidth - DispatchQueue.main.async { videoWidth = w } return ZStack(alignment: .topTrailing) { Image(uiImage: img) .resizable() diff --git a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift index 9b4cecf526..f8c5f3a4da 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift @@ -18,15 +18,16 @@ private let sentQuoteColorDark = Color(.sRGB, red: 0.27, green: 0.72, blue: 1, o struct FramedItemView: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var scrollModel: ReverseListScrollModel @Environment(\.colorScheme) var colorScheme @ObservedObject var chat: Chat var chatItem: ChatItem + var preview: UIImage? @Binding var revealed: Bool var maxWidth: CGFloat = .infinity - @State var scrollProxy: ScrollViewProxy? = nil @State var msgWidth: CGFloat = 0 - @State var imgWidth: CGFloat? = nil - @State var videoWidth: CGFloat? = nil + var imgWidth: CGFloat? = nil + var videoWidth: CGFloat? = nil @State var metaColor = Color.secondary @State var showFullScreenImage = false @Binding var allowMenu: Bool @@ -58,10 +59,9 @@ struct FramedItemView: View { if let qi = chatItem.quotedItem { ciQuoteView(qi) .onTapGesture { - if let proxy = scrollProxy, - let ci = m.reversedChatItems.first(where: { $0.id == qi.itemId }) { + if let ci = m.reversedChatItems.first(where: { $0.id == qi.itemId }) { withAnimation { - proxy.scrollTo(ci.viewId, anchor: .bottom) + scrollModel.scrollToItem(id: ci.id) } } } @@ -84,6 +84,7 @@ struct FramedItemView: View { } } .background(chatItemFrameColorMaybeImageOrVideo(chatItem, colorScheme)) + .background(Color(.systemBackground)) .cornerRadius(18) .onPreferenceChange(DetermineWidth.Key.self) { msgWidth = $0 } @@ -114,8 +115,8 @@ struct FramedItemView: View { .padding(.bottom, 2) } else { switch (chatItem.content.msgContent) { - case let .image(text, image): - CIImageView(chatItem: chatItem, image: image, maxWidth: maxWidth, imgWidth: $imgWidth, scrollProxy: scrollProxy) + case let .image(text, _): + CIImageView(chatItem: chatItem, preview: preview, maxWidth: maxWidth, imgWidth: imgWidth) .overlay(DetermineWidth()) if text == "" && !chatItem.meta.isLive { Color.clear @@ -127,8 +128,8 @@ struct FramedItemView: View { } else { ciMsgContentView(chatItem) } - case let .video(text, image, duration): - CIVideoView(chatItem: chatItem, image: image, duration: duration, maxWidth: maxWidth, videoWidth: $videoWidth, scrollProxy: scrollProxy) + case let .video(text, _, duration): + CIVideoView(chatItem: chatItem, preview: preview, duration: duration, maxWidth: maxWidth, videoWidth: videoWidth) .overlay(DetermineWidth()) if text == "" && !chatItem.meta.isLive { Color.clear @@ -181,7 +182,6 @@ struct FramedItemView: View { .padding(.bottom, pad || (chatItem.quotedItem == nil && chatItem.meta.itemForwarded == nil) ? 6 : 0) .overlay(DetermineWidth()) .frame(minWidth: msgWidth, alignment: .leading) - .background(chatItemFrameContextColor(chatItem, colorScheme)) if let mediaWidth = maxMediaWidth(), mediaWidth < maxWidth { v.frame(maxWidth: mediaWidth, alignment: .leading) } else { diff --git a/apps/ios/Shared/Views/Chat/ChatItem/FullScreenMediaView.swift b/apps/ios/Shared/Views/Chat/ChatItem/FullScreenMediaView.swift index 0e721acdcb..a80c5412b6 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/FullScreenMediaView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/FullScreenMediaView.swift @@ -13,12 +13,12 @@ import AVKit struct FullScreenMediaView: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var scrollModel: ReverseListScrollModel @State var chatItem: ChatItem @State var image: UIImage? @State var player: AVPlayer? = nil @State var url: URL? = nil @Binding var showView: Bool - @State var scrollProxy: ScrollViewProxy? @State private var showNext = false @State private var nextImage: UIImage? @State private var nextPlayer: AVPlayer? @@ -71,9 +71,7 @@ struct FullScreenMediaView: View { let w = abs(t.width) if t.height > 60 && t.height > w * 2 { showView = false - if let proxy = scrollProxy { - proxy.scrollTo(chatItem.viewId) - } + scrollModel.scrollToItem(id: chatItem.id) } else if w > 60 && w > abs(t.height) * 2 && !scrolling { let previous = t.width > 0 scrolling = true diff --git a/apps/ios/Shared/Views/Chat/ChatItemView.swift b/apps/ios/Shared/Views/Chat/ChatItemView.swift index d580fb5f3e..a0c8254496 100644 --- a/apps/ios/Shared/Views/Chat/ChatItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItemView.swift @@ -13,7 +13,6 @@ struct ChatItemView: View { @ObservedObject var chat: Chat var chatItem: ChatItem var maxWidth: CGFloat = .infinity - @State var scrollProxy: ScrollViewProxy? = nil @Binding var revealed: Bool @Binding var allowMenu: Bool @Binding var audioPlayer: AudioPlayer? @@ -24,7 +23,6 @@ struct ChatItemView: View { chatItem: ChatItem, showMember: Bool = false, maxWidth: CGFloat = .infinity, - scrollProxy: ScrollViewProxy? = nil, revealed: Binding, allowMenu: Binding = .constant(false), audioPlayer: Binding = .constant(nil), @@ -34,7 +32,6 @@ struct ChatItemView: View { self.chat = chat self.chatItem = chatItem self.maxWidth = maxWidth - _scrollProxy = .init(initialValue: scrollProxy) _revealed = revealed _allowMenu = allowMenu _audioPlayer = audioPlayer @@ -62,7 +59,37 @@ struct ChatItemView: View { } private func framedItemView() -> some View { - FramedItemView(chat: chat, chatItem: chatItem, revealed: $revealed, maxWidth: maxWidth, scrollProxy: scrollProxy, allowMenu: $allowMenu, audioPlayer: $audioPlayer, playbackState: $playbackState, playbackTime: $playbackTime) + let preview = chatItem.content.msgContent + .flatMap { + switch $0 { + case let .image(_, image): image + case let .video(_, image, _): image + default: nil + } + } + .map { dropImagePrefix($0) } + .flatMap { Data(base64Encoded: $0) } + .flatMap { UIImage(data: $0) } + let adjustedMaxWidth = { + if let preview, preview.size.width <= preview.size.height { + maxWidth * 0.75 + } else { + maxWidth + } + }() + return FramedItemView( + chat: chat, + chatItem: chatItem, + preview: preview, + revealed: $revealed, + maxWidth: maxWidth, + imgWidth: adjustedMaxWidth, + videoWidth: adjustedMaxWidth, + allowMenu: $allowMenu, + audioPlayer: $audioPlayer, + playbackState: $playbackState, + playbackTime: $playbackTime + ) } } diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index 27eb3bd653..7ab4913bf3 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -9,6 +9,7 @@ import SwiftUI import SimpleXChat import SwiftyGif +import Combine private let memberImageSize: CGFloat = 34 @@ -19,6 +20,8 @@ struct ChatView: View { @Environment(\.presentationMode) var presentationMode @Environment(\.scenePhase) var scenePhase @State @ObservedObject var chat: Chat + @StateObject private var scrollModel = ReverseListScrollModel() + @StateObject private var floatingButtonModel = FloatingButtonModel() @State private var showChatInfoSheet: Bool = false @State private var showAddMembersSheet: Bool = false @State private var composeState = ComposeState() @@ -26,11 +29,9 @@ struct ChatView: View { @State private var connectionStats: ConnectionStats? @State private var customUserProfile: Profile? @State private var connectionCode: String? - @State private var tableView: UITableView? @State private var loadingItems = false @State private var firstPage = false - @State private var itemsInView: Set = [] - @State private var scrollProxy: ScrollViewProxy? + @State private var revealedChatItem: ChatItem? @State private var searchMode = false @State private var searchText: String = "" @FocusState private var searchFocussed @@ -59,15 +60,10 @@ struct ChatView: View { searchToolbar() Divider() } - ZStack(alignment: .trailing) { + ZStack(alignment: .bottomTrailing) { chatItemsList() - if let proxy = scrollProxy { - floatingButtons(proxy) - } + floatingButtons(counts: floatingButtonModel.unreadChatItemCounts) } - - Spacer(minLength: 0) - connectingText() ComposeView( chat: chat, @@ -80,6 +76,7 @@ struct ChatView: View { .navigationTitle(cInfo.chatViewName) .navigationBarTitleDisplayMode(.inline) .onAppear { + loadChat(chat: chat) initChatView() } .onChange(of: chatModel.chatId) { cId in @@ -93,6 +90,15 @@ struct ChatView: View { dismiss() } } + .onChange(of: revealedChatItem) { _ in + NotificationCenter.postReverseListNeedsLayout() + } + .onChange(of: chatModel.reversedChatItems) { reversedChatItems in + if reversedChatItems.count <= loadItemsPerPage && filtered(reversedChatItems).count < 10 { + loadChatItems(chat.chatInfo) + } + } + .environmentObject(scrollModel) .onDisappear { VideoPlayerView.players.removeAll() if chatModel.chatId == cInfo.id && !presentationMode.wrappedValue.isPresented { @@ -291,7 +297,6 @@ struct ChatView: View { searchMode = false searchFocussed = false DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) { - chatModel.reversedChatItems = [] loadChat(chat: chat) } } @@ -299,50 +304,49 @@ struct ChatView: View { .padding(.horizontal) .padding(.vertical, 8) } - + private func voiceWithoutFrame(_ ci: ChatItem) -> Bool { ci.content.msgContent?.isVoice == true && ci.content.text.count == 0 && ci.quotedItem == nil && ci.meta.itemForwarded == nil } + private func filtered(_ reversedChatItems: Array) -> Array { + reversedChatItems + .enumerated() + .filter { (index, chatItem) in + if let mergeCategory = chatItem.mergeCategory, index > .zero { + mergeCategory != reversedChatItems[index - 1].mergeCategory + } else { + true + } + } + .map { $0.element } + } + + private func chatItemsList() -> some View { let cInfo = chat.chatInfo + let mergedItems = filtered(chatModel.reversedChatItems) return GeometryReader { g in - ScrollViewReader { proxy in - ScrollView { - LazyVStack(spacing: 0) { - ForEach(chatModel.reversedChatItems, id: \.viewId) { ci in - let voiceNoFrame = voiceWithoutFrame(ci) - let maxWidth = cInfo.chatType == .group - ? voiceNoFrame - ? (g.size.width - 28) - 42 - : (g.size.width - 28) * 0.84 - 42 - : voiceNoFrame - ? (g.size.width - 32) - : (g.size.width - 32) * 0.84 - chatItemView(ci, maxWidth) - .scaleEffect(x: 1, y: -1, anchor: .center) - .onAppear { - itemsInView.insert(ci.viewId) - loadChatItems(cInfo, ci, proxy) - if ci.isRcvNew { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) { - if chatModel.chatId == cInfo.id && itemsInView.contains(ci.viewId) { - Task { - await apiMarkChatItemRead(cInfo, ci) - } - } - } - } - } - .onDisappear { - itemsInView.remove(ci.viewId) - } - } + ReverseList(items: mergedItems, scrollState: $scrollModel.state) { ci in + let voiceNoFrame = voiceWithoutFrame(ci) + let maxWidth = cInfo.chatType == .group + ? voiceNoFrame + ? (g.size.width - 28) - 42 + : (g.size.width - 28) * 0.84 - 42 + : voiceNoFrame + ? (g.size.width - 32) + : (g.size.width - 32) * 0.84 + return chatItemView(ci, maxWidth) + .onAppear { + floatingButtonModel.appeared(viewId: ci.viewId) } - } - .onAppear { - scrollProxy = proxy - } + .onDisappear { + floatingButtonModel.disappeared(viewId: ci.viewId) + } + .id(ci.id) // Required to trigger `onAppear` on iOS15 + } loadPage: { + loadChatItems(cInfo) + } .onTapGesture { hideKeyboard() } .onChange(of: searchText) { _ in loadChat(chat: chat, search: searchText) @@ -352,14 +356,12 @@ struct ChatView: View { chat = c showChatInfoSheet = false loadChat(chat: c) - DispatchQueue.main.async { - scrollToBottom(proxy) - } } } - } + .onChange(of: chatModel.reversedChatItems) { _ in + floatingButtonModel.chatItemsChanged() + } } - .scaleEffect(x: 1, y: -1, anchor: .center) } @ViewBuilder private func connectingText() -> some View { @@ -375,10 +377,58 @@ struct ChatView: View { EmptyView() } } - - private func floatingButtons(_ proxy: ScrollViewProxy) -> some View { - let counts = chatModel.unreadChatItemCounts(itemsInView: itemsInView) - return VStack { + + class FloatingButtonModel: ObservableObject { + private enum Event { + case appeared(String) + case disappeared(String) + case chatItemsChanged + } + + @Published var unreadChatItemCounts: UnreadChatItemCounts + + private let events = PassthroughSubject() + private var bag = Set() + + init() { + unreadChatItemCounts = UnreadChatItemCounts( + totalBelow: .zero, + unreadBelow: .zero + ) + events + .receive(on: DispatchQueue.global(qos: .background)) + .scan(Set()) { itemsInView, event in + return switch event { + case let .appeared(viewId): + itemsInView.union([viewId]) + case let .disappeared(viewId): + itemsInView.subtracting([viewId]) + case .chatItemsChanged: + itemsInView + } + } + .throttle(for: .seconds(0.2), scheduler: DispatchQueue.main, latest: true) + .map { ChatModel.shared.unreadChatItemCounts(itemsInView: $0) } + .removeDuplicates() + .assign(to: \.unreadChatItemCounts, on: self) + .store(in: &bag) + } + + func appeared(viewId: String) { + events.send(.appeared(viewId)) + } + + func disappeared(viewId: String) { + events.send(.disappeared(viewId)) + } + + func chatItemsChanged() { + events.send(.chatItemsChanged) + } + } + + private func floatingButtons(counts: UnreadChatItemCounts) -> some View { + VStack { let unreadAbove = chat.chatStats.unreadCount - counts.unreadBelow if unreadAbove > 0 { circleButton { @@ -386,13 +436,13 @@ struct ChatView: View { .font(.callout) .foregroundColor(.accentColor) } - .onTapGesture { scrollUp(proxy) } + .onTapGesture { + scrollModel.scrollToNextPage() + } .contextMenu { Button { - if let ci = chatModel.topItemInView(itemsInView: itemsInView) { - Task { - await markChatRead(chat, aboveItem: ci) - } + Task { + await markChatRead(chat) } } label: { Label("Mark read", systemImage: "checkmark") @@ -406,18 +456,22 @@ struct ChatView: View { .font(.callout) .foregroundColor(.accentColor) } - .onTapGesture { scrollToBottom(proxy) } + .onTapGesture { + if let latestUnreadItem = filtered(chatModel.reversedChatItems).last(where: { $0.isRcvNew }) { + scrollModel.scrollToItem(id: latestUnreadItem.id) + } + } } else if counts.totalBelow > 16 { circleButton { Image(systemName: "chevron.down") .foregroundColor(.accentColor) } - .onTapGesture { scrollToBottom(proxy) } + .onTapGesture { scrollModel.scrollToBottom() } } } .padding() } - + private func circleButton(_ content: @escaping () -> Content) -> some View { ZStack { Circle() @@ -426,7 +480,7 @@ struct ChatView: View { content() } } - + private func callButton(_ contact: Contact, _ media: CallMediaType, imageName: String) -> some View { Button { CallController.shared.startCall(contact, media) @@ -456,7 +510,7 @@ struct ChatView: View { Label("Search", systemImage: "magnifyingglass") } } - + private func addMembersButton() -> some View { Button { if case let .group(gInfo) = chat.chatInfo { @@ -486,34 +540,45 @@ struct ChatView: View { } } - private func loadChatItems(_ cInfo: ChatInfo, _ ci: ChatItem, _ proxy: ScrollViewProxy) { - if let firstItem = chatModel.reversedChatItems.last, firstItem.id == ci.id { + private func loadChatItems(_ cInfo: ChatInfo) { + Task { if loadingItems || firstPage { return } loadingItems = true - Task { - do { - let items = try await apiGetChatItems( + do { + var reversedPage = Array() + var chatItemsAvailable = true + // Load additional items until the page is +50 large after merging + while chatItemsAvailable && filtered(reversedPage).count < loadItemsPerPage { + let pagination: ChatPagination = + if let lastItem = reversedPage.last ?? chatModel.reversedChatItems.last { + .before(chatItemId: lastItem.id, count: loadItemsPerPage) + } else { + .last(count: loadItemsPerPage) + } + let chatItems = try await apiGetChatItems( type: cInfo.chatType, id: cInfo.apiId, - pagination: .before(chatItemId: firstItem.id, count: 50), + pagination: pagination, search: searchText ) - await MainActor.run { - if items.count == 0 { - firstPage = true - } else { - chatModel.reversedChatItems.append(contentsOf: items.reversed()) - } - loadingItems = false - } - } catch let error { - logger.error("apiGetChat error: \(responseError(error))") - await MainActor.run { loadingItems = false } + chatItemsAvailable = !chatItems.isEmpty + reversedPage.append(contentsOf: chatItems.reversed()) } + await MainActor.run { + if reversedPage.count == 0 { + firstPage = true + } else { + chatModel.reversedChatItems.append(contentsOf: reversedPage) + } + loadingItems = false + } + } catch let error { + logger.error("apiGetChat error: \(responseError(error))") + await MainActor.run { loadingItems = false } } } } - + @ViewBuilder private func chatItemView(_ ci: ChatItem, _ maxWidth: CGFloat) -> some View { ChatItemWithMenu( chat: chat, @@ -522,6 +587,7 @@ struct ChatView: View { itemWidth: maxWidth, composeState: $composeState, selectedMember: $selectedMember, + revealedChatItem: $revealedChatItem, chatView: self ) } @@ -535,13 +601,13 @@ struct ChatView: View { @State var itemWidth: CGFloat @Binding var composeState: ComposeState @Binding var selectedMember: GMember? + @Binding var revealedChatItem: ChatItem? var chatView: ChatView @State private var deletingItem: ChatItem? = nil @State private var showDeleteMessage = false @State private var deletingItems: [Int64] = [] @State private var showDeleteMessages = false - @State private var revealed = false @State private var showChatItemInfoSheet: Bool = false @State private var chatItemInfo: ChatItemInfo? @State private var showForwardingSheet: Bool = false @@ -552,15 +618,14 @@ struct ChatView: View { @State private var playbackState: VoiceMessagePlaybackState = .noPlayback @State private var playbackTime: TimeInterval? + var revealed: Bool { chatItem == revealedChatItem } + var body: some View { - let (currIndex, nextItem) = m.getNextChatItem(chatItem) + let (currIndex, _) = m.getNextChatItem(chatItem) let ciCategory = chatItem.mergeCategory - if (ciCategory != nil && ciCategory == nextItem?.mergeCategory) { - // memberConnected events and deleted items are aggregated at the last chat item in a row, see ChatItemView - ZStack {} // scroll doesn't work if it's EmptyView() - } else { - let (prevHidden, prevItem) = m.getPrevShownChatItem(currIndex, ciCategory) - let range = itemsRange(currIndex, prevHidden) + let (prevHidden, prevItem) = m.getPrevShownChatItem(currIndex, ciCategory) + let range = itemsRange(currIndex, prevHidden) + Group { if revealed, let range = range { let items = Array(zip(Array(range), m.reversedChatItems[range])) ForEach(items, id: \.1.viewId) { (i, ci) in @@ -568,11 +633,26 @@ struct ChatView: View { chatItemView(ci, nil, prev) } } else { - // 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) + chatItemView(chatItem, range, prevItem) + } + } + .onAppear { + markRead( + chatItems: range.flatMap { m.reversedChatItems[$0] } + ?? [chatItem] + ) + } + } + + private func markRead(chatItems: Array.SubSequence) { + let unreadItems = chatItems.filter { $0.isRcvNew } + if unreadItems.isEmpty { return } + DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) { + if m.chatId == chat.chatInfo.id { + Task { + for unreadItem in unreadItems { + await apiMarkChatItemRead(chat.chatInfo, unreadItem) + } } } } @@ -645,24 +725,18 @@ struct ChatView: View { @ViewBuilder func chatItemWithMenu(_ ci: ChatItem, _ range: ClosedRange?, _ maxWidth: CGFloat) -> some View { let alignment: Alignment = ci.chatDir.sent ? .trailing : .leading - let uiMenu: Binding = Binding( - get: { UIMenu(title: "", children: menu(ci, range, live: composeState.liveMessage != nil)) }, - set: { _ in } - ) - VStack(alignment: alignment.horizontal, spacing: 3) { ChatItemView( chat: chat, chatItem: ci, maxWidth: maxWidth, - scrollProxy: chatView.scrollProxy, - revealed: $revealed, + revealed: .constant(revealed), allowMenu: $allowMenu, audioPlayer: $audioPlayer, playbackState: $playbackState, playbackTime: $playbackTime ) - .uiKitContextMenu(hasImageOrVideo: ci.content.msgContent?.isImageOrVideo == true, maxWidth: maxWidth, itemWidth: $itemWidth, menu: uiMenu, allowMenu: $allowMenu) + .contextMenu { menu(ci, range, live: composeState.liveMessage != nil) } .accessibilityLabel("") if ci.content.msgContent != nil && (ci.meta.itemDeleted == nil || revealed) && ci.reactions.count > 0 { chatItemReactions(ci) @@ -746,149 +820,152 @@ struct ChatView: View { } } - private func menu(_ ci: ChatItem, _ range: ClosedRange?, live: Bool) -> [UIMenuElement] { - var menu: [UIMenuElement] = [] + @ViewBuilder + private func menu(_ ci: ChatItem, _ range: ClosedRange?, live: Bool) -> some View { if let mc = ci.content.msgContent, ci.meta.itemDeleted == nil || revealed { - let rs = allReactions(ci) if chat.chatInfo.featureEnabled(.reactions) && ci.allowAddReaction, - rs.count > 0 { - var rm: UIMenu - if #available(iOS 16, *) { - var children: [UIMenuElement] = Array(rs.prefix(topReactionsCount(rs))) - if let sm = reactionUIMenu(rs) { - children.append(sm) - } - rm = UIMenu(title: "", options: .displayInline, children: children) - rm.preferredElementSize = .small - } else { - rm = reactionUIMenuPreiOS16(rs) - } - menu.append(rm) + availableReactions.count > 0 { + reactionsGroup } if ci.meta.itemDeleted == nil && !ci.isLiveDummy && !live && !ci.localNote { - menu.append(replyUIAction(ci)) + replyButton } let fileSource = getLoadedFileSource(ci.file) let fileExists = if let fs = fileSource, FileManager.default.fileExists(atPath: getAppFilePath(fs.filePath).path) { true } else { false } let copyAndShareAllowed = !ci.content.text.isEmpty || (ci.content.msgContent?.isImage == true && fileExists) if copyAndShareAllowed { - menu.append(shareUIAction(ci)) - menu.append(copyUIAction(ci)) + shareButton(ci) + copyButton(ci) } if let fileSource = fileSource, fileExists { if case .image = ci.content.msgContent, let image = getLoadedImage(ci.file) { if image.imageData != nil { - menu.append(saveFileAction(fileSource)) + saveButton(file: fileSource) } else { - menu.append(saveImageAction(image)) + saveButton(image: image) } } else { - menu.append(saveFileAction(fileSource)) + saveButton(file: fileSource) } } else if let file = ci.file, case .rcvInvitation = file.fileStatus, fileSizeValid(file) { - menu.append(downloadFileAction(file)) + downloadButton(file: file) } if ci.meta.editable && !mc.isVoice && !live { - menu.append(editAction(ci)) + editButton(chatItem) } if ci.meta.itemDeleted == nil && (ci.file == nil || (fileSource != nil && fileExists)) && !ci.isLiveDummy && !live { - menu.append(forwardUIAction(ci)) + forwardButton } if !ci.isLiveDummy { - menu.append(viewInfoUIAction(ci)) + viewInfoButton(ci) } if revealed { - menu.append(hideUIAction()) + hideButton() } if ci.meta.itemDeleted == nil && !ci.localNote, let file = ci.file, let cancelAction = file.cancelAction { - menu.append(cancelFileUIAction(file.fileId, cancelAction)) + cancelFileButton(file.fileId, cancelAction) } if !live || !ci.meta.isLive { - menu.append(deleteUIAction(ci)) + deleteButton(ci) } if let (groupInfo, _) = ci.memberToModerate(chat.chatInfo) { - menu.append(moderateUIAction(ci, groupInfo)) + moderateButton(ci, groupInfo) } } else if ci.meta.itemDeleted != nil { if revealed { - menu.append(hideUIAction()) + hideButton() } else if !ci.isDeletedContent { - menu.append(revealUIAction()) + revealButton(ci) } else if range != nil { - menu.append(expandUIAction()) + expandButton() } - menu.append(viewInfoUIAction(ci)) - menu.append(deleteUIAction(ci)) + viewInfoButton(ci) + deleteButton(ci) } else if ci.isDeletedContent { - menu.append(viewInfoUIAction(ci)) - menu.append(deleteUIAction(ci)) + viewInfoButton(ci) + deleteButton(ci) } else if ci.mergeCategory != nil && ((range?.count ?? 0) > 1 || revealed) { - menu.append(revealed ? shrinkUIAction() : expandUIAction()) - menu.append(deleteUIAction(ci)) + if revealed { shrinkButton() } else { expandButton() } + deleteButton(ci) } else if ci.showLocalDelete { - menu.append(deleteUIAction(ci)) + deleteButton(ci) + } else { + EmptyView() } - return menu } - - private func replyUIAction(_ ci: ChatItem) -> UIAction { - UIAction( - title: NSLocalizedString("Reply", comment: "chat item action"), - image: UIImage(systemName: "arrowshape.turn.up.left") - ) { _ in + + var replyButton: Button { + Button { withAnimation { if composeState.editing { - composeState = ComposeState(contextItem: .quotedItem(chatItem: ci)) + composeState = ComposeState(contextItem: .quotedItem(chatItem: chatItem)) } else { - composeState = composeState.copy(contextItem: .quotedItem(chatItem: ci)) + composeState = composeState.copy(contextItem: .quotedItem(chatItem: chatItem)) } } + } label: { + Label( + NSLocalizedString("Reply", comment: "chat item action"), + systemImage: "arrowshape.turn.up.left" + ) + } + } + + var forwardButton: Button { + Button { + showForwardingSheet = true + } label: { + Label( + NSLocalizedString("Forward", comment: "chat item action"), + systemImage: "arrowshape.turn.up.forward" + ) + } + } + + private var reactionsGroup: some View { + if #available(iOS 16.4, *) { + return ControlGroup { + if availableReactions.count > 4 { + reactions(till: 3) + Menu { + reactions(from: 3) + } label: { + Image(systemName: "ellipsis") + } + } else { reactions() } + }.controlGroupStyle(.compactMenu) + } else { + return Menu { + reactions() + } label: { + Label( + NSLocalizedString("React…", comment: "chat item menu"), + systemImage: "face.smiling" + ) + } } } - private func forwardUIAction(_ ci: ChatItem) -> UIAction { - UIAction( - title: NSLocalizedString("Forward", comment: "chat item action"), - image: UIImage(systemName: "arrowshape.turn.up.forward") - ) { _ in - showForwardingSheet = true + func reactions(from: Int? = nil, till: Int? = nil) -> some View { + ForEach(availableReactions[(from ?? .zero)..<(till ?? availableReactions.count)]) { reaction in + Button(reaction.text) { + setReaction(chatItem, add: true, reaction: reaction) + } } } - private func reactionUIMenuPreiOS16(_ rs: [UIAction]) -> UIMenu { - UIMenu( - title: NSLocalizedString("React…", comment: "chat item menu"), - image: UIImage(systemName: "face.smiling"), - children: rs - ) - } - - @available(iOS 16.0, *) - private func reactionUIMenu(_ rs: [UIAction]) -> UIMenu? { - var children = rs - children.removeFirst(min(rs.count, topReactionsCount(rs))) - if children.count == 0 { return nil } - return UIMenu( - title: "", - image: UIImage(systemName: "ellipsis"), - children: children - ) - } - - private func allReactions(_ ci: ChatItem) -> [UIAction] { - MsgReaction.values.compactMap { r in - ci.reactions.contains(where: { $0.userReacted && $0.reaction == r }) - ? nil - : UIAction(title: r.text) { _ in setReaction(ci, add: true, reaction: r) } - } - } - - private func topReactionsCount(_ rs: [UIAction]) -> Int { - rs.count > 4 ? 3 : 4 + /// Reactions, which has not been used yet + private var availableReactions: Array { + MsgReaction.values + .filter { reaction in + !chatItem.reactions.contains { + $0.userReacted && $0.reaction == reaction + } + } } private func setReaction(_ ci: ChatItem, add: Bool, reaction: MsgReaction) { @@ -911,24 +988,23 @@ struct ChatView: View { } } - private func shareUIAction(_ ci: ChatItem) -> UIAction { - UIAction( - title: NSLocalizedString("Share", comment: "chat item action"), - image: UIImage(systemName: "square.and.arrow.up") - ) { _ in + private func shareButton(_ ci: ChatItem) -> Button { + Button { var shareItems: [Any] = [ci.content.text] if case .image = ci.content.msgContent, let image = getLoadedImage(ci.file) { shareItems.append(image) } showShareSheet(items: shareItems) + } label: { + Label( + NSLocalizedString("Share", comment: "chat item action"), + systemImage: "square.and.arrow.up" + ) } } - - private func copyUIAction(_ ci: ChatItem) -> UIAction { - UIAction( - title: NSLocalizedString("Copy", comment: "chat item action"), - image: UIImage(systemName: "doc.on.doc") - ) { _ in + + private func copyButton(_ ci: ChatItem) -> Button { + Button { if case let .image(text, _) = ci.content.msgContent, text == "", let image = getLoadedImage(ci.file) { @@ -936,57 +1012,64 @@ struct ChatView: View { } else { UIPasteboard.general.string = ci.content.text } - } - } - - private func saveImageAction(_ image: UIImage) -> UIAction { - UIAction( - title: NSLocalizedString("Save", comment: "chat item action"), - image: UIImage(systemName: "square.and.arrow.down") - ) { _ in - UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) - } - } - - private func saveFileAction(_ fileSource: CryptoFile) -> UIAction { - UIAction( - title: NSLocalizedString("Save", comment: "chat item action"), - image: UIImage(systemName: fileSource.cryptoArgs == nil ? "square.and.arrow.down" : "lock.open") - ) { _ in - saveCryptoFile(fileSource) + } label: { + Label("Copy", systemImage: "doc.on.doc") } } - private func downloadFileAction(_ file: CIFile) -> UIAction { - UIAction( - title: NSLocalizedString("Download", comment: "chat item action"), - image: UIImage(systemName: "arrow.down.doc") - ) { _ in + func saveButton(image: UIImage) -> Button { + Button { + UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) + } label: { + Label( + NSLocalizedString("Save", comment: "chat item action"), + systemImage: "square.and.arrow.down" + ) + } + } + + func saveButton(file: CryptoFile) -> Button { + Button { + saveCryptoFile(file) + } label: { + Label( + NSLocalizedString("Save", comment: "chat item action"), + systemImage: file.cryptoArgs == nil ? "square.and.arrow.down" : "lock.open" + ) + } + } + + func downloadButton(file: CIFile) -> Button { + Button { Task { logger.debug("ChatView downloadFileAction, in Task") if let user = m.currentUser { await receiveFile(user: user, fileId: file.fileId) } } + } label: { + Label( + NSLocalizedString("Download", comment: "chat item action"), + systemImage: "arrow.down.doc" + ) } } - private func editAction(_ ci: ChatItem) -> UIAction { - UIAction( - title: NSLocalizedString("Edit", comment: "chat item action"), - image: UIImage(systemName: "square.and.pencil") - ) { _ in + private func editButton(_ ci: ChatItem) -> Button { + Button { withAnimation { composeState = ComposeState(editingItem: ci) } + } label: { + Label( + NSLocalizedString("Edit", comment: "chat item action"), + systemImage: "square.and.pencil" + ) } } - private func viewInfoUIAction(_ ci: ChatItem) -> UIAction { - UIAction( - title: NSLocalizedString("Info", comment: "chat item action"), - image: UIImage(systemName: "info.circle") - ) { _ in + private func viewInfoButton(_ ci: ChatItem) -> Button { + Button { Task { do { let cInfo = chat.chatInfo @@ -1002,15 +1085,16 @@ struct ChatView: View { } await MainActor.run { showChatItemInfoSheet = true } } + } label: { + Label( + NSLocalizedString("Info", comment: "chat item action"), + systemImage: "info.circle" + ) } } - private func cancelFileUIAction(_ fileId: Int64, _ cancelAction: CancelAction) -> UIAction { - return UIAction( - title: cancelAction.uiAction, - image: UIImage(systemName: "xmark"), - attributes: [.destructive] - ) { _ in + private func cancelFileButton(_ fileId: Int64, _ cancelAction: CancelAction) -> Button { + Button { AlertManager.shared.showAlert(Alert( title: Text(cancelAction.alert.title), message: Text(cancelAction.alert.message), @@ -1023,26 +1107,29 @@ struct ChatView: View { }, secondaryButton: .cancel() )) + } label: { + Label( + cancelAction.uiAction, + systemImage: "xmark" + ) } } - private func hideUIAction() -> UIAction { - UIAction( - title: NSLocalizedString("Hide", comment: "chat item action"), - image: UIImage(systemName: "eye.slash") - ) { _ in - withAnimation { - revealed = false + private func hideButton() -> Button { + Button { + withConditionalAnimation { + revealedChatItem = nil } + } label: { + Label( + NSLocalizedString("Hide", comment: "chat item action"), + systemImage: "eye.slash" + ) } } - - private func deleteUIAction(_ ci: ChatItem) -> UIAction { - UIAction( - title: NSLocalizedString("Delete", comment: "chat item action"), - image: UIImage(systemName: "trash"), - attributes: [.destructive] - ) { _ in + + private func deleteButton(_ ci: ChatItem) -> Button { + Button(role: .destructive) { if !revealed, let currIndex = m.getChatItemIndex(ci), let ciCategory = ci.mergeCategory { @@ -1062,6 +1149,11 @@ struct ChatView: View { showDeleteMessage = true deletingItem = ci } + } label: { + Label( + NSLocalizedString("Delete", comment: "chat item action"), + systemImage: "trash" + ) } } @@ -1075,12 +1167,8 @@ struct ChatView: View { } } - private func moderateUIAction(_ ci: ChatItem, _ groupInfo: GroupInfo) -> UIAction { - UIAction( - title: NSLocalizedString("Moderate", comment: "chat item action"), - image: UIImage(systemName: "flag"), - attributes: [.destructive] - ) { _ in + private func moderateButton(_ ci: ChatItem, _ groupInfo: GroupInfo) -> Button { + Button(role: .destructive) { AlertManager.shared.showAlert(Alert( title: Text("Delete member message?"), message: Text( @@ -1094,39 +1182,50 @@ struct ChatView: View { }, secondaryButton: .cancel() )) + } label: { + Label( + NSLocalizedString("Moderate", comment: "chat item action"), + systemImage: "flag" + ) } } - private func revealUIAction() -> UIAction { - UIAction( - title: NSLocalizedString("Reveal", comment: "chat item action"), - image: UIImage(systemName: "eye") - ) { _ in - withAnimation { - revealed = true + private func revealButton(_ ci: ChatItem) -> Button { + Button { + withConditionalAnimation { + revealedChatItem = ci } + } label: { + Label( + NSLocalizedString("Reveal", comment: "chat item action"), + systemImage: "eye" + ) } } - private func expandUIAction() -> UIAction { - UIAction( - title: NSLocalizedString("Expand", comment: "chat item action"), - image: UIImage(systemName: "arrow.up.and.line.horizontal.and.arrow.down") - ) { _ in - withAnimation { - revealed = true + private func expandButton() -> Button { + Button { + withConditionalAnimation { + revealedChatItem = chatItem } + } label: { + Label( + NSLocalizedString("Expand", comment: "chat item action"), + systemImage: "arrow.up.and.line.horizontal.and.arrow.down" + ) } } - private func shrinkUIAction() -> UIAction { - UIAction( - title: NSLocalizedString("Hide", comment: "chat item action"), - image: UIImage(systemName: "arrow.down.and.line.horizontal.and.arrow.up") - ) { _ in - withAnimation { - revealed = false + private func shrinkButton() -> Button { + Button { + withConditionalAnimation { + revealedChatItem = nil } + } label: { + Label ( + NSLocalizedString("Hide", comment: "chat item action"), + systemImage: "arrow.down.and.line.horizontal.and.arrow.up" + ) } } @@ -1205,18 +1304,6 @@ struct ChatView: View { } } } - - private func scrollToBottom(_ proxy: ScrollViewProxy) { - if let ci = chatModel.reversedChatItems.first { - withAnimation { proxy.scrollTo(ci.viewId, anchor: .top) } - } - } - - private func scrollUp(_ proxy: ScrollViewProxy) { - if let ci = chatModel.topItemInView(itemsInView: itemsInView) { - withAnimation { proxy.scrollTo(ci.viewId, anchor: .top) } - } - } } struct ToggleNtfsButton: View { diff --git a/apps/ios/Shared/Views/Chat/ReverseList.swift b/apps/ios/Shared/Views/Chat/ReverseList.swift new file mode 100644 index 0000000000..f795b96b03 --- /dev/null +++ b/apps/ios/Shared/Views/Chat/ReverseList.swift @@ -0,0 +1,270 @@ +// +// ReverseList.swift +// SimpleX (iOS) +// +// Created by Levitating Pineapple on 11/06/2024. +// Copyright © 2024 SimpleX Chat. All rights reserved. +// + +import SwiftUI +import Combine + +/// A List, which displays it's items in reverse order - from bottom to top +struct ReverseList: UIViewControllerRepresentable { + + let items: Array + + @Binding var scrollState: ReverseListScrollModel.State + + /// Closure, that returns user interface for a given item + let content: (Item) -> Content + + let loadPage: () -> Void + + func makeUIViewController(context: Context) -> Controller { + Controller(representer: self) + } + + func updateUIViewController(_ controller: Controller, context: Context) { + if case let .scrollingTo(destination) = scrollState, !items.isEmpty { + switch destination { + case .nextPage: + controller.scrollToNextPage() + case let .item(id): + controller.scroll(to: items.firstIndex(where: { $0.id == id }), position: .bottom) + case .bottom: + controller.scroll(to: .zero, position: .top) + } + } else { + controller.update(items: items) + } + } + + /// Controller, which hosts SwiftUI cells + class Controller: UITableViewController { + private enum Section { case main } + private let representer: ReverseList + private var dataSource: UITableViewDiffableDataSource! + private var itemCount: Int = .zero + private var bag = Set() + + init(representer: ReverseList) { + self.representer = representer + super.init(style: .plain) + + // 1. Style + tableView.separatorStyle = .none + tableView.transform = .verticalFlip + + // 2. Register cells + if #available(iOS 16.0, *) { + tableView.register( + UITableViewCell.self, + forCellReuseIdentifier: cellReuseId + ) + } else { + tableView.register( + HostingCell.self, + forCellReuseIdentifier: cellReuseId + ) + } + + // 3. Configure data source + self.dataSource = UITableViewDiffableDataSource( + tableView: tableView + ) { (tableView, indexPath, item) -> UITableViewCell? in + if indexPath.item > self.itemCount - 8, self.itemCount > 8 { + self.representer.loadPage() + } + let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseId, for: indexPath) + if #available(iOS 16.0, *) { + cell.contentConfiguration = UIHostingConfiguration { self.representer.content(item) } + .margins(.all, .zero) + .minSize(height: 1) // Passing zero will result in system default of 44 points being used + } else { + if let cell = cell as? HostingCell { + cell.set(content: self.representer.content(item), parent: self) + } else { + fatalError("Unexpected Cell Type for: \(item)") + } + } + cell.transform = .verticalFlip + cell.selectionStyle = .none + return cell + } + + // 4. External state changes will require manual layout updates + NotificationCenter.default + .addObserver( + self, + selector: #selector(updateLayout), + name: notificationName, + object: nil + ) + } + + @available(*, unavailable) + required init?(coder: NSCoder) { fatalError() } + + deinit { NotificationCenter.default.removeObserver(self) } + + @objc private func updateLayout() { + if #available(iOS 16.0, *) { + tableView.setNeedsLayout() + tableView.layoutIfNeeded() + } else { + tableView.reloadData() + } + } + + /// Hides keyboard, when user begins to scroll. + /// Equivalent to `.scrollDismissesKeyboard(.immediately)` + override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { + UIApplication.shared + .sendAction( + #selector(UIResponder.resignFirstResponder), + to: nil, + from: nil, + for: nil + ) + } + + /// Scrolls up + func scrollToNextPage() { + tableView.setContentOffset( + CGPoint( + x: tableView.contentOffset.x, + y: tableView.contentOffset.y + tableView.bounds.height + ), + animated: true + ) + Task { representer.scrollState = .atDestination } + } + + /// Scrolls to Item at index path + /// - Parameter indexPath: Item to scroll to - will scroll to beginning of the list, if `nil` + func scroll(to index: Int?, position: UITableView.ScrollPosition) { + if let index { + var animated = false + if #available(iOS 16.0, *) { + animated = true + } + tableView.scrollToRow( + at: IndexPath(row: index, section: .zero), + at: position, + animated: animated + ) + Task { representer.scrollState = .atDestination } + } + } + + func update(items: Array) { + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.main]) + snapshot.appendItems(items) + dataSource.defaultRowAnimation = .none + dataSource.apply( + snapshot, + animatingDifferences: itemCount != .zero && abs(items.count - itemCount) == 1 + ) + itemCount = items.count + } + } + + /// `UIHostingConfiguration` back-port for iOS14 and iOS15 + /// Implemented as a `UITableViewCell` that wraps and manages a generic `UIHostingController` + private final class HostingCell: UITableViewCell { + private let hostingController = UIHostingController(rootView: nil) + + /// Updates content of the cell + /// For reference: https://noahgilmore.com/blog/swiftui-self-sizing-cells/ + func set(content: Hosted, parent: UIViewController) { + hostingController.rootView = content + if let hostingView = hostingController.view { + hostingView.invalidateIntrinsicContentSize() + if hostingController.parent != parent { parent.addChild(hostingController) } + if !contentView.subviews.contains(hostingController.view) { + contentView.addSubview(hostingController.view) + hostingView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + hostingView.leadingAnchor + .constraint(equalTo: contentView.leadingAnchor), + hostingView.trailingAnchor + .constraint(equalTo: contentView.trailingAnchor), + hostingView.topAnchor + .constraint(equalTo: contentView.topAnchor), + hostingView.bottomAnchor + .constraint(equalTo: contentView.bottomAnchor) + ]) + } + if hostingController.parent != parent { hostingController.didMove(toParent: parent) } + } else { + fatalError("Hosting View not loaded \(hostingController)") + } + } + + override func prepareForReuse() { + super.prepareForReuse() + hostingController.rootView = nil + } + } +} + +/// Manages ``ReverseList`` scrolling +class ReverseListScrollModel: ObservableObject { + /// Represents Scroll State of ``ReverseList`` + enum State: Equatable { + enum Destination: Equatable { + case nextPage + case item(Item.ID) + case bottom + } + + case scrollingTo(Destination) + case atDestination + } + + @Published var state: State = .atDestination + + func scrollToNextPage() { + state = .scrollingTo(.nextPage) + } + + func scrollToBottom() { + state = .scrollingTo(.bottom) + } + + func scrollToItem(id: Item.ID) { + state = .scrollingTo(.item(id)) + } +} + +fileprivate let cellReuseId = "hostingCell" + +fileprivate let notificationName = NSNotification.Name(rawValue: "reverseListNeedsLayout") + +fileprivate extension CGAffineTransform { + /// Transform that vertically flips the view, preserving it's location + static let verticalFlip = CGAffineTransform(scaleX: 1, y: -1) +} + +extension NotificationCenter { + static func postReverseListNeedsLayout() { + NotificationCenter.default.post( + name: notificationName, + object: nil + ) + } +} + +/// Disable animation on iOS 15 +func withConditionalAnimation( + _ animation: Animation? = .default, + _ body: () throws -> Result +) rethrows -> Result { + if #available(iOS 16.0, *) { + try withAnimation(animation, body) + } else { + try body() + } +} diff --git a/apps/ios/Shared/Views/ChatList/ChatListView.swift b/apps/ios/Shared/Views/ChatList/ChatListView.swift index 6bf63bb2e3..e39d39293a 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListView.swift @@ -220,9 +220,7 @@ struct ChatListView: View { @ViewBuilder private func chatView() -> some View { if let chatId = chatModel.chatId, let chat = chatModel.getChat(chatId) { - ChatView(chat: chat).onAppear { - loadChat(chat: chat) - } + ChatView(chat: chat) } } diff --git a/apps/ios/Shared/Views/Helpers/ContextMenu.swift b/apps/ios/Shared/Views/Helpers/ContextMenu.swift deleted file mode 100644 index 9504d919ef..0000000000 --- a/apps/ios/Shared/Views/Helpers/ContextMenu.swift +++ /dev/null @@ -1,112 +0,0 @@ -// -// ContextMenu2.swift -// SimpleX (iOS) -// -// Created by Evgeny on 09/08/2022. -// Copyright © 2022 SimpleX Chat. All rights reserved. -// - -import Foundation -import UIKit -import SwiftUI - -extension View { - func uiKitContextMenu(hasImageOrVideo: Bool, maxWidth: CGFloat, itemWidth: Binding, menu: Binding, allowMenu: Binding) -> some View { - Group { - if allowMenu.wrappedValue { - if hasImageOrVideo { - InteractionView(content: - self.environmentObject(ChatModel.shared) - .overlay(DetermineWidthImageVideoItem()) - .onPreferenceChange(DetermineWidthImageVideoItem.Key.self) { itemWidth.wrappedValue = $0 == 0 ? maxWidth : $0 } - , maxWidth: maxWidth, itemWidth: itemWidth, menu: menu) - .frame(maxWidth: itemWidth.wrappedValue) - } else { - InteractionView(content: self.environmentObject(ChatModel.shared), maxWidth: maxWidth, itemWidth: itemWidth, menu: menu) - .fixedSize(horizontal: true, vertical: false) - } - } else { - self - } - } - } -} - -private class HostingViewHolder: UIView { - var contentSize: CGSize = CGSizeMake(0, 0) - override var intrinsicContentSize: CGSize { get { contentSize } } -} - -struct InteractionView: UIViewRepresentable { - let content: Content - var maxWidth: CGFloat - var itemWidth: Binding - @Binding var menu: UIMenu - - func makeUIView(context: Context) -> UIView { - let view = HostingViewHolder() - view.backgroundColor = .clear - let hostView = UIHostingController(rootView: content) - view.contentSize = hostView.view.intrinsicContentSize - hostView.view.translatesAutoresizingMaskIntoConstraints = false - let constraints = [ - hostView.view.topAnchor.constraint(equalTo: view.topAnchor), - hostView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), - hostView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), - hostView.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), - hostView.view.widthAnchor.constraint(equalTo: view.widthAnchor), - hostView.view.heightAnchor.constraint(equalTo: view.heightAnchor) - ] - view.addSubview(hostView.view) - view.addConstraints(constraints) - view.layer.cornerRadius = 18 - hostView.view.layer.cornerRadius = 18 - let menuInteraction = UIContextMenuInteraction(delegate: context.coordinator) - view.addInteraction(menuInteraction) - return view - } - - func updateUIView(_ uiView: UIView, context: Context) { - let was = (uiView as! HostingViewHolder).contentSize - (uiView as! HostingViewHolder).contentSize = uiView.subviews[0].sizeThatFits(CGSizeMake(itemWidth.wrappedValue, .infinity)) - if was != (uiView as! HostingViewHolder).contentSize { - uiView.invalidateIntrinsicContentSize() - } - } - - func makeCoordinator() -> Coordinator { - Coordinator(self) - } - - class Coordinator: NSObject, UIContextMenuInteractionDelegate { - let parent: InteractionView - - init(_ parent: InteractionView) { - self.parent = parent - } - - func contextMenuInteraction( - _ interaction: UIContextMenuInteraction, - configurationForMenuAtLocation location: CGPoint - ) -> UIContextMenuConfiguration? { - UIContextMenuConfiguration( - identifier: nil, - previewProvider: nil, - actionProvider: { [weak self] _ in - guard let self = self else { return nil } - return self.parent.menu - } - ) - } - - // func contextMenuInteraction( - // _ interaction: UIContextMenuInteraction, - // willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, - // animator: UIContextMenuInteractionCommitAnimating - // ) { - // animator.addCompletion { - // print("user tapped") - // } - // } - } -} diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 43aa79e0a9..057d6cccbe 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -18,7 +18,6 @@ 18415FEFE153C5920BFB7828 /* GroupWelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1841516F0CE5992B0EDFB377 /* GroupWelcomeView.swift */; }; 3CDBCF4227FAE51000354CDD /* ComposeLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CDBCF4127FAE51000354CDD /* ComposeLinkView.swift */; }; 3CDBCF4827FF621E00354CDD /* CILinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CDBCF4727FF621E00354CDD /* CILinkView.swift */; }; - 5C00164428A26FBC0094D739 /* ContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C00164328A26FBC0094D739 /* ContextMenu.swift */; }; 5C00168128C4FE760094D739 /* KeyChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C00168028C4FE760094D739 /* KeyChain.swift */; }; 5C029EA82837DBB3004A9677 /* CICallItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C029EA72837DBB3004A9677 /* CICallItemView.swift */; }; 5C029EAA283942EA004A9677 /* CallController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C029EA9283942EA004A9677 /* CallController.swift */; }; @@ -186,6 +185,7 @@ 8C81482C2BD91CD4002CBEC3 /* AudioDevicePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C81482B2BD91CD4002CBEC3 /* AudioDevicePicker.swift */; }; 8CC4ED902BD7B8530078AEE8 /* CallAudioDeviceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC4ED8F2BD7B8530078AEE8 /* CallAudioDeviceManager.swift */; }; 8CC956EE2BC0041000412A11 /* NetworkObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC956ED2BC0041000412A11 /* NetworkObserver.swift */; }; + CEEA861D2C2ABCB50084E1EA /* ReverseList.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEEA861C2C2ABCB50084E1EA /* ReverseList.swift */; }; D7197A1829AE89660055C05A /* WebRTC in Frameworks */ = {isa = PBXBuildFile; productRef = D7197A1729AE89660055C05A /* WebRTC */; }; D72A9088294BD7A70047C86D /* NativeTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72A9087294BD7A70047C86D /* NativeTextEditor.swift */; }; D741547829AF89AF0022400A /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D741547729AF89AF0022400A /* StoreKit.framework */; }; @@ -267,7 +267,6 @@ 18415FD2E36F13F596A45BB4 /* CIVideoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CIVideoView.swift; sourceTree = ""; }; 3CDBCF4127FAE51000354CDD /* ComposeLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeLinkView.swift; sourceTree = ""; }; 3CDBCF4727FF621E00354CDD /* CILinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CILinkView.swift; sourceTree = ""; }; - 5C00164328A26FBC0094D739 /* ContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenu.swift; sourceTree = ""; }; 5C00168028C4FE760094D739 /* KeyChain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyChain.swift; sourceTree = ""; }; 5C029EA72837DBB3004A9677 /* CICallItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CICallItemView.swift; sourceTree = ""; }; 5C029EA9283942EA004A9677 /* CallController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallController.swift; sourceTree = ""; }; @@ -483,6 +482,7 @@ 8C81482B2BD91CD4002CBEC3 /* AudioDevicePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioDevicePicker.swift; sourceTree = ""; }; 8CC4ED8F2BD7B8530078AEE8 /* CallAudioDeviceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallAudioDeviceManager.swift; sourceTree = ""; }; 8CC956ED2BC0041000412A11 /* NetworkObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkObserver.swift; sourceTree = ""; }; + CEEA861C2C2ABCB50084E1EA /* ReverseList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReverseList.swift; sourceTree = ""; }; D72A9087294BD7A70047C86D /* NativeTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeTextEditor.swift; sourceTree = ""; }; D741547729AF89AF0022400A /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/StoreKit.framework; sourceTree = DEVELOPER_DIR; }; D741547929AF90B00022400A /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/PushKit.framework; sourceTree = DEVELOPER_DIR; }; @@ -591,6 +591,7 @@ 5CE4407127ADB1D0007B033A /* Emoji.swift */, 5CADE79B292131E900072E13 /* ContactPreferencesView.swift */, 5CBE6C11294487F7002D9531 /* VerifyCodeView.swift */, + CEEA861C2C2ABCB50084E1EA /* ReverseList.swift */, 5CBE6C132944CC12002D9531 /* ScanCodeView.swift */, 64C06EB42A0A4A7C00792D4D /* ChatItemInfoView.swift */, 648679AA2BC96A74006456E7 /* ChatItemForwardingView.swift */, @@ -651,7 +652,6 @@ 5CFE0920282EEAF60002594B /* ZoomableScrollView.swift */, 646BB38D283FDB6D001CE359 /* LocalAuthenticationUtils.swift */, 5C6BA666289BD954009B8ECC /* DismissSheets.swift */, - 5C00164328A26FBC0094D739 /* ContextMenu.swift */, 5CA7DFC229302AF000F7FDDE /* AppSheet.swift */, 18415A7F0F189D87DEFEABCA /* PressedButtonStyle.swift */, 5CCB939B297EFCB100399E78 /* NavStackCompat.swift */, @@ -1134,6 +1134,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CEEA861D2C2ABCB50084E1EA /* ReverseList.swift in Sources */, 64C06EB52A0A4A7C00792D4D /* ChatItemInfoView.swift in Sources */, 640417CE2B29B8C200CCB412 /* NewChatView.swift in Sources */, 6440CA03288AECA70062C672 /* AddGroupMembersView.swift in Sources */, @@ -1176,7 +1177,6 @@ 5C7505A827B6D34800BE3227 /* ChatInfoToolbar.swift in Sources */, 5C10D88A28F187F300E58BF0 /* FullScreenMediaView.swift in Sources */, D72A9088294BD7A70047C86D /* NativeTextEditor.swift in Sources */, - 5C00164428A26FBC0094D739 /* ContextMenu.swift in Sources */, 64D0C2C629FAC1EC00B38D5F /* AddContactLearnMore.swift in Sources */, 5C3A88D127DF57800060F1C2 /* FramedItemView.swift in Sources */, 5C65F343297D45E100B67AF3 /* VersionView.swift in Sources */, diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index 9ffba5380f..1ab2e2b575 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -1010,20 +1010,20 @@ public func chatError(_ chatResponse: ChatResponse) -> ChatErrorType? { } } -public enum ConnectionPlan: Decodable { +public enum ConnectionPlan: Decodable, Hashable { case invitationLink(invitationLinkPlan: InvitationLinkPlan) case contactAddress(contactAddressPlan: ContactAddressPlan) case groupLink(groupLinkPlan: GroupLinkPlan) } -public enum InvitationLinkPlan: Decodable { +public enum InvitationLinkPlan: Decodable, Hashable { case ok case ownLink case connecting(contact_: Contact?) case known(contact: Contact) } -public enum ContactAddressPlan: Decodable { +public enum ContactAddressPlan: Decodable, Hashable { case ok case ownLink case connectingConfirmReconnect @@ -1032,7 +1032,7 @@ public enum ContactAddressPlan: Decodable { case contactViaAddress(contact: Contact) } -public enum GroupLinkPlan: Decodable { +public enum GroupLinkPlan: Decodable, Hashable { case ok case ownLink(groupInfo: GroupInfo) case connectingConfirmReconnect @@ -1040,13 +1040,13 @@ public enum GroupLinkPlan: Decodable { case known(groupInfo: GroupInfo) } -struct NewUser: Encodable { +struct NewUser: Encodable, Hashable { var profile: Profile? var sameServers: Bool var pastTimestamp: Bool } -public enum ChatPagination { +public enum ChatPagination: Hashable { case last(count: Int) case after(chatItemId: Int64, count: Int) case before(chatItemId: Int64, count: Int) @@ -1268,7 +1268,7 @@ public struct ServerAddress: Decodable { ) } -public struct NetCfg: Codable, Equatable { +public struct NetCfg: Codable, Equatable, Hashable { public var socksProxy: String? = nil var socksMode: SocksMode = .always public var hostMode: HostMode = .publicHost @@ -1314,18 +1314,18 @@ public struct NetCfg: Codable, Equatable { public var enableKeepAlive: Bool { tcpKeepAlive != nil } } -public enum HostMode: String, Codable { +public enum HostMode: String, Codable, Hashable { case onionViaSocks case onionHost = "onion" case publicHost = "public" } -public enum SocksMode: String, Codable { +public enum SocksMode: String, Codable, Hashable { case always = "always" case onion = "onion" } -public enum SMPProxyMode: String, Codable { +public enum SMPProxyMode: String, Codable, Hashable { case always = "always" case unknown = "unknown" case unprotected = "unprotected" @@ -1345,7 +1345,7 @@ public enum SMPProxyMode: String, Codable { public static let values: [SMPProxyMode] = [.always, .unknown, .unprotected, .never] } -public enum SMPProxyFallback: String, Codable { +public enum SMPProxyFallback: String, Codable, Hashable { case allow = "allow" case allowProtected = "allowProtected" case prohibit = "prohibit" @@ -1363,7 +1363,7 @@ public enum SMPProxyFallback: String, Codable { public static let values: [SMPProxyFallback] = [.allow, .allowProtected, .prohibit] } -public enum OnionHosts: String, Identifiable { +public enum OnionHosts: String, Identifiable, Hashable { case no case prefer case require @@ -1397,7 +1397,7 @@ public enum OnionHosts: String, Identifiable { public static let values: [OnionHosts] = [.no, .prefer, .require] } -public enum TransportSessionMode: String, Codable, Identifiable { +public enum TransportSessionMode: String, Codable, Identifiable, Hashable { case user case entity @@ -1413,7 +1413,7 @@ public enum TransportSessionMode: String, Codable, Identifiable { public static let values: [TransportSessionMode] = [.user, .entity] } -public struct KeepAliveOpts: Codable, Equatable { +public struct KeepAliveOpts: Codable, Equatable, Hashable { public var keepIdle: Int // seconds public var keepIntvl: Int // seconds public var keepCnt: Int // times @@ -1421,7 +1421,7 @@ public struct KeepAliveOpts: Codable, Equatable { public static let defaults: KeepAliveOpts = KeepAliveOpts(keepIdle: 30, keepIntvl: 15, keepCnt: 4) } -public enum NetworkStatus: Decodable, Equatable { +public enum NetworkStatus: Decodable, Equatable, Hashable { case unknown case connected case disconnected @@ -1459,12 +1459,12 @@ public enum NetworkStatus: Decodable, Equatable { } } -public struct ConnNetworkStatus: Decodable { +public struct ConnNetworkStatus: Decodable, Hashable { public var agentConnId: String public var networkStatus: NetworkStatus } -public struct ChatSettings: Codable { +public struct ChatSettings: Codable, Hashable { public var enableNtfs: MsgFilter public var sendRcpts: Bool? public var favorite: Bool @@ -1478,13 +1478,13 @@ public struct ChatSettings: Codable { public static let defaults: ChatSettings = ChatSettings(enableNtfs: .all, sendRcpts: nil, favorite: false) } -public enum MsgFilter: String, Codable { +public enum MsgFilter: String, Codable, Hashable { case none case all case mentions } -public struct UserMsgReceiptSettings: Codable { +public struct UserMsgReceiptSettings: Codable, Hashable { public var enable: Bool public var clearOverrides: Bool @@ -1494,7 +1494,7 @@ public struct UserMsgReceiptSettings: Codable { } } -public struct ConnectionStats: Decodable { +public struct ConnectionStats: Decodable, Hashable { public var connAgentVersion: Int public var rcvQueuesInfo: [RcvQueueInfo] public var sndQueuesInfo: [SndQueueInfo] @@ -1510,30 +1510,30 @@ public struct ConnectionStats: Decodable { } } -public struct RcvQueueInfo: Codable { +public struct RcvQueueInfo: Codable, Hashable { public var rcvServer: String public var rcvSwitchStatus: RcvSwitchStatus? public var canAbortSwitch: Bool } -public enum RcvSwitchStatus: String, Codable { +public enum RcvSwitchStatus: String, Codable, Hashable { case switchStarted = "switch_started" case sendingQADD = "sending_qadd" case sendingQUSE = "sending_quse" case receivedMessage = "received_message" } -public struct SndQueueInfo: Codable { +public struct SndQueueInfo: Codable, Hashable { public var sndServer: String public var sndSwitchStatus: SndSwitchStatus? } -public enum SndSwitchStatus: String, Codable { +public enum SndSwitchStatus: String, Codable, Hashable { case sendingQKEY = "sending_qkey" case sendingQTEST = "sending_qtest" } -public enum QueueDirection: String, Decodable { +public enum QueueDirection: String, Decodable, Hashable { case rcv case snd } @@ -1557,7 +1557,7 @@ public enum RatchetSyncState: String, Decodable { case agreed } -public struct UserContactLink: Decodable { +public struct UserContactLink: Decodable, Hashable { public var connReqContact: String public var autoAccept: AutoAccept? @@ -1571,7 +1571,7 @@ public struct UserContactLink: Decodable { } } -public struct AutoAccept: Codable { +public struct AutoAccept: Codable, Hashable { public var acceptIncognito: Bool public var autoReply: MsgContent? @@ -1593,7 +1593,7 @@ public protocol SelectableItem: Hashable, Identifiable { static var values: [Self] { get } } -public struct DeviceToken: Decodable { +public struct DeviceToken: Decodable, Hashable { var pushProvider: PushProvider var token: String @@ -1607,12 +1607,12 @@ public struct DeviceToken: Decodable { } } -public enum PushEnvironment: String { +public enum PushEnvironment: String, Hashable { case development case production } -public enum PushProvider: String, Decodable { +public enum PushProvider: String, Decodable, Hashable { case apns_dev case apns_prod @@ -1626,7 +1626,7 @@ public enum PushProvider: String, Decodable { // This notification mode is for app core, UI uses AppNotificationsMode.off to mean completely disable, // and .local for periodic background checks -public enum NotificationsMode: String, Decodable, SelectableItem { +public enum NotificationsMode: String, Decodable, SelectableItem, Hashable { case off = "OFF" case periodic = "PERIODIC" case instant = "INSTANT" @@ -1644,7 +1644,7 @@ public enum NotificationsMode: String, Decodable, SelectableItem { public static var values: [NotificationsMode] = [.instant, .periodic, .off] } -public enum NotificationPreviewMode: String, SelectableItem, Codable { +public enum NotificationPreviewMode: String, SelectableItem, Codable, Hashable { case hidden case contact case message @@ -1662,7 +1662,7 @@ public enum NotificationPreviewMode: String, SelectableItem, Codable { public static var values: [NotificationPreviewMode] = [.message, .contact, .hidden] } -public struct RemoteCtrlInfo: Decodable { +public struct RemoteCtrlInfo: Decodable, Hashable { public var remoteCtrlId: Int64 public var ctrlDeviceName: String public var sessionState: RemoteCtrlSessionState? @@ -1672,7 +1672,7 @@ public struct RemoteCtrlInfo: Decodable { } } -public enum RemoteCtrlSessionState: Decodable { +public enum RemoteCtrlSessionState: Decodable, Hashable { case starting case searching case connecting @@ -1687,17 +1687,17 @@ public enum RemoteCtrlStopReason: Decodable { case disconnected } -public struct CtrlAppInfo: Decodable { +public struct CtrlAppInfo: Decodable, Hashable { public var appVersionRange: AppVersionRange public var deviceName: String } -public struct AppVersionRange: Decodable { +public struct AppVersionRange: Decodable, Hashable { public var minVersion: String public var maxVersion: String } -public struct CoreVersionInfo: Decodable { +public struct CoreVersionInfo: Decodable, Hashable { public var version: String public var simplexmqVersion: String public var simplexmqCommit: String @@ -1719,7 +1719,7 @@ private func encodeCJSON(_ value: T) -> [CChar] { encodeJSON(value).cString(using: .utf8)! } -public enum ChatError: Decodable { +public enum ChatError: Decodable, Hashable { case error(errorType: ChatErrorType) case errorAgent(agentError: AgentErrorType) case errorStore(storeError: StoreError) @@ -1728,7 +1728,7 @@ public enum ChatError: Decodable { case invalidJSON(json: String) } -public enum ChatErrorType: Decodable { +public enum ChatErrorType: Decodable, Hashable { case noActiveUser case noConnectionUser(agentConnId: String) case noSndFileUser(agentSndFileId: String) @@ -1807,7 +1807,7 @@ public enum ChatErrorType: Decodable { case exception(message: String) } -public enum StoreError: Decodable { +public enum StoreError: Decodable, Hashable { case duplicateName case userNotFound(userId: Int64) case userNotFoundByName(contactName: ContactName) @@ -1867,7 +1867,7 @@ public enum StoreError: Decodable { case noGroupSndStatus(itemId: Int64, groupMemberId: Int64) } -public enum DatabaseError: Decodable { +public enum DatabaseError: Decodable, Hashable { case errorEncrypted case errorPlaintext case errorNoFile(dbFile: String) @@ -1875,12 +1875,12 @@ public enum DatabaseError: Decodable { case errorOpen(sqliteError: SQLiteError) } -public enum SQLiteError: Decodable { +public enum SQLiteError: Decodable, Hashable { case errorNotADatabase case error(String) } -public enum AgentErrorType: Decodable { +public enum AgentErrorType: Decodable, Hashable { case CMD(cmdErr: CommandErrorType) case CONN(connErr: ConnectionErrorType) case SMP(smpErr: ProtocolErrorType) @@ -1894,7 +1894,7 @@ public enum AgentErrorType: Decodable { case INACTIVE } -public enum CommandErrorType: Decodable { +public enum CommandErrorType: Decodable, Hashable { case PROHIBITED case SYNTAX case NO_CONN @@ -1902,7 +1902,7 @@ public enum CommandErrorType: Decodable { case LARGE } -public enum ConnectionErrorType: Decodable { +public enum ConnectionErrorType: Decodable, Hashable { case NOT_FOUND case DUPLICATE case SIMPLEX @@ -1910,7 +1910,7 @@ public enum ConnectionErrorType: Decodable { case NOT_AVAILABLE } -public enum BrokerErrorType: Decodable { +public enum BrokerErrorType: Decodable, Hashable { case RESPONSE(smpErr: String) case UNEXPECTED case NETWORK @@ -1919,7 +1919,7 @@ public enum BrokerErrorType: Decodable { case TIMEOUT } -public enum ProtocolErrorType: Decodable { +public enum ProtocolErrorType: Decodable, Hashable { case BLOCK case SESSION case CMD(cmdErr: ProtocolCommandError) @@ -1930,7 +1930,7 @@ public enum ProtocolErrorType: Decodable { case INTERNAL } -public enum XFTPErrorType: Decodable { +public enum XFTPErrorType: Decodable, Hashable { case BLOCK case SESSION case CMD(cmdErr: ProtocolCommandError) @@ -1947,7 +1947,7 @@ public enum XFTPErrorType: Decodable { case INTERNAL } -public enum RCErrorType: Decodable { +public enum RCErrorType: Decodable, Hashable { case `internal`(internalErr: String) case identity case noLocalAddress @@ -1965,7 +1965,7 @@ public enum RCErrorType: Decodable { case syntax(syntaxErr: String) } -public enum ProtocolCommandError: Decodable { +public enum ProtocolCommandError: Decodable, Hashable { case UNKNOWN case SYNTAX case PROHIBITED @@ -1974,7 +1974,7 @@ public enum ProtocolCommandError: Decodable { case NO_ENTITY } -public enum ProtocolTransportError: Decodable { +public enum ProtocolTransportError: Decodable, Hashable { case badBlock case largeMsg case badSession @@ -1982,14 +1982,14 @@ public enum ProtocolTransportError: Decodable { case handshake(handshakeErr: SMPHandshakeError) } -public enum SMPHandshakeError: Decodable { +public enum SMPHandshakeError: Decodable, Hashable { case PARSE case VERSION case IDENTITY case BAD_AUTH } -public enum SMPAgentError: Decodable { +public enum SMPAgentError: Decodable, Hashable { case A_MESSAGE case A_PROHIBITED case A_VERSION @@ -1998,12 +1998,12 @@ public enum SMPAgentError: Decodable { case A_QUEUE(queueErr: String) } -public enum ArchiveError: Decodable { +public enum ArchiveError: Decodable, Hashable { case `import`(chatError: ChatError) case importFile(file: String, chatError: ChatError) } -public enum RemoteCtrlError: Decodable { +public enum RemoteCtrlError: Decodable, Hashable { case inactive case badState case busy @@ -2017,14 +2017,14 @@ public enum RemoteCtrlError: Decodable { case protocolError } -public struct MigrationFileLinkData: Codable { +public struct MigrationFileLinkData: Codable, Hashable { let networkConfig: NetworkConfig? public init(networkConfig: NetworkConfig) { self.networkConfig = networkConfig } - public struct NetworkConfig: Codable { + public struct NetworkConfig: Codable, Hashable { let socksProxy: String? let hostMode: HostMode? let requiredHostMode: Bool? @@ -2056,7 +2056,7 @@ public struct MigrationFileLinkData: Codable { } } -public struct AppSettings: Codable, Equatable { +public struct AppSettings: Codable, Equatable, Hashable { public var networkConfig: NetCfg? = nil public var privacyEncryptLocalFiles: Bool? = nil public var privacyAskToApproveRelays: Bool? = nil @@ -2130,7 +2130,7 @@ public struct AppSettings: Codable, Equatable { } } -public enum AppSettingsNotificationMode: String, Codable { +public enum AppSettingsNotificationMode: String, Codable, Hashable { case off case periodic case instant @@ -2158,13 +2158,13 @@ public enum AppSettingsNotificationMode: String, Codable { // case message //} -public enum AppSettingsLockScreenCalls: String, Codable { +public enum AppSettingsLockScreenCalls: String, Codable, Hashable { case disable case show case accept } -public struct UserNetworkInfo: Codable, Equatable { +public struct UserNetworkInfo: Codable, Equatable, Hashable { public let networkType: UserNetworkType public let online: Bool @@ -2174,7 +2174,7 @@ public struct UserNetworkInfo: Codable, Equatable { } } -public enum UserNetworkType: String, Codable { +public enum UserNetworkType: String, Codable, Hashable { case none case cellular case wifi @@ -2192,7 +2192,7 @@ public enum UserNetworkType: String, Codable { } } -public struct RcvMsgInfo: Codable { +public struct RcvMsgInfo: Codable, Hashable { var msgId: Int64 var msgDeliveryId: Int64 var msgDeliveryStatus: String @@ -2200,7 +2200,7 @@ public struct RcvMsgInfo: Codable { var agentMsgMeta: String } -public struct QueueInfo: Codable { +public struct QueueInfo: Codable, Hashable { var qiSnd: Bool var qiNtf: Bool var qiSub: QSub? @@ -2208,25 +2208,25 @@ public struct QueueInfo: Codable { var qiMsg: MsgInfo? } -public struct QSub: Codable { +public struct QSub: Codable, Hashable { var qSubThread: QSubThread var qDelivered: String? } -public enum QSubThread: String, Codable { +public enum QSubThread: String, Codable, Hashable { case noSub case subPending case subThread case prohibitSub } -public struct MsgInfo: Codable { +public struct MsgInfo: Codable, Hashable { var msgId: String var msgTs: Date var msgType: MsgType } -public enum MsgType: String, Codable { +public enum MsgType: String, Codable, Hashable { case message case quota } diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index 1f58ee2363..d2a7e704ad 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -9,7 +9,7 @@ import Foundation import SwiftUI -public struct User: Identifiable, Decodable, UserLike, NamedChat { +public struct User: Identifiable, Decodable, UserLike, NamedChat, Hashable { public var userId: Int64 var userContactId: Int64 var localDisplayName: ContactName @@ -52,7 +52,7 @@ public struct User: Identifiable, Decodable, UserLike, NamedChat { ) } -public struct UserRef: Identifiable, Decodable, UserLike { +public struct UserRef: Identifiable, Decodable, UserLike, Hashable { public var userId: Int64 public var localDisplayName: ContactName @@ -63,12 +63,12 @@ public protocol UserLike: Identifiable { var userId: Int64 { get } } -public struct UserPwdHash: Decodable { +public struct UserPwdHash: Decodable, Hashable { public var hash: String public var salt: String } -public struct UserInfo: Decodable, Identifiable { +public struct UserInfo: Decodable, Identifiable, Hashable { public var user: User public var unreadCount: Int @@ -89,7 +89,7 @@ public typealias ContactName = String public typealias GroupName = String -public struct Profile: Codable, NamedChat { +public struct Profile: Codable, NamedChat, Hashable { public init( displayName: String, fullName: String, @@ -121,7 +121,7 @@ public struct Profile: Codable, NamedChat { ) } -public struct LocalProfile: Codable, NamedChat { +public struct LocalProfile: Codable, NamedChat, Hashable { public init( profileId: Int64, displayName: String, @@ -171,13 +171,13 @@ public func fromLocalProfile (_ profile: LocalProfile) -> Profile { Profile(displayName: profile.displayName, fullName: profile.fullName, image: profile.image, contactLink: profile.contactLink, preferences: profile.preferences) } -public struct UserProfileUpdateSummary: Decodable { +public struct UserProfileUpdateSummary: Decodable, Hashable { public var updateSuccesses: Int public var updateFailures: Int public var changedContacts: [Contact] } -public enum ChatType: String { +public enum ChatType: String, Hashable { case direct = "@" case group = "#" case local = "*" @@ -202,7 +202,7 @@ extension NamedChat { public typealias ChatId = String -public struct FullPreferences: Decodable, Equatable { +public struct FullPreferences: Decodable, Equatable, Hashable { public var timedMessages: TimedMessagesPreference public var fullDelete: SimplePreference public var reactions: SimplePreference @@ -232,7 +232,7 @@ public struct FullPreferences: Decodable, Equatable { ) } -public struct Preferences: Codable { +public struct Preferences: Codable, Hashable { public var timedMessages: TimedMessagesPreference? public var fullDelete: SimplePreference? public var reactions: SimplePreference? @@ -308,11 +308,11 @@ public func contactUserPreferencesToPreferences(_ contactUserPreferences: Contac ) } -public protocol Preference: Codable, Equatable { +public protocol Preference: Codable, Equatable, Hashable { var allow: FeatureAllowed { get set } } -public struct SimplePreference: Preference { +public struct SimplePreference: Preference, Hashable { public var allow: FeatureAllowed public init(allow: FeatureAllowed) { @@ -320,7 +320,7 @@ public struct SimplePreference: Preference { } } -public struct TimedMessagesPreference: Preference { +public struct TimedMessagesPreference: Preference, Hashable { public var allow: FeatureAllowed public var ttl: Int? @@ -334,7 +334,7 @@ public struct TimedMessagesPreference: Preference { } } -public enum CustomTimeUnit { +public enum CustomTimeUnit: Hashable { case second case minute case hour @@ -433,7 +433,7 @@ public func shortTimeText(_ seconds: Int?) -> LocalizedStringKey { return CustomTimeUnit.toShortText(seconds: seconds) } -public struct ContactUserPreferences: Decodable { +public struct ContactUserPreferences: Decodable, Hashable { public var timedMessages: ContactUserPreference public var fullDelete: ContactUserPreference public var reactions: ContactUserPreference @@ -483,7 +483,7 @@ public struct ContactUserPreferences: Decodable { ) } -public struct ContactUserPreference: Decodable { +public struct ContactUserPreference: Decodable, Hashable { public var enabled: FeatureEnabled public var userPreference: ContactUserPref

public var contactPreference: P @@ -495,7 +495,7 @@ public struct ContactUserPreference: Decodable { } } -public struct FeatureEnabled: Decodable { +public struct FeatureEnabled: Decodable, Hashable { public var forUser: Bool public var forContact: Bool @@ -526,7 +526,7 @@ public struct FeatureEnabled: Decodable { } } -public enum ContactUserPref: Decodable { +public enum ContactUserPref: Decodable, Hashable { case contact(preference: P) // contact override is set case user(preference: P) // global user default is used @@ -547,7 +547,7 @@ public protocol Feature { var text: String { get } } -public enum ChatFeature: String, Decodable, Feature { +public enum ChatFeature: String, Decodable, Feature, Hashable { case timedMessages case fullDelete case reactions @@ -690,7 +690,7 @@ public enum ChatFeature: String, Decodable, Feature { } } -public enum GroupFeature: String, Decodable, Feature { +public enum GroupFeature: String, Decodable, Feature, Hashable { case timedMessages case directMessages case fullDelete @@ -890,7 +890,7 @@ public enum ContactFeatureAllowed: Identifiable, Hashable { } } -public struct ContactFeaturesAllowed: Equatable { +public struct ContactFeaturesAllowed: Equatable, Hashable { public var timedMessagesAllowed: Bool public var timedMessagesTTL: Int? public var fullDelete: ContactFeatureAllowed @@ -968,7 +968,7 @@ public func contactFeatureAllowedToPref(_ contactFeatureAllowed: ContactFeatureA } } -public enum FeatureAllowed: String, Codable, Identifiable { +public enum FeatureAllowed: String, Codable, Identifiable, Hashable { case always case yes case no @@ -986,7 +986,7 @@ public enum FeatureAllowed: String, Codable, Identifiable { } } -public struct FullGroupPreferences: Decodable, Equatable { +public struct FullGroupPreferences: Decodable, Equatable, Hashable { public var timedMessages: TimedMessagesGroupPreference public var directMessages: RoleGroupPreference public var fullDelete: GroupPreference @@ -1028,7 +1028,7 @@ public struct FullGroupPreferences: Decodable, Equatable { ) } -public struct GroupPreferences: Codable { +public struct GroupPreferences: Codable, Hashable { public var timedMessages: TimedMessagesGroupPreference? public var directMessages: RoleGroupPreference? public var fullDelete: GroupPreference? @@ -1083,7 +1083,7 @@ public func toGroupPreferences(_ fullPreferences: FullGroupPreferences) -> Group ) } -public struct GroupPreference: Codable, Equatable { +public struct GroupPreference: Codable, Equatable, Hashable { public var enable: GroupFeatureEnabled public var on: Bool { @@ -1107,7 +1107,7 @@ public struct GroupPreference: Codable, Equatable { } } -public struct RoleGroupPreference: Codable, Equatable { +public struct RoleGroupPreference: Codable, Equatable, Hashable { public var enable: GroupFeatureEnabled public var role: GroupMemberRole? @@ -1121,7 +1121,7 @@ public struct RoleGroupPreference: Codable, Equatable { } } -public struct TimedMessagesGroupPreference: Codable, Equatable { +public struct TimedMessagesGroupPreference: Codable, Equatable, Hashable { public var enable: GroupFeatureEnabled public var ttl: Int? @@ -1135,7 +1135,7 @@ public struct TimedMessagesGroupPreference: Codable, Equatable { } } -public enum GroupFeatureEnabled: String, Codable, Identifiable { +public enum GroupFeatureEnabled: String, Codable, Identifiable, Hashable { case on case off @@ -1158,7 +1158,7 @@ public enum GroupFeatureEnabled: String, Codable, Identifiable { } } -public enum ChatInfo: Identifiable, Decodable, NamedChat { +public enum ChatInfo: Identifiable, Decodable, NamedChat, Hashable { case direct(contact: Contact) case group(groupInfo: GroupInfo) case local(noteFolder: NoteFolder) @@ -1370,7 +1370,7 @@ public enum ChatInfo: Identifiable, Decodable, NamedChat { } } - public enum ShowEnableVoiceMessagesAlert { + public enum ShowEnableVoiceMessagesAlert: Hashable { case userEnable case askContact case groupOwnerCan @@ -1443,7 +1443,7 @@ public enum ChatInfo: Identifiable, Decodable, NamedChat { } } - public struct SampleData { + public struct SampleData: Hashable { public var direct: ChatInfo public var group: ChatInfo public var local: ChatInfo @@ -1460,7 +1460,7 @@ public enum ChatInfo: Identifiable, Decodable, NamedChat { ) } -public struct ChatData: Decodable, Identifiable { +public struct ChatData: Decodable, Identifiable, Hashable { public var chatInfo: ChatInfo public var chatItems: [ChatItem] public var chatStats: ChatStats @@ -1476,7 +1476,7 @@ public struct ChatData: Decodable, Identifiable { } } -public struct ChatStats: Decodable { +public struct ChatStats: Decodable, Hashable { public init(unreadCount: Int = 0, minUnreadItemId: Int64 = 0, unreadChat: Bool = false) { self.unreadCount = unreadCount self.minUnreadItemId = minUnreadItemId @@ -1488,7 +1488,7 @@ public struct ChatStats: Decodable { public var unreadChat: Bool = false } -public struct Contact: Identifiable, Decodable, NamedChat { +public struct Contact: Identifiable, Decodable, NamedChat, Hashable { public var contactId: Int64 var localDisplayName: ContactName public var profile: LocalProfile @@ -1574,12 +1574,12 @@ public struct Contact: Identifiable, Decodable, NamedChat { ) } -public enum ContactStatus: String, Decodable { +public enum ContactStatus: String, Decodable, Hashable { case active = "active" case deleted = "deleted" } -public struct ContactRef: Decodable, Equatable { +public struct ContactRef: Decodable, Equatable, Hashable { var contactId: Int64 public var agentConnId: String var connId: Int64 @@ -1588,12 +1588,12 @@ public struct ContactRef: Decodable, Equatable { public var id: ChatId { get { "@\(contactId)" } } } -public struct ContactSubStatus: Decodable { +public struct ContactSubStatus: Decodable, Hashable { public var contact: Contact public var contactError: ChatError? } -public struct Connection: Decodable { +public struct Connection: Decodable, Hashable { public var connId: Int64 public var agentConnId: String public var peerChatVRange: VersionRange @@ -1637,7 +1637,7 @@ public struct Connection: Decodable { ) } -public struct VersionRange: Decodable { +public struct VersionRange: Decodable, Hashable { public init(minVersion: Int, maxVersion: Int) { self.minVersion = minVersion self.maxVersion = maxVersion @@ -1651,7 +1651,7 @@ public struct VersionRange: Decodable { } } -public struct SecurityCode: Decodable, Equatable { +public struct SecurityCode: Decodable, Equatable, Hashable { public init(securityCode: String, verifiedAt: Date) { self.securityCode = securityCode self.verifiedAt = verifiedAt @@ -1661,7 +1661,7 @@ public struct SecurityCode: Decodable, Equatable { public var verifiedAt: Date } -public struct UserContact: Decodable { +public struct UserContact: Decodable, Hashable { public var userContactLinkId: Int64 // public var connReqContact: String public var groupId: Int64? @@ -1679,7 +1679,7 @@ public struct UserContact: Decodable { } } -public struct UserContactRequest: Decodable, NamedChat { +public struct UserContactRequest: Decodable, NamedChat, Hashable { var contactRequestId: Int64 public var userContactLinkId: Int64 public var cReqChatVRange: VersionRange @@ -1708,7 +1708,7 @@ public struct UserContactRequest: Decodable, NamedChat { ) } -public struct PendingContactConnection: Decodable, NamedChat { +public struct PendingContactConnection: Decodable, NamedChat, Hashable { public var pccConnId: Int64 var pccAgentConnId: String var pccConnStatus: ConnStatus @@ -1798,7 +1798,7 @@ public struct PendingContactConnection: Decodable, NamedChat { } } -public enum ConnStatus: String, Decodable { +public enum ConnStatus: String, Decodable, Hashable { case new = "new" case joined = "joined" case requested = "requested" @@ -1822,7 +1822,7 @@ public enum ConnStatus: String, Decodable { } } -public struct Group: Decodable { +public struct Group: Decodable, Hashable { public var groupInfo: GroupInfo public var members: [GroupMember] @@ -1832,7 +1832,7 @@ public struct Group: Decodable { } } -public struct GroupInfo: Identifiable, Decodable, NamedChat { +public struct GroupInfo: Identifiable, Decodable, NamedChat, Hashable { public var groupId: Int64 var localDisplayName: GroupName public var groupProfile: GroupProfile @@ -1878,12 +1878,12 @@ public struct GroupInfo: Identifiable, Decodable, NamedChat { ) } -public struct GroupRef: Decodable { +public struct GroupRef: Decodable, Hashable { public var groupId: Int64 var localDisplayName: GroupName } -public struct GroupProfile: Codable, NamedChat { +public struct GroupProfile: Codable, NamedChat, Hashable { public init(displayName: String, fullName: String, description: String? = nil, image: String? = nil, groupPreferences: GroupPreferences? = nil) { self.displayName = displayName self.fullName = fullName @@ -1905,7 +1905,7 @@ public struct GroupProfile: Codable, NamedChat { ) } -public struct GroupMember: Identifiable, Decodable { +public struct GroupMember: Identifiable, Decodable, Hashable { public var groupMemberId: Int64 public var groupId: Int64 public var memberId: String @@ -2037,21 +2037,21 @@ public struct GroupMember: Identifiable, Decodable { ) } -public struct GroupMemberSettings: Codable { +public struct GroupMemberSettings: Codable, Hashable { public var showMessages: Bool } -public struct GroupMemberRef: Decodable { +public struct GroupMemberRef: Decodable, Hashable { var groupMemberId: Int64 var profile: Profile } -public struct GroupMemberIds: Decodable { +public struct GroupMemberIds: Decodable, Hashable { var groupMemberId: Int64 var groupId: Int64 } -public enum GroupMemberRole: String, Identifiable, CaseIterable, Comparable, Codable { +public enum GroupMemberRole: String, Identifiable, CaseIterable, Comparable, Codable, Hashable { case observer = "observer" case author = "author" case member = "member" @@ -2085,7 +2085,7 @@ public enum GroupMemberRole: String, Identifiable, CaseIterable, Comparable, Cod } } -public enum GroupMemberCategory: String, Decodable { +public enum GroupMemberCategory: String, Decodable, Hashable { case userMember = "user" case inviteeMember = "invitee" case hostMember = "host" @@ -2093,7 +2093,7 @@ public enum GroupMemberCategory: String, Decodable { case postMember = "post" } -public enum GroupMemberStatus: String, Decodable { +public enum GroupMemberStatus: String, Decodable, Hashable { case memRemoved = "removed" case memLeft = "left" case memGroupDeleted = "deleted" @@ -2142,7 +2142,7 @@ public enum GroupMemberStatus: String, Decodable { } } -public struct NoteFolder: Identifiable, Decodable, NamedChat { +public struct NoteFolder: Identifiable, Decodable, NamedChat, Hashable { public var noteFolderId: Int64 public var favorite: Bool public var unread: Bool @@ -2175,18 +2175,18 @@ public struct NoteFolder: Identifiable, Decodable, NamedChat { ) } -public enum InvitedBy: Decodable { +public enum InvitedBy: Decodable, Hashable { case contact(byContactId: Int64) case user case unknown } -public struct MemberSubError: Decodable { +public struct MemberSubError: Decodable, Hashable { var member: GroupMemberIds var memberError: ChatError } -public enum ConnectionEntity: Decodable { +public enum ConnectionEntity: Decodable, Hashable { case rcvDirectMsgConnection(contact: Contact?) case rcvGroupMsgConnection(groupInfo: GroupInfo, groupMember: GroupMember) case sndFileConnection(sndFileTransfer: SndFileTransfer) @@ -2217,12 +2217,12 @@ public enum ConnectionEntity: Decodable { } } -public struct NtfMsgInfo: Decodable { +public struct NtfMsgInfo: Decodable, Hashable { public var msgId: String public var msgTs: Date } -public struct AChatItem: Decodable { +public struct AChatItem: Decodable, Hashable { public var chatInfo: ChatInfo public var chatItem: ChatItem @@ -2234,19 +2234,19 @@ public struct AChatItem: Decodable { } } -public struct ACIReaction: Decodable { +public struct ACIReaction: Decodable, Hashable { public var chatInfo: ChatInfo public var chatReaction: CIReaction } -public struct CIReaction: Decodable { +public struct CIReaction: Decodable, Hashable { public var chatDir: CIDirection public var chatItem: ChatItem public var sentAt: Date public var reaction: MsgReaction } -public struct ChatItem: Identifiable, Decodable { +public struct ChatItem: Identifiable, Decodable, Hashable { public init(chatDir: CIDirection, meta: CIMeta, content: CIContent, formattedText: [FormattedText]? = nil, quotedItem: CIQuote? = nil, reactions: [CIReactionCount] = [], file: CIFile? = nil) { self.chatDir = chatDir self.meta = meta @@ -2596,7 +2596,7 @@ public struct ChatItem: Identifiable, Decodable { } } -public enum CIMergeCategory { +public enum CIMergeCategory: Hashable { case memberConnected case rcvGroupEvent case sndGroupEvent @@ -2605,7 +2605,7 @@ public enum CIMergeCategory { case chatFeature } -public enum CIDirection: Decodable { +public enum CIDirection: Decodable, Hashable { case directSnd case directRcv case groupSnd @@ -2627,7 +2627,7 @@ public enum CIDirection: Decodable { } } -public struct CIMeta: Decodable { +public struct CIMeta: Decodable, Hashable { public var itemId: Int64 public var itemTs: Date var itemText: String @@ -2690,7 +2690,7 @@ public struct CIMeta: Decodable { } } -public struct CITimed: Decodable { +public struct CITimed: Decodable, Hashable { public var ttl: Int public var deleteAt: Date? } @@ -2717,7 +2717,7 @@ private func recent(_ date: Date) -> Bool { return isSameDay || (now < currentDay12 && date >= previousDay18 && date < currentDay00) } -public enum CIStatus: Decodable { +public enum CIStatus: Decodable, Hashable { case sndNew case sndSent(sndProgress: SndCIStatusProgress) case sndRcvd(msgRcptStatus: MsgReceiptStatus, sndProgress: SndCIStatusProgress) @@ -2787,7 +2787,7 @@ public enum CIStatus: Decodable { } } -public enum SndError: Decodable { +public enum SndError: Decodable, Hashable { case auth case quota case expired @@ -2809,7 +2809,7 @@ public enum SndError: Decodable { } } -public enum SrvError: Decodable, Equatable { +public enum SrvError: Decodable, Hashable { case host case version case other(srvError: String) @@ -2831,17 +2831,17 @@ public enum SrvError: Decodable, Equatable { } } -public enum MsgReceiptStatus: String, Decodable { +public enum MsgReceiptStatus: String, Decodable, Hashable { case ok case badMsgHash } -public enum SndCIStatusProgress: String, Decodable { +public enum SndCIStatusProgress: String, Decodable, Hashable { case partial case complete } -public enum CIDeleted: Decodable { +public enum CIDeleted: Decodable, Hashable { case deleted(deletedTs: Date?) case blocked(deletedTs: Date?) case blockedByAdmin(deletedTs: Date?) @@ -2857,12 +2857,12 @@ public enum CIDeleted: Decodable { } } -public enum MsgDirection: String, Decodable { +public enum MsgDirection: String, Decodable, Hashable { case rcv = "rcv" case snd = "snd" } -public enum CIForwardedFrom: Decodable { +public enum CIForwardedFrom: Decodable, Hashable { case unknown case contact(chatName: String, msgDir: MsgDirection, contactId: Int64?, chatItemId: Int64?) case group(chatName: String, msgDir: MsgDirection, groupId: Int64?, chatItemId: Int64?) @@ -2882,7 +2882,7 @@ public enum CIForwardedFrom: Decodable { } } -public enum CIDeleteMode: String, Decodable { +public enum CIDeleteMode: String, Decodable, Hashable { case cidmBroadcast = "broadcast" case cidmInternal = "internal" } @@ -2891,7 +2891,7 @@ protocol ItemContent { var text: String { get } } -public enum CIContent: Decodable, ItemContent { +public enum CIContent: Decodable, ItemContent, Hashable { case sndMsgContent(msgContent: MsgContent) case rcvMsgContent(msgContent: MsgContent) case sndDeleted(deleteMode: CIDeleteMode) // legacy - since v4.3.0 itemDeleted field is used @@ -3027,7 +3027,7 @@ public enum CIContent: Decodable, ItemContent { } } -public enum MsgDecryptError: String, Decodable { +public enum MsgDecryptError: String, Decodable, Hashable { case ratchetHeader case tooManySkipped case ratchetEarlier @@ -3045,7 +3045,7 @@ public enum MsgDecryptError: String, Decodable { } } -public struct CIQuote: Decodable, ItemContent { +public struct CIQuote: Decodable, ItemContent, Hashable { public var chatDir: CIDirection? public var itemId: Int64? var sharedMsgId: String? = nil @@ -3083,13 +3083,13 @@ public struct CIQuote: Decodable, ItemContent { } } -public struct CIReactionCount: Decodable { +public struct CIReactionCount: Decodable, Hashable { public var reaction: MsgReaction public var userReacted: Bool public var totalReacted: Int } -public enum MsgReaction: Hashable { +public enum MsgReaction: Hashable, Identifiable { case emoji(emoji: MREmojiChar) case unknown(type: String) @@ -3110,9 +3110,16 @@ public enum MsgReaction: Hashable { case type case emoji } + + public var id: String { + switch self { + case let .emoji(emoji): emoji.rawValue + case let .unknown(unknown): unknown + } + } } -public enum MREmojiChar: String, Codable, CaseIterable { +public enum MREmojiChar: String, Codable, CaseIterable, Hashable { case thumbsup = "👍" case thumbsdown = "👎" case smile = "😀" @@ -3153,7 +3160,7 @@ extension MsgReaction: Encodable { } } -public struct CIFile: Decodable { +public struct CIFile: Decodable, Hashable { public var fileId: Int64 public var fileName: String public var fileSize: Int64 @@ -3221,7 +3228,7 @@ public struct CIFile: Decodable { } } -public struct CryptoFile: Codable { +public struct CryptoFile: Codable, Hashable { public var filePath: String // the name of the file, not a full path public var cryptoArgs: CryptoFileArgs? @@ -3268,22 +3275,28 @@ public struct CryptoFile: Codable { static var decryptedUrls = Dictionary() } -public struct CryptoFileArgs: Codable { +public struct CryptoFileArgs: Codable, Hashable { public var fileKey: String public var fileNonce: String } -public struct CancelAction { +public struct CancelAction: Hashable { public var uiAction: String public var alert: AlertInfo } -public struct AlertInfo { +public struct AlertInfo: Hashable { public var title: LocalizedStringKey public var message: LocalizedStringKey public var confirm: LocalizedStringKey } +extension LocalizedStringKey: Hashable { + public func hash(into hasher: inout Hasher) { + hasher.combine("\(self)") + } +} + private var sndCancelAction = CancelAction( uiAction: NSLocalizedString("Stop file", comment: "cancel file action"), alert: AlertInfo( @@ -3311,13 +3324,13 @@ private var rcvCancelAction = CancelAction( ) ) -public enum FileProtocol: String, Decodable { +public enum FileProtocol: String, Decodable, Hashable { case smp = "smp" case xftp = "xftp" case local = "local" } -public enum CIFileStatus: Decodable, Equatable { +public enum CIFileStatus: Decodable, Equatable, Hashable { case sndStored case sndTransfer(sndProgress: Int64, sndTotal: Int64) case sndComplete @@ -3355,7 +3368,7 @@ public enum CIFileStatus: Decodable, Equatable { } } -public enum FileError: Decodable, Equatable { +public enum FileError: Decodable, Equatable, Hashable { case auth case noFile case relay(srvError: SrvError) @@ -3380,7 +3393,7 @@ public enum FileError: Decodable, Equatable { } } -public enum MsgContent: Equatable { +public enum MsgContent: Equatable, Hashable { case text(String) case link(text: String, preview: LinkPreview) case image(text: String, image: String) @@ -3547,7 +3560,7 @@ extension MsgContent: Encodable { } } -public struct FormattedText: Decodable { +public struct FormattedText: Decodable, Hashable { public var text: String public var format: Format? @@ -3556,7 +3569,7 @@ public struct FormattedText: Decodable { } } -public enum Format: Decodable, Equatable { +public enum Format: Decodable, Equatable, Hashable { case bold case italic case strikeThrough @@ -3578,7 +3591,7 @@ public enum Format: Decodable, Equatable { } } -public enum SimplexLinkType: String, Decodable { +public enum SimplexLinkType: String, Decodable, Hashable { case contact case invitation case group @@ -3592,7 +3605,7 @@ public enum SimplexLinkType: String, Decodable { } } -public enum FormatColor: String, Decodable { +public enum FormatColor: String, Decodable, Hashable { case red = "red" case green = "green" case blue = "blue" @@ -3619,7 +3632,7 @@ public enum FormatColor: String, Decodable { } // Struct to use with simplex API -public struct LinkPreview: Codable, Equatable { +public struct LinkPreview: Codable, Equatable, Hashable { public init(uri: URL, title: String, description: String = "", image: String) { self.uri = uri self.title = title @@ -3634,7 +3647,7 @@ public struct LinkPreview: Codable, Equatable { public var image: String } -public enum NtfTknStatus: String, Decodable { +public enum NtfTknStatus: String, Decodable, Hashable { case new = "NEW" case registered = "REGISTERED" case invalid = "INVALID" @@ -3643,22 +3656,22 @@ public enum NtfTknStatus: String, Decodable { case expired = "EXPIRED" } -public struct SndFileTransfer: Decodable { +public struct SndFileTransfer: Decodable, Hashable { } -public struct RcvFileTransfer: Decodable { +public struct RcvFileTransfer: Decodable, Hashable { public let fileId: Int64 } -public struct FileTransferMeta: Decodable { +public struct FileTransferMeta: Decodable, Hashable { public let fileId: Int64 public let fileName: String public let filePath: String public let fileSize: Int64 } -public enum CICallStatus: String, Decodable { +public enum CICallStatus: String, Decodable, Hashable { case pending case missed case rejected @@ -3690,7 +3703,7 @@ public func durationText(_ sec: Int) -> String { : String(format: "%02d:%02d:%02d", m / 60, m % 60, s) } -public enum MsgErrorType: Decodable { +public enum MsgErrorType: Decodable, Hashable { case msgSkipped(fromMsgId: Int64, toMsgId: Int64) case msgBadId(msgId: Int64) case msgBadHash @@ -3707,7 +3720,7 @@ public enum MsgErrorType: Decodable { } } -public struct CIGroupInvitation: Decodable { +public struct CIGroupInvitation: Decodable, Hashable { public var groupId: Int64 public var groupMemberId: Int64 public var localDisplayName: GroupName @@ -3723,18 +3736,18 @@ public struct CIGroupInvitation: Decodable { } } -public enum CIGroupInvitationStatus: String, Decodable { +public enum CIGroupInvitationStatus: String, Decodable, Hashable { case pending case accepted case rejected case expired } -public struct E2EEInfo: Decodable { +public struct E2EEInfo: Decodable, Hashable { public var pqEnabled: Bool } -public enum RcvDirectEvent: Decodable { +public enum RcvDirectEvent: Decodable, Hashable { case contactDeleted case profileUpdated(fromProfile: Profile, toProfile: Profile) @@ -3763,7 +3776,7 @@ public enum RcvDirectEvent: Decodable { } } -public enum RcvGroupEvent: Decodable { +public enum RcvGroupEvent: Decodable, Hashable { case memberAdded(groupMemberId: Int64, profile: Profile) case memberConnected case memberLeft @@ -3819,7 +3832,7 @@ public enum RcvGroupEvent: Decodable { } } -public enum SndGroupEvent: Decodable { +public enum SndGroupEvent: Decodable, Hashable { case memberRole(groupMemberId: Int64, profile: Profile, role: GroupMemberRole) case userRole(role: GroupMemberRole) case memberBlocked(groupMemberId: Int64, profile: Profile, blocked: Bool) @@ -3847,7 +3860,7 @@ public enum SndGroupEvent: Decodable { } } -public enum RcvConnEvent: Decodable { +public enum RcvConnEvent: Decodable, Hashable { case switchQueue(phase: SwitchPhase) case ratchetSync(syncStatus: RatchetSyncState) case verificationCodeReset @@ -3884,7 +3897,7 @@ func ratchetSyncStatusToText(_ ratchetSyncStatus: RatchetSyncState) -> String { } } -public enum SndConnEvent: Decodable { +public enum SndConnEvent: Decodable, Hashable { case switchQueue(phase: SwitchPhase, member: GroupMemberRef?) case ratchetSync(syncStatus: RatchetSyncState, member: GroupMemberRef?) case pqEnabled(enabled: Bool) @@ -3921,14 +3934,14 @@ public enum SndConnEvent: Decodable { } } -public enum SwitchPhase: String, Decodable { +public enum SwitchPhase: String, Decodable, Hashable { case started case confirmed case secured case completed } -public enum ChatItemTTL: Hashable, Identifiable, Comparable { +public enum ChatItemTTL: Identifiable, Comparable, Hashable { case day case week case month @@ -3978,13 +3991,13 @@ public enum ChatItemTTL: Hashable, Identifiable, Comparable { } } -public struct ChatItemInfo: Decodable { +public struct ChatItemInfo: Decodable, Hashable { public var itemVersions: [ChatItemVersion] public var memberDeliveryStatuses: [MemberDeliveryStatus]? public var forwardedFromChatItem: AChatItem? } -public struct ChatItemVersion: Decodable { +public struct ChatItemVersion: Decodable, Hashable { public var chatItemVersionId: Int64 public var msgContent: MsgContent public var formattedText: [FormattedText]? @@ -3992,7 +4005,7 @@ public struct ChatItemVersion: Decodable { public var createdAt: Date } -public struct MemberDeliveryStatus: Decodable { +public struct MemberDeliveryStatus: Decodable, Hashable { public var groupMemberId: Int64 public var memberDeliveryStatus: CIStatus public var sentViaProxy: Bool? From 4bd6517d19aff7f5edd9caf4216691f8cb20ece6 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:58:37 +0400 Subject: [PATCH 20/43] core: servers stats improvements, fixes (#4358) --- cabal.project | 2 +- scripts/nix/sha256map.nix | 2 +- src/Simplex/Chat.hs | 2 + src/Simplex/Chat/Controller.hs | 1 + src/Simplex/Chat/Stats.hs | 174 +++++++++++++++++++-------------- 5 files changed, 105 insertions(+), 76 deletions(-) diff --git a/cabal.project b/cabal.project index 3f05fb8561..e5220e2156 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: f392ce0a9355cd3883400906ae6c361b77ca46ea + tag: ae8e1c5e9aa3155907f1bd075e9c69af5fce2bee source-repository-package type: git diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index d046469ea8..712a0dbff4 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."f392ce0a9355cd3883400906ae6c361b77ca46ea" = "0id9mg30kmhlfcpnn2np3f0a4bb4smdzvhrbw6km8vv26si1js60"; + "https://github.com/simplex-chat/simplexmq.git"."ae8e1c5e9aa3155907f1bd075e9c69af5fce2bee" = "1k6phsn0xslqwd30g6l5bsg3ilghwjh2csav2g4bk6hb5a5ga2yk"; "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"; diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index cc829eaa16..131fbb7089 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -2266,6 +2266,7 @@ processChatCommand' vr = \case servers <- map (\ServerCfg {server} -> server) <$> withStore' (`getProtocolServers` users) let srvs = if null servers then L.toList defServers else servers pure $ map protoServer srvs + ResetAgentServersStats -> withAgent resetAgentServersStats >> ok_ GetAgentWorkers -> lift $ CRAgentWorkersSummary <$> withAgent' getAgentWorkersSummary GetAgentWorkersDetails -> lift $ CRAgentWorkersDetails <$> withAgent' getAgentWorkersDetails GetAgentSubs -> lift $ summary <$> withAgent' getAgentSubscriptions @@ -7616,6 +7617,7 @@ chatCommandP = "/debug locks" $> DebugLocks, "/debug event " *> (DebugEvent <$> jsonP), "/get servers summary " *> (GetAgentServersSummary <$> A.decimal), + "/reset servers stats" $> ResetAgentServersStats, "/get subs" $> GetAgentSubs, "/get subs details" $> GetAgentSubsDetails, "/get workers" $> GetAgentWorkers, diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index 366e767154..14f8d6ff5c 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -507,6 +507,7 @@ data ChatCommand | DebugLocks | DebugEvent ChatResponse | GetAgentServersSummary UserId + | ResetAgentServersStats | GetAgentSubs | GetAgentSubsDetails | GetAgentWorkers diff --git a/src/Simplex/Chat/Stats.hs b/src/Simplex/Chat/Stats.hs index f6ea195e1c..f14353f0e0 100644 --- a/src/Simplex/Chat/Stats.hs +++ b/src/Simplex/Chat/Stats.hs @@ -5,7 +5,6 @@ module Simplex.Chat.Stats where -import Control.Applicative ((<|>)) import qualified Data.Aeson.TH as J import Data.Map.Strict (Map) import qualified Data.Map.Strict as M @@ -20,8 +19,10 @@ import Simplex.Messaging.Protocol data PresentedServersSummary = PresentedServersSummary { statsStartedAt :: UTCTime, - currentUserServers :: ServersSummary, - allUsersServers :: ServersSummary + allUsersSMP :: SMPServersSummary, + allUsersXFTP :: XFTPServersSummary, + currentUserSMP :: SMPServersSummary, + currentUserXFTP :: XFTPServersSummary } deriving (Show) @@ -29,8 +30,10 @@ data PresentedServersSummary = PresentedServersSummary -- so users can differentiate currently used (connected) servers, -- previously connected servers that were in use in previous sessions, -- and servers that are only proxied (not connected directly). -data ServersSummary = ServersSummary - { -- currently used SMP servers are those with Just in sessions and/or subs in SMPServerSummary; +data SMPServersSummary = SMPServersSummary + { -- SMP totals are calculated from all accounted SMP server summaries + smpTotals :: SMPTotals, + -- currently used SMP servers are those with Just in sessions and/or subs in SMPServerSummary; -- all other servers would fall either into previously used or only proxied servers category currentlyUsedSMPServers :: [SMPServerSummary], -- previously used SMP servers are those with Nothing in sessions and subs, @@ -40,13 +43,14 @@ data ServersSummary = ServersSummary -- only proxied SMP servers are those that aren't (according to current state - sessions and subs) -- and weren't (according to stats) connected directly; they would have Nothing in sessions and subs, -- and have all of sentDirect, sentProxied, recvMsgs, etc. = 0 in server stats - onlyProxiedSMPServers :: [SMPServerSummary], - -- currently used XFTP servers are those with Just in sessions in XFTPServerSummary, - -- and/or have upload/download/deletion in progress; - -- all other servers would fall into previously used servers category - currentlyUsedXFTPServers :: [XFTPServerSummary], - -- previously used XFTP servers are those with Nothing in sessions and don't have any process in progress - previouslyUsedXFTPServers :: [XFTPServerSummary] + onlyProxiedSMPServers :: [SMPServerSummary] + } + deriving (Show) + +data SMPTotals = SMPTotals + { sessions :: ServerSessions, + subs :: SMPServerSubs, + stats :: AgentSMPServerStatsData } deriving (Show) @@ -68,6 +72,24 @@ data SMPServerSummary = SMPServerSummary } deriving (Show) +data XFTPServersSummary = XFTPServersSummary + { -- XFTP totals are calculated from all accounted XFTP server summaries + xftpTotals :: XFTPTotals, + -- currently used XFTP servers are those with Just in sessions in XFTPServerSummary, + -- and/or have upload/download/deletion in progress; + -- all other servers would fall into previously used servers category + currentlyUsedXFTPServers :: [XFTPServerSummary], + -- previously used XFTP servers are those with Nothing in sessions and don't have any process in progress + previouslyUsedXFTPServers :: [XFTPServerSummary] + } + deriving (Show) + +data XFTPTotals = XFTPTotals + { sessions :: ServerSessions, + stats :: AgentXFTPServerStatsData + } + deriving (Show) + data XFTPServerSummary = XFTPServerSummary { xftpServer :: XFTPServer, known :: Maybe Bool, -- same as for SMPServerSummary @@ -87,34 +109,64 @@ data XFTPServerSummary = XFTPServerSummary toPresentedServersSummary :: AgentServersSummary -> [User] -> User -> [SMPServer] -> [XFTPServer] -> PresentedServersSummary toPresentedServersSummary agentSummary users currentUser userSMPSrvs userXFTPSrvs = do let (userSMPSrvsSumms, allSMPSrvsSumms) = accSMPSrvsSummaries + (userSMPTotals, allSMPTotals) = (accSMPTotals userSMPSrvsSumms, accSMPTotals allSMPSrvsSumms) (userSMPCurr, userSMPPrev, userSMPProx) = smpSummsIntoCategories userSMPSrvsSumms (allSMPCurr, allSMPPrev, allSMPProx) = smpSummsIntoCategories allSMPSrvsSumms (userXFTPSrvsSumms, allXFTPSrvsSumms) = accXFTPSrvsSummaries + (userXFTPTotals, allXFTPTotals) = (accXFTPTotals userXFTPSrvsSumms, accXFTPTotals allXFTPSrvsSumms) (userXFTPCurr, userXFTPPrev) = xftpSummsIntoCategories userXFTPSrvsSumms (allXFTPCurr, allXFTPPrev) = xftpSummsIntoCategories allXFTPSrvsSumms PresentedServersSummary { statsStartedAt, - currentUserServers = - ServersSummary - { currentlyUsedSMPServers = userSMPCurr, - previouslyUsedSMPServers = userSMPPrev, - onlyProxiedSMPServers = userSMPProx, - currentlyUsedXFTPServers = userXFTPCurr, - previouslyUsedXFTPServers = userXFTPPrev - }, - allUsersServers = - ServersSummary - { currentlyUsedSMPServers = allSMPCurr, + allUsersSMP = + SMPServersSummary + { smpTotals = allSMPTotals, + currentlyUsedSMPServers = allSMPCurr, previouslyUsedSMPServers = allSMPPrev, - onlyProxiedSMPServers = allSMPProx, + onlyProxiedSMPServers = allSMPProx + }, + allUsersXFTP = + XFTPServersSummary + { xftpTotals = allXFTPTotals, currentlyUsedXFTPServers = allXFTPCurr, previouslyUsedXFTPServers = allXFTPPrev + }, + currentUserSMP = + SMPServersSummary + { smpTotals = userSMPTotals, + currentlyUsedSMPServers = userSMPCurr, + previouslyUsedSMPServers = userSMPPrev, + onlyProxiedSMPServers = userSMPProx + }, + currentUserXFTP = + XFTPServersSummary + { xftpTotals = userXFTPTotals, + currentlyUsedXFTPServers = userXFTPCurr, + previouslyUsedXFTPServers = userXFTPPrev } } where AgentServersSummary {statsStartedAt, smpServersSessions, smpServersSubs, smpServersStats, xftpServersSessions, xftpServersStats, xftpRcvInProgress, xftpSndInProgress, xftpDelInProgress} = agentSummary - countUserInAll auId = auId == aUserId currentUser || auId `notElem` hiddenUserIds - hiddenUserIds = map aUserId $ filter (isJust . viewPwdHash) users + countUserInAll auId = countUserInAllStats (AgentUserId auId) currentUser users + accSMPTotals :: Map SMPServer SMPServerSummary -> SMPTotals + accSMPTotals = M.foldr addTotals initialTotals + where + initialTotals = SMPTotals {sessions = ServerSessions 0 0 0, subs = SMPServerSubs 0 0, stats = newAgentSMPServerStatsData} + addTotals SMPServerSummary {sessions, subs, stats} SMPTotals {sessions = accSess, subs = accSubs, stats = accStats} = + SMPTotals + { sessions = maybe accSess (accSess `addServerSessions`) sessions, + subs = maybe accSubs (accSubs `addSMPSubs`) subs, + stats = maybe accStats (accStats `addSMPStatsData`) stats + } + accXFTPTotals :: Map XFTPServer XFTPServerSummary -> XFTPTotals + accXFTPTotals = M.foldr addTotals initialTotals + where + initialTotals = XFTPTotals {sessions = ServerSessions 0 0 0, stats = newAgentXFTPServerStatsData} + addTotals XFTPServerSummary {sessions, stats} XFTPTotals {sessions = accSess, stats = accStats} = + XFTPTotals + { sessions = maybe accSess (accSess `addServerSessions`) sessions, + stats = maybe accStats (accStats `addXFTPStatsData`) stats + } smpSummsIntoCategories :: Map SMPServer SMPServerSummary -> ([SMPServerSummary], [SMPServerSummary], [SMPServerSummary]) smpSummsIntoCategories = foldr partitionSummary ([], [], []) where @@ -171,7 +223,7 @@ toPresentedServersSummary agentSummary users currentUser userSMPSrvs userXFTPSrv addSubs :: SMPServerSubs -> SMPServerSummary -> SMPServerSummary addSubs s summ@SMPServerSummary {subs} = summ {subs = Just $ maybe s (s `addSMPSubs`) subs} addStats :: AgentSMPServerStatsData -> SMPServerSummary -> SMPServerSummary - addStats s summ@SMPServerSummary {stats} = summ {stats = Just $ maybe s (s `addSMPStats`) stats} + addStats s summ@SMPServerSummary {stats} = summ {stats = Just $ maybe s (s `addSMPStatsData`) stats} accXFTPSrvsSummaries :: (Map XFTPServer XFTPServerSummary, Map XFTPServer XFTPServerSummary) accXFTPSrvsSummaries = M.foldrWithKey' (addServerData addStats) summs1 xftpServersStats where @@ -205,7 +257,7 @@ toPresentedServersSummary agentSummary users currentUser userSMPSrvs userXFTPSrv addSessions :: ServerSessions -> XFTPServerSummary -> XFTPServerSummary addSessions s summ@XFTPServerSummary {sessions} = summ {sessions = Just $ maybe s (s `addServerSessions`) sessions} addStats :: AgentXFTPServerStatsData -> XFTPServerSummary -> XFTPServerSummary - addStats s summ@XFTPServerSummary {stats} = summ {stats = Just $ maybe s (s `addXFTPStats`) stats} + addStats s summ@XFTPServerSummary {stats} = summ {stats = Just $ maybe s (s `addXFTPStatsData`) stats} addServerSessions :: ServerSessions -> ServerSessions -> ServerSessions addServerSessions ss1 ss2 = ServerSessions @@ -213,56 +265,30 @@ toPresentedServersSummary agentSummary users currentUser userSMPSrvs userXFTPSrv ssErrors = ssErrors ss1 + ssErrors ss2, ssConnecting = ssConnecting ss1 + ssConnecting ss2 } - addSMPSubs :: SMPServerSubs -> SMPServerSubs -> SMPServerSubs - addSMPSubs ss1 ss2 = - SMPServerSubs - { ssActive = ssActive ss1 + ssActive ss2, - ssPending = ssPending ss1 + ssPending ss2 - } - addSMPStats :: AgentSMPServerStatsData -> AgentSMPServerStatsData -> AgentSMPServerStatsData - addSMPStats sd1 sd2 = - AgentSMPServerStatsData - { _sentDirect = _sentDirect sd1 + _sentDirect sd2, - _sentViaProxy = _sentViaProxy sd1 + _sentViaProxy sd2, - _sentProxied = _sentProxied sd1 + _sentProxied sd2, - _sentDirectAttempts = _sentDirectAttempts sd1 + _sentDirectAttempts sd2, - _sentViaProxyAttempts = _sentViaProxyAttempts sd1 + _sentViaProxyAttempts sd2, - _sentProxiedAttempts = _sentProxiedAttempts sd1 + _sentProxiedAttempts sd2, - _sentAuthErrs = _sentAuthErrs sd1 + _sentAuthErrs sd2, - _sentQuotaErrs = _sentQuotaErrs sd1 + _sentQuotaErrs sd2, - _sentExpiredErrs = _sentExpiredErrs sd1 + _sentExpiredErrs sd2, - _sentOtherErrs = _sentOtherErrs sd1 + _sentOtherErrs sd2, - _recvMsgs = _recvMsgs sd1 + _recvMsgs sd2, - _recvDuplicates = _recvDuplicates sd1 + _recvDuplicates sd2, - _recvCryptoErrs = _recvCryptoErrs sd1 + _recvCryptoErrs sd2, - _recvErrs = _recvErrs sd1 + _recvErrs sd2, - _connCreated = _connCreated sd1 + _connCreated sd2, - _connSecured = _connSecured sd1 + _connSecured sd2, - _connCompleted = _connCompleted sd1 + _connCompleted sd2, - _connDeleted = _connDeleted sd1 + _connDeleted sd2, - _connSubscribed = _connSubscribed sd1 + _connSubscribed sd2, - _connSubAttempts = _connSubAttempts sd1 + _connSubAttempts sd2, - _connSubErrs = _connSubErrs sd1 + _connSubErrs sd2 - } - addXFTPStats :: AgentXFTPServerStatsData -> AgentXFTPServerStatsData -> AgentXFTPServerStatsData - addXFTPStats sd1 sd2 = - AgentXFTPServerStatsData - { _uploads = _uploads sd1 + _uploads sd2, - _uploadAttempts = _uploadAttempts sd1 + _uploadAttempts sd2, - _uploadErrs = _uploadErrs sd1 + _uploadErrs sd2, - _downloads = _downloads sd1 + _downloads sd2, - _downloadAttempts = _downloadAttempts sd1 + _downloadAttempts sd2, - _downloadAuthErrs = _downloadAuthErrs sd1 + _downloadAuthErrs sd2, - _downloadErrs = _downloadErrs sd1 + _downloadErrs sd2, - _deletions = _deletions sd1 + _deletions sd2, - _deleteAttempts = _deleteAttempts sd1 + _deleteAttempts sd2, - _deleteErrs = _deleteErrs sd1 + _deleteErrs sd2 - } + +countUserInAllStats :: AgentUserId -> User -> [User] -> Bool +countUserInAllStats (AgentUserId auId) currentUser users = + auId == aUserId currentUser || auId `notElem` hiddenUserIds + where + hiddenUserIds = map aUserId $ filter (isJust . viewPwdHash) users + +addSMPSubs :: SMPServerSubs -> SMPServerSubs -> SMPServerSubs +addSMPSubs ss1 ss2 = + SMPServerSubs + { ssActive = ssActive ss1 + ssActive ss2, + ssPending = ssPending ss1 + ssPending ss2 + } + +$(J.deriveJSON defaultJSON ''SMPTotals) $(J.deriveJSON defaultJSON ''SMPServerSummary) +$(J.deriveJSON defaultJSON ''SMPServersSummary) + +$(J.deriveJSON defaultJSON ''XFTPTotals) + $(J.deriveJSON defaultJSON ''XFTPServerSummary) -$(J.deriveJSON defaultJSON ''ServersSummary) +$(J.deriveJSON defaultJSON ''XFTPServersSummary) $(J.deriveJSON defaultJSON ''PresentedServersSummary) From 1180edf80e0441d0f41fc6113117382fccf27477 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Wed, 3 Jul 2024 16:59:46 +0400 Subject: [PATCH 21/43] ios: servers summary (#4321) * types * chat list buttons * update * wip * xftp summary * sub status view * reconnect server button * reset stats button * refactor * subscription icon in server view * getAgentSubsSummary api * view * subs indicator with timer * rename * variableValueAsPercentage * encodePrettyPrinted * totals, timer * reduce interval * show more/less stats * refactor * sort * rework indicator wip * change offline icon * rework indicator * show percent * file progress * fix * onion * user servers, icons * dashes * Revert "user servers, icons" This reverts commit 805e7e9bd6ad838b14901771f60f6442a021f7d2. * remove icon, remove total, remove session % * exclude sessions * move starting from * file stats * fix * open server settings * file in progress * update * wpi * wip * rework stats * arrow for sessions * texts * reconnect all * single user * rework file stats * update * dont log terminal items * center * update * _connSubIgnored * rename * update * large titles * refactor * update * text * upd * single dash --- apps/ios/Shared/Model/SimpleXAPI.swift | 37 +- .../Shared/Views/ChatList/ChatListView.swift | 125 ++- .../Views/ChatList/ServersSummaryView.swift | 741 ++++++++++++++++++ .../Views/NewChat/NewChatMenuButton.swift | 7 + .../UserSettings/NetworkAndServers.swift | 5 +- .../Views/UserSettings/SettingsView.swift | 2 + apps/ios/SimpleX.xcodeproj/project.pbxproj | 4 + apps/ios/SimpleXChat/APITypes.swift | 158 +++- apps/ios/SimpleXChat/ChatTypes.swift | 2 + 9 files changed, 1034 insertions(+), 47 deletions(-) create mode 100644 apps/ios/Shared/Views/ChatList/ServersSummaryView.swift diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index eb66071ef8..4751968496 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -92,18 +92,22 @@ private func withBGTask(bgDelay: Double? = nil, f: @escaping () -> T) -> T { return r } -func chatSendCmdSync(_ cmd: ChatCommand, bgTask: Bool = true, bgDelay: Double? = nil, _ ctrl: chat_ctrl? = nil) -> ChatResponse { - logger.debug("chatSendCmd \(cmd.cmdType)") +func chatSendCmdSync(_ cmd: ChatCommand, bgTask: Bool = true, bgDelay: Double? = nil, _ ctrl: chat_ctrl? = nil, log: Bool = true) -> ChatResponse { + if log { + logger.debug("chatSendCmd \(cmd.cmdType)") + } let start = Date.now let resp = bgTask ? withBGTask(bgDelay: bgDelay) { sendSimpleXCmd(cmd, ctrl) } : sendSimpleXCmd(cmd, ctrl) - logger.debug("chatSendCmd \(cmd.cmdType): \(resp.responseType)") - if case let .response(_, json) = resp { - logger.debug("chatSendCmd \(cmd.cmdType) response: \(json)") - } - Task { - await TerminalItems.shared.addCommand(start, cmd.obfuscated, resp) + if log { + logger.debug("chatSendCmd \(cmd.cmdType): \(resp.responseType)") + if case let .response(_, json) = resp { + logger.debug("chatSendCmd \(cmd.cmdType) response: \(json)") + } + Task { + await TerminalItems.shared.addCommand(start, cmd.obfuscated, resp) + } } return resp } @@ -543,6 +547,11 @@ func reconnectAllServers() async throws { try await sendCommandOkResp(.reconnectAllServers) } +func reconnectServer(smpServer: String) async throws { + let userId = try currentUserId("reconnectServer") + try await sendCommandOkResp(.reconnectServer(userId: userId, smpServer: smpServer)) +} + func apiSetChatSettings(type: ChatType, id: Int64, chatSettings: ChatSettings) async throws { try await sendCommandOkResp(.apiSetChatSettings(type: type, id: id, chatSettings: chatSettings)) } @@ -1336,6 +1345,18 @@ func apiGetVersion() throws -> CoreVersionInfo { throw r } +func getAgentServersSummary() throws -> PresentedServersSummary { + let userId = try currentUserId("getAgentServersSummary") + let r = chatSendCmdSync(.getAgentServersSummary(userId: userId), log: false) + if case let .agentServersSummary(_, serversSummary) = r { return serversSummary } + logger.error("getAgentServersSummary error: \(String(describing: r))") + throw r +} + +func resetAgentServersStats() async throws { + try await sendCommandOkResp(.resetAgentServersStats) +} + private func currentUserId(_ funcName: String) throws -> Int64 { if let userId = ChatModel.shared.currentUser?.userId { return userId diff --git a/apps/ios/Shared/Views/ChatList/ChatListView.swift b/apps/ios/Shared/Views/ChatList/ChatListView.swift index e39d39293a..9471e09d5e 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListView.swift @@ -115,9 +115,7 @@ struct ChatListView: View { HStack(spacing: 4) { Text("Chats") .font(.headline) - if chatModel.chats.count > 0 { - toggleFilterButton() - } + SubsStatusIndicator() } .frame(maxWidth: .infinity, alignment: .center) } @@ -131,15 +129,6 @@ struct ChatListView: View { } } - private func toggleFilterButton() -> some View { - Button { - showUnreadAndFavorites = !showUnreadAndFavorites - } label: { - Image(systemName: "line.3.horizontal.decrease.circle" + (showUnreadAndFavorites ? ".fill" : "")) - .foregroundColor(.accentColor) - } - } - @ViewBuilder private var chatList: some View { let cs = filteredChats() ZStack { @@ -272,6 +261,75 @@ struct ChatListView: View { } } +struct SubsStatusIndicator: View { + @State private var subs: SMPServerSubs = SMPServerSubs.newSMPServerSubs + @State private var sess: ServerSessions = ServerSessions.newServerSessions + @State private var timer: Timer? = nil + @State private var timerCounter = 0 + @State private var showServersSummary = false + + @AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false + + // Constants for the intervals + let initialInterval: TimeInterval = 1.0 + let regularInterval: TimeInterval = 3.0 + let initialPhaseDuration: TimeInterval = 10.0 // Duration for initial phase in seconds + + var body: some View { + Button { + showServersSummary = true + } label: { + HStack(spacing: 4) { + SubscriptionStatusIndicatorView(subs: subs, sess: sess) + if showSubscriptionPercentage { + SubscriptionStatusPercentageView(subs: subs, sess: sess) + } + } + } + .onAppear { + startInitialTimer() + } + .onDisappear { + stopTimer() + } + .sheet(isPresented: $showServersSummary) { + ServersSummaryView() + } + } + + private func startInitialTimer() { + timer = Timer.scheduledTimer(withTimeInterval: initialInterval, repeats: true) { _ in + getServersSummary() + timerCounter += 1 + // Switch to the regular timer after the initial phase + if timerCounter * Int(initialInterval) >= Int(initialPhaseDuration) { + switchToRegularTimer() + } + } + } + + func switchToRegularTimer() { + timer?.invalidate() + timer = Timer.scheduledTimer(withTimeInterval: regularInterval, repeats: true) { _ in + getServersSummary() + } + } + + func stopTimer() { + timer?.invalidate() + timer = nil + } + + private func getServersSummary() { + do { + let summ = try getAgentServersSummary() + (subs, sess) = (summ.allUsersSMP.smpTotals.subs, summ.allUsersSMP.smpTotals.sessions) + } catch let error { + logger.error("getAgentServersSummary error: \(responseError(error))") + } + } +} + struct ChatListSearchBar: View { @EnvironmentObject var m: ChatModel @Binding var searchMode: Bool @@ -280,9 +338,9 @@ struct ChatListSearchBar: View { @Binding var searchShowingSimplexLink: Bool @Binding var searchChatFilteredBySimplexLink: String? @State private var ignoreSearchTextChange = false - @State private var showScanCodeSheet = false @State private var alert: PlanAndConnectAlert? @State private var sheet: PlanAndConnectActionSheet? + @AppStorage(DEFAULT_SHOW_UNREAD_AND_FAVORITES) private var showUnreadAndFavorites = false var body: some View { VStack(spacing: 12) { @@ -299,26 +357,6 @@ struct ChatListSearchBar: View { .onTapGesture { searchText = "" } - } else if !searchFocussed { - HStack(spacing: 24) { - if m.pasteboardHasStrings { - Image(systemName: "doc") - .onTapGesture { - if let str = UIPasteboard.general.string { - searchText = str - } - } - } - - Image(systemName: "qrcode") - .resizable() - .scaledToFit() - .frame(width: 20, height: 20) - .onTapGesture { - showScanCodeSheet = true - } - } - .padding(.trailing, 2) } } .padding(EdgeInsets(top: 7, leading: 7, bottom: 7, trailing: 7)) @@ -333,14 +371,12 @@ struct ChatListSearchBar: View { searchText = "" searchFocussed = false } + } else if m.chats.count > 0 { + toggleFilterButton() } } Divider() } - .sheet(isPresented: $showScanCodeSheet) { - NewChatView(selection: .connect, showQRCodeScanner: true) - .environment(\EnvironmentValues.refresh as! WritableKeyPath, nil) // fixes .refreshable in ChatListView affecting nested view - } .onChange(of: searchFocussed) { sf in withAnimation { searchMode = sf } } @@ -374,6 +410,21 @@ struct ChatListSearchBar: View { } } + private func toggleFilterButton() -> some View { + ZStack { + Color.clear + .frame(width: 22, height: 22) + Image(systemName: showUnreadAndFavorites ? "line.3.horizontal.decrease.circle.fill" : "line.3.horizontal.decrease") + .resizable() + .scaledToFit() + .foregroundColor(showUnreadAndFavorites ? .accentColor : .secondary) + .frame(width: showUnreadAndFavorites ? 22 : 16, height: showUnreadAndFavorites ? 22 : 16) + .onTapGesture { + showUnreadAndFavorites = !showUnreadAndFavorites + } + } + } + private func connect(_ link: String) { planAndConnect( link, diff --git a/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift b/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift new file mode 100644 index 0000000000..ca55d9493b --- /dev/null +++ b/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift @@ -0,0 +1,741 @@ +// +// ServersSummaryView.swift +// SimpleX (iOS) +// +// Created by spaced4ndy on 25.06.2024. +// Copyright © 2024 SimpleX Chat. All rights reserved. +// + +import SwiftUI +import SimpleXChat + +struct ServersSummaryView: View { + @EnvironmentObject var m: ChatModel + @State private var serversSummary: PresentedServersSummary? = nil + @State private var selectedUserCategory: PresentedUserCategory = .allUsers + @State private var selectedServerType: PresentedServerType = .smp + @State private var selectedSMPServer: String? = nil + @State private var selectedXFTPServer: String? = nil + @State private var timer: Timer? = nil + @State private var alert: SomeAlert? + + @AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false + + enum PresentedUserCategory { + case currentUser + case allUsers + } + + enum PresentedServerType { + case smp + case xftp + } + + var body: some View { + NavigationView { + viewBody() + .navigationTitle("Servers info") + .navigationBarTitleDisplayMode(.large) + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + shareButton() + } + } + } + .onAppear { + if m.users.filter({ u in u.user.activeUser || !u.user.hidden }).count == 1 { + selectedUserCategory = .currentUser + } + getServersSummary() + startTimer() + } + .onDisappear { + stopTimer() + } + .alert(item: $alert) { $0.alert } + } + + private func startTimer() { + timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in + getServersSummary() + } + } + + func stopTimer() { + timer?.invalidate() + timer = nil + } + + private func shareButton() -> some View { + Button { + if let serversSummary = serversSummary { + showShareSheet(items: [encodePrettyPrinted(serversSummary)]) + } + } label: { + Image(systemName: "square.and.arrow.up") + } + .disabled(serversSummary == nil) + } + + public func encodePrettyPrinted(_ value: T) -> String { + let encoder = jsonEncoder + encoder.outputFormatting = .prettyPrinted + let data = try! encoder.encode(value) + return String(decoding: data, as: UTF8.self) + } + + @ViewBuilder private func viewBody() -> some View { + if let summ = serversSummary { + List { + Group { + if m.users.filter({ u in u.user.activeUser || !u.user.hidden }).count > 1 { + Picker("User selection", selection: $selectedUserCategory) { + Text("All users").tag(PresentedUserCategory.allUsers) + Text("Current user").tag(PresentedUserCategory.currentUser) + } + .pickerStyle(.segmented) + } + + Picker("Server type", selection: $selectedServerType) { + Text("Messages").tag(PresentedServerType.smp) + Text("Files").tag(PresentedServerType.xftp) + } + .pickerStyle(.segmented) + } + .listRowBackground(Color.clear) + .listRowSeparator(.hidden) + .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) + + switch (selectedUserCategory, selectedServerType) { + case (.allUsers, .smp): + let smpSumm = summ.allUsersSMP + let (totals, curr, prev, prox) = (smpSumm.smpTotals, smpSumm.currentlyUsedSMPServers, smpSumm.previouslyUsedSMPServers, smpSumm.onlyProxiedSMPServers) + + SMPStatsView(stats: totals.stats, statsStartedAt: summ.statsStartedAt) + + smpSubsSection(totals) + + if curr.count > 0 { + smpServersListView(curr, summ.statsStartedAt, "Connected servers") + } + if prev.count > 0 { + smpServersListView(prev, summ.statsStartedAt, "Previously connected servers") + } + if prox.count > 0 { + smpServersListView(prox, summ.statsStartedAt, "Proxied servers", "You are not connected to these servers. Private routing is used to deliver messages to them.") + } + + ServerSessionsView(sess: totals.sessions) + case (.currentUser, .smp): + let smpSumm = summ.currentUserSMP + let (totals, curr, prev, prox) = (smpSumm.smpTotals, smpSumm.currentlyUsedSMPServers, smpSumm.previouslyUsedSMPServers, smpSumm.onlyProxiedSMPServers) + + SMPStatsView(stats: totals.stats, statsStartedAt: summ.statsStartedAt) + + smpSubsSection(totals) + + if curr.count > 0 { + smpServersListView(curr, summ.statsStartedAt, "Connected servers") + } + if prev.count > 0 { + smpServersListView(prev, summ.statsStartedAt, "Previously connected servers") + } + if prox.count > 0 { + smpServersListView(prox, summ.statsStartedAt, "Proxied servers", "You are not connected to these servers. Private routing is used to deliver messages to them.") + } + + ServerSessionsView(sess: totals.sessions) + case (.allUsers, .xftp): + let xftpSumm = summ.allUsersXFTP + let (totals, curr, prev) = (xftpSumm.xftpTotals, xftpSumm.currentlyUsedXFTPServers, xftpSumm.previouslyUsedXFTPServers) + + XFTPStatsView(stats: totals.stats, statsStartedAt: summ.statsStartedAt) + + if curr.count > 0 { + xftpServersListView(curr, summ.statsStartedAt, "Connected servers") + } + if prev.count > 0 { + xftpServersListView(prev, summ.statsStartedAt, "Previously connected servers") + } + + ServerSessionsView(sess: totals.sessions) + case (.currentUser, .xftp): + let xftpSumm = summ.currentUserXFTP + let (totals, curr, prev) = (xftpSumm.xftpTotals, xftpSumm.currentlyUsedXFTPServers, xftpSumm.previouslyUsedXFTPServers) + + XFTPStatsView(stats: totals.stats, statsStartedAt: summ.statsStartedAt) + + if curr.count > 0 { + xftpServersListView(curr, summ.statsStartedAt, "Connected servers") + } + if prev.count > 0 { + xftpServersListView(prev, summ.statsStartedAt, "Previously connected servers") + } + + ServerSessionsView(sess: totals.sessions) + } + + Section { + reconnectAllButton() + resetStatsButton() + } + } + } else { + Text("No info, try to reload") + } + } + + private func smpSubsSection(_ totals: SMPTotals) -> some View { + Section { + infoRow("Connections subscribed", numOrDash(totals.subs.ssActive)) + infoRow("Total", numOrDash(totals.subs.total)) + } header: { + HStack { + Text("Message subscriptions") + SubscriptionStatusIndicatorView(subs: totals.subs, sess: totals.sessions) + if showSubscriptionPercentage { + SubscriptionStatusPercentageView(subs: totals.subs, sess: totals.sessions) + } + } + } + } + + private func reconnectAllButton() -> some View { + Button { + alert = SomeAlert( + alert: Alert( + title: Text("Reconnect all servers?"), + message: Text("Reconnect all connected servers to force message delivery. It uses additional traffic."), + primaryButton: .default(Text("Ok")) { + Task { + do { + try await reconnectAllServers() + } catch let error { + alert = SomeAlert( + alert: mkAlert( + title: "Error reconnecting servers", + message: "\(responseError(error))" + ), + id: "error reconnecting servers" + ) + } + } + }, + secondaryButton: .cancel() + ), + id: "reconnect servers question" + ) + } label: { + Text("Reconnect all servers") + } + } + + @ViewBuilder private func smpServersListView( + _ servers: [SMPServerSummary], + _ statsStartedAt: Date, + _ header: LocalizedStringKey? = nil, + _ footer: LocalizedStringKey? = nil + ) -> some View { + let sortedServers = servers.sorted { + $0.hasSubs == $1.hasSubs + ? serverAddress($0.smpServer) < serverAddress($1.smpServer) + : $0.hasSubs && !$1.hasSubs + } + Section { + ForEach(sortedServers) { server in + smpServerView(server, statsStartedAt) + } + } header: { + if let header = header { + Text(header) + } + } footer: { + if let footer = footer { + Text(footer) + } + } + } + + private func smpServerView(_ srvSumm: SMPServerSummary, _ statsStartedAt: Date) -> some View { + NavigationLink(tag: srvSumm.id, selection: $selectedSMPServer) { + SMPServerSummaryView( + summary: srvSumm, + statsStartedAt: statsStartedAt + ) + .navigationBarTitle("SMP server") + .navigationBarTitleDisplayMode(.large) + } label: { + HStack { + Text(serverAddress(srvSumm.smpServer)) + .lineLimit(1) + if let subs = srvSumm.subs { + Spacer() + if showSubscriptionPercentage { + SubscriptionStatusPercentageView(subs: subs, sess: srvSumm.sessionsOrNew) + } + SubscriptionStatusIndicatorView(subs: subs, sess: srvSumm.sessionsOrNew) + } else if let sess = srvSumm.sessions { + Spacer() + Image(systemName: "arrow.up.circle") + .symbolRenderingMode(.palette) + .foregroundStyle(sessIconColor(sess), Color.clear) + } + } + } + } + + private func serverAddress(_ server: String) -> String { + parseServerAddress(server)?.hostnames.first ?? server + } + + private func sessIconColor(_ sess: ServerSessions) -> Color { + let online = m.networkInfo.online + return ( + online && sess.ssConnected > 0 + ? sessionActiveColor + : Color(uiColor: .tertiaryLabel) + ) + } + + private var sessionActiveColor: Color { + let onionHosts = networkUseOnionHostsGroupDefault.get() + return onionHosts == .require ? .indigo : .accentColor + } + + @ViewBuilder private func xftpServersListView( + _ servers: [XFTPServerSummary], + _ statsStartedAt: Date, + _ header: LocalizedStringKey? = nil, + _ footer: LocalizedStringKey? = nil + ) -> some View { + let sortedServers = servers.sorted { serverAddress($0.xftpServer) < serverAddress($1.xftpServer) } + Section { + ForEach(sortedServers) { server in + xftpServerView(server, statsStartedAt) + } + } header: { + if let header = header { + Text(header) + } + } footer: { + if let footer = footer { + Text(footer) + } + } + } + + private func xftpServerView(_ srvSumm: XFTPServerSummary, _ statsStartedAt: Date) -> some View { + NavigationLink(tag: srvSumm.id, selection: $selectedXFTPServer) { + XFTPServerSummaryView( + summary: srvSumm, + statsStartedAt: statsStartedAt + ) + .navigationBarTitle("XFTP server") + .navigationBarTitleDisplayMode(.large) + } label: { + HStack { + Text(serverAddress(srvSumm.xftpServer)) + .lineLimit(1) + if let inProgressIcon = inProgressIcon(srvSumm) { + Spacer() + Image(systemName: inProgressIcon) + .symbolRenderingMode(.palette) + .foregroundStyle(sessionActiveColor, Color.clear) + } + } + } + } + + private func inProgressIcon(_ srvSumm: XFTPServerSummary) -> String? { + switch (srvSumm.rcvInProgress, srvSumm.sndInProgress, srvSumm.delInProgress) { + case (false, false, false): nil + case (true, false, false): "arrow.down.circle" + case (false, true, false): "arrow.up.circle" + case (false, false, true): "trash.circle" + default: "arrow.up.arrow.down.circle" + } + } + + private func resetStatsButton() -> some View { + Button { + alert = SomeAlert( + alert: Alert( + title: Text("Reset all servers statistics?"), + message: Text("Servers statistics will be reset - this cannot be undone!"), + primaryButton: .destructive(Text("Reset")) { + Task { + do { + try await resetAgentServersStats() + getServersSummary() + } catch let error { + alert = SomeAlert( + alert: mkAlert( + title: "Error resetting statistics", + message: "\(responseError(error))" + ), + id: "error resetting statistics" + ) + } + } + }, + secondaryButton: .cancel() + ), + id: "reset statistics question" + ) + } label: { + Text("Reset all statistics") + } + } + + private func getServersSummary() { + do { + serversSummary = try getAgentServersSummary() + } catch let error { + logger.error("getAgentServersSummary error: \(responseError(error))") + } + } +} + +struct SubscriptionStatusIndicatorView: View { + @EnvironmentObject var m: ChatModel + var subs: SMPServerSubs + var sess: ServerSessions + + var body: some View { + let onionHosts = networkUseOnionHostsGroupDefault.get() + let (color, variableValue, opacity, _) = subscriptionStatusColorAndPercentage(m.networkInfo.online, onionHosts, subs, sess) + if #available(iOS 16.0, *) { + Image(systemName: "dot.radiowaves.up.forward", variableValue: variableValue) + .foregroundColor(color) + } else { + Image(systemName: "dot.radiowaves.up.forward") + .foregroundColor(color.opacity(opacity)) + } + } +} + +struct SubscriptionStatusPercentageView: View { + @EnvironmentObject var m: ChatModel + var subs: SMPServerSubs + var sess: ServerSessions + + var body: some View { + let onionHosts = networkUseOnionHostsGroupDefault.get() + let (_, _, _, statusPercent) = subscriptionStatusColorAndPercentage(m.networkInfo.online, onionHosts, subs, sess) + Text("\(Int(floor(statusPercent * 100)))%") + .foregroundColor(.secondary) + .font(.caption) + } +} + +func subscriptionStatusColorAndPercentage(_ online: Bool, _ onionHosts: OnionHosts, _ subs: SMPServerSubs, _ sess: ServerSessions) -> (Color, Double, Double, Double) { + func roundedToQuarter(_ n: Double) -> Double { + n >= 1 ? 1 + : n <= 0 ? 0 + : (n * 4).rounded() / 4 + } + + let activeColor: Color = onionHosts == .require ? .indigo : .accentColor + let noConnColorAndPercent: (Color, Double, Double, Double) = (Color(uiColor: .tertiaryLabel), 1, 1, 0) + let activeSubsRounded = roundedToQuarter(subs.shareOfActive) + + return online && subs.total > 0 + ? ( + subs.ssActive == 0 + ? ( + sess.ssConnected == 0 ? noConnColorAndPercent : (activeColor, activeSubsRounded, subs.shareOfActive, subs.shareOfActive) + ) + : ( // ssActive > 0 + sess.ssConnected == 0 + ? (.orange, activeSubsRounded, subs.shareOfActive, subs.shareOfActive) // This would mean implementation error + : (activeColor, activeSubsRounded, subs.shareOfActive, subs.shareOfActive) + ) + ) + : noConnColorAndPercent +} + +struct SMPServerSummaryView: View { + var summary: SMPServerSummary + var statsStartedAt: Date + @State private var alert: SomeAlert? + + @AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false + + var body: some View { + List { + Section("Server address") { + Text(summary.smpServer) + .textSelection(.enabled) + if summary.known == true { + NavigationLink { + ProtocolServersView(serverProtocol: .smp) + .navigationTitle("Your SMP servers") + } label: { + Text("Open server settings") + } + } + } + + if let stats = summary.stats { + SMPStatsView(stats: stats, statsStartedAt: statsStartedAt) + } + + if let subs = summary.subs { + smpSubsSection(subs) + } + + if let sess = summary.sessions { + ServerSessionsView(sess: sess) + } + } + .alert(item: $alert) { $0.alert } + } + + private func smpSubsSection(_ subs: SMPServerSubs) -> some View { + Section { + infoRow("Connections subscribed", numOrDash(subs.ssActive)) + infoRow("Pending", numOrDash(subs.ssPending)) + infoRow("Total", numOrDash(subs.total)) + reconnectButton() + } header: { + HStack { + Text("Message subscriptions") + SubscriptionStatusIndicatorView(subs: subs, sess: summary.sessionsOrNew) + if showSubscriptionPercentage { + SubscriptionStatusPercentageView(subs: subs, sess: summary.sessionsOrNew) + } + } + } + } + + private func reconnectButton() -> some View { + Button { + alert = SomeAlert( + alert: Alert( + title: Text("Reconnect server?"), + message: Text("Reconnect server to force message delivery. It uses additional traffic."), + primaryButton: .default(Text("Ok")) { + Task { + do { + try await reconnectServer(smpServer: summary.smpServer) + } catch let error { + alert = SomeAlert( + alert: mkAlert( + title: "Error reconnecting server", + message: "\(responseError(error))" + ), + id: "error reconnecting server" + ) + } + } + }, + secondaryButton: .cancel() + ), + id: "reconnect server question" + ) + } label: { + Text("Reconnect") + } + } +} + +struct ServerSessionsView: View { + var sess: ServerSessions + + var body: some View { + Section("Transport sessions") { + infoRow("Connected", numOrDash(sess.ssConnected)) + infoRow("Errors", numOrDash(sess.ssErrors)) + infoRow("Connecting", numOrDash(sess.ssConnecting)) + } + } +} + +struct SMPStatsView: View { + var stats: AgentSMPServerStatsData + var statsStartedAt: Date + + var body: some View { + Section { + infoRow("Messages sent", numOrDash(stats._sentDirect + stats._sentViaProxy)) + infoRow("Messages received", numOrDash(stats._recvMsgs)) + NavigationLink { + DetailedSMPStatsView(stats: stats, statsStartedAt: statsStartedAt) + .navigationTitle("Detailed statistics") + .navigationBarTitleDisplayMode(.large) + } label: { + Text("Details") + } + } header: { + Text("Statistics") + } footer: { + Text("Starting from \(localTimestamp(statsStartedAt)).") + Text("\n") + Text("All data is private to your device.") + } + } +} + +private func numOrDash(_ n: Int) -> String { + n == 0 ? "-" : "\(n)" +} + +struct DetailedSMPStatsView: View { + var stats: AgentSMPServerStatsData + var statsStartedAt: Date + + var body: some View { + List { + Section("Sent messages") { + infoRow("Sent total", numOrDash(stats._sentDirect + stats._sentViaProxy)) + infoRowTwoValues("Sent directly", "attempts", stats._sentDirect, stats._sentDirectAttempts) + infoRowTwoValues("Sent via proxy", "attempts", stats._sentViaProxy, stats._sentViaProxyAttempts) + infoRowTwoValues("Proxied", "attempts", stats._sentProxied, stats._sentProxiedAttempts) + Text("Send errors") + indentedInfoRow("AUTH", numOrDash(stats._sentAuthErrs)) + indentedInfoRow("QUOTA", numOrDash(stats._sentQuotaErrs)) + indentedInfoRow("expired", numOrDash(stats._sentExpiredErrs)) + indentedInfoRow("other", numOrDash(stats._sentOtherErrs)) + } + Section("Received messages") { + infoRow("Received total", numOrDash(stats._recvMsgs)) + Text("Receive errors") + indentedInfoRow("duplicates", numOrDash(stats._recvDuplicates)) + indentedInfoRow("decryption errors", numOrDash(stats._recvCryptoErrs)) + indentedInfoRow("other errors", numOrDash(stats._recvErrs)) + infoRowTwoValues("Acknowledged", "attempts", stats._ackMsgs, stats._ackAttempts) + Text("Acknowledgement errors") + indentedInfoRow("NO_MSG errors", numOrDash(stats._ackNoMsgErrs)) + indentedInfoRow("other errors", numOrDash(stats._ackOtherErrs)) + } + Section { + infoRow("Created", numOrDash(stats._connCreated)) + infoRow("Secured", numOrDash(stats._connCreated)) + infoRow("Completed", numOrDash(stats._connCompleted)) + infoRowTwoValues("Deleted", "attempts", stats._connDeleted, stats._connDelAttempts) + infoRow("Deletion errors", numOrDash(stats._connDelErrs)) + infoRowTwoValues("Subscribed", "attempts", stats._connSubscribed, stats._connSubAttempts) + infoRow("Subscription results ignored", numOrDash(stats._connSubIgnored)) + infoRow("Subscription errors", numOrDash(stats._connSubErrs)) + } header: { + Text("Connections") + } footer: { + Text("Starting from \(localTimestamp(statsStartedAt)).") + } + } + } +} + +private func infoRowTwoValues(_ title: LocalizedStringKey, _ title2: LocalizedStringKey, _ value: Int, _ value2: Int) -> some View { + HStack { + Text(title) + Text(" / ").font(.caption2) + Text(title2).font(.caption2) + Spacer() + Group { + if value == 0 && value2 == 0 { + Text("-") + } else { + Text(numOrDash(value)) + Text(" / ").font(.caption2) + Text(numOrDash(value2)).font(.caption2) + } + } + .foregroundStyle(.secondary) + } +} + +private func indentedInfoRow(_ title: LocalizedStringKey, _ value: String) -> some View { + HStack { + Text(title) + .padding(.leading, 24) + Spacer() + Text(value) + .foregroundStyle(.secondary) + } +} + +struct XFTPServerSummaryView: View { + var summary: XFTPServerSummary + var statsStartedAt: Date + + var body: some View { + List { + Section("Server address") { + Text(summary.xftpServer) + .textSelection(.enabled) + if summary.known == true { + NavigationLink { + ProtocolServersView(serverProtocol: .xftp) + .navigationTitle("Your XFTP servers") + } label: { + Text("Open server settings") + } + } + } + + if let stats = summary.stats { + XFTPStatsView(stats: stats, statsStartedAt: statsStartedAt) + } + + if let sess = summary.sessions { + ServerSessionsView(sess: sess) + } + } + } +} + +struct XFTPStatsView: View { + var stats: AgentXFTPServerStatsData + var statsStartedAt: Date + @State private var expanded = false + + var body: some View { + Section { + infoRow("Uploaded", prettySize(stats._uploadsSize)) + infoRow("Downloaded", prettySize(stats._downloadsSize)) + NavigationLink { + DetailedXFTPStatsView(stats: stats, statsStartedAt: statsStartedAt) + .navigationTitle("Detailed statistics") + .navigationBarTitleDisplayMode(.large) + } label: { + Text("Details") + } + } header: { + Text("Statistics") + } footer: { + Text("Starting from \(localTimestamp(statsStartedAt)).") + Text("\n") + Text("All data is private to your device.") + } + } +} + +private func prettySize(_ sizeInKB: Int64) -> String { + let kb: Int64 = 1024 + return sizeInKB == 0 ? "-" : ByteCountFormatter.string(fromByteCount: sizeInKB * kb, countStyle: .binary) +} + +struct DetailedXFTPStatsView: View { + var stats: AgentXFTPServerStatsData + var statsStartedAt: Date + + var body: some View { + List { + Section("Uploaded files") { + infoRow("Size", prettySize(stats._uploadsSize)) + infoRowTwoValues("Chunks uploaded", "attempts", stats._uploads, stats._uploadAttempts) + infoRow("Upload errors", numOrDash(stats._uploadErrs)) + infoRowTwoValues("Chunks deleted", "attempts", stats._deletions, stats._deleteAttempts) + infoRow("Deletion errors", numOrDash(stats._deleteErrs)) + } + Section { + infoRow("Size", prettySize(stats._downloadsSize)) + infoRowTwoValues("Chunks downloaded", "attempts", stats._downloads, stats._downloadAttempts) + Text("Download errors") + indentedInfoRow("AUTH", numOrDash(stats._downloadAuthErrs)) + indentedInfoRow("other", numOrDash(stats._downloadErrs)) + } header: { + Text("Downloaded files") + } footer: { + Text("Starting from \(localTimestamp(statsStartedAt)).") + } + } + } +} + +#Preview { + ServersSummaryView() +} diff --git a/apps/ios/Shared/Views/NewChat/NewChatMenuButton.swift b/apps/ios/Shared/Views/NewChat/NewChatMenuButton.swift index c3452ce18d..3be1095bfd 100644 --- a/apps/ios/Shared/Views/NewChat/NewChatMenuButton.swift +++ b/apps/ios/Shared/Views/NewChat/NewChatMenuButton.swift @@ -10,6 +10,7 @@ import SwiftUI enum NewChatMenuOption: Identifiable { case newContact + case scanPaste case newGroup var id: Self { self } @@ -25,6 +26,11 @@ struct NewChatMenuButton: View { } label: { Text("Add contact") } + Button { + newChatMenuOption = .scanPaste + } label: { + Text("Scan / Paste link") + } Button { newChatMenuOption = .newGroup } label: { @@ -39,6 +45,7 @@ struct NewChatMenuButton: View { .sheet(item: $newChatMenuOption) { opt in switch opt { case .newContact: NewChatView(selection: .invite) + case .scanPaste: NewChatView(selection: .connect, showQRCodeScanner: true) case .newGroup: AddGroupView() } } diff --git a/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift b/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift index 6d849479e5..19ae3e61ab 100644 --- a/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift +++ b/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift @@ -30,7 +30,8 @@ private enum NetworkAlert: Identifiable { struct NetworkAndServers: View { @EnvironmentObject var m: ChatModel @AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false - @AppStorage(DEFAULT_SHOW_SENT_VIA_RPOXY) private var showSentViaProxy = true + @AppStorage(DEFAULT_SHOW_SENT_VIA_RPOXY) private var showSentViaProxy = false + @AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false @State private var cfgLoaded = false @State private var currentNetCfg = NetCfg.defaults @State private var netCfg = NetCfg.defaults @@ -58,6 +59,8 @@ struct NetworkAndServers: View { Text("XFTP servers") } + Toggle("Subscription percentage", isOn: $showSubscriptionPercentage) + Picker("Use .onion hosts", selection: $onionHosts) { ForEach(OnionHosts.values, id: \.self) { Text($0.text) } } diff --git a/apps/ios/Shared/Views/UserSettings/SettingsView.swift b/apps/ios/Shared/Views/UserSettings/SettingsView.swift index 89582ab810..a2df236738 100644 --- a/apps/ios/Shared/Views/UserSettings/SettingsView.swift +++ b/apps/ios/Shared/Views/UserSettings/SettingsView.swift @@ -61,6 +61,7 @@ let DEFAULT_CONFIRM_REMOTE_SESSIONS = "confirmRemoteSessions" let DEFAULT_CONNECT_REMOTE_VIA_MULTICAST = "connectRemoteViaMulticast" let DEFAULT_CONNECT_REMOTE_VIA_MULTICAST_AUTO = "connectRemoteViaMulticastAuto" let DEFAULT_SHOW_SENT_VIA_RPOXY = "showSentViaProxy" +let DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE = "showSubscriptionPercentage" let ANDROID_DEFAULT_CALL_ON_LOCK_SCREEN = "androidCallOnLockScreen" @@ -101,6 +102,7 @@ let appDefaults: [String: Any] = [ DEFAULT_CONNECT_REMOTE_VIA_MULTICAST: true, DEFAULT_CONNECT_REMOTE_VIA_MULTICAST_AUTO: true, DEFAULT_SHOW_SENT_VIA_RPOXY: false, + DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE: false, ANDROID_DEFAULT_CALL_ON_LOCK_SCREEN: AppSettingsLockScreenCalls.show.rawValue ] diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 057d6cccbe..4a0dc23bff 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -177,6 +177,7 @@ 64D0C2C229FA57AB00B38D5F /* UserAddressLearnMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2C129FA57AB00B38D5F /* UserAddressLearnMore.swift */; }; 64D0C2C629FAC1EC00B38D5F /* AddContactLearnMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2C529FAC1EC00B38D5F /* AddContactLearnMore.swift */; }; 64E972072881BB22008DBC02 /* CIGroupInvitationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64E972062881BB22008DBC02 /* CIGroupInvitationView.swift */; }; + 64EEB0F72C353F1C00972D62 /* ServersSummaryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64EEB0F62C353F1C00972D62 /* ServersSummaryView.swift */; }; 64F1CC3B28B39D8600CD1FB1 /* IncognitoHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F1CC3A28B39D8600CD1FB1 /* IncognitoHelp.swift */; }; 8C05382E2B39887E006436DC /* VideoUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C05382D2B39887E006436DC /* VideoUtils.swift */; }; 8C69FE7D2B8C7D2700267E38 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C69FE7C2B8C7D2700267E38 /* AppSettings.swift */; }; @@ -474,6 +475,7 @@ 64D0C2C529FAC1EC00B38D5F /* AddContactLearnMore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddContactLearnMore.swift; sourceTree = ""; }; 64DAE1502809D9F5000DA960 /* FileUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileUtils.swift; sourceTree = ""; }; 64E972062881BB22008DBC02 /* CIGroupInvitationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIGroupInvitationView.swift; sourceTree = ""; }; + 64EEB0F62C353F1C00972D62 /* ServersSummaryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServersSummaryView.swift; sourceTree = ""; }; 64F1CC3A28B39D8600CD1FB1 /* IncognitoHelp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IncognitoHelp.swift; sourceTree = ""; }; 8C05382D2B39887E006436DC /* VideoUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoUtils.swift; sourceTree = ""; }; 8C69FE7C2B8C7D2700267E38 /* AppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettings.swift; sourceTree = ""; }; @@ -802,6 +804,7 @@ 5C13730A28156D2700F43030 /* ContactConnectionView.swift */, 5C10D88728EED12E00E58BF0 /* ContactConnectionInfo.swift */, 18415835CBD939A9ABDC108A /* UserPicker.swift */, + 64EEB0F62C353F1C00972D62 /* ServersSummaryView.swift */, ); path = ChatList; sourceTree = ""; @@ -1256,6 +1259,7 @@ 5C5F2B7027EBC704006A9D5F /* ProfileImage.swift in Sources */, 5C9329412929248A0090FFF9 /* ScanProtocolServer.swift in Sources */, 8C7DF3202B7CDB0A00C886D0 /* MigrateFromDevice.swift in Sources */, + 64EEB0F72C353F1C00972D62 /* ServersSummaryView.swift in Sources */, 64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */, 5C93293F2928E0FD0090FFF9 /* AudioRecPlay.swift in Sources */, 5C029EA82837DBB3004A9677 /* CICallItemView.swift in Sources */, diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index 1ab2e2b575..a54effbf91 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -10,7 +10,7 @@ import Foundation import SwiftUI public let jsonDecoder = getJSONDecoder() -let jsonEncoder = getJSONEncoder() +public let jsonEncoder = getJSONEncoder() public enum ChatCommand { case showActiveUser @@ -78,6 +78,7 @@ public enum ChatCommand { case apiGetNetworkConfig case apiSetNetworkInfo(networkInfo: UserNetworkInfo) case reconnectAllServers + case reconnectServer(userId: Int64, smpServer: String) case apiSetChatSettings(type: ChatType, id: Int64, chatSettings: ChatSettings) case apiSetMemberSettings(groupId: Int64, groupMemberId: Int64, memberSettings: GroupMemberSettings) case apiContactInfo(contactId: Int64) @@ -122,6 +123,7 @@ public enum ChatCommand { case apiEndCall(contact: Contact) case apiGetCallInvitations case apiCallStatus(contact: Contact, callStatus: WebRTCCallStatus) + // WebRTC calls / case apiGetNetworkStatuses case apiChatRead(type: ChatType, id: Int64, itemRange: (Int64, Int64)) case apiChatUnread(type: ChatType, id: Int64, unreadChat: Bool) @@ -142,6 +144,8 @@ public enum ChatCommand { case apiStandaloneFileInfo(url: String) // misc case showVersion + case getAgentServersSummary(userId: Int64) + case resetAgentServersStats case string(String) public var cmdString: String { @@ -226,6 +230,7 @@ public enum ChatCommand { case .apiGetNetworkConfig: return "/network" case let .apiSetNetworkInfo(networkInfo): return "/_network info \(encodeJSON(networkInfo))" case .reconnectAllServers: return "/reconnect" + case let .reconnectServer(userId, smpServer): return "/reconnect \(userId) \(smpServer)" case let .apiSetChatSettings(type, id, chatSettings): return "/_settings \(ref(type, id)) \(encodeJSON(chatSettings))" case let .apiSetMemberSettings(groupId, groupMemberId, memberSettings): return "/_member settings #\(groupId) \(groupMemberId) \(encodeJSON(memberSettings))" case let .apiContactInfo(contactId): return "/_info @\(contactId)" @@ -301,6 +306,8 @@ public enum ChatCommand { case let .apiDownloadStandaloneFile(userId, link, file): return "/_download \(userId) \(link) \(file.filePath)" case let .apiStandaloneFileInfo(link): return "/_download info \(link)" case .showVersion: return "/version" + case let .getAgentServersSummary(userId): return "/get servers summary \(userId)" + case .resetAgentServersStats: return "/reset servers stats" case let .string(str): return str } } @@ -375,6 +382,7 @@ public enum ChatCommand { case .apiGetNetworkConfig: return "apiGetNetworkConfig" case .apiSetNetworkInfo: return "apiSetNetworkInfo" case .reconnectAllServers: return "reconnectAllServers" + case .reconnectServer: return "reconnectServer" case .apiSetChatSettings: return "apiSetChatSettings" case .apiSetMemberSettings: return "apiSetMemberSettings" case .apiContactInfo: return "apiContactInfo" @@ -435,6 +443,8 @@ public enum ChatCommand { case .apiDownloadStandaloneFile: return "apiDownloadStandaloneFile" case .apiStandaloneFileInfo: return "apiStandaloneFileInfo" case .showVersion: return "showVersion" + case .getAgentServersSummary: return "getAgentServersSummary" + case .resetAgentServersStats: return "resetAgentServersStats" case .string: return "console command" } } @@ -663,6 +673,8 @@ public enum ChatResponse: Decodable, Error { // misc case versionInfo(versionInfo: CoreVersionInfo, chatMigrations: [UpMigration], agentMigrations: [UpMigration]) case cmdOk(user: UserRef?) + case agentServersSummary(user: UserRef, serversSummary: PresentedServersSummary) + case agentSubsSummary(user: UserRef, subsSummary: SMPServerSubs) case chatCmdError(user_: UserRef?, chatError: ChatError) case chatError(user_: UserRef?, chatError: ChatError) case archiveImported(archiveErrors: [ArchiveError]) @@ -821,6 +833,8 @@ public enum ChatResponse: Decodable, Error { case .contactPQEnabled: return "contactPQEnabled" case .versionInfo: return "versionInfo" case .cmdOk: return "cmdOk" + case .agentServersSummary: return "agentServersSummary" + case .agentSubsSummary: return "agentSubsSummary" case .chatCmdError: return "chatCmdError" case .chatError: return "chatError" case .archiveImported: return "archiveImported" @@ -984,6 +998,8 @@ public enum ChatResponse: Decodable, Error { case let .contactPQEnabled(u, contact, pqEnabled): return withUser(u, "contact: \(String(describing: contact))\npqEnabled: \(pqEnabled)") case let .versionInfo(versionInfo, chatMigrations, agentMigrations): return "\(String(describing: versionInfo))\n\nchat migrations: \(chatMigrations.map(\.upName))\n\nagent migrations: \(agentMigrations.map(\.upName))" case .cmdOk: return noDetails + case let .agentServersSummary(u, serversSummary): return withUser(u, String(describing: serversSummary)) + case let .agentSubsSummary(u, subsSummary): return withUser(u, String(describing: subsSummary)) case let .chatCmdError(u, chatError): return withUser(u, String(describing: chatError)) case let .chatError(u, chatError): return withUser(u, String(describing: chatError)) case let .archiveImported(archiveErrors): return String(describing: archiveErrors) @@ -2230,3 +2246,143 @@ public enum MsgType: String, Codable, Hashable { case message case quota } + +public struct PresentedServersSummary: Codable { + public var statsStartedAt: Date + public var allUsersSMP: SMPServersSummary + public var allUsersXFTP: XFTPServersSummary + public var currentUserSMP: SMPServersSummary + public var currentUserXFTP: XFTPServersSummary +} + +public struct SMPServersSummary: Codable { + public var smpTotals: SMPTotals + public var currentlyUsedSMPServers: [SMPServerSummary] + public var previouslyUsedSMPServers: [SMPServerSummary] + public var onlyProxiedSMPServers: [SMPServerSummary] +} + +public struct SMPTotals: Codable { + public var sessions: ServerSessions + public var subs: SMPServerSubs + public var stats: AgentSMPServerStatsData +} + +public struct SMPServerSummary: Codable, Identifiable { + public var smpServer: String + public var known: Bool? + public var sessions: ServerSessions? + public var subs: SMPServerSubs? + public var stats: AgentSMPServerStatsData? + + public var id: String { smpServer } + + public var hasSubs: Bool { subs != nil } + + public var sessionsOrNew: ServerSessions { sessions ?? ServerSessions.newServerSessions } + + public var subsOrNew: SMPServerSubs { subs ?? SMPServerSubs.newSMPServerSubs } +} + +public struct ServerSessions: Codable { + public var ssConnected: Int + public var ssErrors: Int + public var ssConnecting: Int + + static public var newServerSessions = ServerSessions( + ssConnected: 0, + ssErrors: 0, + ssConnecting: 0 + ) +} + +public struct SMPServerSubs: Codable { + public var ssActive: Int + public var ssPending: Int + + public init(ssActive: Int, ssPending: Int) { + self.ssActive = ssActive + self.ssPending = ssPending + } + + static public var newSMPServerSubs = SMPServerSubs( + ssActive: 0, + ssPending: 0 + ) + + public var total: Int { ssActive + ssPending } + + public var shareOfActive: Double { + guard total != 0 else { return 0.0 } + return Double(ssActive) / Double(total) + } +} + +public struct AgentSMPServerStatsData: Codable { + public var _sentDirect: Int + public var _sentViaProxy: Int + public var _sentProxied: Int + public var _sentDirectAttempts: Int + public var _sentViaProxyAttempts: Int + public var _sentProxiedAttempts: Int + public var _sentAuthErrs: Int + public var _sentQuotaErrs: Int + public var _sentExpiredErrs: Int + public var _sentOtherErrs: Int + public var _recvMsgs: Int + public var _recvDuplicates: Int + public var _recvCryptoErrs: Int + public var _recvErrs: Int + public var _ackMsgs: Int + public var _ackAttempts: Int + public var _ackNoMsgErrs: Int + public var _ackOtherErrs: Int + public var _connCreated: Int + public var _connSecured: Int + public var _connCompleted: Int + public var _connDeleted: Int + public var _connDelAttempts: Int + public var _connDelErrs: Int + public var _connSubscribed: Int + public var _connSubAttempts: Int + public var _connSubIgnored: Int + public var _connSubErrs: Int +} + +public struct XFTPServersSummary: Codable { + public var xftpTotals: XFTPTotals + public var currentlyUsedXFTPServers: [XFTPServerSummary] + public var previouslyUsedXFTPServers: [XFTPServerSummary] +} + +public struct XFTPTotals: Codable { + public var sessions: ServerSessions + public var stats: AgentXFTPServerStatsData +} + +public struct XFTPServerSummary: Codable, Identifiable { + public var xftpServer: String + public var known: Bool? + public var sessions: ServerSessions? + public var stats: AgentXFTPServerStatsData? + public var rcvInProgress: Bool + public var sndInProgress: Bool + public var delInProgress: Bool + + public var id: String { xftpServer } +} + +public struct AgentXFTPServerStatsData: Codable { + public var _uploads: Int + public var _uploadsSize: Int64 + public var _uploadAttempts: Int + public var _uploadErrs: Int + public var _downloads: Int + public var _downloadsSize: Int64 + public var _downloadAttempts: Int + public var _downloadAuthErrs: Int + public var _downloadErrs: Int + public var _deletions: Int + public var _deleteAttempts: Int + public var _deleteErrs: Int +} diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index d2a7e704ad..46cb384a58 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -11,6 +11,7 @@ import SwiftUI public struct User: Identifiable, Decodable, UserLike, NamedChat, Hashable { public var userId: Int64 + public var agentUserId: String var userContactId: Int64 var localDisplayName: ContactName public var profile: LocalProfile @@ -41,6 +42,7 @@ public struct User: Identifiable, Decodable, UserLike, NamedChat, Hashable { public static let sampleData = User( userId: 1, + agentUserId: "abc", userContactId: 1, localDisplayName: "alice", profile: LocalProfile.sampleData, From e963ef53e7d02b97be4d6aa7f3f805755b5e3179 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Wed, 3 Jul 2024 21:31:09 +0400 Subject: [PATCH 22/43] ios: test ntf server (#4394) * ios: test ntf server * reset on change * fix formatting --- .../UserSettings/NotificationsView.swift | 81 +++++++++++++++++-- apps/ios/SimpleXChat/APITypes.swift | 4 +- 2 files changed, 76 insertions(+), 9 deletions(-) diff --git a/apps/ios/Shared/Views/UserSettings/NotificationsView.swift b/apps/ios/Shared/Views/UserSettings/NotificationsView.swift index 4876d60eca..1d924f4085 100644 --- a/apps/ios/Shared/Views/UserSettings/NotificationsView.swift +++ b/apps/ios/Shared/Views/UserSettings/NotificationsView.swift @@ -14,8 +14,26 @@ struct NotificationsView: View { @State private var notificationMode: NotificationsMode = ChatModel.shared.notificationMode @State private var showAlert: NotificationAlert? @State private var legacyDatabase = dbContainerGroupDefault.get() == .documents + @State private var testing = false + @State private var testedSuccess: Bool? = nil var body: some View { + ZStack { + viewBody() + if testing { + ProgressView().scaleEffect(2) + } + } + .alert(item: $showAlert) { alert in + if let token = m.deviceToken { + return notificationAlert(alert, token) + } else { + return Alert(title: Text("No device token!")) + } + } + } + + private func viewBody() -> some View { List { Section { NavigationLink { @@ -34,13 +52,6 @@ struct NotificationsView: View { } .navigationTitle("Send notifications") .navigationBarTitleDisplayMode(.inline) - .alert(item: $showAlert) { alert in - if let token = m.deviceToken { - return notificationAlert(alert, token) - } else { - return Alert(title: Text("No device token!")) - } - } } label: { HStack { Text("Send notifications") @@ -79,6 +90,7 @@ struct NotificationsView: View { if let server = m.notificationServer { smpServers("Push server", [server]) + testServerButton(server) } } header: { Text("Push notifications") @@ -109,6 +121,11 @@ struct NotificationsView: View { notificationMode = m.notificationMode } ) + case let .testFailure(testFailure): + return Alert( + title: Text("Server test failed!"), + message: Text(testFailure.localizedDescription) + ) case let .error(title, error): return Alert(title: Text(title), message: Text(error)) } @@ -133,6 +150,7 @@ struct NotificationsView: View { notificationMode = .off m.notificationMode = .off m.notificationServer = nil + testedSuccess = nil } } catch let error { await MainActor.run { @@ -150,6 +168,7 @@ struct NotificationsView: View { notificationMode = ntfMode m.notificationMode = ntfMode m.notificationServer = ntfServer + testedSuccess = nil } } catch let error { await MainActor.run { @@ -161,6 +180,52 @@ struct NotificationsView: View { } } } + + private func testServerButton(_ server: String) -> some View { + HStack { + Button("Test server") { + testing = true + Task { + await testServer(server) + await MainActor.run { testing = false } + } + } + .disabled(testing) + if !testing { + Spacer() + showTestStatus() + } + } + } + + @ViewBuilder func showTestStatus() -> some View { + if testedSuccess == true { + Image(systemName: "checkmark") + .foregroundColor(.green) + } else if testedSuccess == false { + Image(systemName: "multiply") + .foregroundColor(.red) + } + } + + private func testServer(_ server: String) async { + do { + let r = try await testProtoServer(server: server) + switch r { + case .success: + await MainActor.run { + testedSuccess = true + } + case let .failure(f): + await MainActor.run { + showAlert = .testFailure(testFailure: f) + testedSuccess = false + } + } + } catch let error { + logger.error("testServerConnection \(responseError(error))") + } + } } func ntfModeDescription(_ mode: NotificationsMode) -> LocalizedStringKey { @@ -212,11 +277,13 @@ struct SelectionListView: View { enum NotificationAlert: Identifiable { case setMode(mode: NotificationsMode) + case testFailure(testFailure: ProtocolTestFailure) case error(title: LocalizedStringKey, error: String) var id: String { switch self { case let .setMode(mode): return "enable \(mode.rawValue)" + case let .testFailure(testFailure): return "testFailure \(testFailure.testStep) \(testFailure.testError)" case let .error(title, error): return "error \(title): \(error)" } } diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index a54effbf91..c5c35c1d1c 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -1220,8 +1220,8 @@ public enum ProtocolTestStep: String, Decodable, Equatable { } public struct ProtocolTestFailure: Decodable, Error, Equatable { - var testStep: ProtocolTestStep - var testError: AgentErrorType + public var testStep: ProtocolTestStep + public var testError: AgentErrorType public static func == (l: ProtocolTestFailure, r: ProtocolTestFailure) -> Bool { l.testStep == r.testStep From 5f96f6c117ca81c9508070c7ccd1e831b482412b Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Wed, 3 Jul 2024 19:34:58 +0100 Subject: [PATCH 23/43] core: extending queue information to debug delivery (#4395) * core: extending queue information to debug delivery * simplexmq --- cabal.project | 2 +- scripts/nix/sha256map.nix | 2 +- src/Simplex/Chat/Controller.hs | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cabal.project b/cabal.project index e5220e2156..4efa8ad2fd 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: ae8e1c5e9aa3155907f1bd075e9c69af5fce2bee + tag: 9d0774a58e3307892e0b38500fe96fb5d15d9def source-repository-package type: git diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index 712a0dbff4..06ecfab261 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."ae8e1c5e9aa3155907f1bd075e9c69af5fce2bee" = "1k6phsn0xslqwd30g6l5bsg3ilghwjh2csav2g4bk6hb5a5ga2yk"; + "https://github.com/simplex-chat/simplexmq.git"."9d0774a58e3307892e0b38500fe96fb5d15d9def" = "1g8794xspbvlsk0qdv76xjpi7ippa2l87mvkiz0ryks6j7zzcrw0"; "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"; diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index 14f8d6ff5c..fdb07b0bd9 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -69,7 +69,7 @@ import Simplex.Chat.Types.UITheme import Simplex.Chat.Util (liftIOEither) import Simplex.FileTransfer.Description (FileDescriptionURI) import Simplex.Messaging.Agent (AgentClient, SubscriptionsInfo) -import Simplex.Messaging.Agent.Client (AgentLocks, AgentQueuesInfo (..), AgentWorkersDetails (..), AgentWorkersSummary (..), ProtocolTestFailure, UserNetworkInfo) +import Simplex.Messaging.Agent.Client (AgentLocks, ServerQueueInfo, AgentQueuesInfo (..), AgentWorkersDetails (..), AgentWorkersSummary (..), ProtocolTestFailure, UserNetworkInfo) import Simplex.Messaging.Agent.Env.SQLite (AgentConfig, NetworkConfig) import Simplex.Messaging.Agent.Lock import Simplex.Messaging.Agent.Protocol @@ -85,7 +85,6 @@ import Simplex.Messaging.Encoding.String import Simplex.Messaging.Notifications.Protocol (DeviceToken (..), NtfTknStatus) import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, parseAll, parseString, sumTypeJSON) import Simplex.Messaging.Protocol (AProtoServerWithAuth, AProtocolType (..), CorrId, NtfServer, ProtoServerWithAuth, ProtocolTypeI, QueueId, SMPMsgMeta (..), SProtocolType, SubscriptionMode (..), UserProtocol, XFTPServer, XFTPServerWithAuth, userProtocol) -import Simplex.Messaging.Server.QueueStore.QueueInfo import Simplex.Messaging.TMap (TMap) import Simplex.Messaging.Transport (TLS, simplexMQVersion) import Simplex.Messaging.Transport.Client (SocksProxy, TransportHost) @@ -577,7 +576,7 @@ data ChatResponse | CRContactInfo {user :: User, contact :: Contact, connectionStats_ :: Maybe ConnectionStats, customUserProfile :: Maybe Profile} | CRGroupInfo {user :: User, groupInfo :: GroupInfo, groupSummary :: GroupSummary} | CRGroupMemberInfo {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionStats_ :: Maybe ConnectionStats} - | CRQueueInfo {user :: User, rcvMsgInfo :: Maybe RcvMsgInfo, queueInfo :: QueueInfo} + | CRQueueInfo {user :: User, rcvMsgInfo :: Maybe RcvMsgInfo, queueInfo :: ServerQueueInfo} | CRContactSwitchStarted {user :: User, contact :: Contact, connectionStats :: ConnectionStats} | CRGroupMemberSwitchStarted {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionStats :: ConnectionStats} | CRContactSwitchAborted {user :: User, contact :: Contact, connectionStats :: ConnectionStats} From f5eea018d9a158848f8000e11fb6a846d56fb2c8 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Wed, 3 Jul 2024 22:42:13 +0100 Subject: [PATCH 24/43] ios: chat themes and wallpapers (#4376) * ios: wallpapers (#4304) * ios: wallpapers * theme selection * applied theme colors and preset wallpaper * more places with background * one more * accent color * defaults * rename * background * no change to cell color * unneeded * changes * no global tint * defaults * removed unneeded class * for merging * ios: wallpapers types (#4325) * types and api * divided types per target * creating directory for wallpapers * creating wallpaper dir at launch * ios: wallpapers appearance (#4335) * appearance * changes * refactor * scale * lambda to function --------- Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> * ios: wallpapers user/chat overrides (#4345) * ios: wallpapers user/chat overrides * chat overrides * color picker updates colors correctly * fix state update * labels * background for light theme * small optimization * removed commented code * ios: enhancements to wallpapers (#4361) * ios: enhancements to wallpapers * colors for background * ios: wallpapers import/export (#4362) * ios: wallpapers import/export * comment * ios: wallpapers theme updates (#4365) * ios: wallpapers theme updates * group member background * colors * profile picture colors * unneeded * optimizations, images, state fixes * fixes * no editing of title color * rename Menus and alerts, refactor * tint applying fix * fixes * migration of accent and themes * fix updating system theme * migration changes * limiting color range * ios: wallpapers rename enum (#4384) * ios: wallpapers rename enum2 (#4385) * ios: wallpapers rename enum2 * change * colors were commented * fix build and look --------- Co-authored-by: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> --- apps/ios/Shared/AppDelegate.swift | 76 +- .../wallpaper_cats.imageset/Contents.json | 23 + .../wallpaper_cats@1x.png | Bin 0 -> 22941 bytes .../wallpaper_cats@2x.png | Bin 0 -> 61087 bytes .../wallpaper_cats@3x.png | Bin 0 -> 51580 bytes .../wallpaper_flowers.imageset/Contents.json | 23 + .../wallpaper_flowers@1x.png | Bin 0 -> 43669 bytes .../wallpaper_flowers@2x.png | Bin 0 -> 128699 bytes .../wallpaper_flowers@3x.png | Bin 0 -> 134210 bytes .../wallpaper_hearts.imageset/Contents.json | 23 + .../wallpaper_hearts@1x.png | Bin 0 -> 38297 bytes .../wallpaper_hearts@2x.png | Bin 0 -> 98986 bytes .../wallpaper_hearts@3x.png | Bin 0 -> 80475 bytes .../wallpaper_kids.imageset/Contents.json | 23 + .../wallpaper_kids@1x.png | Bin 0 -> 29406 bytes .../wallpaper_kids@2x.png | Bin 0 -> 87507 bytes .../wallpaper_kids@3x.png | Bin 0 -> 171840 bytes .../wallpaper_school.imageset/Contents.json | 23 + .../wallpaper_school@1x.png | Bin 0 -> 91468 bytes .../wallpaper_school@2x.png | Bin 0 -> 253494 bytes .../wallpaper_school@3x.png | Bin 0 -> 238390 bytes .../wallpaper_travel.imageset/Contents.json | 23 + .../wallpaper_travel@1x.png | Bin 0 -> 30379 bytes .../wallpaper_travel@2x.png | Bin 0 -> 88068 bytes .../wallpaper_travel@3x.png | Bin 0 -> 80606 bytes apps/ios/Shared/ContentView.swift | 27 +- apps/ios/Shared/Model/ChatModel.swift | 16 +- apps/ios/Shared/Model/ImageUtils.swift | 37 + apps/ios/Shared/Model/SimpleXAPI.swift | 31 +- apps/ios/Shared/SimpleXApp.swift | 1 + apps/ios/Shared/Theme/Theme.swift | 200 ++++ apps/ios/Shared/Theme/ThemeManager.swift | 303 +++++ .../Shared/Views/Call/AudioDevicePicker.swift | 2 +- .../Shared/Views/Call/IncomingCallView.swift | 7 +- .../Shared/Views/Chat/ChatInfoToolbar.swift | 12 +- apps/ios/Shared/Views/Chat/ChatInfoView.swift | 177 ++- .../Views/Chat/ChatItem/CICallItemView.swift | 9 +- .../Chat/ChatItem/CIChatFeatureView.swift | 15 +- .../ChatItem/CIFeaturePreferenceView.swift | 9 +- .../Views/Chat/ChatItem/CIFileView.swift | 10 +- .../Chat/ChatItem/CIGroupInvitationView.swift | 10 +- .../Views/Chat/ChatItem/CIImageView.swift | 1 - .../Chat/ChatItem/CIInvalidJSONView.swift | 2 + .../Views/Chat/ChatItem/CILinkView.swift | 4 +- .../ChatItem/CIMemberCreatedContactView.swift | 9 +- .../Views/Chat/ChatItem/CIMetaView.swift | 21 +- .../Chat/ChatItem/CIRcvDecryptionError.swift | 9 +- .../Views/Chat/ChatItem/CIVideoView.swift | 1 - .../Views/Chat/ChatItem/CIVoiceView.swift | 27 +- .../Views/Chat/ChatItem/DeletedItemView.swift | 8 +- .../Views/Chat/ChatItem/EmojiItemView.swift | 3 +- .../Chat/ChatItem/FramedCIVoiceView.swift | 3 +- .../Views/Chat/ChatItem/FramedItemView.swift | 67 +- .../ChatItem/IntegrityErrorItemView.swift | 4 +- .../Chat/ChatItem/MarkedDeletedItemView.swift | 6 +- .../Views/Chat/ChatItem/MsgContentView.swift | 9 +- .../Views/Chat/ChatItemForwardingView.swift | 21 +- .../Shared/Views/Chat/ChatItemInfoView.swift | 41 +- apps/ios/Shared/Views/Chat/ChatItemView.swift | 40 +- apps/ios/Shared/Views/Chat/ChatView.swift | 67 +- .../Chat/ComposeMessage/ComposeFileView.swift | 4 +- .../ComposeMessage/ComposeImageView.swift | 4 +- .../Chat/ComposeMessage/ComposeLinkView.swift | 6 +- .../Chat/ComposeMessage/ComposeView.swift | 10 +- .../ComposeMessage/ComposeVoiceView.swift | 18 +- .../ContextInvitingContactMemberView.swift | 6 +- .../Chat/ComposeMessage/ContextItemView.swift | 11 +- .../ComposeMessage/NativeTextEditor.swift | 1 + .../Chat/ComposeMessage/SendMessageView.swift | 16 +- .../Views/Chat/ContactPreferencesView.swift | 9 +- .../Chat/Group/AddGroupMembersView.swift | 22 +- .../Views/Chat/Group/GroupChatInfoView.swift | 51 +- .../Views/Chat/Group/GroupLinkView.swift | 1 + .../Chat/Group/GroupMemberInfoView.swift | 19 +- .../Chat/Group/GroupPreferencesView.swift | 8 +- .../Views/Chat/Group/GroupWelcomeView.swift | 5 +- apps/ios/Shared/Views/Chat/ReverseList.swift | 1 + .../Shared/Views/Chat/VerifyCodeView.swift | 5 +- .../Views/ChatList/ChatListNavLink.swift | 12 +- .../Shared/Views/ChatList/ChatListView.swift | 25 +- .../Views/ChatList/ChatPreviewView.swift | 38 +- .../ChatList/ContactConnectionInfo.swift | 22 +- .../ChatList/ContactConnectionView.swift | 9 +- .../Views/ChatList/ContactRequestView.swift | 5 +- .../Shared/Views/ChatList/UserPicker.swift | 20 +- .../Views/Database/ChatArchiveView.swift | 7 +- .../Database/DatabaseEncryptionView.swift | 10 +- .../Shared/Views/Database/DatabaseView.swift | 27 +- .../Database/MigrateToAppGroupView.swift | 2 + .../Shared/Views/Helpers/ChatInfoImage.swift | 5 +- .../Shared/Views/Helpers/ChatWallpaper.swift | 102 ++ .../Shared/Views/Helpers/ImagePicker.swift | 3 +- .../Shared/Views/Helpers/ProfileImage.swift | 29 +- .../Views/Helpers/ThemeModeEditor.swift | 445 +++++++ .../Shared/Views/Helpers/ViewModifiers.swift | 19 + .../Views/LocalAuth/PasscodeEntry.swift | 5 +- .../Shared/Views/LocalAuth/PasscodeView.swift | 2 +- .../Views/Migration/MigrateFromDevice.swift | 53 +- .../Views/Migration/MigrateToDevice.swift | 46 +- .../Views/NewChat/AddContactLearnMore.swift | 1 + .../Shared/Views/NewChat/AddGroupView.swift | 9 +- .../Shared/Views/NewChat/NewChatView.swift | 22 +- .../Views/Onboarding/CreateProfile.swift | 10 +- .../Shared/Views/Onboarding/HowItWorks.swift | 1 + .../Onboarding/SetNotificationsMode.swift | 7 +- .../Shared/Views/Onboarding/SimpleXInfo.swift | 2 +- .../Views/Onboarding/WhatsNewView.swift | 5 +- .../RemoteAccess/ConnectDesktopView.swift | 43 +- apps/ios/Shared/Views/TerminalView.swift | 3 + .../AdvancedNetworkSettings.swift | 4 +- .../Views/UserSettings/AppSettings.swift | 10 + .../UserSettings/AppearanceSettings.swift | 1059 ++++++++++++++++- .../Views/UserSettings/CallSettings.swift | 8 +- .../Views/UserSettings/DeveloperView.swift | 11 +- .../UserSettings/HiddenProfileView.swift | 6 +- .../Views/UserSettings/IncognitoHelp.swift | 1 + .../Views/UserSettings/MarkdownHelp.swift | 4 +- .../UserSettings/NetworkAndServers.swift | 13 +- .../UserSettings/NotificationsView.swift | 40 +- .../Views/UserSettings/PreferencesView.swift | 9 +- .../Views/UserSettings/PrivacySettings.swift | 37 +- .../UserSettings/ProtocolServerView.swift | 8 +- .../UserSettings/ProtocolServersView.swift | 9 +- .../Views/UserSettings/RTCServers.swift | 3 + .../SetDeliveryReceiptsView.swift | 5 +- .../Views/UserSettings/SettingsView.swift | 160 ++- .../Views/UserSettings/UserAddressView.swift | 20 +- .../Views/UserSettings/UserProfilesView.swift | 21 +- .../ios/SimpleX NSE/NotificationService.swift | 13 +- apps/ios/SimpleX.xcodeproj/project.pbxproj | 65 + .../xcshareddata/swiftpm/Package.resolved | 12 +- apps/ios/SimpleXChat/APITypes.swift | 41 +- apps/ios/SimpleXChat/ChatTypes.swift | 19 +- apps/ios/SimpleXChat/FileUtils.swift | 11 + .../Theme/ChatWallpaperTypes.swift | 402 +++++++ apps/ios/SimpleXChat/Theme/Color.swift | 114 ++ apps/ios/SimpleXChat/Theme/ThemeTypes.swift | 736 ++++++++++++ .../chat/simplex/common/ui/theme/Theme.kt | 1 - 138 files changed, 4824 insertions(+), 627 deletions(-) create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_cats.imageset/Contents.json create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_cats.imageset/wallpaper_cats@1x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_cats.imageset/wallpaper_cats@2x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_cats.imageset/wallpaper_cats@3x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_flowers.imageset/Contents.json create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_flowers.imageset/wallpaper_flowers@1x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_flowers.imageset/wallpaper_flowers@2x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_flowers.imageset/wallpaper_flowers@3x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_hearts.imageset/Contents.json create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_hearts.imageset/wallpaper_hearts@1x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_hearts.imageset/wallpaper_hearts@2x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_hearts.imageset/wallpaper_hearts@3x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_kids.imageset/Contents.json create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_kids.imageset/wallpaper_kids@1x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_kids.imageset/wallpaper_kids@2x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_kids.imageset/wallpaper_kids@3x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_school.imageset/Contents.json create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_school.imageset/wallpaper_school@1x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_school.imageset/wallpaper_school@2x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_school.imageset/wallpaper_school@3x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_travel.imageset/Contents.json create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_travel.imageset/wallpaper_travel@1x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_travel.imageset/wallpaper_travel@2x.png create mode 100644 apps/ios/Shared/Assets.xcassets/wallpaper_travel.imageset/wallpaper_travel@3x.png create mode 100644 apps/ios/Shared/Theme/Theme.swift create mode 100644 apps/ios/Shared/Theme/ThemeManager.swift create mode 100644 apps/ios/Shared/Views/Helpers/ChatWallpaper.swift create mode 100644 apps/ios/Shared/Views/Helpers/ThemeModeEditor.swift create mode 100644 apps/ios/Shared/Views/Helpers/ViewModifiers.swift create mode 100644 apps/ios/SimpleXChat/Theme/ChatWallpaperTypes.swift create mode 100644 apps/ios/SimpleXChat/Theme/Color.swift create mode 100644 apps/ios/SimpleXChat/Theme/ThemeTypes.swift diff --git a/apps/ios/Shared/AppDelegate.swift b/apps/ios/Shared/AppDelegate.swift index 7204625ad4..d52c950d81 100644 --- a/apps/ios/Shared/AppDelegate.swift +++ b/apps/ios/Shared/AppDelegate.swift @@ -9,6 +9,7 @@ import Foundation import UIKit import SimpleXChat +import SwiftUI class AppDelegate: NSObject, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { @@ -17,6 +18,7 @@ class AppDelegate: NSObject, UIApplicationDelegate { if #available(iOS 17.0, *) { trackKeyboard() } NotificationCenter.default.addObserver(self, selector: #selector(pasteboardChanged), name: UIPasteboard.changedNotification, object: nil) removePasscodesIfReinstalled() + prepareForLaunch() return true } @@ -141,6 +143,10 @@ class AppDelegate: NSObject, UIApplicationDelegate { } } + private func prepareForLaunch() { + try? FileManager.default.createDirectory(at: getWallpaperDirectory(), withIntermediateDirectories: true) + } + static func keepScreenOn(_ on: Bool) { UIApplication.shared.isIdleTimerDisabled = on } @@ -148,13 +154,79 @@ class AppDelegate: NSObject, UIApplicationDelegate { class SceneDelegate: NSObject, ObservableObject, UIWindowSceneDelegate { var window: UIWindow? + static var windowStatic: UIWindow? var windowScene: UIWindowScene? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + UITableView.appearance().backgroundColor = .clear guard let windowScene = scene as? UIWindowScene else { return } self.windowScene = windowScene window = windowScene.keyWindow - window?.tintColor = UIColor(cgColor: getUIAccentColorDefault()) - window?.overrideUserInterfaceStyle = getUserInterfaceStyleDefault() + SceneDelegate.windowStatic = windowScene.keyWindow + migrateAccentColorAndTheme() + ThemeManager.applyTheme(currentThemeDefault.get()) + ThemeManager.adjustWindowStyle() + } + + private func migrateAccentColorAndTheme() { + let defs = UserDefaults.standard + /// For checking migration +// themeOverridesDefault.set([]) +// currentThemeDefault.set(DefaultTheme.SYSTEM_THEME_NAME) +// defs.set(0.5, forKey: DEFAULT_ACCENT_COLOR_RED) +// defs.set(0.3, forKey: DEFAULT_ACCENT_COLOR_GREEN) +// defs.set(0.8, forKey: DEFAULT_ACCENT_COLOR_BLUE) + + let userInterfaceStyle = getUserInterfaceStyleDefault() + if defs.double(forKey: DEFAULT_ACCENT_COLOR_GREEN) == 0 && userInterfaceStyle == .unspecified { + // No migration needed or already migrated + return + } + + let defaultAccentColor = Color(cgColor: CGColor(red: 0.000, green: 0.533, blue: 1.000, alpha: 1)) + let accentColor = Color(cgColor: getUIAccentColorDefault()) + if accentColor != defaultAccentColor { + let colors = ThemeColors(primary: accentColor.toReadableHex()) + var overrides = themeOverridesDefault.get() + var themeIds = currentThemeIdsDefault.get() + switch userInterfaceStyle { + case .light: + let light = ThemeOverrides(base: DefaultTheme.LIGHT, colors: colors, wallpaper: ThemeWallpaper(preset: PresetWallpaper.school.filename)) + overrides.append(light) + themeOverridesDefault.set(overrides) + themeIds[DefaultTheme.LIGHT.themeName] = light.themeId + currentThemeIdsDefault.set(themeIds) + ThemeManager.applyTheme(DefaultTheme.LIGHT.themeName) + case .dark: + let dark = ThemeOverrides(base: DefaultTheme.DARK, colors: colors, wallpaper: ThemeWallpaper(preset: PresetWallpaper.school.filename)) + overrides.append(dark) + themeOverridesDefault.set(overrides) + themeIds[DefaultTheme.DARK.themeName] = dark.themeId + currentThemeIdsDefault.set(themeIds) + ThemeManager.applyTheme(DefaultTheme.DARK.themeName) + case .unspecified: + let light = ThemeOverrides(base: DefaultTheme.LIGHT, colors: colors, wallpaper: ThemeWallpaper(preset: PresetWallpaper.school.filename)) + let dark = ThemeOverrides(base: DefaultTheme.DARK, colors: colors, wallpaper: ThemeWallpaper(preset: PresetWallpaper.school.filename)) + overrides.append(light) + overrides.append(dark) + themeOverridesDefault.set(overrides) + themeIds[DefaultTheme.LIGHT.themeName] = light.themeId + themeIds[DefaultTheme.DARK.themeName] = dark.themeId + currentThemeIdsDefault.set(themeIds) + ThemeManager.applyTheme(DefaultTheme.SYSTEM_THEME_NAME) + @unknown default: () + } + } else if userInterfaceStyle != .unspecified { + let themeName = switch userInterfaceStyle { + case .light: DefaultTheme.LIGHT.themeName + case .dark: DefaultTheme.DARK.themeName + default: DefaultTheme.SYSTEM_THEME_NAME + } + ThemeManager.applyTheme(themeName) + } + defs.removeObject(forKey: DEFAULT_ACCENT_COLOR_RED) + defs.removeObject(forKey: DEFAULT_ACCENT_COLOR_GREEN) + defs.removeObject(forKey: DEFAULT_ACCENT_COLOR_BLUE) + defs.removeObject(forKey: DEFAULT_USER_INTERFACE_STYLE) } } diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_cats.imageset/Contents.json b/apps/ios/Shared/Assets.xcassets/wallpaper_cats.imageset/Contents.json new file mode 100644 index 0000000000..a1747ab6ba --- /dev/null +++ b/apps/ios/Shared/Assets.xcassets/wallpaper_cats.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "wallpaper_cats@1x.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "wallpaper_cats@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "wallpaper_cats@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_cats.imageset/wallpaper_cats@1x.png b/apps/ios/Shared/Assets.xcassets/wallpaper_cats.imageset/wallpaper_cats@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..7d4624c3f9c4f504d18674f6f29ebbd9dea61083 GIT binary patch literal 22941 zcmV)8K*qm`P)PyA07*naRCr$9-3PR7OI8-(0t~bP6Nn0mISU396DlUegjvL#Gv+p+V!{Mw#f*wb z8!;ndiy~%4P!z?8BG}Rxp$!P=`Sw`<9d+wft*Tmk-`B5QW1Ml{J7@2;s%Fjk&wqxh z^=9Sy>pPcHURO%_N2QdvDy6)8DdmqfpZS)hlp{(bW~|NFyB zDIZo!`9Gb%UH#P;D5d=PQp)cxrF_ohChuKJ`RHR#KKhQOldrIb%U#{Pv%DX;H*_N_}PKeUwc`${SQbz}T*`?SVC zrj+sl3vwUb_G^_=jEjD`$oF@aQhvoTmhX71$9H?0%LkiKeSP&($~P{h{Lxa%mwFO} z#ryr8C%ye~V}c@(FZZDVK{?;+Fp!;lf4fr3*C?gDp_K9^j_3XPr!oG!YJ6Y0ltO-F_a8ULosWK-1GN6! zh41>x7khf{PdpUd|9_cM%J(Xz{PAN=eq1T#za0AahE_R!;b$F!|L;!%`Z@>Fe0V7Z zqFB84VhM!#2QDh-*Dj@e`%=mmIV}AzA1M5VN-3Y)JTun&w+=)+lhF@2EcBlphW0B< zDL?hNr|(ff!uZcmDEJ$z8&OmUH$%nmc_{Bc*;uIeIL6IT{@Z~T=J-vY4Cikj_c3n@ z^oKU?YaJPp`9VbU`Gf=M7!f5WJKlkDe)h(_eUvc*u7Can48P_{p1*0}DOYa$-Jf*q zvq~u+Gx+cqJQVfwd&(*PRtIG;$p3u^B)6pyfBgyizfmcL5}#eh{}T@7{(hyD*OpS=4qlb z20y#H`^(!3m;XU5Br<~j?B>cnGBr^aA zicmwL_M!;Ctoh{^eL~8gdngIFf)M|;&UcMN00uSx!a>+6(hockJYV^~hsC|?#O*S! zuXpe^3rG+YmQpelN@5O>&vPJ;zz4 z3qTfJ@t-+plW}vOqkA$mG=Q6?ECN2rh#U7VM$DW2%Y`wnd;~QDK;&qxf6?KhSH7Fi zpm0FP_)#ig#}EObV9VTi(D&&n=T|-cIC3j2-A&u;ryab9@apTwK5?qJlOKFU@908% zS$y2 za40b(a-k6vN6<%cjjeWNiS}oU!>gFjrybF%=UWu_3Td$*C+-Wu2^XRoPo2N@d(VcD&=4P736Ln% zpIi_QN+F;ykEBg}4O-x`0wjvD8eHL#KmBm6?&)IO(o|P2NM+u$v>$#8Sjdkjk`rer zzyuv*d;(@`E68nW-e_!S4rO)^hI;d8J>`UMKG@4!j&ANd5EpWeF4iC@p)fcGOUJt? zGZz4zzQ>`QTrUN~^-NUYAQ(w71<|-}R;&=vUILk4{=^YqeFPue4+9V+C93`8>Pz9+ zP!g|(B#iSTCwa`BfT$-IDH;?-z_ODNcQ0dQa5()vfliHhlH+IV{xgms1_fi7T(dP` ze9)WcBR6yf%Aa|GS|0Qe-xkmT3G%q1R(nAji!V@Ex#R`$!r!q_3BpBKUxbk7bHSde z>LlQxy#KUv{T5N`g=I=*Ks6}btAJ$8QdEKv0;7C_ADoGTLWo)!pc)EMb2f942$1_;WOE+|#;^noj2k}|5DG@*asU1k z7yLUH1#B(R1bIwK$i*_eRFV`u$Y}Nc?w2492mzi1v8zLThae|{jVGA2C=4GPX}<5s zAtJ%jBe>v7!gzI1kNg}oWIVrRa#P }iHFlF7-{XpOg0at7VI1Y=~R(qoYXEvufT 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 Y02D`lJvElvi~s-t07*qoM6N<$g8CC-v;Y7A literal 0 HcmV?d00001 diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_cats.imageset/wallpaper_cats@2x.png b/apps/ios/Shared/Assets.xcassets/wallpaper_cats.imageset/wallpaper_cats@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1015139393e37eec2be9b7c23b728a4c569dd654 GIT binary patch literal 61087 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

b6uI88-43?h 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

iW_Pu3E{U|Qf|b6?;W5T}!!SC) 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%0Ds54J!$oajXYi;)hU3 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�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∋IhNU-Yh8-h`J16J{BM zm-l4w=Q_YaW}2;1=?Ao)bPmFL3&a`^lr6c``s{DVv=|51DLUSJqDbDOsqnFdr6r2Q zj(K-P_|+4=#pUJYE%75 z>LiF95c)v^JXNW0c*E4tMSRr*uW~SKYVS5tzga0+2jC9`5L9(3rx?>u5)6wR~+Ahh;o;BRi4SFr&6g{ zLB8E?uS`u%B`r-m4?}3;+T!=gQ==U4#9YoLDXni#PEJ}W(|kd%7gd+nm+#*0%0&0c z1k*_ogwi8Y*SRjSC>f<1SRfUg9(CnMSb`M;6|_ypW;bJ}+T-2PxG5^2Fo7PNu+!;D z#rcHqgY2muOKMumGEG-9W(WaN(=-*f)*j%bQ`c^H#%)ul9JOrsUURfjCAPes@^10% zkc84`qf1<2*UcBV{O-s0kOtzj6SD^q0=d|12F`TuEI@IjC#4ZZQIO=^(@Yb4QB)#A zpl-KIorPLLOI+0Rd$pD33gsZT-HOFx0sQDW1HRpz_8sY-o$*yIX|QX9N|oTu+Egl)SDH47)Om(D6A1ArMv+9N)*9>U0GrL`SgU@)acf>S9zqMR^}2kQPCsn9o9{N6A=nOroVw zE(bl?z|QKED*$WTT{GsOMNEvUaBO!B6(hm`?im5^4;0VHSWrcpw_+wUjj7b3w(s9R zt|1*5M=}H;#1-XQEiPPbvRFAL=cmh%)eO<8Zl-hi4Bmlbhf*ioR>q~@;6jVhQ&i~} zR_dzC7L0OKpc-auqk=IZo@%uk(G2Xg(8F{pbq+9gV5QmoY&xAjm^6}8_2v4gM4geJ znYp^{`_*>4{p2(N<5N@T_j*0q>h-8$XvdAZhrQn1dKf;^YPA-N#iA7i!NDL1W`*xl zH!{~OtK%>Fhnvu(LV4`eWRqD3jOg^<>gq$Sjnv+cax?S!d{O88Wu;1mxLC%CvPQ?t zXJ%$xM4ZrkZK>9(tluo#A6GNtQD5r$pNCX=p~$P~Nn)g>#H%C&mEBZ!zy znI<(1SfIj6V|A6hvT;B5ALZoHwJ9w^D;2?jQU*X)DV-6wh+$b7%S@gnq{xd14tJu? zS9i*F5nCEl`Wcbvew|S+7;$}ZadAtQKWf%shIrw8wfZ!#dURsa>2z*7m7))1xA;%Y zWil^OU`#EpFMfE!oH#X=HYTe}OZQJrOE(8t*x8l@D4C%P8)n{dr#yBaZ0EG}?d2w;9=yl|j+U&%{sbCmI6{=RK!pEA;W@mD8(veb{ zEMOr^vV;Ldq%k#hUP9M1Q4|r6#;T0ebi@=1Xwt_`on%(Y0y*pr*|*&UH}CQwXPl z0w0C?+JKmyx|CSNuH_tHz8155?W%ye+lequ^Az$>=(%{FcbN=Br`l+IDmyiGnF2nw zw7NuiQ$3r_&MYo263l8>QBBPIVkB;$28m*^n2>?I9#B{i@%x86-zc1AlFf}`SY6k> zfGI_|>*KopY}>x3R;!Uw+HLx0S5q|V5f2U?a0-ujLAvX@msU36(jKt&?c(Cvq-E{% z0YtCYJ3_{~-So>!S1S{#iI=Z6*FN3pbO=UCn>IZ?eMUkzU+nwcZwG5@_lsoGOeT}3 zX_}U*R;%QJKbr=L&Dr*ikz@gh>2A4jJKmeh)tJ{}$4Fw#dBRL4Go9l6Y^7;#DCKu4 z0w!k9#l=Nh$U9Ug>U27%i%ut4YPFsy7K^;s>yhe|3%=i4Y&MBL;aOeq$GjJysHW#Q z&St2gG0s7DYGR5IY`Sg*h*Ag<3u&09nT05t;EWlJn+AH0_n$PxDDt}xtp`E5)oMLP zUTG4NGt6L<6H^oW+PyY%&YLSMD{-~>-_T}E08D6>m5P*}00Te^!|qD2N2w1gPExvr zK8C%7FIFL+KVLEJLI!e1NvsoR?Pg6BKZN-rAqR>m$m6FDJ&G*G?O5D$c(J~uVpm8G zP17|0fnZPM8OwmL;wmQ<0E>FP$(2GE0s#rDLK}bpPW2Jv#g6` zAlKGc#y7dQ6KFFtGo;x{yhfH`7#R)m zWMs_c63JLQ??Z*5isZe45D`FxT(YhNzN8G*=Dl7dq~wd84jH(AE2)s-sfw}5{eS51 zWK_tLjvGs!#e(PF9@qc=NAaR9HfBT_$Llhb4 zy1t*-^=Rc10*?$w1e;7VseoK55T6)$NU;b2WBWEEmEY2z~JcGgzV9Y_6sf>1=ti z_L)o~aauZ)In?p}Cwjf!;k2e5(38n5Q;hY3?()*wS}a8Tqnzzn#k|{njs$Kq5KnD` zliuqvwQM$ft_l=iT3;fSZ@OQ-0FY^BGSh}(OmU^SAjV9@2DO{Vcw^2Fg02%85}`o; zEjo=`%~xDwBkBz7VJ6hVSnkl`Jjpe!pmF_5p_G9LA#ntJNP(&cq4Dcm;e9(07*qoM6N<$f^y&rZU6uP literal 0 HcmV?d00001 diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_flowers.imageset/wallpaper_flowers@3x.png b/apps/ios/Shared/Assets.xcassets/wallpaper_flowers.imageset/wallpaper_flowers@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..59246eb50d32fe826dda42a83c10b89610eb5719 GIT binary patch literal 134210 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

>A(xmD8#d> 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

%(%6Em91S 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

    9UfQ@fRI~A9fLOnS{&UfV7`QOOzij; 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 literal 0 HcmV?d00001 diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_hearts.imageset/Contents.json b/apps/ios/Shared/Assets.xcassets/wallpaper_hearts.imageset/Contents.json new file mode 100644 index 0000000000..556d01a6f2 --- /dev/null +++ b/apps/ios/Shared/Assets.xcassets/wallpaper_hearts.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "wallpaper_hearts@1x.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "wallpaper_hearts@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "wallpaper_hearts@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_hearts.imageset/wallpaper_hearts@1x.png b/apps/ios/Shared/Assets.xcassets/wallpaper_hearts.imageset/wallpaper_hearts@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..780ff1351349e43de6e3f0b7dd2ef3c0e4550ee9 GIT binary patch literal 38297 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 literal 0 HcmV?d00001 diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_hearts.imageset/wallpaper_hearts@3x.png b/apps/ios/Shared/Assets.xcassets/wallpaper_hearts.imageset/wallpaper_hearts@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..35da7c7aedbf8989af39dcebd74e2011d3798ae4 GIT binary patch literal 80475 zcmV)3K+C_0P)00Hy}1^@s6%hunD00009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yPEC*_XWWB%LUKw$8A|Dw-Z0^iw({Cqn&LAc{8 z|1B??#$l&p+H-HC%=-mS4N;U912T#(VI=aK^O*mKA9@%xkYDA;j-e`0Bv25je7o-~ z$kVY8t|QX?V+1-XA(IRA{J!9Qj>W12Ob@AC>6bkJ|6bnX{JK8Y3iEst%Kv?5wl5}+ zER$pAz`}fv=hg)Y*!TGz%nTMKCdkMuhVv@gtR@=DB8;H^WVG8 zh25+C90}CC_xZ$%|E2k7pDO^L;l#j-ZK{836n%tJNbK_84$+@~-sqvp#Sp_EwyvOgc=M7i#8{iQsD<6l4L)EqfuROC?ZjKU_z`=U0n&5gqE?uDH2j)vZ*vQ42P*ef{^8p{FT2 z!jA?izlXt4W0{W*ovsXc&&-^8iHhk+!$B&tjTZU^Jmd6$E*OI-`U55ehaqC`xfg(T z|5pXHiIo?zaGW@F{MFv}s3(t=33EmwmJg>MuMLD!xMW##nCIf+H?gg1+*W!*O5lY1 zfa62QJ@4)!jH~CL7dpP4$K)|Q1LT4>cnc>CEoA67`2|Mccikh*j~w#a!x@2^$@;2FRPT4p(I+&0TLV%s0k73kGLp+dqNLonV@2MRwuQRm?tah@1X94yo^ z;Z0S)jKa<#%Rd#u(S>Dxu#CveYO0Z94R2KhK-c?);S@tkIQaa!#m?qn~1y`)^|T8$4B@P%B-B z7_ZquXxQ#*wH9qUzYf0wLnSb=SfftJ3W&w>vxV+>SDKVDPx4&twg^5}<2Lm>TQTOd zQM@>&{zjBsDOQX}gI(>ra)nO#T--RA5}fU>z`WOFbnRd`QZR9OOyI1+DJI1w#geVH ztO{Hg`&P%^us$}wR#&ia&F@Dpl`)f&;>_;HmeLq}A&fxZr*|7(AAr$KL8*hW%N5?RL z3CiGB3Ceaib2R2U?O-@kv0Pi-bW#FclfaZ%Eztv$)qK%^m=e4Ef32}a(H_fPSZn=e z#r_C!zAn!Hzsh65NxrSO7MZi%Wr+!9-TpPzOL!7>w-gK90@ewKFSSYdo${iil7o61by7RN?wKY;doqSm=_rS2dg zYS`s`z!z<=6}Jx`cB5*PqbMl9!l{AF%FMgbE;xx0hIgK(3WFI5r9rWSkzgh9_kt{h zh;x3hQg|L=ms2zh0)d5a3dRT^gCK>WAc7eq(2+-B?{0E3NpT(_v*tS8xLC^LMIPlN zb|wd%sm&j^jHI?Kjgwh!#ksDz%xoOWI2z(fy@VCuy>Nv&W}#D3UJAZgEGcb2e56DT zkl}(C@RV_JQI7d8io0b03!GO|ls`&FLW}_qd?!p5hNiHl_v~JeFB)U-_22n#(Bmgp zB6^OYH9`{j?BJNFQS^`I<0fJ4Q$iGHYAgPv z&US4B;NCgkmobw-g>(b!a-S$TGgoF$KQc%7OU{nQEPH&eNR^2byb`!ni0+)!dP}v^j1ruSm9kjpKu~s5*3}G4O38F$7 zy)cKx5@7F=Dp!oENNTM|KM8^ENk*B>IuBCQEo%^St=l9pXllc%fZSE~M;BrV1q~2& zqy`%nBr)^^PdG09XbMjdmCRghgmZuY#uxuX_h>HIw_FbOAij!wC|IRerXh>xZ!!(#s(+;G(3m%221Y7mvJjb>2Mm_?vG3&7bh6G_Fkb2sSd2+F zG-To9rZA$5qF_kdbU7wpUt%>-q3iAcPM61|xu`te97)Ai^#MFxxbk3l30p3U3Wc9o zLht3*5v&}!yXlK~$&VojLO9XsJ;%kmX-iSGho3)hyPjKjtCGoaxv=b#DCM+^RNAH6 z5&1cH;L=(Wfx~@=eG?~kJ`3M@P2&_FQm!diFayvcf|BF9(>=8Icb|WUma|ry#1-<* zPmPSafEh)o)7ZD3Q?7*hV%scG|L7#VOB{h1`$n}xuHi24`c4`zk@OTO=-BR;-z}Uw z|A6}6oB}FN6I5q7^HG{Vn>MBPY~kFC!EIIB+61rK<(>=kPnO0`U9=R80GE{g=orTm zJ7zf9{OB6b(l2ZjJ&OHzZTsrqYr9c)&;#t!x8r-cP{HFix$Ah4d=jhFOv3ylRJ$(K zA>m}9$@#NIt+_!8J;4)pTCRxN$4wyD+{wbeN3BU`g{57rpcpN?&lBN3M@8wL6VKxM z18M>Oz$|hv2C&FgVSBxRmC{bip$^kgC`TFsI*ik_A1X%N#{l20_t5-)B|y~~dTt9m z=A^)i;b{Y(c@h5}8cX-M-K9rsoi2A4Fkc+^>q9hxU5Kr6U;k{pL7&+Lc3{RNn$U@k z6St4c1990|7cKec&v(rCd|B-K;lm}aceOKCUbbS@?T}1byhq#`v1CmnWhBYh`|ly$ zm$*~hxC%>lBqY@N2RzM2yj{?UsN*jv^9JxZZ$(TQpUWOYA`@rcOJRN-Ttb8s zae3`sx-Nxt&7BxL$(Z{NyCq^7?<=-7{R2v(rY0!;&Qtj)y6S@y()cQKhV&9ZMLomz z^rgaci5c*@$M2?cK2pq+nnU4lR&-EZ{$$@HDudk)b?bZ2SK?_Yr+(l(lJGJrPs50> z$nEYeUt68ay~YLmS!=4pk7?rY)pTbj5Z622<8fkW4DSxSA5M7msJj6&RwK}v z2KCPKf{qpDz8F>tPT%Z~$8uxTorF5?Yrl-lGtO~VJ9&hT8Dzq#QAX(eWD&}jxo^yV z!-6k?e!$fdD8H;c2`^@(gCqeqHxe}CH zVxyG1wWE^1K}w8j*@sHN>McKtfujex*#p;Jh^v&)APmJ1R zlefB)B5Ww)*%zvH&aXpGK3afO%cR+Ml^%=4(78nERc(?AS!j+?XOh-alN5vy)H?i!2b11rmGYLfFxEbk!@BI@FmLK&WrMiAbI zH$%q>m%qLiC3X}J1Q_EX+JkH&b$xvuomr=~ti5VVv0@XlSyT$;JdSgPmL0RW+>3f| z3gqKO)J<#(M0|JTIbAnYP#-h*kRD@^g+kE{CrB zS3nbQCqXspd90{eEM_4Hb0`@0=1Wmu!!5$O@QIjNh&4z6cT- zUSXFO1vtJPq99a4S0j$!yX3O*cy=zq+2n<=Vfr5Gk}yZ|7qpz)Enm|iok;|`AVxp| z-c$o=E+&P5Kim_)LYG(Yc&lfic23mdtX>p&pQD8mML7BEH*`z(+Ry&oRHILP+LzD| zN1b&WMWhJSo>0d^|7I_Ma-Qv=$+9Mi$cOD11=C6PYK@^=`;uTV))L~ZgnH&CWCn;c zuK|ug44&&z$+MVXTsV9f4_%0rYL8XTcR1Oa^iD0CUq?_oiV$YQm*#@joQA(SW+`Uglbzhbw! zPZ2n9oT%ca$_KJcs*9l~3l(?Hs!mW8@27KNxgm|s(cU5f)n{XNf!@Ga2EesqSnPcL zu)Dwg1%VNjtuzx}wF`dlFz2QWJ)!bGSfFz?&#h2$F!uj(R7b)Y!3q@K1Dvapn($!f zs;O`nCRpP*#4|{s*9!3FIH&?D8^MA2IMt7?)U!@8*ctl8qJc^iF19<(|31f9r-LR- z++-Jj=Vy%{WuCWSukwdpx_N7)K=0+w*P$3&m{0v8URvksiHN9z;oO9}=RG}%$-NU~ z_qVAiPboPLJsdwK;$%q0GRD3~Q4#CBkPjbT6)}I}MCb)*WqVOm5^kgSn^H4o^74xWj9obE^=i#c)btuJZfc$qLG< zHTR>Eh&r6ligV@HIXJ}Sxpu|ZK8?Vb7)!jTb0BM><~$`h&uDxJn~x8KD7A0aaE}T( z*G-834Rc!Kb(dm4qZ_Y|doo4NDz)hA8OH3TINv`o5-ijYVAJ}d>oV@sIB0R$ ziq*M=sN|ScaN39=FgTw68f^B=IR8B6;~1^=Nt1+mKE)iM_IYZpLfi(!n7{t$^u^C){VIVw;r)u|PZ^~#c~|J{lw9t}sa zQqYaF{gfcb^T}H0g`rm>*l*!?@1>{o7soL+mcj3_naQr!W)u@kngN@?n98QEEzLQ4bcjol2@O0q^GKpGBw?fBt-clAS2- zv1bh3GUB_UJCTS@Ff@;ML!MLCC65G8h%X#EVM>x0lPDiyRtnlh2!B3#}5S`>y12|+Spn$wiZ=@#tHiU#=JCP0>U`vKcMd?diBeD<$13HP8v z!UCQ6yVpdS*c+^I$K?v@i##VhwV^nf_Y&xW!OcK18A&R(c@$w1{A^(f1qP`$ZPJq_ zDBg#Jc3F#Vlpr&KTsxMufk~b_IGNtVCSZ!8DVP9tLSrhA5y#b2Cp;4ahhu}{!^=@5WTR3)o`Tsep-s<3fLqWxTzR++LkqvG zJ?7RCiC8`?_Rz2qhZ%%rzuNAomL*kcjX6{FFQGyI-gHQgg~@nW5arE7dSXxt-ojn?yA7aty1xtH6e`0@&kX2r;D=D0e<7nVzG;&9V4uE`N35$ z_-xfF8>xN43ehsnStfvVZB9CQwm?C79WnGkCYyuM{x=Q65Pu^HbdMJ6WX8vp?TomUJsGWS#4ABZ-8Z*2!!U zmKoRibz)q1#Ji!y@@PVq*->q}v`peHL(Bn>@QhZRhd?J6s=;?y4ystPuc-@U+&FEa zWvwVJt=6u!v9{b|=+Ggq4eahYKwTF%0%_P-jz)^c$Cio;bhpL1&{cW@M)!P`CbXAe z(sBRm>xUwVEWb~=ki%=~CFF|Q)rFcew1I`kmP0dA(Zc`tT#+!VU|%$LZjT#Gda^o) zaT(PcD7nT_NyB$&2Lr&NHwESIO<-Y)=dSRuC_V+&%d^5P0zIQ96IjaiLS!MjlF+nBH<)5urk9*$lY@(Udpk3@+g$s#Ff$)pF%={YO!WJ608tD@-sn2E9S58|Gl=@ zsby{oQ^OXj>8#edR3rer9vK$u58^uUe(hlJi7m1ZJk}moj;z|9QY}(J^NdlLOrUdX zxwjyh=JXehmKn&&TWh*F(f<7TSBu3uYX)-zlvs|T50C||yf>=*j=B_VS6N$T##@=3 z4oxjiHYo&x8~@VhlL?FHwP;Fqp#+x8=Ch3B=4YXPzbKdh*^;bqc6_`|k=R4ow>uu`Dlbb|NpW7a+ubM3Ia&G{Cx+kx z-AWGXPZHuHw#WuZxLa-@78nIi)mx z=!8J%-6BqfaXkZUH*OlT7GHSgx;8-RvQ1e%(z8m%1(v>{5Qoy6cAsDK_h$~esOW<2=l%|rUHIRANd278e6@RtO{5UVzJ!U5>{gQx5h0=`+v_C zM73xjkCX_fC0Chv{~mVA}uOS*L^_px6@sB@X+J-DGRqCS1M#vG6}K;!|L zF{C|rYf#Qyj27rz>aZ27Ch0LPn1m8`WsP%*O^-1G{nw@qF$N3+vT*gll!_O<$cux? za%`b)D@Thf9_I{4u)nvIDb9+|*Bv>5u2Y=dNrpR)vGmzJ?DBoPNPxTx?+ukJ*zX{Y ztF{SPiRCT|KqEZlOC;2(Rp_jq#oGQ5#CLHI&nUp&;VTYp+DYAVJId>NTvP9a3mAbK zs?tf_HaPj@FT+b9!UF}qYg!JmSXR&vVXXrn945LoL7OlJ0@a6p>bI~E+10+lqb zY`KT3i~Z%ZFel|Re;!}*`-Efr-+Zk6%lQRcXjbfE_9lLXm0+BO?ic2>Xe!K#g%iaN zWFPcplfL3&i6{vBKwfw77oD5FBx2PLRtCpXkIOIe7wj3c!ODt9np|pp6pKv~phT~G zwopDhtbT5Tow0HFnEx_W9DBj^w&CwlVEdYT81yB23I?vKI9PG(iJRzfUeiZUlCr*s z?B!c63IZo8bu}JK^soeN943+j+cs5VId;Cg48`d&7J~&kTf!C<=iG5lez4b??vm<0 z|60`badGiG4DWxf#Bwl!&M&shW&N<$&QcC@7b1P`g0&3zeMW(BUDFL~19lH}yLR`-kX)&Le_RQ7WtWe{lA`!o6NCh3#4iGw%Ep7BzzS z(83|&?ptNNbcm%e89HEZg4nZ8R%PL}SCYCpvG5D53?1vFs&INSV@c5qc;d)kBosns z;<(E1N#_P2JQ4jcf9LxSem3HmiB%RxIOveY_+y(Y1Pl)#1K|Jk7s&L77Bx1i8PN!a zUzh|1#B)O2dLRU5Q~f?Zb7P63HT@2Tooge!GZ=^ewa30ySA8Bzh?<)PCBl7*isU4f z70d@9iH!^t3{OC8t2TN!$9v=uR~Z~dtXb9W+b6sdMSCu99R+vZZ5t!J&m{}^KBvC1lWqt|O-?f$D z1@^>zgO=;h+|GCd=ULBn*Ur1GuJwRb0-R{-CNDO_nNx>a=<=mi&n{67sonn#Gon$L zjBvL#B-R)x!JA3ss%MVF|C4ejHfUaWQW8oQ!oQO9uHS3ilIt>Z3}lhaS(AkcVm@;u9<-Eb-|C} z2{B;a02D&q)3TMzlr4z-8e>did)mtY_26ZQh<<|--(A)06V&^`C8K+LrJlQ`EO}M& zhLxTVJ+F)x=oBk`h8==PVPXjP_ZEDb{m2%cMf}}m%&KYnQgaO4*C-pYI0j|-<}YWo zLUM+#sA1ef99bY7ofi;=-M1ylMW#mNY0xtgd$9Z1e+-xqr-SH278-sf(>{C8uG z?`vJt?badZ`we{Wo*Z}#m)YOQ_up0nKLBiDZk+Qj0{!0H-EGBtgTLSPX2n3cDZ63~ zvg9q-@-%MxQqLDQ&x9t~(G@r)y7gnD34y2~%Sj1!7ASkM>d3LQ%Drc$W{2#FVs-3HWY1^u|TiOJrIxh4=v=ErAY1# zkIUA$-+zq#Ej+2p_v;Z>496w^jzc|5TjxqF$1Trf2US7b$7o1u&N~P^$C){FBjq8_ z?@~U7PI!*R@}cWoBEj>D!eztd{tEg*iRIB{11F9|EDv_KS6%?DccfB|#NJT5)?bDa zbqdF$3?n|RaX)&_97aD<9M(YBJIs` zN|6z$REECKGQqqrcL|7n^*nk}IcPViVo8>IJVn?%@;e9xH%?wAy9H-_DhNVKT+cSC zk@hPmf{$!5tqSbH*oswyGF_u;@AWMVgwA*HDSb5Y?AeQh3dDmq6hs#8w^Op#3-69= zkvffIx++Q@3hO;QV;JmEMPuS3yWZdNIDG?MA?Mq$-6By?ODp}WhiPyMw!K&^kMV}; zdtu7fFzy!jxY$%I$36Ew8&q6%P|D zb=9dSAgCTkY3evm%5paRzxT1&Td;GEn?ggWVok}*C6s--6`TN~vWLSSYzj_90#quA z3Qr2udiMugKXN?9K*@faBQAB`6oJn>+`mObsGbuwG6n%sEji7OSSJ@vVh7`*m3L z#dNUa-JeH3>r@=KZ@9}?<~y-Ub*XSLB`+Qe*VM80a{p_0Kf5ORGb()07dVNDII_>W zNubOh_)=J1^!dbj2GZUBEX+rM6|M3flD92}0Py7aq@e{Ydkx$?4dWTz!}J)NkEVum zxuehCxIc(gWziVU-0-;SLQV!aLC-_FBHhS6`PPG8M*cG8_w=C{Q&fHNIa&b$OC=K( z-Gt*{Wd!%(?XStQ?`2&J3s;Fr($H$YhUW7pg3r1lzy+JxY!ttOkmZtobTn3gy8DN^je!w%SY$YkOk4mbmo3?I0{SiYq5>r@HyTejEG_h27q2ZUicuxBVq%`< z6@jfJ=_=j9NU(*9^`)D+gt_Z(@6+ye3UD0jRtR#fD6SxOB`1?mRLA(f8KD?Mhw>W_ zqtu%K$_17S{w_){cObk?Z1v*vNNNtD`2P*KLY|WDu2|`qH6McCq1N|^EwRm066QrN z#l^*|{MneXedHXV$FcJddQ5oS7;hW)Z@{XSn?A?Ms%=UUOHtbnLeWsByw7z|Fuq(e zE(H3Z7Y?<1k=(PA$#)LmR* zPVQ^%i`{VSggtRF$hMpa8Ur7-p*Aw3JKy&@KhE!96hRE3kx=iHqr+ow2ey)UYQp@| z;jQ2=bU%#mfGn%n%!=0CkGbC_SHTGMK@)?=O8>ON?Bwv6s#I-$#A10pO?F68H17Xo zWmObYjP2HAa)xg#Rs~C5#Cw}hwrOFdV=~jtjjwxOV@uA+?z*-U3JALLcc(NN&kc4h zW4Oc40*hlE2WyHSmBupCXcMJ4hmXgX$A*S#=co6muc)Zv=g-gL9EtO->RYxGQHQOK zP=1lD~x`ai+ZXwwk24!LB=IZ;~9<*K20`8Uxn4WTMXwP8s1jk%J(r zHbi(26Toz?<7BTNT-t=z!9ABXebtF9w(uP-+}-l7jzX>^aFUd{;ZQdRJaFk`3jMJI zN!HPy!0N2Q?(c6>-UD(64i18o8 z<^ByuAgXdy->s4DD**6CiFx^%gkoCk#quU(6$K0OJI#CUYe8$nP4)`Gj40oYu8CW6 zg7_N(!)x(Vm%ZzuR<+&_OV~<03v>pLKbwiH?9pIa@V;S+=Y2#iGavYQyyos}rnRaB z9&c}iu%~|e&{P=_Q4^t;Ajc(9GAA$)UZGCqY?pkES77(UP<#&tkG(}oH{Vcromot7%Sx z|7d|8B3o7r0>!H~XC~Co&pMZrZ4||@HrU+Iqx%qRS7g0a^efgcN5qx?PFqJ*&n(9@ zA|CB6AmRJy zaV+1?we~!pqmgE=DTZ-fIjiAWW+()Xljr|$*(-5+Ryo6wcgJXk5@dN!6zIWD$gUMR z2#in}+ zdY9^gSv)CPFrd{JXhJQ@*oqYaJb|Z-iwn%pkP|+-&|gM@5*#DbxW>;~+1m)=;|0xS ziHLgmomds;pL-4|oLdNUa>ayYQ=w>Ggnr4QYKud1t(;h^Mhh-0+zAf6jQVB2&p-FN z)g-mtEML$8oZ?f1CpsloB`^S@6vjaHv5E@s6S1mo#}M$ab#H{S>Zrk60)33@b5>N@ z6eqV<)(V|vZd=P(Q$5P!^+7Y7k+p7TrVpn|#js0ZpoPd~VWBRs?_W3{D6t$*^{#T; z(ob5X}5r{1Al5!BWY@!@Yz{%bYnRpfqb^_Qi zrNbt7FumS;2^Y3rcL9_+S$>vw*&(VnLt1?p>y+P{(C~Qp9;U9z$FVA`>p`u4`8Y=_ z^c5(Vg|CmOdC#cKnGJ-rSTTb3)(1AszPf_k;FqbaO-)u&twFpNRFDcz0Vism^Ca@M zrz>5-`jCPdxTc{&4^-$<=j`?FgY<-Si=P{y0+R54_omO2cFyePsV z$R|J?3kO)rOHlO=?O+BVTN_ZR+gPMf3Xfo(yl9>dX7hs@mnFQ6w6`#(Sy3(NPzeRZ z5C465x3vynp^h<~opA4>p!tTJ-O=6`6~rtgj2;@B2oDjHNKT9S*cjQ z?9-V{W5HhUE(CcEujo;JX7^CXF}Z`a0%OHek)*tupb&iIf8@tcph~Y((H)az{!GZCrlV#~*au*uVJuo?)7?4;%1c>ucSEKy z{p3mf+Cc#5_Yvcf_VHaPpvD)*%?`TxMV4XdTwDp+P+m`*3-w8aY$eOzpMAc1XbRUG zE6hDkk$NJ)kVifS4q!Jc0-(k?agmQ8JV@X+%qd~mGaC)FAOhX$4n!A-TE}1R1lr(& zztcRvYl^K0jGc=tYn)u(O&Z6OAv$z{Rq;<|N!m{fQ zmhfRC1roMXxWHx7)h9R)D6#xommS=U{gq6nQsDJg>Y{3Q!^N%iDSK9Db-kp?3g7pA zhj`mP5a&7mZ{G1OOrh{meBb;vxYTilILXl6k`RJD2AT)(L!Kjoq79=1my!?SgBUE( zYkR#~8)**UzkQP_uX|C6t&s#xmIXeYyWMY^C z6bm)Wi#($c@UVRDD(nXfJeA&>)zXz%-RAT*GXaLtEVzQZ> zbT`aJTh_40fBXlQ%!>NK#q+Vy1^cs%fsg`?hRIi z({hDwgfy!Qv}kT)3v(tl8{1krCjyYWw?pkPYb`H13s@!);Q#x! zUcW&Rz&iJ2`s&F}93S1{ak+!G7Pk5CKfS)c^FU4@F`NNLO^Qg!K^gDlk-50QcV-rH zjv6=kfy=QJj6}`56aKxByyV^Jcl#n1%O@oSJxIjz$tWi5Suk=5(@VjQUU~6E#2V-^EF?KRiAmXt0*;&@*)m0nj%+f&{uFiP-3}@fF9zepA0+( z2<`P*AT-CE9?h?sL+pi=mejLliyc13to!7P3?er^L3^#4Ec!Nm5Ee1>YIB=C1OR)rwqjLKW;y3vmzL5^WJA3a_a0DU`6LCpCqX!f0yhC%?^g^g z7qEAN*ArSrvCkTauYXDbMR&Vn6VgATFAY(kcP*KOC+ zt2#G(;~}u^;h%pZ=e1O(uKP~Vo-F9WG5J-&Zu8r1g0z*%HN2#Iu^dF%il`N3seITRm+dR07n=NtQwZ%{h_8%2b zs2^sZZ>MMsc?G)HRY7HB-+$3Wa4U-fq6 z)oL@iE;&j0(+B$T0=ehBROBR-2+{uwOU|9;XpZJAw1-r5~Ai@6C44jsSl8EKb z6pbEN`$Hho3$)Z#@psRJCw=|WYI8g+CkiE&yTs7z1n9EX5+zNRac>%qLf!u1*dRd&OWIfufFeU2rgdjo*T{nX zwWkye5d%F$^H8p;2eF!Xq|hC2!FII=i81luloMR+B&T%24jRHHCx~7li~^M7Arr?I zy9XS@MLy?Ltd8@~qkfmhm$JzOuVhrUgc~{wX+7Hlc2J0_3xqIt6Yh2}2kiRxS8yWm zD04d)iAqjOaWXASyh7T+E3wbDDe;vGI?IBWo#N#*zF+Y*DQH7!Ag(&T9(CQYg3aBSCUgH7m)_|SbQhMTx!GE*Ueh-EGi#`)y=Ie{T@|LxA z$n4gm*i7Sfk9~KJfSRoXo%Up1T)c(4p2pV3Q zO^w6^I#ItOblvp*{cG^ohnEkCVquF3a|BKh`R7foJHCvyf7QtnB|5v?!LiOK`pr8K zak#!#x;Jb>zxx|&w=tY1db!PYX<#)kp|8iIGng9nqweF5V~n!6+ppQS+y_Bdp~&Al z#4|Hd+gTQHJF)6^B4K{HsAXOP-M=!9p1|5+=S|?XcTxts%q0~-OZA5C?eqKlY=JqW{qbSuD;=Nkc?D^n=}#s_wox z)(*X_eXp(Rt=NTZ03`BAaE$q0bj2Z^e?VFV)U*3B3dD%!bv1YVt^6BGC6}1mM#q~y z_rLcu>~tPq!x$_F{rS`6lpKM^S#TG>_j<0c_d-GHbaFq{)R%%05 z4ouQfCs+7TmoZPyy+Z;u$J((wwoa?W@Po=Hzwbaj?dw?nNS^^p^B(r8AW{-FwtGq!^XU8h}XP&d9l9Q|H=zmkr- z&{#(TsVw_@DkH>EL`S{9Q=;My?`Ygq<|jmlu%7mi*@=;LQ2FOt&dVJY0^H9P>~;I4 z(0$z4+fErWqGuuJYSlJQM+@{*h9%rVyJ@-!Svfg%9r)D=t@DfR#E%}vuxQnIR@MrW z>p((CSdN;xZ~$txb((}e_pETh>~!?{B-IVHC4Rf)ZRm5-pUd<&(J%iz<=KEmb0TI zu;O{wVPD+75bTZbf0p5#(q&#$T=yPSN$;3%gYT^ws})6bR)Nj~hb-gLvcr$!&vzD( z>$dVSHd@~BZdSc~sR@0obg9iAbSCFWIGzggEJ6SWI}N%h`j3~DcS~}`W1QEt>eD%L;;*I^|tY0y2c zDbG1cwk(HEa6q9@B>`InO^&vpF8&{D*%V3!g+iKNr~oe8tlF-3#KG1j$R)G_b8+#B zHUAPd#eVtoER;c0Na(|M!K%e%f*Z;vKK^LYQ%$0G2NKD|bxn{U*fqI!euI zV(D2Rw!RKRSwVwf?`5q!?RweZ!E<*Jh{{|C%cW1wIggx3_t;5U$PI)19lC)5=#Uej z#Ioytcdvs4I|_@bEMlHW+zw>jvBDB7H-6qlxK=cD8?9E5s}PK_PEQ3qNpFD?isI@9 zK})H&P+yYS1mk+UpDW2~3~H^C77J>``CLVIiA?iW2u0Gb+y$72h9;a%36F6yszj|4 zR`f$bLw|b~&Smm{NHO24f)V8@tJ&uaIR)M z%rr?>duXty>Z5la8mag=xiCj|Z7Wy+zN!Php0SlK-Q4F5O40;Lu!-p>-1QS%b$hv2+w+Z&HiEq|%S}Gn=s3WLBZ`;Mi@1D?}np>=R^@f)qwC0O6amZ&Y5e zm-xYcfd-AR_$~JR9F^sM%5Wwjyq~{53-sX-$}_s}+TxF$-R0SYY-4kyCeK0*Ezzya zYa?Q?L*dD5n9oB?b6i~6p&=u_ha3LL_tUuHw>4pul>bjW$57ypSL6C|9vZ(_B#8If z96NH{!J{>`O2*`fxS5l2i)gfndnDftPP)sg#2a2ED65itRPJqy`}4s2$P$J{-E>QX z6*asc_;P<9=aTpFvdeuEnN;m+Eg4a|E*C)XpX3p^tcm7C&6@a z-DUl==nc{?%tn=KvSVRZl1EXR=f=rvUfPxtDraMTo;{ohSWv|L=i%9!UO$`+aLOZK z3eYZ-HB4S_eCdVqyp#8lU^0nak~3Gn||1C z_`3ZR6F+UBE&;ayfIxr0ir$vB#}J%EiHrDTwi{@m>wT&u7)P@yj@yz&uLR8|0F|_0 ziOQvCyS@)60h=fTVd`CD&n~T#T8jp1DGh4{KaclZr=555L04R&R%W-?jjk(^7NSshwoxSTMvns`5$g-k}n_K_yOIo39!Osn4 z5kA4$J2@q5E=4oYHI02VF<~Layh@#bAn)T2BeXD_Stbf`fnBc0<*g#)k4wzSC_@9aMJxPf{P@P>hb5BPI_ zP4{cCL`D7L@0N$6Y>YCv1gitfk%D?{x3_oX+~Kj@ny{+-XSs8!+03BO-Kn55hYYJn zcD;R*2=&n3)2um@T|u*8Z>k_bH~bd-LONwv^}#t_cQ?E(wCnaOLa|vpA4aR3%qHrO z;6r4c*cO_-1e_C_=|qRx2Mq(Lw-qdoc`vlZQ4DN)a4?PSifZOjIAAye2Vo zBtX(}h-~Fi4s?EbaNAc9xH-zXz#CgFc^hzSqC!?pFj~R=%O>ohzGhT}`heJ|*V`Ai zjChh~lZ|JGtBb9pwfXZ3xCRUMhB}y59$9(R;3MvS*VG?0hEnudnpM#9|~M^JmI? z=cxhVzZ8h-Re8f)^~%GhtBkV@<%ugAT!HRV0d^A1jv zG0wya=Xkl=*aKaU)nZCfr3d*FvCa)Vo|Qq*!s`N##?`6M;W^0$Hdk?u;ZJg7feOSX zisSvVa#X)y_aBc8k4@dRX-`;{7k-@KXbbd7E0rRsp1gl2v4Oq5`yxNj9*9%-Ayg^M zISKTvuCo?%7B>mptd8>1u@WkiHzpw7-ECpW_1c!rEX;2r6CXAH%O1Nbp!@ju6vApq zoGny!${2XY+}V_=^+6V>?|Igb!{(TFA4~-5H$M zBggq@_kA6-2aBqY(hi%)`Dc&D6!V&!V<O@LX&&h&o=I@Oxg-^I`y+*0s7jx?k2=gC)j<)h1kBQV87Q&l6x!?+_yme zH9kWZkb(0F`hfT&_{T+)zM~hOlm7?(p~P|wCjgFn$(Lg?H^|h`6Kf#4T|{9eP1nnAH!k%N!Vfw2Mk@<*7>YC5G#ayZX5P!4MzTKcPy}^ zg@?-I*N(@2C6@Ov6ZpDONGi|QDO9ca82o~L&+p$Y_yjvr=u(KcRj}*hmB%WNgLA{h z#arPSxP>-Pt(^?q1#(>c4in-6!XW5Co(0G-XO{<^?qnp{pD6yigOOnC8S99Z=j${m zF#?sT@QI^Au1fD=$!l@%oa>fj^}DX#3v?$IFT5+*%L#T#&y*^b$SwJ=o~SUUiMcKG z!S&ztq{)^GjDSap?0i4Z75w{Exgr`pd9%mNwJsB_ObX%Wf|a+pT#@|^GlH%47anUp z0lNM@_>^S7VBfLV%zgK+guw19*!Nx~DOb$dGqB_1yym$gwYH`0_s|d0t)B$->^Z0k z^oxuCK~Gc$a$qYfG_=*`TC}I_DwLY|4g!HK^(r|?cb8gMq+&UU70G3F@)>KdLmxrz zLd4|kkOWOo-xgG4l~|5jwvCGk4#OxzLDqS3{&Qr68wgb_1&Wsz9y6)~#IE$giCJ+X4K zixl9&sc89lh1-3sYnaRGw&jZK5dwBL($`BuT^`RQF2yhwSWegn^$L~(D!aqa!E>HL zNj_|yOQn4W&zKZCu6}=i?XfPeIiDkTcDWSW`~x#VhkSBZxc*?}23WE6YD}EMoNZ-6wbO@jUZ{_i~>tIox4w*6+#Su5CS zo^g|8x4o0zTEKG0^@f>eb_W3wRZf0$la+t;V|=sf?FR4~PYKrW_F@$Z^GVpX1a~@W zsIQ>ijhy1O4eZapE0X(8n4v4PX?O?qXwIt5K?c{z_dM^;Nw6H!+-UUg?{Ti!As^~> zy`gKR&j}Wf$Hcq z24C4`wKjbVUAn1_lwX4H0^j3iWjCPr@WQzWDR_>(ts3I+Hp|P_M13JrM=n0-6q_(TT-&Qv`c(RnrSTewsEnnzKLslX; z!o1(TJZeS4Q`I~1buI7w63EJa4hBKnGmiN$ z^NfSK*&9z!o&c$o^mS#+kX1ajV#h*VChA;4PjD<#x=%xw@|_yw`*)aQ{E2)HTe(`W zeAqKCT*N>mO+R$C5mp#cm?*WjGO=zW*nK5su3)EgS3?qx!PH5xV@$nA;wa0TPwb(P zGT_L+?V3XlFZlBs0#ot20$mQs?&KB{_Jd5CN-L&BX4+87d zckCJx-M+D5^?Pl6-N`j*73`Qe+CedAUX!ojHmoYkWM6A;3oL=<|<#w zu!Ui7OKT-iFcfx^mqED*A;4CzjJw6mchC*8QiMD`Q$rO?L%bqpS7PFFC-2JSdCp*^ zGA>ul&ubBtERU)EMYKrxv!NEF#(12SpTQRBcFEfC_>Wy$vFSCbjf9Aoo8N+3(z}qQY0N%WmlR|) zv0e|+Q@Ry*-0ui>$>1U$kpLK^^i?L(3HhqKfL)+vy)e1$l8(FYL5_i&o7I+ox~Qp@ zemd5=t5hym_wA=&?OO^N5H+#>I>g#YBEhbpBzKWW*kb>KEqb3|kAZtHuwcJ|4hp9w z*hwhgwl-6_xImApG{TJWs9He1I!D3I zMno)DEvi%^I8jrEREAJ`2Lmg*J_==nw6ccW=;(@%dB216{goh!F?|>wouilpx;vd2 zUnRKlDx48fLBDRR4&X9b=@nhH+hDCgA3HHd)lN`D>vKDSnZdSV)ggHDTLb$Tj09Vn z#c}&s_?0lngiJ&eqBsA6L#l&Vd?GDiyWaaKS@_-*1QgjAHn%p|NtDBKW_*V&UBAAJ z%>SO&0lytD}cQKS*{S?$Qz~MGGP}gjQ zC`x_DU>&gMbi;T5iU% zwu($P{3#3etn2}9pkPHxB`03Jiw5-Yo)Us!#tqMGfmq|};^X)p#88*PUkdh*U`pcJ z%G0b1)69w8jUm??jLO8qCgnpK(lr{o5(J z;sxuZ%+-1F#5!Fe!ZW^P%CD9iy=!Yz1KVPMESjx!IgZJeZxQM|UYD<|aZqQW2eSw& zNkSdV0J?w+_;+GeaE2`pmFR777Oy~YV2<6|wa^Qd4faNsNrmQX>*mB0T}-BHYz|Vf z((Q&OP5T`u&q1+Cc+#mSqrweettH+FSA4<$y=I6~)pDN1#M@_K-W#=<@MR79Z@pTZ z+Q-;&Dcf77irp4gd$SibhW1J$EA+aS`6oh6#8{eRXkXia+`3TSBsEr>E$Ylmnnj$H zUPC~5Xbh)O80#}tDcDM)mc-n)}kjdS?N{R58t+d92h z7L{_DuQB?a^o+SlDM~%(j{!NmsUjoxY@(Rj^Ya>FzXtp)Q4z9}33D&xny&LyQ8RZT z4t$RlZ?^?}_oFC*?y!!*$3fXa6x~_&JLi;ay2uhoo-H=N^1Bq9zatjn^a4?~o)M7Y z;=|w(z-7|fpb5&F(5GR4t6VQP;|Kc#R3T*Y@mY4~|;C^(rsB zNlJSKU77I$%!6EaUN+tdEGt{jO&swF(EMk4(~ZkL<`}X3GJ$}Is=c)@hsHhG{Wxv> z!gi^-*BSF4iSk%75KBQR}E3#l2+LJ(1tlEiajqsFz zZinWe2zuh3Sgl~eBrZ}Uh=u$0U;GW&lq92Wg;OO9(*44uJt8RaF+n~+K-S4; zlxV4v_-ft(lX%%Oe!w|~DN{>eI4lp%9Ku|@zyAVp#3$ehjYpRCV54`(sE!x5vtq^r ztd1cTU9aN@c7u01#{^bpjSDMXQ@qc0D|6G2=6xJDcD~QAuwpo&n@+#c+TXrM$2LL2 zN|JFW;^c$LgR!&ODy_@HYDcELZoLT(I*Ib<&+kC_BdElxuD^?w0&}l^({5a{e*DS; z360xl7yCRAl?1W#l>#*6oH>){JRI-W(B4t)K9@bcGt-^|yR413 zNL(Q96obS>u7u2P71_%T!awjwxgu=*uX6kehypUVFZ+aU&#b=H<-4UPrJ+hqX17V5 zMDYv>kBhEfTVh`bWz+>}p%lDFd}tJtGZBa+&>u%Ay;O?-Hv$|HLsvWt@?$h z5$wDVDg!9kn_Tj}^P=Vu=vj07RUFfwfk&)%}zuJU22`7%;TT#xM`b>8|$mt3t zwxkobpkKipodxlJVGr*-WD@%Q6k($n1Yycro{dNt``x7EW_Dz_#!WQlW<`0ii8PtQ@U|^@v^8QAZgO!4IQbCjX2<_>CylXnArE~F)_>} z!@c!xKuXwSowtvFBWAY$mj8J(zzHSQO$wzLe$6RWCm-!M)T~gP&i}YGz9vG z4_^uo$%t{=M!>SRnD`P9IRtgCb>oUx_{SXgtYa)xqVpsk0t2qk2gS;x5%7wSt)IgL zUXBB}GiHpSfe_!$& z2yR_rz-tKV%5O;Q=zdY_HP@H2*TP)m#;Vz_hvr-WZ0Br3MN@`w>tpN&!9C7a zcoyN5)wS-A1`Y}Gs>`3eM7`(YRS0y1SHO_#>1JvT+GCvudx>OFKe2|c>IX=0zNKtZsKYAwy^$I>om;0Ftbe>4FHS+*039qoMiG_+7v8!lLCe(R; zvb{web1hg=c~zUVhyq>CF9AKO4cFw4mDBmB;8v-6JIOHm8${Iw7#{kzN{W$rE~^pf z2+m$cCZ^c>f`r(^R52PSK`&U=w3ChP!f59TZ0`IRsFBSjG$UB7&7({iUh3ZWo5LtL ziJ>4*JewR~WcMd0K`c1o&lIr6*bEcf9B_nznY@6@$o}DVYOdJo+TgX!Tb@0KJGUT{ zlj*+hAaDaBk0Enp4_$9#!AV-gyav41dxrq(s!4ly#0fOYrriX@_+hdpO=a-x6h)KZ5-VJ-YdTP#^geIT4&J#JXPwxlK+jS-1uLX-of0((uwEs(gA!aK zz`I_Yw@NJ>JUP~(6Q7MyZEj>lN86PQ_CawXk4542RuuKYZ6q8tiQx+zv{Y*9vXLp^l&!r! zb-`9CJM9hyHFd-1gi2me%`@*1`}IL_{?K6Im{t2Hya^G;bIvh}f8i7%!Vn3Nr!_9W z%#6%J5~LI+pfX;qKsU&`67dgkV@_$EPl>FV16#p}3DXlM(D6GF53kE86$hEFez!Qq zKz{Tk;88$MdSc7mn)qrLtT_Mt4iq!2vsiHZvlQ%=dBsyP)0kCWdh!%dX`a7J-w4HU zj<8jBVvLUGfL~w&h_VsHsPZ?SsP|bLYn0RkJ0Cnu+tRtg*SQC}FRq3k>-8T#Btu+t zsHNw^GKF%YLGEK;2CT#ph_%Rs6Q&ndWiugwIY>svL0;eCl!duQ^}X5EZOXA#QUpmM zG>BouI9)aDd=yn9%-y)Fw?v8WpD(Et&x7q|*UTp`uUWw}CPz?#&Pg)Y;8<`hAV$Sc zdC)%a$HbRo;6amr-|N^Jk@F{F)h(PLgu=4}*^ZJL86cs5e=7(ru2N}=Yqm*&1bDiL z`}pV2zlDIn-+c}1MIx5}h7$&R%wn;s@x5W;w1-kD-+}Flrg3_GJ<5eV1ciIFY@0~} zD2k4P8~)IfBOwO+dG9LUyTY85VK1Q;uFLoNEUa|1%?8M&`;~=yUnNnAMN01lMcf0)gCY{PGW<04Nr1ke<4QfL0QhM(v=SFk>JqDDFdg zfC4&yR`>!+4co-S@!8E|g*O8yL6dN}K?QBKacN>RBhch+A(IV4%2uiW`MaPvsjrJCArZ?;&UH1yyvuLK zF(WCt--)mo9ut+>9rOdf%jO*?o(O=^Y-bMQVu>nxo-r|k#L#OJWE9wJP2#M}_U6te zZt$`+yooj)Xmzb)n4})E#MdIkEjT4Hy_+n|1*bm%PMV7AQ7<`pChl=KE!ervbyn|) zCw4w6=Y*?3aGaKN#Kd!hx9++hQfTltTFG!ulC39Eu5;G6n^Xxz*iu^U^elS4pB}ce z`?fMz?bW!rz&x5uu3C6(xMrDf{7j}a14aw7&q~hg;AnIjQj()H=1fW||U+QC3tm7M~ zoV#ZduQP`99Lq+@X2|ix^-84}p*TO~P}~pn7LoFK1&-IQ>78?!)K0!s^As@N%XIAI`&BAVh3jkzV9y`UwqpHnedCdsZc>K&3168rl4UW+)*p)bm-x*4dmhl*xBF?( zc%oyX|#E{(Uzl*Pob@;vOyXGh$Cqd6VCj$2P zNToq^0b?MucQNUz%Px50Ec-0>`vYczQ*v|U#GyBlHAMDCHz}aq$+O5U^}fb5v8JloDUXKot(X@2MA*yl0jt@$TpnOgWF# z5vmNsD{)-w`dR55%6w-KgH0x5jva%YKQT0KNGjhO?|MwM9064D^?1saH5^mo^DbZK zhFFd*igQvdW!XRQ3=JF)>{UcX)fVRDPQTT2H8!>>KlpB6^LytSVJ7sWLps0U2}Zc) zF2%+4iIK=MjDD_$F_04k@#iXdBH&o%_?TO-liCCuZb+t*jZb+M-+PAxkdUKn(Rjt> zPfyCd$CK-eO6EA;(+?kF?piq19b1;uwNK<_zC=Ee_kNc7b&7n0I7D6qTb^;bq7*PS z9wZ`4iX!7`M?p!)XeKd=J?j#&d>A_Cusa{bb(?uxLHYhnofIm6d$T7%8hcb3@Z?d` zrnXDZa|Lt{4F`)oZ|arVb$5CAjEezg>kra&Y^#UsK7C3O_UQ! za({G6bi@)blTemrr=I044Y*qGrYC{2%a}Q9XvMKQCk<*L9hGEau3(SR<*rF#SbLZS z`~#$`=p#^OrOECyLfw=~?2TK2we0~XJuf1eA>fHjiB;_r(oj&XDxraZghMbWXv}yp zBp02b#}jF}2JZ)tlQRI{Q;b>4i8L{8xdD&@@q35uOG}YF1pUry3%=hWEL5>n73MG7 zya9M`Im|(BQQ~N*-Ik3MgA~GJs8Q7)woCumu-#7lr9$VloZ7qX@dA;zl0qAU4Js|z zY3?k>pp2pK=M?HNL~FzBbn+;~y>_dXs_o&a!q%)~m)NTpDc7dloFBBVkOf%jbeo2~l_0f1p2%m>j)fKl}Cz;Qe~Ji`1CGI3XoK|Oz>K$j0@ z&#vjNs7usn2PJ8J=CU1}(Dy)r|2IV<0KF&=;3oUH_Eqvzb-7qMty1w$f`r?^&rl=iad1g4MRnREIr$lYPuywok3+x0B(zcm#T1Pi8le zf{}eDQl6`9BgH1%8s&C&?-}RBp!GkWg>EOe#ole`Hy0t(v2!iTBb`Ks8U9G7Q&J%yWr?7OXY4`klPO}r(%Qgncj9H72#5> zn}g?HzSFPVFPY;b5vz7E5L~1E5lYSw7pu-k$jbJ(1|}(ZvS);Oa2GnRN?N>u>EP3D z-AMQC#4RjY1Chx!oh&f+IK*PrQ%r`FDDN3&@lFMrsLk?=j(hFJa@^OF^jPUzc!mjS z$lB+mrzfs2G2e1^>^3mtrxxa1xn zPv_K-%GITrfAN3xyg0)5VW@Rp)ZDwmoQ$z+O;Xd&YV`_b=n5T}s}bli_S&HGx65c<4|_H*cr0!2@22{e~n&-HYX^1=q=dt60)< zMHHq!-H(lPZeo@rr9weB+=iO8`JI>6@NpVJj>*1lhU+ZA40l@_VCnUC#!vf=^)2O!tuU#AS0E*fVx_K*;BFV zNfFI7!uD_tRd%`vzF3^I@B%Su$%`U4hAb{QIa4kTWdQFWETr-Ax}rP=9GV2-y?Z`P?wly0FgV!NZhIa;)|3;2bc+WDYouwp!t#{V06 z9w@H;VyN(CH~UVkGBM|3-08Blo11^R{Be~Ey04Sx+~I*r`_u|WD7oGr8i+yC{3hdf zG0el#6&FhlvW%`%*B5+j%&zUKF5zrj{|o;1cRA;1RBC&LZ7KZarlcbJqV}T*!tns$t8- z`MYV`vqx5?Vjby0aH-D#fOxuEhEaOY!Dq!dnfvS%$2|-;ZhigzI*H&UUvTE$(j0j+-!xtX&*JVe*gt8Z4A1a5azhJ3zKOCGwkVSP?kZf90%> z#qtB3DlRV2>W=xZV@qh_9!AhZ&j6XExY*dQZJ+8XbJ;=@qyj*0`UC=_Qd8dC{`4Mf z5*gfY--)T}+(3gr7Hh`U;#XTu9yy-&j^ldl2KWKu+z+MH#ZrN2dOM;OAFSC9oXKwd#B{<{mSMCDa@5qdp=4rUlQ75C>51_ zerWnF6^@DFG{)0FGS@9gUe??XUApF465c!tz^CAD5nHJ^vV|^jVOy^{-rv&HucPCn*gjv zqUC!O(xscDEn9dPIZY?9buJ%Xrx-A2WFk}5!9HNN(;1Uz?1tCB&EXObP~R)FZT}kE zG01~hEGrm?v{(vUmUISCV!4wNWf8>K%w$I)$X6@O4Ln3z?(a|5VEyr&m-xR7W1Z{p zS+1lbwKjjQCihU#oD}n43i>D}Ri$#j0^=+Z%Znz0HVSmsW~H`q)w2Bos$H`Z7zrOQ zZl4$hPed<0OjR*Zm$|bO>`cxJ5>}-n~?S1LJd%=^tBtkz+7|{r~=NZ85Z7 zU|!`fHFcc|#zV#%lL@qAC6-57{w^EXlgpi$0jCg8+$>H9~#6SmLuyQJunq=pxWjILmC|cCD2xVY3gq-h0KQZ~)<; zLoE^9OzM%mxE$LxZg_Vv#qjgzy=e28zzIRew~1HTPNWGK)AVEtqjnr_;w#BG-UM>x z%VUJi={RjX-wS9J>M=K}ieYZpf=@z?37dK8Rm=9(zV|H&bq^{^iXHao1s3Wr!Jflo zSjOWjW#R!AMAT&?7OZs9BvALQ`(O;JY=vo>2hf1|`STyKep9$^sU$51|73IIb3Z~r zuseST_1dt?zfbdPeuxBf(VCzY4@xpg>@Re-WhlXDADYV65^H4??eqII$a-Ke4t`?( zA3{89>pDrXN#Plwv(t+|bW)>&Ck&@Ovx@^Om4FIN}=aEs~282Tl6( z^QRq8DwQ|PESAE%&RQJZaqC&2S5dU5WawDyA%W)`k3l_Mjn|P|nBbd(kSl$} zJMA1-v2t+q2=fEGw6C3P^ugz6!|8`OR?v5`#V}JakzjY;CF~c{yP;G_{L*ndRV=kM zM6p2hn+Xg7S(jL6em{rcphodz4css%(0rSzC@yu{La^Um{{S!N#;^FzMwLj zB>&&D;q=On0XFl=uj}B^jxV*h#n-IIcg^)^&DnUyAgsnkxF(=Sh{rQ3fwA+oalgNw z_&xVonut*fx`!$9HPhjuLcSB5DiQ9&N+4uEqwzxT`LJuS6^1mlV$IKF%bu1U*n&L< za>e8N(1Kkme~TG-2K@zkmu^dDQ+h!#p5A32#sA|3qZV~rFi$aC?Fk^Qsh=V<0g5qc zE0sC2@%qs+#aK3m7Ib1(*GYiSNx~bgSv)U=B237mW=Bl{Icuvvgt%8*sJ~Brp!B~~ z7InHTSZfASiJEa_m!Ca(a4(CO`8YRqDqp1be12DZ;Tng5a6>Gd5WHbe#73OwH7hh5P0Nbj$SOLAT*djN{2(ra znNZBz6UEp$f9b0^-kiV9hpra-lLx=Jd;Un$hgWQsZaN++hT%ABiwYAAv+VCR3Mal# z_<4kNKw20Io?(YUYGxTuv_%-)UC_Ds7qMke1t2`M=;MQ1`_y+6Z-xNT~Vb_JJ(i7|0Su-U}1z zK^(bEc61^ZD}r|Bw~Z8f{+=2k8cdk$bI7n$nR9L)yG?&o4Pz#Q+7JGK~Xz*1;Ae{zz!|P2`bFBw}d=T zSI{=zxeTqPT#piN%Zim=F?1&{;40rYc!*~VvMT>T@0(mqpiqf%AIHVkT&|cax4Y=iKX2jG zU^m1-3}WdLnbB^!&gZ7`%_1b_ySFm?xW#o{;a})i1{w2nyvm>B{m|#wl1WYHp^6V= zyCfw7!)9eWVDchV6_LThobSsgeavq6L}%)=m!(Mn-Gbfmt@Hfvl**~K33CJ*r}=d% z;kh!*rrniYe z%Ue4fWH_s1$Jn=oe*RpR)?{rTG(D?)k9y4ij%Rn(q1w!4Htpd$cS2cakm?w6?r{C`1l3;3Ao`sLU>SV4UY}9&SYlvo3V+S4eslL zZneQBY&-*xT_)d}=NL9#O^V7E$ZC%}?4p&TpP5zsqR4VmD* ztauBo`JkszcIbsy&(i3yN_PIOQ?uapK^K88V+@t}3CFTxFhnR>=F?6Te-@=n?SsrT zt&bv1uz3NpRVcd7vdoaksB_3ZuT6@f$>BR^+~YmKh6t|9bX7vV@`4e@)5zBGeXmro zvoem)v{Ie~J-}W%+3_&=^RA62lVEbKNCoI|$gew$OH!{3c9kHN*^3Kri7or)-(x<@|&*OwSoCfk0%maw!p$%)}c8{CAC{Kc(sJLb)BM=p8WV(pbgX+1}p=dWPp$VN0;amLeP3QQM)ZpRkF z11E<2CE}5+!BVpj6j04syWMd@8PPQ^yV^|6!gE3Npq(!EMi^3 zvF4ACRXbdmSG^sRTOVFe2q~EF0(%8)jq9h?`&zs6V2@FvGwE5 zwVlL$9VyV=`?ZMMy=zh&KAa|Dhl4{wnJxSe9X-Ms|_=FTz1~}xE+#`Y%KWOoo72KwP^>z{&}t!n}7Ew=UN5} zbA3!Z7hyJP%eGKou=Cg*A&)G$R{Oq6_+r$a@Q4pOKS3{5^CDg|&-)%mv^rf=ZFX0T zO>T3>(jxh0tpeSEOAt(X1`6K;Q1g+rSIwR&g+kYlUl=NwA%nO!9!iz~p8K(fc9w7= zj2l}wAcc?iCT7$aj@6g`>p zv-d{tEYPQbn24%^aALQmLx-p!P?M86GHFA=Lo`wuzztdNMRqY5uMAE6K7l_;!qHmM zBG?frAh&b?;m(RAo-6Tujj_>PG_I+Kv{)8zJTVp4694Rj%+nMktM)Y)JJ>lf752E& z!r!t`lKC{fawc5wXMSyy$Qj2XRxrX4tlYZ+<=L!Y$a!#f<#17fZcvkCg_ukbIs-Z= zgHh(Eh+LIm^CZ+*1Gpv*SDTbn>+v8wxpGIgF5iQ%CwvLXZH|OJjctRitZA~ws|plN z+_!-&7CB)~=JsA1m5KNiN~|1#4&-U`#i@^Ml^5T6>d$Xcp|4Tidkf?l1-g&YRsng# z{^~N`mkQfsR{47$TtfBypoy|@(5=N9MidwONGY{pH&L$h7!v$_=ULw zhbur^qOLFp_}2+LjKw?x%w}jahygud`TLYV(>>HQ0?LTX{jI(iStft?VWi@U&%rc) zG0E1m&3mh`&|P?}y-|rhp5xCF#4W^mM=T`bm`}bQeHODfmjjdOX zYwvffUzAdDIH`oADKMfevf-fNEOP6x)vVoL&-vM9E9-0B1vUNC4J!E)K9V8+B+!5X z7P_5#Fy+a5!6^b6r-I&75QD0#*pknuL^tB~UPY$*O&phhpQL zZ?cJs1)&n>jobFoeA)e|9HBTqaaDgscNFt(`yjR2V?~1>Ak2AN8MeT@h#kn6h&&We z7ASO4``0gcuH0Zn0Z=YNA4OGZ_bBd56XjIyVfl`zC!mPQXApDPY~7%|A0G~Gs8Zy^ zNW{>A6|(QW;PW1x^Gpl87x+$5LbLL0VdmZ#e2jxM&%F*b&gFa=o8-xOji8u-{eO$e>4U{+uYVcf6pxWl<1;pGJExgiXQ#nUW*%YU~5a&ed5uq=B8b>-4z zk^c<=lA*23qOpXE#aq5Moc~go0jm}02&{+Z!Ds}+C3a*wg|ZTZtlA5`dEii{rFrox zF)$BO!1y+RDJ^^pvK-KKm%6@|!g(XUSI)U(bM686SzhNxC?`cs3176eCmbyW7V-+7 zu?#3dG3LKwSUEfjGgzUta$QrObEUmKc6e{cAMRRd>8qtSCd?^xyRBwjH8*4j#ncmGu zSJI?kcCan~~JpGI%U0AYVaGu)s{q6@dks-K!ymHG-&h4W>|PDmV#&t_O#mBp2f5 z^szu>G8+o$d;P-P++-}^zw+mYraVM}i!K-YxVIgIWKt|i4H>`?AK2OFLqIQkHCfJH zw}auwm#(jv|38TH#PE#OqvCBDJMK;olUi^g!Sf?p+NoF_^Bm;DR19egIxBm*8<;uj zQLMWhq|mtnt@IF%0(%`|vFa992-oco&72fLa2ggmP&^&N-W(;4^?S>?Q6Sa1bWp%2 z{E4A1gR)CJ+P)5%thTLa+N70UYwaBS7SrdAeu*fFuJeTCiAVhn&v=HcTEJ#J=MFo` z>Ia+R5ps@a0yXDba=XyJ-Lgt4iTe0Vm-t(;%XhcLsAP?avq0XguJF#lr zO|aze&poG8S5K@uDXs$Q<(u$dcyoqRTS`&_DtBnx{s!8cxfmRQnz~?&s!z{mt5m31 zsxr>KYe=vtG;6^zUst|nkcj2Os$Y;9fZ>!VJdx2U0>_eRfr(zR&6#J}%TUyRaDrf- z_C3_K_$|qdnh=ZRKtAx`#I_xf%ihejDAXbP^UvN^wczG3P-{<+#$FOk7G)||P%+xW zL^vsduDOQ8-5i{-&46!>>+-o%5Z!b*46qR&od7mMAXWrAXRgP^+8$K6f~{=V@Pgwt zC*toZtn;{7TKPn2x=iK&k7{gk4sgc&W(d>aseoO|QqYZ3=-3jwWHvH9ZVcrdq4ImF zn8oa`&|{2`w-xWbuW3|Y3{vPg6aNj^eIu~fdcuZ@>T(=y+1numrM;4;0IZQW1X~o^ z+`~jTEejnXZw?LAJq&}4>!M=tu5}OFL!kekp%md#oPR&$OSXQtw*lmZJzG4MQPEy9Te95%KtL&6F8|ZyY_%BQb-Jj|GNW}7Cj3CJcJYp?$;7)etz1P=d6c!9Cm}FG~ZgT{iZaA*-?BO-1FyK1yJp!97 zE73{DNY7fsY?+yEY7|N=IJ^;fi7=OS3&H7YwdTb6RcS2bpB~v zvr+Uv{{MHe?h!_S>-tmY#j;~sV|ndm9I^}>Osg>T1%)tZV#VY}DYP->Rfag?r!Lg> zm?6f&1jtH9Md&mvqdu@Ry$8M1MVV^5OWOr*kN0^86Sa=+$#H<&p=S^0n?Ja;_1hTZ zg@yV{RA4|V3Y4U~&3`-om5N0x6#a)K&`u?|4b z+Dz&R;QS#;pt!L}KKXC^xTB{6#(%-ib{~5@{QbsL=w_-Tl7`)DJ3USbephv!T3DNKNq$#OUFk(agR$C2LQfP_yXqo@w;?W;NCCML z-?b7zgg`-ciPjPcWA|R7Fp@8)5!x~S!My}-o$tRu02GZY(9)&P7v?wkD!KP@nM)vl z@NfC56(lT;%w4)uXUj@dvXzmfsDX#!k01Q`SC=Rc=VM64@?=~bCnwM~ zkfPDRXUTTQ9z^qyF178B)*PB}Lkc^3=+dI?l8xUHTCm!+{fJR7i_m5b4q(&JrZ5lW zHN*wU27~K%-7H%zw2h$j2=zqwksb?jS^I=>0>r&% zk!^+k1>=y2<6`(gx(so`8hd;%w0q3GFFt~elKR&C?MtYgxvUQevwrFIHsR}b^jn9D9&-g@u13;qZP?#w87!DN5x9Ke><^d3_~D2%i}`DwRpDB z5w_K_sdFVdty~dPSe*CHwOqSGKD3q2uC5UA^Q1gzgax?L1^)n3fSS=DVsL3J>u4~A zPzSg1kG+kKnX|k3HQ05!pI{hdLf(e0JPqw~EtL=jK8|X;UwwFmvJ2>*sp4;nr^j$2 z&|Wy12$w6Hy&1>cM7qF?Wi>+m(>dfVtQJuu=YhZEoaoMv1IN1(%P~xVQ%#EV)jAJ9 zoZppbO;RHHB`(gJTTl=fY$do>dJ0kq%oscE0n5Ffe_o2e(`c&fcIn1)64z?2bOZ_P zk2MK$W}9o{QsxQPZ4fjpmR60+C*p6D5cD#tb_I;VcK7XJ0eBRg&8Z~GaY$`1Rw?Mo zWid99t}BF4mx|=+=Pj%NMGI?z_!QW3iBZ(B~|Nuvgg3} z*=@sl1 z4(yzU-p@f~j7z2MYh7)(sB@0N{Du|qSXUIBFjWAPAfuL>@|_(d%vq71+&Y)2D4aAN zpIz@gA*vFR){TiBPa+n}LuJmU;rKytiWa(MosW(EN<`FxaLd9}RW_hz3a{tr@Z*^* zubgYST8*ZDap98k#A0~|BcLwWX+S3aLK}0 zx@d>G-Ve@kyh5Ghy*8`g3RuJpbQORtY(8cyBAvlWoZE!%#Oh&|IYGX2$Jx9j_81;i zIyD9K{iP}sWPrQUuI%+H8~E(v;xC%d-*FB6OIEV+c|Leb*AlVcKQIg%ag1PcOXBnd zx}Axb!URB#n3;?u(E-LZ2i2I4xDI@2r8a24C}Xm%L&8-yN{qM8i5q(hM2Y#s`+Mzh zgu$gqYEzD@{EC$}%R{6t|2w@HmQPOPBp)!US4!ddLO|I*Ixyr<_9!f^TPb&)##9|paNcMuo z@1R3nxk2Y81+vS`QW%Dfb^Zx(QUW~$=W-u7L~ z*~38S_#s+Sm<)uIEqOjLG3fmmt2!#FgjbWiCBhW)cYPiu%n4;_=1fFM0(ON2cT$@Z zoJ{tOpKsEzX$;hOO{&V zJxsOp2{%c~KS+r6gWc+8-KBWXkDBCZ$hqZQNpsR6GmV-qE?#k#eeAua+#A%zJA5(% zz49{U+Ub&6zH>t)bogJE+?vZL&s&%g+9hmTkp^R8l?bdxaFcQx589cF%yawI!w_K6U5(f0V>y6#d_+D+n$Evo#TqQB! zy(r)PEW`Tr-eClfGWe^`J)*JN)go8WqHv#%KzAn2r(&H;uy8{S+3&uZ@kQYQiW5t9 zFb=d-v$CydDus#TnXzF6t2@zAIOeTqJNvrHBENOY5-E$EUV5oO*+QLM_K(he7-b0x zfvD@_hgMV6DqEO$5=E%-8@FK$*a(PX!}3{<@e15K%FyJ>H@_RM8(8sJ9Ofdeo&#xs z4bQ=>*0FUR_FOpH^U!)e*Ynb2Y;c%#Td|58yf-`#;C`<0q99-kVGbAm0o2a4D+Y~a z=N`(i$q*>05$q=+&^?pWld{fTG`Ni_uIS0Gpb=!}0#b#x5n4y-wPnhe>-MVAeOuWN|y8SFB zwIpl86@$GD4d;=H$^#}(!2)m;i%E@}8bYn!UMTM~vOR1vG=ze@N!X?NXCF!i@cVYD zW86f^`Wu+~bUS=7=(p>0eE9ICA$iz%J5r#^E#)XRZ$Tzw+Sg;fpQ{(>9v2f@Z;NQg zV_^*(IZ%H7#CQ!_5r?i55XXb<<`N}>PiD@!U5%Z;&~ctOFaVyAiY?S#*EW3;ac&wD z!X?UXbF|tn18KNgrTn^h`=Z zq|j0O?2t(HW`YT{?wo_Q*W%dK#J1vjdlJxY`M$=y#wS>BF*(n%yp8a7t$yuU@Wp`h zm*rQ-(!cdsvNzx)+(k2%IOi2i5MGEsYCuhy}hbDKD~bcy3j@|U<5xDC1^ zuN*7e#M9;Zr1kE)i{J1urM3Clxz?2bPsDYPQgHerur(#!x`W@nsf7BJ$#1piv<3RR zDbLm6TFS8-sG`Jk4k?I&x%Sz}v8lB67n)b(Z)mWDYm@C3P@ub_QVBG|lUW?1#;}Ss zDLp~KN(8&tjW$9H<>R4+{1*BN*Ay`6i832immTztzPPxnjh9d|5`O*>YmEy&u58~? zAh%lU0iJD*rWwrY%6wVgS!Jv=;A_O7Xq7lGG~70=ei9&ctHM(KenWxi`+3 zOaWV=+Sa`5j-NbXNy3>pMq4e8Vlz05AZo%#x$*f}u@goy$D7=9=Lqyktl}QmGKsLY z&LN+FV5Pwt6C}uQ`v~NU!nuF~-36XGE$DUfeK4H#mOw90xS(JU=|v( zE1a)=2d>gUnZ-ESe{On^Jjl`Nu(i(~E>C{Z@i)id`wiqOOra-gvf2kvq(u%ueqWq= za@#sCVO-@qHvujG_u8?RQDKtSG);E4kX9_zW5<=RCu)xnISB3aA(i&F268-}`JP3P*fdc`}#6T=QlR66WZV^AqtO zwUvyqRg8t&pFK|yz83?JW9UaOoonBSYnNVylwSnoe}8Cu;WYgqamm~4aMZ^04muzr z4tU)Ev-dX;3)#0m%uT}j4ul$X{E#HVb3l0+Iy#F3nM2A}gyl+Y` zk(Wb3VCefua^r<(y~m&Dn66Ow=85QYQ$EU8tUj`$pTf*=#_Zzc zR@OM4K#*DC*p&)&gp(k+xT3WrBHzj)6TChaYmfr*%;NtFYTB6=Me=CzqP1%$ElDWW zG*cJ=k0u{9rjoUBs!tHZ@tkv%aL9-qsg9_iW#_Q*N-qz58N;?GeLFU-Js@D$jQglq z-Rswut0(ErCKyl4 zCyG&9*tB&g+GZOvUa2QXU)$5%!e;lB9V@3ewTyp%w4MXT;&DGaPVOFCD+p1wr+Lh= z?j6{1(oej-^2C2}45!YqQ>e=U7}$-iBNDOv9YTZ3I1OS5fQVWHe-`K1nJ#*nuTvT- zP%|YM)`5k$600s@S;%qz8-xZ{ag>MjktmclO4y5_?EQYrLg`xn zMzTU)hpc)KeUvc-P#sIAJj@o3iK75qGLL`~``vkjwM3$0=ujkS*$HlR4oh(7*Sh2F zA3fVYg405k$Hs%_-0@^BBrh(07uTgAJd{`tCphRH9>m`}ogi7QQAX?Y&63t|0V(80 zBnbw>)c0dAmZurJ0pL-zo~%HRU?4=&SOR1*wP~xw{1Zigv&EN2AxZY71vFE-lFDj{6q=A#*{7r{U4q=;PMx^67Hzlq1K3Gx6#K5{PCoMZ(9g_q(I46Me(iI; z^Y)T5_Q)$$eC^#`j+rscX0DNwV zwPty@`_#CH@?A^DJm-lKn}w%pog;z@^o6h$%juavOqm$AnTzx%G#Z6%Wn-QECS&Ib zkT8+Vc`?`uLc*34PDW|Xaqq%C} zG`SPzUA2gpU}bQWj7i>sQ^8=D`)Yu#NDZ(t#~DMrz;14Ez$Uy3|KGz2LYJo9+@M=K zY1wqclL-E9<7WSau}jY5Fs}Pc`vegRmzR!9UE-33?!EpC6SOEvFXsKfu+?Z>?;Cc# zzvk<|&aeNKIPV{p>z^3s9y#vn#@T;|aFChc|G`9%aqPl|q3I zh>#3a{`m`tE20<4M^?5zzRLHf@>{}eVK)zgd3sua@5p;TA3oo!XabV45h%SRS@sW1 z3^Nwim``vH7J4F@0C^l=){$^8{VNuo&$pJITow&c|3?} znrjXP_7cSWn^WHZC6r~KuVFcq0zHbRROVbO{ccsIVNvvlSpEVNK~sEVX(fekzILVK zo)af6&|UXls05moW7^u&8R3av*MltI^0yn;UsK&VyUCew!#6fI(sHgTWkX1J{6|sU zpt`vJdE0xSGQf9HNCJ>7lau-nm>JB?@X~pXntnN(uMY(EQn1^pA|7>QF@eHWpD26P}d9pIq-dke0V-DiT#2M8ww7ZH3`63SWXHUG9^+ z8|%RJ_qK;)S~4AR@=EUpUGm6+{G8{7SS(NaJ1bWD3L2pZN^679!AnB(b8u3n>-j+_ zYuns<*JNrFSnjN}zHj5QI0u)z!BY|F=Z9w3`w^Ng@Qp{P%41&@rA2kyp%TOr90Z7FtrSC>Z6=-&+?&zlr5Jyfe~D-z;gR z3rcJQ1=N5m)bUIAdVQYHj<-#80wyW`F;~&V5bjzo!7!~-$In`!e(D0f&U!m%#BgS4 zalOY-A19aXNq0~u(8|nQ+~(MFoVrprL@JIcEpJnzcC0)96xNJ0X&l#JjaED^6J|ww z=$;R&VU(K(QVE?bhHl`gPWiY*rH!|z1`!Y`2mr^uUb9iIxaRKtn!F7}kTHl>c}-r3 z7iT5VSCyzS9prCZ%*7fSEv|QTD}VNW!`g6*P&H+2oods)*F)uVmTTSArt|hqO375# zOe~fatObrTG}(J;ch)l{f=>ytSXM9t_`Oi&ikZSH4AF=s7OQVVWZkn>{so#FaG81L zz(T+JUK6?5vF03?U6i0AFNCb}jdT3kehnur&{-psH|`S79kNW1+%V^Zde{4=Lf#@_ zH⋘j&jG_)GH2D>b9x5o(+@Q)W#9@v2D(MsM|IW@;v=x7;kj;Zm1oEC9U`BAoKw7SF6yd-SE^zz(K{xwIVJ@t4Y6w-2&tO_M*Jrn* z_5Q{cxa>BU0vgZbl~pw^cCkTi<0*{`5i3aMcAo@+U8Zo#bf{e*2f=ZU#2-PO`7fCE zx1_};{J&|R`$G%)ksZZalGnBk7I-OG>xJsB!#S+DV1*Tq&Qp##CjlmE?)DbiNg7#iI7E)>r-?^}d^rT2ixDwlYWya+`W zd-FLyH+duYetmUg=zEwD`bLs_cE_&UPkK3@WJhp7yDUbNx__2}zCZQ@pUlO`1I#DL z70?Uyjs@m5|Lu#J?#FO@LmgoZTF5_t-hfX?*rYFYLUqUAH}T24wdqwBIs5#TI3g=0 zspr^R2!;8}mO3FLmbl3TIyf%;=mgsckA`FjTqxY)5H@W>cz8LMZ4N z6dCgEq%exldj&17cqCRbmUD|$ZniJZt>>9`#RB))`o1X6#~JxjpdY4+Ls@QHa?gHb z*X@>Fn0t2Fej8}n$@<8+64yKj*yTBDs!5ConBDfXe3=aE)?R<^?j9^EOjpUE=leAq zKm*zkPv3YbSARuY^ew2y-^b< zY$Zws@oWeG~L5)|OL(bn0M%C>5O@OaQGN+g_R@*LSwQ zOiTf~^$2#Y5f4$+Scp~`-blMXfS>*Cm9wo+sBXpg^`&N2#c&7plc�ugkh`a;^12 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 ^Z)|4C4&STFWaJnQ}0kqNOgc_iq@1ioO+Nndqgs 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

    +5`yQPfmA6l@GW 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%0ARdlYN~d!R-;I)|YM z+h|8V??Ey#w1tj9t=b5%bl`U`cp=q&y~_uvfH;Kjmw0gOZcoLo2M7lg9M$~@xhS#L z{f-5mdHBeh_u#89b==*9dU!XKG_sg_zvn>?rojmB0d{x#o8jw z^~aE=)E3UV;()XHudMx4doBqyXg_hEUy6NCMVJG7M9g2`UW=%c$9s55awYx>YK=4&r9iN(Ph0cO z*fU~hL^|XkBg;;tQi7J!#aJ&2Kfms}{-)C50>^>A?havYXk1hA-l585cZEC&Z8sEf z4@9{t@6r8}5#|Vc@%{_e0zIEpZ)0x9(}se2TxUR@0bE0|>H`(eH$ZD=`}d0imH3;fm;sc5KRX-+`&BGA3&+4@vdJxk$LI&sg%)B77rN@86nxh}w2$&P?qCFj z7HWiH1|#wehM%ZIn2RjuR$=bTfTskXeM87o_HGJpZ844AUqRlZ^0Vc+ui%NGsN3`M zj^ZC!3wD3(6rM6D(>&GNbvVYK1N!Ke0Clczx1W7?`WsElf&+TtW6X|m|bs#H=cK2PU5|otkZrYEhc7>{~ZE@!yfNEZ<$Q?TzqaX z-q*=--gAD4ICyQ16rU zVnDKPHovO2isDxoi7G5bab$U)@HgF_7+vok>N#>T;(Hg>+#M&h+i+ZCOqAzDo{1F9 zJs_ceKDBR0!0U3|?l{&$3-m!oVH^v629i1!wRh?eb-7i!FGzC$P8QjLLqGzdVV5%G zFc*@Mk7-VmW*qv~vPh)@K*E0tl-Lg6qu8GTZ-ot50sGT=|Gjp_`Qqj1LL_&wI~h{z zFVn)c*$`%YX;CCNf+?%t=v<)5{YncAeH<4abYpij0FF+^i3oY`2ah}ES};nUZ!yI2 zvM&Wfx<%3_AMkl~gfpkYWX7j3R7o(6URD4S>6Fj**J@0ohpkjrST3wLPvc~}E3usp z`9iQd^cYB}0gP^n!Mo03MgtffGrGCCWdfO7Xm(Ok5D=_1NUL)XGvINB-uMQw)}HPA zCXvH5sQLt2PzD2A-I=rd;0W^+Y<4&*vuWpY$4Rw^KFyZy;ag5F+=+L#Bh0B$#t)z| zo54I>Xax_I|BwnQBLymvUK4wwA%0Wn- z(Egolfow*)-Teu=Q;u0DLJp|%I0=Ey*g?&OJdNOlC=b7jJ-U+(TPH}Y@BkCR^rASy zGUu(30%E+CO!TJN=ZgBK`Ns+!3*#5tdKe7z=_X%fk}&|TH4Y=|cBu-8H5Rw{C zBF)qRmR4Iu@gD?6;&1=h-9Uzf^G(Z1>V1|9@PN4ZTZ=fAIhS002ov JPDHLkV1n0f`U(I5 literal 0 HcmV?d00001 diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_kids.imageset/Contents.json b/apps/ios/Shared/Assets.xcassets/wallpaper_kids.imageset/Contents.json new file mode 100644 index 0000000000..aba5903ec0 --- /dev/null +++ b/apps/ios/Shared/Assets.xcassets/wallpaper_kids.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "wallpaper_kids@1x.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "wallpaper_kids@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "wallpaper_kids@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_kids.imageset/wallpaper_kids@1x.png b/apps/ios/Shared/Assets.xcassets/wallpaper_kids.imageset/wallpaper_kids@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..83e48b4f78842a5a5d30314396829b30e0d4c2d3 GIT binary patch literal 29406 zcmV)yK$5?SP)PyA07*naRCr$P-363o%Xb#=`V-t;gFC_99fAcR4J?{9xws?NJgDc`Y_@;gc?A6`oNl%w7ODR9?Ff>2^!iPb=%!vNqQ$9f{ z<=H=HnMx_Ywv_Vm4?rUPAN)cd{|ynv+hQ1) zkx!V>JqP_MN-5v$a6}j(r}R$`oxsNK&i;A^_->_?&sIwLn5C4zT}t_gd(Q9;yw?{k zrF^tf%AYyt_vb66{D4x*4=knp$WqGxcmv1$|J#s&;%6y zV}6-Z${#(vA0vF{b6oZY-#arv@!)4a1mGS) zoc=bi``@{!PdA zE6-@JVGkJ5S1P6a$_G07_l|%6t5V8en%odju$RA6O8JMY4<8vI%m0R@ln*JT{DlL( zTx){gxRmnyN-2NiFiJwEu#C-sA=D=?rF`y#)(>}!2zx>b(SMwrtgWk+ObVnG( zz=Qzk0p*g}6+%9IR}b*acFfV*mM2iswpb z@!;R;!2rM8GbJci!~vjDIEwh28@Y?8WS3{G!n*#D!%%rXaTmSv2MhCm2{LO=#;*D2 zmBKSZ#vo=xeXo4jg_x5a$PN6?1(|YM-}M2+|4=FAPj?=QQ2`+!Da4@lJPccw$sLzNg5w8z5DToh1GKXZ=P(_TkM-jDc*gH?=*yX5eAz=T(*9XfYx3Po zDZlUtb9gyQp0$>}{F6tm+T0{il1#ZJbLsv8fXvl>ttA7hjPPf5N?5?@(;Q9# zt9%v4^$ZYwz+-2150gYu|L$b9Pzkj}3lF()Wd;eg&OW@CXSj|cn=nN)35Li^5sqt6 zV!|LCUJ(tG!S(yubFL^`{T=h;ZPks)>>nTFL!H{iCvS>Q4vh6P9$-gNegDcww)*QI z3#xg75!N5ITr31t|HMaVp|q5-iPb2*aid-gxEJG}jm?@0S+FAiW^jM&n4`Rac{2WLA7j?h53zx8Y4k} zpTo-<2V>+>ETS<>3xDbZ5x?X^x6U6wya;c|b9=^fe=PdfIu;!psO9B%{^VoK7K&mr zk}R5^Q!a6}IbaEXzw_bQC>aE1#4R9_6E7%s@-bF*&!9J2^pB2vFht`9ZmS=Lf%g9N z!`pe5?kVGvIV2Z9WBlLzplE1X?}Iv0Qh5U(#!Mf7%TX3{AK*ZtL-!QP>(A$}l0W2& zY25Q8L8C@)-59vFB(wK9zzZM>1<0Ax@HJ}3s^qI7DJNePQhOx=?ULsR<;{3`6(3_{q+;A3 z+kk*EGLUb7BoHXr%7;P$N^u>JSATdZB_3-+34xEFp^HCt5Vm}W1B7%TQE=b?1BaZf zx1Xmj4WuREv`GGy>cLqD%!s$tTyf8jxp=O%;{mZVy1=W+`1$}64u-z-n4ALn(t$_W z)Y<@{4fMdJDZnkqgRh|Efye7V5rd0;v`G#-eMi`+$;oW$NO^* z`Zg*SGel*U4`?VRIewNSdGa%kv9HL&TmYraH;;9uFP_a{0N1xX=Gc?Z_d2`^;1%0KJyw8`NVo`te1~2< za%?d`-5)qDV}MjI^+6>eHlwdUf^33^AYv4rBc%ph+eA$2>m5ezTAn~^Iv;^DWxS_B z0x0n;R7HnnPK_1K{)2}XSnZrKKJ?E$QLNOCEUHYRe%#eq%)KZmmNEKJ03J)?tp1Q2 z&&RV+j>Oh89bmM|HW&;A2aJr2@uVhhV-TY7E;SQC(^1+MV62Dd zw)0BjMndGQ4CXojY7ONV+~4)Q?MVLOceK*{jG03St!7ht5@m5~kV6Z_WQ->ZP8q)6k+5hfWly9s&0;@F z(|$Z#i2{YIlN-J37%3+7OD36FbCX^E#Ya3OZ1FSCCtq<8dGQR&Kw`{%d{2DTquH|8 z>Sz)bHLdhr@iwa4t{;j^4}MZb>GLc)TMOLjhV{ZwB(>;}F)*5T4SZKJ z38P@Zbd224Yw)sF*Qlh#j!R`l5bV*(<71R;LkUN+rOk=_(4(Xh5AQl9B@Tf8xom96e|mK-R7XZm%s{a$G$d@x1kjX13ckgB{?E&pC;?Mm6J(^~ zBqb9HAF)&!hL$RTl*b=(834@tI@-W7!C~JOVKuRq}spkqkA+?k^v@^ao z{xBY3pz#+<8b2A62`cy#kNJ{6@6O|n5@N>Uemp4eRxhrfqv)QGWwdJoL_DLV%s|b3 zN10?EN1V#zFlfM}<0T24fQmK17$~nASh9cS4eUqlTD+#;kxOlW5_YJ1?*oi^LGf+m z4Fu?snp^uZM>LX=SzC0M4fqIgfJny2vjJQ4t*NYX3GbM!voMML$yNM`b;Wi(i<7_@ z9(@R!lH=tY~ z0l+q+%Mp+>eF$~rUESM7k{0zHxEQ}g(J@McaltM!> z0$0R^#L}p|4kQ@4{nnVdd~OzXkff;N9H_u+2vpA!3y{JBSzME0RM0aq1cl?NDW?1J z5Rw>_75cc&oWwE|mN8_}wU&uZe#8;Ktj4<*iy|Zm#H;Y2bx$L2sC`Nnv5t4hC|-&T z($^T-`5i+clLYbBLS{726UWFP*O}s4_DQ5sfS|vEw3;Z|hX(OVz|PuGtdvc7D8TFI z^nfgZnQY^T`6ze%f{IeQ2QalJ?p1$yMLGre=n)`5)y!8D$LNDLi>Cs5u5)sO=Z-R( zjFy~uGDZe;v7#1y=mzf^k4JAg8!@8+4$Nw3Fu7baIObR`)xN1fK!@}{LlnUiFM{yN^K?5k5X4%z`@$gXQC8@(B3BH5Q z#s;0ux2B5Z2l+gYd|hu2u0dt9kQ6{N3cB)G=_>ijhpf_=yj#y=ke*8^Ji|EsO*R2X zOb1=^b8CfSQQ}c1muvxq5>du4-OgK~fIN3-nrBm7Mv0OKVCaIiORU>l2Wy52khd7l zc;pLst47l@^qLVZu+U#y+^@pSYMC~yq) zR0u-Oau4KB2LKzU0i2)o0mlGG%IJ#(%+nB9&v+~%k7)opTTB9inE-?Id!C4Lt$Y+? z37udluZhItBxOt(KkBHb;q#Q&GkLi*fukQ5nsWQM`v3;@yVX()Do0@ef{$RI2dU8; zQ1G_#h!$BO?^-dd>(lRPY-lHMA^y!`S~M{R8ijeF$l?;7g)-=|1cs|#dqvKz7hQ?< zzvsbD>b2wvqG;Aj*kYUv!o10yyi=s+G0kn(B1VqZ6hJ61@k{`0aQFPePMu}fx;W-S?@Dh0T@P_u*r9U1W;mFyt+A=t9yr)kp=zedhVG4dN5@Y0Q)cm z5AksEm_LjXEtG<;6@;=8KIGr2#W6gd%6)k;-%Yc#`{!^bUWqp{Vc8|fj1CYmBr-0xb&31@ZckWwN}`N_2DoWE04-s(l<_n=SES}r4%`ZuD7wVF|L4DSKccI z=!>qS6zSnKL5j(<+)`T`DM6mczzM|SCi_Xj{hQz*8n4DE&<-92RU}wK5d--nlgP7< z7KR}~@q7Xr7K~9-9`x9=cvVJZj11etg?b9$U4v@R7Ddd0GN)IOqKSXi6n&(*Wmzpa z<1{{?LwWq$b9iX-muPtIL#$9^h4-+5cJ0!GX>E)TkOC77AhH0Y$|VeW*PB~YlwO*j zPVg%JSZ_66U^{Dq;K3#M=ng>faSx!8QWiM^UTm(8yCv^1vzh1K0=88H+`8$7i_t8L zR@Z(;w;@C^2W6F{k+`9Rf@;NP0+JN5_>`3a@-)0j8$X1CxQ^mLJ>#Hkyq<)V7>1Dn z9}3_@0VtEW6Pwr>{b(?6Z*U4BC{}@}#eB=o*qqBR=)W@2U72PGb9Y!M@soUG~EFL^1 zEITI*zKtXxmyPlDBF9Xa*$(iu-`($4UkFiihN=7(mP2g#pLOBUjG5|6P_IWv| zn*bceU{n@~(Tbz$7}l5t(L9XczFtU5BBmkw`Ml%1b-r>Fx*Iy1`NRpvV+y<>(2@EfK*O zpf&?hV}WXrXS7wtxX>J)Ms|~jO6P;0O9Y_}JOD!!EJG{XM8vN3{w(*BT|{xE$$NCs zSk$qUL?n86px&_riRqLJr07><5E&b{#g}wp%(AOIxUm8jAOGfAjpIylff@sBW6Rz3 z>|HMvFIgecwA;jx`vFf0E$rpi4aisLM7|PRuLkdi>&UM5q)lNS)5tn9->>+o#~Eo+4uLM9YPEOxeY9txwG=$m9fjYjUv z6EZpp5Qf0e88jicM#jU*uANafluIp2u{l}1k#N;J01Vh18#6wem{4KC|adf4^dYyi~daaQK#D$!OuvVlOqem5-zWeyuAd zJB6jEp;4RuUAfg}o3rs1*s8JS~RKQfHuNkVi5zR&2(K2f;>AOgSBzqHy21j6)_Q;I4J5?RGc@PL(X=F8>`%m8cC)OQQ$mg&iy#j=7J4U+ zmQd5y2)JekYVoeZ7fCCgZFZV~k`5LI0M#ee1?vys5$_6J+{@VYb+#c0*xE9-wVrdxvhK&sxX4(x zlQ*KgJU=RS@8_?|0d>Px^g7Nwx>|2MD2mKm>=+=L$IHmfjuJ=|S&-D4NwG0aSXtCWAb;E@91aO$4gbpvsLAe(&VA$A| z|7-9*&6=(lU<~!SJQHt(lJ@Ays#2|72S^~Bp3S?~awZQaV{K+)4U1z8&+?*=6(Jng zXyw!6dzRP{|7q!x@DOt`K(WwD2aCsG8ajt0gJx}rXgaS<2V`;?B{qeIQvQ`Nf%4l) zqc%J%l`tONT{6pU;*cSWLm3WMBfP4;u_) zYwPAx_x+2VUVdvp&p*?7(pOG+?eddmNP zN4ZHVes)5%XEFwJ<>gVi8F;(iGbBYQE3gt9%jo(T$1DlvI) zm$x-elo>0N#FE*sjYl1nhenYZn(cRWhFbhD-pvjZzyjokyGyPbptwa0C)jVh+EJVt zZ+}kZ8r>V}x5orL_c%~eUH}~dR?wX{nVk;(oZ~{lBv-86nPD&pF~2y6VvDnQjM+O9 z&`zFH46k?q}yrS55v;v}E;AguNo zGSs|ek|Mg5lqAH2^>(WId*-LdRqU7@@N`AYJCm)jz zvUEs=Yl~^>U>>p>48)%apdAe4^kpk`t0;b(28)O@V9KODdl;J9Ld zyqtlgXEW_Oj3+O%Aox*BS+CGZI1HPSjp8Heb5y4Ftc1lVX6a`JM^F}5oe33m#)x(> zV6j4zjFYiYK!}}P)LC4#M*6(%J8c&~%?)IUMMyrNH-O;Y%)xvm9Q;i|Z0uc$r(_{1 zJ{l>h!7wykSZ^f`rIZ{oA`Ho~9~7DKcm~>UZY$kEatb^JMuqlb5=tNBAsZtN(bTuK{MoGfTNZ&iU2L!BNm_q7l+k0S>5WPD&MM(8_mr zC@Fw3Zi)b;R?A4{VvnWW8i~DlKc0gODLJLXcpTHgP^~==k9IR&tV1nt#o&EUjI8+X z1K=3Bm=gd1E!&~!maHm01OUdw2pKt#h9=SlWe=XMcPLXUKkJBrpyeZ@ZMTmBey1@Q zn`hMD1FYBvnHvY=)6)3l)ofP`aJ2aDCFUUzC^qWaCrGDiQMkGY?t5x3dPG|x@Qlz` z>{S1b!73O-^%b-mjh*p8RrjYtqr-Aul0}NfQuw_oh zhY8Aj#^YH7V4H)VUdw#P0C_mBT3j$n@fsMnjQ^h*L=N4ljm`HMrg~G$l~G=cU!O{4 z(Fs8t*F6gOGGWGL4iq3~k>=fggh}A{>YQm6pVElCblk6ajC`NxfU>>vfH`>~%I-bg z+j^sf6k5hx?2Nigy_10$Dd(P$Ro?VOr+}3hHwPcBf(9B+Z|aVy9OG!7s4sx>JfO^D z0tCtp_&hs%JLv_sLM|&cW?mib#=v?YYQq5v4^TK7ol9*QPJK{Lfu7c{7C@=#mNLsD zyVx;6Je(I|G@}!`Rt4?3=#3gmIwbr|{l=cSHX$Oh(Y`i|QKD3{BCjz)=~e3GT8M8^ zAtx}|X@*{vLGLL)+&cJ8&lqG0wC1-?6F)~Lmrg; z>oYwwHqM8)l?cL;T52nnCo6{E0*`eP5A({8)^*1KDZCg7s@PPys?Z~agpvkUqZ5zD z!`3u_5K&V~mcc`1KYMc2cjsZ~3E{Lof43OQbA8u(gONydv@}w-6D<@o@j}Kd77~lE6zb39M=ux+5Ngj3B_BE?)0zEz3}F;E zV=r_{7Iwt|jf))fy7hXT@*X(=+Pv%g<>fqiKS=$(oY2jFwBo`=^tGj3zHKvtW3giZX>*e7QZ(+B zEzH~JR)7>+ivvBQ{ZKgGn(^l~(W?r+A}<+HeW!pP&Fh6c*|DI@2$KTbb^K28$&j2@ zGu&ZITXSJ1w?9O$tLvS__FAe1DOB$A1ijCmxd9RrkZg(Lz@Z=A8fQn-XQ zYwR5foe{23t@``MY|+n<78e)z%7QtsW!9Foq7*NEP0o5jxgU&FZvX%w07*naR3s>p zF;#n{Xjf_F>O6QEa_e=z@IH#sx@n&4!^p*Cz=%h}imW*~c)s6La0V*t={f*Kr+7Yk zC1zVKN7VE14D~@--GoDV(X77SfE$M)ZpY$!yCoQ%5*NnCfZ5IE7*LkUeli{_TW8eO z1m6-T_t?ircnX`02X!Q1=s^(ZjT+DlY4Lc}35B^=-=}c|tO(Eo+>&*DE~UNaePul< zcUrpYI9hptV$PbL?=c?FWmw`&fRAn}dGJmv+0CnCkmT{q?BHkAHgL<{(@93k`*J=l zNb$~+U%F<*gFGaU`b1tk9x!#QP&r-*_lHWXKV2aZTdm0TP}V$Y+eLAu~3bR z4Ulp}wV8*>BzPKiupE(BXGXbZ#>9&$1oM&-IN}K|xei1jiw<&ejv)4ok}?LdsAt;J zQ&UT=LJ%@(>K$R{TJnH=0(WB+SL7)7&<@v7K+1XceuFE|zxQ`)uf2P3MP{|P9K>u7 zrH&3%5CF-#zFj}$B1RO`No3JiURBZxz(hauhN-$STfG=dBb)X>FQpQODU+Ylm>h(} zQX4zIl3f-^W=YDL0j$PzJcP`S1+lYy^h#yV$Qwf$Ew2bwpoZV+qLA&X4{$wOSO&}U z%2wILnT)A>-9ih+jcPs04m_*{=_N8OoVF;veOFTL&#km%EZzX9gc25Pb%; zk_Xs^Yt`o%on!|2L-#8ohcN+3e}E|kH$Gz{Z(z65(R7Opjh}}?Wz8)wsxh|gO*IzH zB%Fa_KAlZQmeD%Q2?*EaGFeh})B3%DsA%4u(cPUvY5j3SZdE6U-3;hrQrV-)rr=5; zd9^E9H$`2ZO9pAzc+dm8ml@&iciTDf*5XFvn0Ynh<<)mj$g=QcG*kR5$|Yfg_VZeK z368iVF|%+$B8L%0=Ek36_{G&lr`ZlASjm^+<9xO~o;$Sdm29mfs)X4XO_Vs+k+zf&uDft*b zPq32s$UFEbGmj=~%ix3zXF$z>c*it?3t3jyB;y7Yn33`Jc1r+H05m%)f{bK&WmdJ6 zNvPNvUysEYfmGzdW|Bk%HsqGm0D2CBPP}_B2}5D>KC|b1Z8bqL!j(3mk)o?rY0{Qu z+C@wE%+@0N&qfrweKz{b<;E3f5ae(10ID8b)rwOQ%N-Zj2(K0cw;pFWN4!xvSyiC8R5g;yWn1UE8x52#~p_ z?gnc6Kaay)3{)yo62y)tP+i?;0Nk_pJJa1@iwKhI;p<51c(uN7Bg=aPasFMP1K*0%khOq-H2m7vo;42TPTL2B42x$o-`YToQAdZ)r1}J~o%NQSum(w@cqXH-nF-J#LkW!lA{Ihs)&;vD z4@Qy%hqcQ)FM2X(yu6S((PQ`F+3nU~97H(U`{0~E2W4dKkvhIA8W*%ToLrwC3^Zgl0N8yynLD)LYg0g!hMHDF4JK7l*q@w^70!3qd#!(v@#P|ErQR%%gSWsx&z6-s+R@^`t#Z^GZ zGkB(SXZSs(WIQ zEK=mAFu;nz?!LXqdNaJR8S@qg31I++aT|lNyG9AgHO3(8%*e!-5@4?9VPv*_^;CGtSOmUI|e7N%X>R`Z0p4^8MiesU-|*~B?qS; z256(8!KSF{VHR$uf3Bqy3=hJNyaXh2@>OksvoeCo>(SGR6QNo}UR0-f9ly-(WxNz# zThZ!K6uu)J4?)k8D2&3qwLl5_W%Gc6t|5!aaMVmA8w-YN)$bY~EnFI~QKIaV%4nCjS`Y#0BxtlqHBiHdY-knPX6!T5*XqxVT~jS z13}{f0nabgVT6)_K1yNj$9gLJ0O?WVwRp{#0j>4Pdm|%fJ1LY1R`(}n3^}R-K-C8b z`?)dm*4Tr%mp%eQa$Y$=>h-pj_N|{&%f0ae$gib`>z*AaUO%dh z!jvBJ{)~7!0KnL4uu&X#ow{$Gl+ftFldQ(1z?9b&=lWO=b7p+`IinHkWT!kZHD^qS zK}yzONIZ$TFiswmM+_^Fl|(OX6>2~9$-2-324)UCZC(6UX5wsiLmVI~gkn_IPCS|# zHhs+aQtuY?V@OMJW-klcQv$-IsH^p#75n6Y(8mY_N?VXoc9EwLFXXhXBw!fDPO942 zpcRVT>-6_~2@OhA(^Cq})AA5AqlJjP2nC=Viq1Jb4sud7i)7B?F15AUVN<9pkC7ec zkufFb?d%*ty@e0rNyeU6b=QVRX_EOgzP3?aK^dJ~-SY{|6t-(wGHle%ynt0siY5c= zhIud+&j2j0%}EMmYi)o=ok>J#dC<`bYrdb*gkIOiL00zak;|?D0+hV^4pS5(pV1cXvRwj9mD%;C81mrAOh_( z3dQ@1xpsC-P%5$U>|k1RHV(-xUe01ccuMNusA;yPFh~jyKxX%4P}T(l$T1DRLovzH z?sY7|dYP9P)Ea6VGZx7e*;ukU11v_$i>3%Yi;;PI@h#8P8jS2Dg|Ce-I)R32^srw~ z(xl$vBVI&X+c-)bh=J_Jah^&3WWRDkTdlW1o_xisIU{uxf}rE*ucIes3AID&lbGvxImwRDt?ZN@;Hpp&+CPy7|_gCk2Zse&JdPsg2E6r zF-8QNZ6s$$#3zvh;Zas7Zt-R>>huiHmS6%B6p4{&(q%ki8wMfkN0H*yM*I6HIKyJZ zc^`qrO^>JN`9HACP7(^ju#gWP?{P^R_F1JV=v;`D~4&&UG` zSRoSuQV?+#uYvYR8q84f?BS>*DjO7&os+nL8nf668c}R%`_&kQQ8Iu!*`w*&&qgtz z@iStXVYG-c5$bGw^}Hz|BQQ?cOI};-lb8z?<%Jo}*?rMh-kdts20BZvr zf$azwjK|Rw3%z>uuz8KRmT-8p-U@<{jSm|ZT`V0B#X z#k&JeKq|{Dc{uvMq#~9vJKpm37)J&ObqRw4iWdk2%K1Nf1Gy*^gp_t&*%!uxKxEev zV3ZDGit*4pv{5W1sls6V4gg5gqgD`H+^{^s!D^sbgsBuVQhwthABHL>l5XDl_%1Xw zesL{2rdW$sQCx;OJ09Ni#L7G$g?GOz%6B&Iwq(O2VIX2)AUyJ3fXSK)0f1dE+FQpL`(*q2TG$iTcOnGCl9%N z0>fDr)bG$aF@Zl21XUnt)Qv$hMhgZZMkirsGT8$1@T>?{Q|PREyA`A~H0BP*P2X8Jj;m-{ooytiU0*>Mbneqm4; z-bz!sdC_?ZCiBH=M!R5yQrN@RE}4}wgjh_Po5vFmqHPu{O~pwgo183Vn@*=Vs2Eht zKET<+xF_$&)hFKReMhpx^LDeK?nTiA<+GEMd3%{R*{z-a#@={yw8cs+R)3$-nxp<% zS>M)c%O1;kirsg@10jW?zG8V;h4`2;&33_99~n+YNJe?ZwyY~!y5pVdxtbrg!TZ)9 zYs~{GZEy@~aygr5rcd?nCHUy?EEc5Co*}tJ7Mzfh%Lo7^d4SQ%F`2K&vtodROksE- zh6r&4!T30Lo^vz_NG7h$l2SU}Y?qR(2vuef6`ZP+);l0*p~I2m8_Qse>nF3pGg38yT22;GMVhd}e@XlMV(H6QVIN zF$rNy4kT8C(7YRpB~3h2=vw%Y6rGjP-1TI}pJOis{bw1scEJG$&*7PxXwMQMynkM> zv9gurigB%cM|PFB(v4AjQQ#-8J)6Jp+P0;(dA#a3y@AlZx=3+uOD# zVaHqA7_g)J(?YzoDg((&B?%z4kepH#s*!i3?GA$CKu~Q$S3gi#A^B+s7zNh(4alLR>`oqqOLt#2D&%cK9&>02%=f z-dKFSlCZGjT&_XQm={F%c*&JGZX^?H&v3-Q*aMFbob(#!ZMpS#m085gJ!%eo#Pr+! z(`Oz~{e#k>l(M1(MZhfG!wgtDU)mK)2tpatEE&@Z1e#iuQ7onlLGgGNf5}z~k}2kD zAEU8k8%~aL7`24CzoZNn0CZ$)cRlt!43{BE3W;H6G|}^NzNPUqf{_OTvMDEwJQ=zw zh5|xCdLD~0@C<0(Y_~r^7kkndG;-!Kj7!h1duM~Vz1 zoQ0M_{hij;&t=DzjFc=AV={IIYqxv*ksSplv!qUUJTn92re)p)_6(7MiHCF*Fv<*! zvhtKWp2vWoC&QMq9%Tk~!7D|q7T&KYbiTu|%ndckUbT1wiVhu(Ll$kOJh>+&;x%Q^ z$Wu^Hp0|2WJ&Ke^Y3A zSITI2w2anEY>)CYFltKdxm6F?%Lgj&K8x`>A7c^nP>?)B@U z#_qAx*7$nPGXso~m}pK7^Pm(&S-w6$ao4Is)&i%Pg7~vDCJBjfc4E6*j41DYvNn&NxM(aW4_Y5-8=CgCE% zW#<8}y7SUel+K*;UJQUQ+ud#w_8hX6bC~TUY4yQetOJk$uxixkBcp2>oagY8fTssw zfJf4579w5pfc2Nq9;gE`4GQOna4T`h$RNaD?sfK_1B;mhckf|XFLe*GEANe()JN>` z0FYfAr=K-xZa){J?JguEq)Zf-!b`G@6w>{9PNf?jnbN6i&5G`1mRCQwUO-k<5`rPr zEGC{mSw&$>c6`=?|s%(donBQ2Sof1p{>dwlHs=Jd>o4-|LKFh*y}Hab%-G`+e&qLDM_g8Z~8n zXASG8`uBD)Kx2fSyUCrGGCZt+;qf9exfCmP&9jZd&>pHv`-?~Xjhb5Uq}i8_HK-=a z8|mTAdjZ95K4ge$p}ek1##%yUwwal7^A2LIHc{sO3=_@l)yH@@;fvCV+Ho(=M=#ao zM*A%NPWHLpZ)i?=^_TIHJIcCSnyGap{j5EJ!4}$60?CnQG_SLEIPs-10zZH#dHI@> zza0$lsv%Ku$VI_c&-~nd7Uh6~;)9(yC(luTLK)lonI;F>H3j#bPfq7TV@EL|z(7|e zg4A@qG~~?NDr1mgeOzFSTG5_D_0Dz`UWfy+0m_#X0owW4Xe(~RFoaZS{?a^~A zLS1t8oYs*%?PTwP1n@y`+kJ$9(x0>5T*jwmQ+Y$}HZLF5W%DXb*fBuYS`6vqOMG`n zlP+8fZDnkI#0aPyMMKL*0rZ8(y#5LWBV2XRm7U|gXN@v~;tmQ)!B=H14g?5V&D?ji zV}zV|Xp|6b)>$JVH1f9StLxEF@hUHv-RqRT?O}kpz8_N zezaAkSef{}uHi8(wr+HBgPNs!PEOw1Jqu(uF0!DUy+eX#-<|#5TqpzNM15AgD>|!8 zfEroXv#hALDzPUckx8^eU>0)%HA*LmqvIpng6g^Ot_+$|s`(i^FhPk&;}HX*ur|A* z;5~UJ6DiJX$7!vFD7UnxnFA&x_HH|Klq@udw~4A8S3d$@Muy4o{I$IR44(5<=6|*w zNnl^6%EdR^)&54?pcw?^k|78bmAJSin;NfY$AYXQN+-1p<^8OFUDQbVWwW3$16~0b zi4%&od&bDj_%ave7ofrWP_EILF%}wnOHzo1D5RR-S%f`G-8eC&wlst;I80MyVYV%6bT0s4d?+lSsCNU9t8&5YBstkt8B7cY zz+1cCTdHJt-4AHk0YewXRmOic49L95gPyborNhUcTIV?;J5zewp?Gv*4?SWxp`yl_ z*H!b_I(t5X0rn6rgR*6ZL7)#7S}~q0&Jo~wry65g@fz;y;glrj=X<_;i!T`@`cj|V zyrQJ_HH?mMD5C)1Q4)E#TYE3U5ffQ>mM_S^O3 zp@bpfL21Q-=5WSTWI?0sC=rD+=UWpQ?b!0Jh_-~#UZ)|0hqLasRH3<=^Lxz!)(cxv z|1)lddergOrUnId390rzN*xTarlvY`tP3M+KjaFGYA-ERaUX4N;z1z>5d6S&Eu5uq zvpocFu}7_Lj`(c~u~wm5$NL z@P+m$p7W$qIE!=0chO?#sC8KCWgiR&>2%;W4hd@X{!v4xiy(${&$Bv2v6bKg_8 zP?s|w9sj#sC1-QODgfZhaqt)gFHU|Kk*0st`fPulb!LPsjRZ5 zK|{J+NDm-*I+U}G+Zh~Ym29%a(}$WY3b^tnB%Kga&Wr>#g;2HEb1w$T!zrqsDS%cZ z_v(2jSu{JJaqb+uJ`-N=_wHj%BTta?EK!&G)!4kEx%ysxc1`;Xz(fuVl>+#`)-(Ut z0Eo2dZly%L^%aD=|4E+}*K1dKU20rY1x& zryRb_Bh&|FF;KF^equ}v3+-EFRk#ke1 z&n}{@Bar!Ui^ik1HJ*B~Tt21JjgnR!{evD(SuLPz)KL7J;?6qsSwGJ?+L280pbW&= z-eWbBboG1V<#CO}coa-2fo&(fttY)(QzW3|Z;D11gnQ<(+(&GOQS@RRURX`f@5C8r z#_Ug^$aMH6}jbAW$iu1lGq4cz>s87*#w6G+~_m?R$}@fH%l$b z1^BeU7B%xbXkamT34w1GhQhhlV5Q?JGCsVDRy-UxeU`$9mgtlW)a-nc4V!y%DddGx ziuU3;8Cta(&%F{8ksE_JI~T<>peR|3?P?02H~&hkpyD%cBr7O^A%;UMc^W92?iXNa z!L5yZ@p6(D(*9?=*l&@k@ABZ7M6$}xMa`Rb>wELqx@?S7nL~PhRgXqv6xUkM9PR{= zW}Q@wkEd&O4X}9uP;{T2a1NRzdMwX9B(&7|tg~^@FP>fO2j~DjqyFGJ3+mqnY>|=> zQTRNgl2X8eX6|?gH7O|Lo9*QS1Spnb_j7&3qr8zUBd-pHp%}$p@g%)*F#;Y;>bWgI zi|NEWp=LaQeP)rL?OBwi*L&D|mV^pJ^?lTn0-!!QNvsVM@_z{dG1_kYzPb*Wm0Do- z$)Te?dQ0)qVdIxP6I0((>SDxdzi2zhp`63GXH3ePV+Ad(w2ovIIf*+t5aa9tg@llM z@b2aY?6j=$ih!MciMd}jaF5Cmeoj%ubE7!O?;O&k?lVJ|cF`;b6P$tA8B zN!zf2DvGT$ZUC*8?b_A=F+rXY2m%7xU-ISs(=aaQBEk47|1qlr<|L}#em$;L+=RAy zus6Y&$-f<5o-(wVYIcO%o(OAe; z0$_A-Z2LX2o*3KqWr25n`oc3kGCyaL4JEa*hN zX;$q`*dn3ENH7~9=$U{V+tPe6k}u}r_ifn0D=V3$&UoelfvwO5!xM`;N`vRc;AENo z%v>>^S9y|=0lJXlPv`GP&iGpIi*6ccvX|JAagb>%J2oJ8mq^l^$_daxTeaAfc=u79*)u=}lGh%4 zfNdI3iUo74N&_Yd$r$JE9xUIbD68*8XIO-n*K$Q@>XH_b(fix~6*(Cjey%y$0-(t$ z@Iw8o9_ES?zT|hT4>{FwD+-1xk#&7iwTxrR70)G)-U(~;jaTC7w5HYc*Z9#hitF@% z9tHP31#MKDM?~Y%R+((II+UNY0JfPIqx!cRlK=o907*naR1kv!V(eg)(BnZll(r=2 zp6%H)`al_TTe9GkjK$A^0dX>p%?SO=IXdD$_ZIHF{`3rxyH3W8u%MO+?P-{$NsulJf;j-?PA$qE7o>3QQ|fINlutB;^Kd$y7QFJ=!QO3etBI%J!zx2&!; zmvqTGM^AhQ3m9#?GB$>ijBLgM{4t3dtaP>X`c-*xSyLHRaiC|j9Xd|tPeQYq0a{RA z4(Dck&;W|oT^TvcW92LpN`b5A5L8K+*(q6&1Y*}QAYkB0jl<%4c1{Pgps1)iBf2Yw z0p6;j1LHi1A&F09+lt)8KJRLw(Q>%UtCE%pgxe#v+L8b zDVPi&AkhH6L&sN)%^L9@Vwjau3`!sQNVKH0Lo9+t0HIlzPH$Z3q_|Niu(SDxTTCpHz^prgDs;R6Qb+ji+6hGebk2+{?Ha3r`NncrgnqjuV4RI_RdD88`(>#!F8eE_hJ`mVIUI9?OPibwVx4Gb%5NL~z{{QO(u#D2dV{zSGy zATk9i4Ak1WMu}|3l6Y?8uff1QwVs)yxYXa0F~hmdJYbI=w(fWZ#a)xlpOlnAJLBW5 zXVi0Waz@j>OAm^V_<>4dS9Cp%5PnA<#xraAqj2IqUO?Ot_M!;R zGv*~HE9-{ch}ly!G)FPb?kl1dvVjX$k{6vaIsivu&w7#Tanc9uYsUloKAj_1o)8cS zM=%%dc>ZmC(M5*CThC59;D|V#nwc>`URs7!_=D=7ZZw}6;L0McT$7^@APX;vCd^Qb z0Vu*lq?+3LF7#nw?g8BhGdt`ps(99rOd5qHl^BHaF;K!4>!Gvm z1x>{Y?w#kS{^>cCf`X!>40FW*$zQQn)|Pjmh{kIU6ecH;^IWb)X=Y^~o>Kw<4T8WK z2c=*D?%4w%az!&4sps(s3iS+LC%@+d2w<@iuhn{?_0G7kpB%7j>k)6SS$o#JpL>xr z*^6ygzhixc4(UU659>y!%n4JfTLH-*h+31gZX|02?CR!m_r}(+G2zx!PA_GEc27Va zH7cl1i6Jy^GE!7%$Mf_8Vn_plC<)_cG%{ZnhZph;#wL3ueayHZl9;gWs9|s#l2Hl# zA6?4ZaVQ%v#OTB+JS_!gh!lsxpeZp(3oTxjg(UnHFH5n|I|^^HeLvkG=0j0&h0AoAIX5EnbGmqjwl!4N6YNB0d5rygcs!RLB*Ox#tR9tPRi{#GT4bz{z@8 z7eKKxpZZ?POJp-^W6XEN#AI3<3cb&kDC<($8iuD%*D9)sQ3S>S?MFxlsa-<|l!}7-9?FCUpj`R@^;HVGC2KT3 z^MFwx1}mnLB;fHVhWiqzeoY7_tH?Nkhq6mf?n3j#X0lwoFw|46}DQ+RbWsILdu^{6*b1t>6w*^Yvhaou_i*-5NP3R&wBK$9s$ z<)L> zgqq?gfj-01HPqY1E+Z>@YFv~$#+yv2(t-I~Sagkd4Ta_nQNdjbxT^HLvHGgHg{>GP zItsX+>$$7rs{srck~7d0tH%%l84v`9z~ho(91I{yKy-98cY5M?mt=EhfV={QMBlh_ z^oVkyK`S3hD)r5it6fmnQooRoVlF9{9x!W%^|UeZlGcVd%8`CKIzmh)3pk5^X3F6Hs4cH<47@9Efjs~m z6pteFgkn-&aD|o3o?HK3SB~zKm2GM5eSs~uM9#q8wxM+XT=GVPfnzpmh{{oP|JKvj z9zEvF03{UAq?}=a;#sh>%usGFF2ldi;yB8Sisdj|=(Qp^hJju}I>tyb2uQpn0~N2d zst9CYdz8AA7}BCjIzVPhXn|2xH6upI&@6ONn77R-Y7jkHQXMzF`Ct}|ho==|@cibI zBjt@B0ElUg3xH)$oo8w`M{ieJ|ITFKK9~b<%&>Asi@AEfb=JXQofxT@SPky#DFN+R zcrYNnT9@q^pzq790uW&iaJ#F491j%+0C^yZA*|Ldr#g6MfKXWb5}`9f8AL`hqd%02 zFw~t~k81Ho1fJRn^rE;X!mI4Wl@vk;gA5(C_BW$}qMnCR_Reb@34?GYeNa`PLE+uU zy%_%}7yW-cjrgfyvLi z3M6D!>tO9TfCXbRR^dfUEqN0xpgrnOR+Pe9D*!M{ka?~(c0Ux;^_~?_62F<-rB^#2 zKu3=Nnb=>P-@d0Jb2kQSbPJ7UD|A4{+FSsoQqL@0%6UB9XU~!_j42)HioodDtRK+> z8383i?Vu?^5j^Fhs8Q0Z0$~v7q1qf}@=WzA#~o%r*c5##bVKzlr16?FMdwkm0I?Y= zW|5`M)9H?0doINk^D$zJEOBxLg?UDvE=M95LyG^rE^r`Ih3i?H)Y;sXXn2h)XKB(G zG6o1UAm%Xu2;jhoJWmlm&ow9D*S;BQb=~Ug0$8K(qNhCf=zLQ8igwT5672qDK>rvu z&>w{YbVCIID*|X7(i6`)Ge8f7RN@YT(oL{J6Kg@#&)EI$*Y6lRtX>=GKt|Ub`c4-(2+m4Af^h?LGI&(ST`@opfbyuvRoXKX-qqj7BQQV{ zU7v9Ei}vPyX~RtqWK6c4zL;pm#-75v+GEcng`)fHo_Tlw%b zsPwI|Ud8~CovDJw+#)AB;~pBLM=5@>vR1Ar8&4-6Ag0Z;{ohWPt7U>#wv=2`hAedp zQck`0^WMHyKnFN)-K>qFSU>Z@Vq|6kQ09xiOJqJeb7s{5cNFO*uN9~2ve6-bh4%Hv zicY#G1;O_%Y~E21WyNj;D-J~wEu18fc+n#0we-E+EkDo`WudI%3Pyj=H!q>r#&y;p zu)22kll*FTjL1oN zcCVBmwDO%>5-So{#!Lr{9}B{Y)K#%5&dX660GwC!tXGEkb~iw!0Q`OBX#LfN)Meqr zAW%R_BHqs8C2o<9=9$E|;z!v+$|%0cX3xCx}M>z(r$q4+30co9S!~N z-^Q%~RS0u-A_K$nIRkj*6bT?YfytPJyRrGs)-&|y}_1E4Si;v!=XS_hf zmM8Htc~~ReJ!B_@k*K14Jc1TQw4dkFhR1ltYyM5%8n4CRJ8``@Q?8<}12Zt2sN2SV zaT%i=ZLczRxq$Y5?YaP6Ni<{Sxp{RzqeC*i*n(1ziU8T$7>q5w|J&UFQ$!xUe(Z_@ z%Mube;aLFL$j~-%jo6Mtv^2-{k(wG3AC2j-9@k?f&_MxAL?3OMVm;z5n8K8RQ5npdn18E`Y! z_SFE9BS6K5WVKfs;IRuaXf^=|MR;+?EMjQpfF;onc>{kw;O%aJGPLHf^7^Zpg68*< zDVhTW(lUO@rYKEtb>H10u(X02Jq zkH#}HiY!!6B4Rum;FY%k0hwAuMn`!W=2>Ef_uxrJ=koBP8Z_$cDlZER>Len=7s9mL zp^RBf$B?c446HB<*P15-7ltUoptt6#1Ov2<%NpiIM=1J--P-`&PrI7fNzHH8Ru<*t zJy4fjrH~v^j+ha)dux^2)`=uH+35(Sb`L*wp| zg_d2VRLQokj?Z&P(nt)3%Pf;0G%~vZXQc57}sN_X#Tv)iIpG7Fj3zcy7)CiV!T+dRjuo)GmC zk4boFf8${#7|0RbX7~W0RZNI3;lyxnt=-Wfl+Bt;V0k{dqv*I9szIzlB0e za=wecObewMycbtlC)ZG(9P4+>SScq3VFV~8qXwENz09K|g4(KoyOy$}Qm8j(^IRVu z#5@55;}I9O2kqwBfCL>?LTJGPCCr&Yl4d-SWSIs5;e`yWI6pg5a?jnCHNeQ@xnDdy zpybIJvDgpL`Xd=b=O0n`9Royz7>FBKII&9aJP#@6?7dUVLN}zX+b#nGqKFn<3Rj1Q z@$BqkcrHb__kG2U(A9!aVDho)*1}mp$70CTofXI-tYm^j1!}}_EH=aDLB%UqIyuNZ z@4T}KSkggOSsdeck|+>djCQN{U6Ct_5A1o0+4C@`nn}>7G`pknK&1sVAqyi^8ZfuK z$6*HgX-el&eaG1Ro6P8W4%IRSpus-KGS9bOk}{9p(zIiM0#j~W1}vQ*=w*vgVhjsP z(Fg$QNPV|7RA8QC@OR=7-*NN=?=j=(D+~VI*FbWM)V`?+{gMsLJXUrYFhGpK9>Tl> z16AS)JVRn*rbxZ{@^bFU$lWh7ZZ?}?76zD9>FofV7^~%Nk0s zFd8jdE2R{zPD&vb)%R)-L7p*A>tkNdcbR4Jp36`uorIjRP|_%9POQH7bCm$Bd+$|x zXV2nA={6(MTA0lS#;a^1JmM(<`53^F#-BJfOZku2#yQQdwBBg2X_r z#F8ou5T(S0Sv{&%U&9z2n1nv?3@sNw6If`g=kubv4m24H*3n%%*C{-jhbmKYahLy7 zSTv7v5Ilo~NKnlm@xm>AlD%;|TLfjPU&EE_j6;D~;d*6ptrrEBEp2z(YX-0%PQ6Qp z5b#k->$aO+zSTI46R22UFxs*Xl;$f98oad z4!8mx-l(OojL@;}z1Knao=<@_MC4r#*37ecmehZRMZB$cGvkp=+07-mzvCyIS2}x} z?o3Y0zh5;#ZdlgL^^!4^nPM|MUWh_Ofh!u)T?-F9B1v-0D%&!8>+_O#Gv{)9pgu4#&&jy6C)O?sEy6WWlbbIT$fF~ z{tZmSR(O6)2*sm&GNAQo*Q*ABaw^fd-;1z@RRffzqll1*!I*qJ5hJVLXbOpB=XgTN z6^nx+pa#%5jnkS_QByyk9Rp5)6c6RKxPt7KDx#bAbU9d8#tx<9aVep(0uXT{!xTeF zG(gc2Wg(mNd5SNgJg>gHk=3FCf|VF=RZ(`X;}xvmN?q&hz6{ISVnMxR1;Aod)*iUd z+P4_1@>Kgy_MN%qS_N(m*Fe^~&EG&e<&*(GQ-o3r*O<8i$j6=d%fhewN$f^&VY%jE^T@I^7WBLB?O zSQcz{=W=PDF66_dLkPT7y|EZQTJf9RQHGoML9T1tUzaCx!$7W|`2Q zIPLos(nQZMi2T)8$Wh~hzjexV_jRrqpvj<*2E=>RNY2O@TTZbyVb^QEWvmt-U8VGn z1(1@rEd}*NYx8PpMQOd2u0tbH4r$z4X~dpTma&V`cu&6{8DHXyUkZ;xP8nxh`kpXZZ9Xr5rJ+&}VkUg!Shw>vER( z)ZAr|^PzWYxp}E*PA1?GG)D9c9b1$b;{cR*{7tVOUAtm{x?Z#dxi&}g)xwa0WE^T9 zXqrK?d`O9xhl=ocyr7uG&n&L&pX3ZQw7}`ZqX3Mz{iJpyy(_`OOUiQM{HSCOIP!d3 zW{h2($1~E=VGml{yzO^{45m0Qu?&6oxPR2DesKC)V-Z9s*MiGO-tJg^FP)V(8hSTQg63%kP1oUGiec zUXum6ks%$#W@_VNyqo~(v69bU=AljWgdO`kTeR%Loz1G7?a5%PH0BlFJ+}v6u7p`L(S6ijwa^? z)th+Ivl!03c`OSf-jk4#x`uSUu6E3}#0&ZwFP-PMlm)#)D0SLPNA{ zOl$`ad3XTVtkN8w$a7IS<&Bx5c?JRVwCT*@$sj)J+8Qv~SX8Km=R;EQ5s!bby4q|J zU-I|ra;SGYhA5`BvnGk-$*`tk{+;VnQ}ws+l54h9Sz9_lrl_?)@&Nw!GkOymDu$F) z$$DTkjDo?5%SLgxv54OopY^2|JdZjoUE~1d9F)oY8-uB1a!$l)2n@E@G_kuDLZ2`f zdgFOm;Uhg=F+dd26Z7Vs4C-F*4HKenVrU;1pY&1BrboM?4CJ^s!Jt3zY|WZ)HrjD$_UV zI`UM?;{DJ)GL+P7^^&};iA<#|CtVO8#V`Rgr*XA`BDQtvbY=!fu#C%1R(n8F} zf>P&&o|N8#pqw(gC`>zF#-dAtq4J2URGG112n=0{-QO0LF{WwS!l!u|$U%F_ASD36 z*T&7Wxy^pBG@?z-PV}8b((Jx(((lP#43C*U_6^1axH{Jj#kwIVC z9`X$G8{U#}prVwFH;9tUmO)Jl$SA~s>XWNSsY?XpT$iAl!7f3m#tGysc8^}U5#&wUO9Osz;~1=N?=5NA=wQ5hqH z<~1q21Oy}Iah`j@^KA6OwjI))Tv7l45_CyKK~ybqb+#7`q?n9w^)xVYrRZ9m)F^d! zjQT(spfov;tE0dD=;UF9vZoB@miI*{wmY&xtxcB*@1|W(Mp%N#+M%ZAZ!>kqY~QC6 zh1f^Z22iagp?V5gclgx5Hx3CdvO8l=N=cZ=S>LYsO?JC?AF>9DJtJp?jGH$k?@_ox zCuCbW7G8Me7>p;fxVHgXK)aGrCWa%(w{MSv*>Nl$%KHK8!B7GPe*%%YvfF@=#Z9*? zH0mVAQ=eS9k8z+ik}SNEj3-Kxy>6>LiogTCbHo98wA8YmyTpucA<8EPY(Lh>P6Y8N z`Rd8M`XOVAQ*VyeT|&{)St98p*-~#x^<0H&^-6yO13)$NQoV7CrFnW_Qy;F&V1TxI z>k4(r+LXSfMT-|p%-pc?5 z=up)|EhvTI`5;4RTV9-@W1SItwn-X%j_GqfWjAm}xVt69Gbu8J_FQEH9wP`PE+Z&( zYNR~qnc_Z0%YH@ol(Aeb(k9bLktl&g%IE`aC1JGsky~$Eyr?>rwmthDZ~3&|$CfPK zM9UPVrJTwzJRQ25x7+5Kq-7#)c{dKF%8Al5mIO4 zprXx{_WtF?gbYmTyj^U_#lvL4ey_bqP>*-}o3hKcQMw)a>0YRwY^I|b7@%w;l+{O= zt_TSRN<2ziLuiFrXm&N;VpQY;NO+R7x4@#HuGQPB2eD^>el8|~$j&~w;(0~}fqL`S zJ`74-jFC|^GRt*$8$(dr>njEo-k zx|^^YAh5D)zSdz5hO8JBK=wCd>=0~9;*u(qKg} z?<5Bq8eQX60Tic^*Rj(-Tl2D$hjEf6fYOTA1^iV55x zVK7Pv4DD}uUGqrEJR9xQZGst`Z45!ob|qsEq8TfuLY$CePG605>np@Vhi5hyF<4=iLM&1v2&=O)mL@0*Dbj-(ngU zAyX{l=k=T$f@%R1hM3dcW^`%xd*eu>wSPNm!P|_CDXneBV$7Li{%t{dVxAeW0j)G< z=RhgQ%0sv>gk{jKp*-d{qhr1CYYwn;#rjfsp4b{wF6-&OJe+a+8Q|?11S-c^Mj$hi zoi)Q&YL>&h19ogHo=HvsJqO@1R$#?@lGi=n_&ZzQ{2ma|FSsnS7XSf_>={IXXD6_& z8rbZ*gjz~MS=)dl#s$=QH}RfqD4XH+;wg=rQzNe>4`@IXOnuCkvskI~xw&+!56iC? zQ{9hX+t&hTlIWkoqpsJK3VBLgkq1MT*x^lNv-2)O>&JUIV2YuJ zhFaT|_iD_HYvuQJj4kx?27m$>asc!iP}61hW9)f}j`_WQ7s|{7t_%u_qca9oA7sOb z2rE>=bp*&bD0+^RXgwg~Vw}B0nKB;ZHYvT06pj~xIFN@i<=haH=c#yT6h;Zcv$Hc%OLL+$t6rujKVy?1fZ7(xz3Qg#6`7B&A(u2K&pKvw_>jv=V|nj+ zJePG>#6K&ujK->zA=zRLfI9{u@g{Rgk5E)=M>c3Vitqml=*I5fvgYDfyZKkZ?-tqm zE`YLI$c{W`Ekp>+2zfrW7RjH)rw~V?0WygfBxx9aPQK2&;1~d-oKaA;%(L9* z)=%2?a_qyc_p84z4u{n3OLN+1m_KhUyf}*?0VjHuK2ZPW{q=`Rgs2DZDnEVE9h4&| z85bayuoC}MRAEBAqf_qa5WN6gvc&+C{Bj)sO8MkgIje>9UcHinM4v2v@1U=oC4_oD z%7pd|@ahKKya$4jQDzAbnMbI`;4HE@hv!N!A#W1FF;wYxu@Ub#s{uktRF1(*SM#(K zfuZnp{s06&0|bPY!m@0iIL&vVkwn1kd5n)yzZBiMsw@&e;%mw<`?yxJNQ`COQ77vs zV~4Gvvew1Fu?!TE7m!%fY#?iSWq)9Hc~HpOc>Uk0Xzrg4v9jS=8`p{vu@T`19RMQr zs}Xv0rsp!uj0e~PA0AY)koR1n&*Y=5B+gdDOnmOUWT5NHy?S92CxF$lgGZm*0R5X0 znG~g@q=dfu@qMUeflyD2MrnB@!h`~h(!iykap4*blnA8b8Q;n=>gbDWO&+3p7Nist zs85R3WIOXhMRX4UpfKneWusiaYiu)*D?z&4mmx7&00xxu z8Uk^c+Nsb&rco(`{D7M6TiAp|*%i-&Lee#5r`iB{KV3=^8P~z@+F7W~V*~@Ua1m4y!^_0~~CD9XvVN zpf*4?G~US|JwPmFVmY~rpjM~`OJ~HgjSQJfHc$fWp{3{Qsq;ZeS5xYF1Cp^qG>XTl z#hAJvP!#|IF$qN75Aud8Sb&_G?Yq5Q;kB|7vitW873Fhp@+7ZhgzsTwkXPrBF{ULe z@3rVDzcrN5P-0lA7mB$lk(4_5ldJmzU<$6Z!)y4xu}~@=lH4V^u6)F86u2!R$b|A1 zyq+<5hL~1@iCzFs37-&&!;`cYSO&iv&RddGv%H-?E(<+TT{ zH%`XQ(@GjWsW}=%{@67DO)NA8f_B_19!|k5y3E}yR?Lht##7F?t>_yUG16^Ol_%7S8txiD1qaL42v^DQ({d;E-H^?S2#< z81N8kW3%m7E6R&zQ&#AjEjG~B&(Osd6d4DQkqqEDW*_UD*92IHba0Rzk3$!Lmy#3( z^Lqw_Nvs%n@A<$CnAGp$bDedgsF+gZY>jgGaLt%_BO$@ci+!w#a+>+Y2~1D5fOD z%GMsrf@c#p%9-}GoC=n69^3ad)Dx!|f_}<9q6roP8X6-SYO=aB&?oc)9hQVK4#J?6 zlt}Dghrvn}RDT^O3DZYh!#osrx2@Cu{)*XLMSAqW8vOhHPy{ zxdD!b9C`b8uJ1tsLJ$4YWDMBg7>|X3gsx!#;sD6LQ*>2sKs|XU!V{mQ+v04(o+&O& zf@DN@+~2sh$+<6sqIfoSQc|c#A&mjpc%~SU@EJ|LCvBvtj=#qcfRy`FTA&5R{R{mqxqC|@pp`(-@5OEC4!QbH6xF@4 z1__jvSlXP?Figcg$eRu@HerY{GeEH+@C618gZI69Mh*EfKCGm74@xa`u%DkIyJ9nXQ@>=krw7?!-U7BYrmLevv+~Z3)>E^s_f97X z8U?j2917zh77tS7WNQ<#AiT!PiC`u{kQNSF<~z`c5%=f|WlK_oa#L~{Qwt@7d zhT=4H+Bu%1_k1M?SPWAP9%RqvIRv)w0fy)tz_6n2Ey>sTOcBk4*-b=wE)_OIip}Rw!`(t%lPPOas>X(v(QU1LLH(a!ShQ4=##1RgNx#iP|P0__P5ibF>CSCW93Vm1P!z`Q3KHLLl} z7Nh<>n#_oKguLO1&>`h5$4BHDC})mCbWaK({<-yhn0Af~EBg+C1_NV!^nk(TJ?%h7 zEOeEA=DC;zHiZ5Gtk#40Jw5Oz=X&~g-ZMfE0k+!PZZ{7{;QP0Lqj}I*42%(CB{}Og zH9~)LWSSj%4(Ht{H%`yUD6dp4M53TPhZ~EbP$w~=2d-`W4QVu(Dm09|h?87gm3-qE2yEBCCgfs_(p z?r#o2MGSVO0Dksta?8nRo<~+`x)&GbO~@-rtJOJLYuQz`V<4F(bKXY0rfh%-nJZ79 zcT~8R;sbZdqkE2Nb?ohR*2%b2AEbZQ%g=`ip4tF?nU^4V0*4Z5t>NM!AuDg2r*{VI z`;7anZezd<5Xz#I=#NF>@_Cszu@Fv;L00001b5ch_0Itp) z=>PyA07*naRCr$O-2=Ea&6geUn%K5&+qRuaGO;~zGO=yjPA0Z(+qP}Izc0NeHTCcA zs%o5j@B7{JJokBV`*c_B+E{z-UDfYZO8K^>l#f$N`M#x;|6V@u=cANT-nW$U4@xON zvy}1?mtX(8Qp!gyrTmmq%4aR5{Mk~Hqw=rIcT|$l@oL zQvUePgg#>_<#U!&er_q{f4uaGzmES^0iBigUETw$QQp$fVrTouQitoRT4*z2=Vl>hcFnCI&hUnTG=fmaETzz11=fc^hf ziR8nSQa<{UH2tem3O4XXB?Jk6=H%}mwv_VGmP!1}jztd#Og7Ha#go$TwxUM27OnU?Gh>-G2E_<-NB1ivr0^gn#KH-Yanmr{P-o3hyNZnDE?Et!$vC++<-Z=ByZ zFQt6?B@0B8{^e52Pklp`iux}q-F?<8@-&0{GE3d|XOvR@bt&ZwFAY0CsFd;rODP|G z$^22{-{#FV-|j7JXnGpSzdrR<0?$tZGCMv%zsGN1eEr8;GCk!mjgk60GytMMzg{Wj zFO^b$)zbU%{ARQ=qLJX2uYHI&(ft!Gb-#bSq`z-tW6O(JxC;lVL-!}V$>e44KYKxL zGQsyLrF`Xu3fJWGyWaf%o{^x}X{m#qYPhG*U zpH~SywFETj$+R?LJh~HGFwh|Ax!5VEB|D^*!6#Y;pTDrIcU!W`6&43F^SGJ`e$01Dv4$br*URMfw~w*;QG- z2EV6NvFGz_bcT)le`9HGa!`Q}WA@43Pg`2P)Ixpy+vhX<*O9ynB_PB4YzsL1+e-}^ zGod5#?jXo-I>>_Km+@dh>;wL$Z|vibz8TkV+}P`^j`od8DSvV4js!H-%-rj9ya}A2 zcquRZ`e)Ek22gyJCCmH0O8^w?$Xy0Y#{Se4qZdHX7bsuM=WOs(2P7of1DedAC;+Lx zg~bDNoM+I0`}sUI8hSB{dT^k+cQr8S=K6sPs;h5hon?Ubc%n$#(|`^>_VsJ85}1+z ze}Inrl1nD?dzP+4{z2_YVBv)C@)t5q01!3!2i`P$2)qflSd#Z%0^47${GKrjeBWxx z@RS$S{Nfh{6u$Gbmr}m!lKp8WagV#^(G$AZ;N&lqrfm(s^G%TcHA_~TF*)#r%#Gh^ zR#k*0P~n(B+fr;3UY&miRBVvh00E6|$S(x@3i0 zd!pIk$6V@aGC_2sMzgy!*)358XxP>uc%x-Cxkzl1{R;Nh0cbwk0GaI-*3(*|js;bJ zUjCU4e%baQ+N%L6c%m5uKfx$U=sFQx0CTOtr>WxatRNZJx{h$27(>DS;gU7#hQf#Y zLBT;*P#<9^t}=j;pnAFBPTtUbAu95R0@006h4AXB7>|8DKYm%)?^)FV)ijLz`@aH@ zldC`Wb$0O_bYg6@_g*Elu-!^aJwNlSm#nA-z=FqjTYSeaT71-1BXgRG4oJZ8w=JET zYxm~&1UgPz`@hc*SZK_jHh36_j#1kT1lnKvCfNU$Ck%i&0#l>Q7heJ(-|IvdTciYf zd;IwJvma~B$N!;)4*u>-V~uS7412gbu9@KHT08pf_j~_kL!-c>t7#88h~`cQ!H+u% zP3D$~Kyr{0-q`;`7LG}SjG%}dr{j7CfM!)-{`?E=fl}qDWr8ooQJBZ~Smf~G;cy5fgJ8&op^RJ(KC7^_W{vvBA`*Op-clejyoy`M^Iw@_U z_M@CqAGK9KkS{?mIfMRjViYJeyT-IlwxKbCWiUW76;oJ$XQ)O&<1>Lf`9$oCjnqlc8z9cAAjWz z!@qC%m)=>~L?Gj2)tUeB0PDcl@F%WEO`i1$z@V;2LCE>WG9I0p>=h{V;j^$+0s=d+ zHAoht1}0gk`I~L6(6$Z z+jW!5`UF++W;U=IrzRq0G>5SOE$^WRqrngIvAJ0q|H}_LT#Ed|mx8G*!ckhz1r^yv z`q>5wf)Y#xKmmYqy_B=%&>9R{Hf<!Guf&APdVd$c>@jb*?JIC11S0Q(a{IJ#cb` z5p3N9VA53wG;ne#a&iC&=mS0QgAw3(AXLHntOLArPVK#|FL`4=zVYHzU()!mlGUeM zC`@tyzOX`^e*(_lbNDJXKd)h%2{vo@6vWV$0-Jj(xfqi*sn>;W(nB__{$;$fKD`gv zEqV&%>PV%(95h{ZUq4$mEEvePzS819Z^?ot7ER!{T?6|ju&7CntjWY9-l^Lvv;63# zyfs@({2EI<;Uj=}uioPeKG0`0_-SRevC-kyN2vtQlI_^zqVTK6hXdCPGdsCV!aXUc z6GsFPS=49-HM1Ba*Ft<015ogHiqBBCf<@}0UI_)Is+;b8+?PWD9DdVMFO&hwdbJ?m z^+8Pw)&j~|M=~=;&lG$etZSYM;GBjvx5j?ZPsZf$Kx*6wcGd2I9z9g{7 z<}_FUH(P5cTM{rZ7d^Y$8*dKpcMo+g_Phl|QWoNmG~9%d5#+F50*1`h#&;i$eAqN# z&YbO=)x+SpNPn+0Jc0GQE&O82FLNmsmBR2O5XuKI4(gzP_Qmo0y>h6SrY-HdM-f_jpQZJvIDfZz@-*E z61cDk&Rpd*y;xd+7bvu-3!o!_6*Hp*LH?Y)=R3&wksoWP=wkJzWM&)@XS5Fn@DH)5&t#y_%N>AMo_`P)`Ga!(C`wp610nwNt3dU}xGqo>rk$jcl#G7dP~Tt@FR zdY!D0bEkv4=}_@>gM*_VkCw0T=w?LGaMm0qN{?Lq9*zD${HKIAFu6WnAB zTRQ)x7X~KI0y0mNhYTF>dXIX^sIVulW5dSF;bTGsF=LlK(GMWVDI#RTZ?P=_-o9V~ z1K6~#0<|oG&FPlqY(q6p4CftMQs&L?ZGjNu;A1d9wm)#RC~HkRz9TU6ae^AQi#-E2 z^lZzIlD!~+>gO8-40<8B18=e#`~TR=(Q?s@9L`)zhk_9(t} z>;b9=^~dIN%-r7mI0pJI8)$1mbPEdBIk&Y@SitcdbZgx?%z+4q)<|R3U7u{0mg&mU z$e-iOhg|`XHn;0ER5ugU1Os*kJP3q2X$pwQ^#TbSI?@OS+yV`N?%EzUwyw75V0c-H zni7BF-v9~PxR$5!X~aN9%gD`RkF_Bev>oR!5DI_}46$z-aI@aEobFnmGxwGCVG|tr z#{bId^*5}6I_qeAidtX&UO+(;7~}`}?KPRPVS!K0lwYwW&las+`HTcV4;Mu_r&~4~ zo{{eIT@($4f*90xM11uy^`aauE8`T%(XLRKnvXO1MjK=-4o5(+YBLlu!ISVc1fifH z4T~q3)yOQT*H~adnPY)Sp*!PM--yE{bBpI03b%J{XShK0)3+c8GIUNTWK5yeLPlQi z!r@SEbpS{|O-B9%4mfx~LcL|Q%aem7ZxjnhLzl>$L+jNirYGNgfkWgVWV=8SePZbJ z164VqoAjCf(d9P4DF?_(*zcAOan|XOtsYkP2&;M!*;0D6mtb>1$ z#kwYQ-lLS=k8a8?ttDGwGkk-_L3Z<;KWtQaNCq!BS+A`P`|M9&1D$I#Jm5~#kj$~& zD@lL+Uf?4ebytCwkKR2QW+eD=4!Ca)g@HZC8WRIXC!z)HrGeOtcP+K1xX`d#8v#kd zM^HYBMYe}};T$6e&xX_?KXePn45dOlnqBIQjlAt)K_vkbelN}Ee3JPI(%)>!7EvTG zf!iN7z@T5*3PVO4@16ZBW41?1$0y@~=mk38VIV1jyN-bYHw=#R%SK$3i%gCj_p)be zV|<>&(V(rIuPAFcOZ9KbN5+y)+UTGf9Tr1C9MMb8(cGcj_NXlsnK^6ypP|UeK^HOk zaz=M$7@otC(|JL^*ZgLU1VNdPfRIKCwKVo8%P>{}l%1(r%6d}@8P!wQ@p&>YY*Iac z>m~a_vC5W#t>}mKl)1}bWjAYjlkcP3)w9@ruck^qKn&&xXqM3f3!XEgBQx{9`daf9 z*aT}nnQjZ(wQSflsu=aB; zK}m7w&oTHBFh@!uWmZtv9;GP&q97QE=9`fKBfvqCI!o(w0|ik56e1yfU_o&gCBi`q za5aKYVILnZ_zJ4(0_jSFWT0)1_qo!{M+}6bawufsq!`G3E3;zkoP(^04l))F4zgna zoDpZv@EH-A=0`A~uh1XoB`ZRO(OdVRCwp5%I54#tSp(w{KseUB0$?pmwILY+L*H_q zqq4_<0BfAL&dAa6%dAnZC{%Cyxa))&Ht0E?$EIXwqmG>467V@i`r*e~TW9O%#|Nvz z>7r6c@9leZNgY+@z}Y5iHs%0RI!qU9xytP9Uk1eYwj;QXFVW0ntw%CAHX$2Vhs{1# zW9S9WQGL1dI`c(8^Ru#d`Y2ONECFiS8(DAdW0XOnO@So7(tY@F{uO|5FFFD6NYc7n z=(d8N>;-Slap0!oaGtZEApinsgU!~WG8Tc)k6_tz4rmTR&GmIUEsN8B+)^W2$EDyL zE`(Nt28s;ns3rJ+&Q(D5ceDt~4n;6qle|-bkKUUj5zr|&BiHq6u4~Q+h(Y7YyaX@n zqFatZkV)N8v^O4lou9l_+Zc4p0UL}3ttlg1(`nxotQjl^tJS)uxsS@C_dP6ttb*e` zbCQnCm(w?P0BfY?#c=?G@4I9(YLFxC{k=J@{hoXQ8_&|H!x7E|r~00uI#br*X#EKO zz?NFs>}Gd5OMch`-v`nJK5HY;%D&pbXH0ZU*DQ9ZM_C)ACJx|&!yYMZ2h}O?J=w*>8r_X3+%GfyuhKGXe(L!nfoF}THc1&suG6}7@wXn(7 zf^y_*^-_+;0+P4y`>vK|SqrKOo$@w(&^5AgpacTns>R8+)Ku+rvL=F_><7hhh5m7l zsqLYSG}@>?q_eP?7YHI~(2k3mdpcfX&(Uy5jqi2f>LvWpVVA{b6E&0NJvp zmOcBzLJFc-Hcd}T8a2p}tfBbHRCc)gX@j3)zjU1QQFC~kUmL_3qO>To%&q5aAW8KJ zMvLZ*LzY2uHspn-tQ|G^a-6bg&!~eYiZ+2%aAd3szV4xu>q>{v(}O#H52-0ctAVJI zqB_=^8Pw=FUg%F|2sMWi?PcRf#+}+8M@82G56(xRT??`dR@Mrv2!OK25hpb}HseBd z3;ODQM}w?!a*mvdCa|8<&sGWFlSObqf;{BBwt;+hUhVaQt>A9H4ktpy5Wwod3lsFV_n7}-%7o%tT83Wagx`1iGD z6UbM#!{B5a*5Xl218NX8ZEYBhHKq4!L5K6R#U-1tXOCMNks}%m2m-Kd@IMmx>4j_$ zXtlp>WPcu=l5MLuVngUT9kkWKJ~yrBSLzs$BalGwN-DLyJzqB`Co8~lZUP@&Cwtou zfDs*@09CJ6uSUihqA<~mGau}i@6%xi5Xd$Fiao!G#^sb}8f+vSYO8Es&>R6he221$ z@9ph<8=0?lw+#z809cKOKVy^Dfj-bH_KV#@IgaR6`|NDbkd?8Yyais+(=n?-WlOf^ zn~vn1p0yT;F*?Q$%yzeiCHQgR8aH&!)#uWU2=Ap{W6=d3PJ$7RI2-cO$f5-rJwzFx zHAc!Pp-ePHItwj;`*I|v+5qS7A<(mGu3m?lWaKnIO%Zg1}=K-CPYLIaVks_iiBjaQ}uoN}a^Oi-x3 zW8wf00aBfR#Ge=gdj_m9Nc3vt7%y2c)wCMU`N)Jf8#Tid;&;4+rRxtDzIk)Bc0iMofMYI@4X44 z3)m9;AaI*qE$~&Zr|2oyQ~#cFb2O01%!?Q)sceN~5Ok#2kf_DXnVXObXK8T-B>@R4 zME&^=CE}ncke1~v6cogXL0WzUN{BN76-5LEhq_BM2L~@G zXVi{3s!=^xJJ!7h5RB4axi?*rO<@H9y0e|4?kl)(u;i;ea7As2-B>HxZS6Qwt^lPP zASX8TnjdI5#SV*W&)D=1GA~!NeI|#uMFf_0vO$! z`2e@{iZ21adf6Xv39wn~Bim2}PxVXVMB}G>x*c=&89IZREs>%1;QQDc`?hAIpq0>lX1jR6?be6;7Q=@s^7sDUbI4>f=SqDWUAIX1KSkG@ub z!R0d=omM@iHa@6Cw!$G;I7$O3pe$R8l4FLfI1q|OxdkfO4JV=&=Hv)SJsWU2E&zl> zO{0!^G+ z1zE?vj<>aY1&q-TSyeV%k3M(rIy!3|&F08hJcPQpg0&Zs!i+Z83n(>;O@Q$ly7?i z<$<(%N}a%`z^n!!d*et2r4)n(Mp*~6+SaVdm~#8L-rsG)r{IuK6kYIQ%(|G;Y1b-~ z=cJX}eE}8Y$mtU1rZI=&Fh-gD%-f^S${s~QNjW$fZc9C27@U}aF1AN$^(B)VgK%%z znR}pj1t;|=&Ym1B^fhfZ=H~(&9DZ0 z^3?<)NJFk&%4WHd?lw&w0>639Qk}i^reo$xXVsUEoRR4n)&i@6vZVWwzjZ=Yu>oZS zju`bxhjjs3XTa2TYzsiwb;%Ajg|S__4kW4@wRIjD1jo$I*4DB&e?UkFGTIbK-E;2j zQjnE>^cpwTo{J5!mKc#9rA}so4H?aVTNyU_VXA;+@Dcx5bH-~`6i8GMBT5tixcRVY<^Z%TdF$(arNc70MLWAl< zoG^gUQXzu7-wW2GFCMmL)=IXWGe89gPLZLF?EB+5bF7`Uw;psIg|=1{Co{DkGUv$F z4jQlyf&n8H=&xW)I1gFh2pF?IniMbxC|Zu`iZQIMJK1}dZ2jooL%M6t$*R_QvgSMi zApwJqaQ?bf$zcry0GWaj-Qc(AI?5MVX=|l?8wN!7AW-ydy`4Y3abH=f#9%MWGA_>& zYjnWdT;3c!7m}s2QgRRjX?k8BH zWh@5NuRa6`=S>my%U&r|I@KIxiy{rR3eCtODR3Q>P;Lx9=clSk;`SBUIce#>dt`l5 zjLz|Dkg0lKluyP(aXCiw?QOa}yC&p8xdryM`jDbN8UxF~_E)2=OJqGW-f(9qMW+;FKbQ(vqb`9zX#YH!4w(U_qd-6qHa_F4MNCN{DEGPk3 zIU;Um{phqc>SY-G1C|6R1ETht4Yr=o9?i{1wpPm!GeDw%l3Zk04VdbMJ2kA14d-6*3UDxY(f1_h7Jf}xYoc3CQ=|1 z9A$YD8TOjJr(1fKL&NnO3<1GVayA*F94JappfVTe26|4T$Bf~PUTbWE6{XT$H0rzs zIy6U)v`VdvQV}@BKl*AQ3oA%5EZ{)!5zH6^3XMW=B3p9>@nWpUAy01B7Yevr)=&-?6gMsvc0U0w& zSDn=Q0Xxmdw z0*35i%bA~RS+@0%DFcCM+>uNcNT%z?ZTxMmO+X?`!4#OP$DMtS{HFPDJx}(HweWrR zw6)E^o?bd`>}0id9kvIhFWb}zrnEpO_U5Z*4luj#P_tjUJsF{btJIZ%won)P0#bl_ zA>O@fM}yqfbx;REN_QcO(aySTVXzp`0|Q{-1ma#J3X?I(o={+v1Em513nU8m7EZRM zjzLj5ty*y`v^n_yWPPE_%&V?JSYWb+_)-H@{jDzpCpSTjWAlIhj-610ubqSJkS@|OdZMmzBp7+V+KXpH z`+FG{kU-z9+t!(jdt&EbI3;!j^tD~A)>%!5UJGErgbZS&TawPn9Nm|V`?vYjG9ypH z+uG%rvI#Z$fJ*^UwLf~i_s&O5fIyp8{@G_)6KgEXUaKX`c-2IK!O^{TWQ6V~+ci2? zaO7Vx4uEDG+-*#kom;Cd08P%ojdfO!+`3L8K$iqdL41ow$GBj=)Lh8{@aiRHz&C$v z4nua4;K%TwY>EekSv-o$0U0o-O#rUpBp458jKUg9F=w@4DR3%|LgZ=!doO^jZ?FEw zSw(@4Ah6s|J2AQx8YO(q91IOz=?4O{2Zn4ot2lN+4}z1i)(b2cL1BPHD5tz^l*|Q0 zSrliVJ%SWVEkt&}QA1a#(K>szj>c+Cbx`HJP-(KRyIxBJv2!{cvN^Pw1jj)!fhK`$ zFMHF~=UM&E%y{aa?(+5m(ssL{_*`K^Ftqyme^qNB9A=g7ve z9BXe>XQP6j(gc9VL9>sM;0Nppm}+wT7u!_ksDV;WaRL<11V3vcOT}RD1zSx{f(-dP zG-I@Bsg^rik|hIFZT84dkPSar*G>0qLFOi~`A%IDX}`mF0G)LMUarAV0Eu+WyxP5e zz#1lud;m1TZ?AX6fdK%e>-P4unlIl=*XuWDtj*W@W0hNdR%x-;ujU+WnV8lzo9eA)6K+uiFH1hA|* z$4!yx+YtvcI}ZU@W(?$6=N3_$n*b-f(~;N)Z}vhjIAg*3t`7rei+;$8WAmZ&z?T2> zBhcj#1nU7fu4UV3LSwcrwG*PJ==yXN3SJ|1$hCO`dji5%cb}}#z14x(ksvGJw)ETD zy=4w*UNV1mCu6Nq|5cfv=X(Z!XC1cQ1cO22tH^Y8?^``LHV*X3>}r}3K$37MIa$wM z7L%}=(iwET0JH^i#Td2U?8(~$ z!(`ny46f+{n?T#9iEt?4se_-J5;6l4!683}ML7i%PB__!B4kc|=P-ILt}_mS!a^ES ze5ekRgI?4Zw_b$k{+xj(0LlkZLJVg=f;?1%iZDmPkSw5B6ooNT3_%VW6TGDBG6)%R zZ2%AyC8Qh*^PyiU9tBWa(#Rm&;6%yay~tmYTJU1nes6s=El_R>Lb27->V17_G>|ot zUyp7)Dl5U&eAkdYCn_+YL|R(0ex9*9W=x$;233QGt#Q$l=&I+SpJf_?n7PWzH8lYP zJsLy?$RN!_$6f7Q(lJZFY;9=icMeHC$@&3YGqn0qnb)VWxJPRD?3F%{0r~iUdb5Uv z$sF*~0E96Brs$Roj2vZrfZnL1ZRcVfWC_FoduzeKzFEuwhfi*NiLvl4du!(2GIitA zY{YKZqOwgbfAVl|*9fd&0Fae|4s{$hLbE1mdg9FaK0X;B23FK) zds$F@O8`Ok&*$uAL;NgTp~qYLt9+4T?|^SQVtfK2U9oP~guU(UKXf0@F(&J^1#qn~ z5J#5-=Ex_Fe*Vwj*(F~r$m?-1kD*T+{PHFL??L_~jI~HA$cWw)&|>#CW)2N#p$qZa z90_`la2RAZ!mhQ^3kHISpp5hNy(^rMOpD>7Iyh5-M9L1C;m;WtIavseFzQGOv#xCo zE$3L~1PC&9y*dFWA>ct#ltYGL{Lm)q()^(ts84|N-MqKV8inSn*NL$RB*wqhSv9&Q zTh~!MwEzyLttZ4m8JltJ=?7hsApi$?FXGlS-B;kJBaD&L&Wmkjmh^>DxJdx3@ctCct7c!L1>MT9FzgF-BY5{oJmGTL;N8lR)g^?}aB$K1Fdo*O-htSKov)>Z1 z@^|y*=d$I9TqFQJdq?X^rr4#VfZz7xyL=vBmvTV1JH(%QR)U_nT7Ulsi0tiId=EX| z3VtIBZ%{HL4Hak$j(P8`+`W53ow6)-Mf`mB$oZbh3Ldy=&XmH{o5OXKQ8sPgSDtX; zxs=eov&mEK#W)F^<7EUEjq_K(un4V@363(Gx*N&8DLSVqU6-wJ=%FuDyWpTG1iC=y zrUe!#V{o!v_t(8gCgjNR$Ql*jWh8fHeb!2lg@W6r6i$Nd%x#Yv2LMpj<|TXG0xb*< z2+(ZBIAoIQRcOlWugp1+^qM1*J#&(>3k@mIKSaJ35Xcby$!_`s{y*jK>$+oPcy>G}RR;z*fO(5@w@w;W1YkkRI{LS=fo3NeTb(ho1$Kbq zw5N=Zkh$8pP1jn=nx4>2I!ITB=&*r_vv;Kq8CmuKvN3Yx583C@U~A(z`cOaz24pqB z@YY*LwuZ}A=<42~-gLfxtHjxkaOaoEOl+u^tALt`<$Af z0}Vi_0*^mYC08kU#*b3t`08S+>@0^&d!`=tw{x_FAJ0Ltua{jo9AC z{v7B}klv~Zn!C(iO~pDmVMm5V;d|?yQ*Y=feL=%+)v$mJjXSz|>0zC{%QiV^nLCG9 z0~{zDGUsTMwVx2{i~lOU7jX0k(D6MTWXtF>dIUt1B?bf#%mEJU8@nUeSaTFRKf?}X zmVlE$*#f6zHP$TqXRi{jXA8svJiVnG#sm7Po zLOp*n<~#V1`ZaAwWdt1ZUjpvh2`;%W5CfzG3+$IInV&!N_XM}2W9feHZ1D2{iVm%C zP85`|p`N_`y>(8RcupumVF)m4W)^zy{KaH}sd)sY&MHP%Fx3UdE4!gg0+RXV?Fk8X z#)F0wkOeggjJnXB3C(iA-d_a;=ja`c6tV@NLB=49Bulj?h9r}t9D;phg-*@(2L)#1 z5fEID4rXxvkAoN~6wk<^y_WH-f!WuzcASv8$+l#}TXa)S>p)d+y(S3CmNk=&mS=|C ztKqd{wLZ|Mz-Rq5Pi@tI7;iF`x{SIIoJ(>TE?4SF0ff*nIy@h?~ z*(Wwd#)Ni5(bHc*5P0HK*q{I-qp~J|55`26D5wEMYx^CQDbx{_X95M{F6dOe8%dSw3GAhsF(~KE#Aotd$;$wSj zSIg6S>FO5zw$9+ZQvRpzbw%(qfYc65-r{lm6j&gG-XK5Ek}Yv&$=W!6=mu2;-OM_* zQrt3weK9z{H^;nV&s-=P1u%a!hR!G%T_{MkGE@e%gyKlYoeV_{i}Ir` z1x^7ZomHq^XHQaCg=WtdJY`xO$k7e96XJO1Qdub4Ti|Llsk~lCHoCVT$@d|D!DuZz zKogsjfG!*JoEc-R=R{8SJZb)cbhp~Y=`Pw`J*RB|pxdZXLBC}<)Pgk_`17jsK4;hD zxm*v}k%JRUM$WlRSp(?coRt{Zj{leS^BvYbM_yq+&}$mOWPw|Zfoss-XO3nYk*RD| zuvUIy&pIRN7wT33+uEZ{Ck1}MOpq7o_yHgn7(QB~WH*AoQWSq6%c9px5p2`%0SLgP zJxqbWQD+3!1xY?yAA|e!wh)-Vh9Cg&T@(DGAe0sA6W}xn$Wl-b{vTrYLlFc9f2zNv zNnu3Ep7NS>)R|k}*x*n9F9-^134qy55A~4;I#`V&U7qL?K~85E+CiqA{dqEBMvFpY zxRfq0e{{Y3FgC^_5ON4IXGMKYLITN=HtSj0s=<0Lny&>d9Dv_5zO55TWXez?3UTd7 zq`U+epwP@PddR`vJUAP2hkBvYyiue6jto<#KyOiMwPWQNP;=zm?k5sh1x*2Pt8u`+ zWxMX<@1dw)iVckFh^&K-3Ob{JmL0Jz027lW2%t@~y@|sHxC9IIrp62`v z?62pzN9VS6U77^dFO88tuzlbzpg6KHmb{qS{A7&gDp_#t(V&;HVV=z0mZ8{Ix+L?S zJ|Lq$8<%Z3Xd_$QWYlalag5C?5%E*+y5QF$Z36Y<6N)mt?kF8_Rw?iL ze!W3?@0?SPRiddm!seI>If)d_u$0Vkh_AoYXs1< zh4@+rI8caO@KS4CbBY|7HLyRe&G2OJbhoX`0wXdO!O{J5Urt-S5My91W$>wW2!Nco zOi}F@2s(0H*#ra7qDdA>aHU%Mm8=%PhixXCJ6H@ z*3KNrpFOI%qI0+UI@CI`T*?b08UN^fZn^F%+Vhsdy(KqQ=gWK1WP}``K^qAzNiLH!@XxVC3DWkV2>T@24WZJ@^)oT z9rA;q)elf5j21#?9BVJ%RP#VdaZu2F>Y)B)kZjOUJ z>PQth9+AD@VPf<}vk-j-&W_U50hj(1_~<}7{YLZw*kEHa{il9Gcl>PrysD#iYyGfp zwv3qnUgJr=&o1dR-?H@%PytXdRf3_TYoI2b)dFPiK$1IjZ|a_}!SDZzi_=F(3I_Q4 zD`+-IN;8Vu5hu?Ppwc)>&Os0eJ;WenZT^q3=dk0vip5%`r5}o9+_?BSN!bQEnc|He zvnAMRR5Av^N<)FbmxdYRHCD(~0903`^s-c_oPxKFDuT2?>^rV?4HRfzg0}m~7-e9L zRFGwK8XW{nRI=tGb3@t8W)33;Kz^EM(3fh7YuVpchG$)T&ryKDK<$Xh(g6)>w&n}0 z05~WhbLYJM)N@K*ivz+E2+H(N_H?A#VPyVyUL(sTAF`1BKgEZwpr3Q5=ou#DDaL>H znEEMQu!mC$Mpxf-_nULJLY0 zXz=kIri^7|gTIV~gAnipA4alQ7ZJ45c}Y%ckLx=zqmxX*^^?8BjR z=9YIA+NUMUbuFhUdlf*@fM-wS*fSDqqS1hpSZm6$ZW=Hcbe-YJO350{EHjU+1#QhR zw(O|2Xd*(}Z#56O2POna)>p6wO4GIO_ai>&==?7E-g63mXd)TH-9m#* z1UR(=ioxMPsoH^^EaCa+0<{}RXtZFzwjk&~^J0h;Ps=`vvF$!H2AsRM2FU+_xJZG=iPM}bYy)cMH3G#&V^Kw%C}zmX9c z>qs3VopNNO#>cqSYGj0?V>)6C)?2phpaJ^^+h+kD0-Vk_b&z}j4YVFQH1A!@3ve|% zkOu%V^OpL0{G5#Sv6d)bd%o^Eq~M6$dfy>WuU$e7kG^@JchA}1bN;}jF6tw1qnLf( zbGx3;p*L(0qaaWLk}`3At$jhW<}Mw~{N2`T>Hu2_fm*oI$C_>Ob3hv(a0g>^shpon z@Kd1G$ieYhfIEu*48o}lf}d>4;^cfj)FiY5t;@y)L5^GPX74cOy~Q9~b5d`h45&5= zDa)dOEgI!OISd_?oGv9a2F_3>ln|mzTYsneQXM3&g28)3Kv3zrA9dwpnPqM_nJa z-z&!PRQJ$SMYn-A`a@Th8U!%R1>k1CYxLB*Ikk!%V>9X_+sr{tS_d>xj@4KLV;W;H zPkgD2`)IBAVKRFT!H?htB^eQgRTEolK|doD*##5`@#KY+wiH11oUF8;Ge`Xy52F#B zWMM~XC)5k4s@|taEPLY+WJ_B|V9D+jo^6_?w8pxH`i)b4MTP*0dCo|Y*}UyT5@6eR z5YEWheAM;?a#<&X;{1gk zWllw-j;v7-^gU|@SQ&5qMvWO+u3ZcCXey#FKveH_P-mZa=KFM=V@2y@A?Pi6%z~gZ zW5{>e5C;sj^j_9`#q*xyJ!E@;sDl@rd;=)wJWT6^()T;1g=BDaU71F+9o9wNS?yY_ zpFQYQcTal1mi4JKYKYNgI()eFQws0O;Flw)>{sFJNB7mBAPJWP*Y#*o&`?*V&77(t zEL55^{vdW#9YugimMMMPn6 z&=8d@kOPL)D6sv5qYXMb9F0kUIYTk$J%p%QMq&-mzB7+XvZYp&360o})W;lIs8 z3a?l`8pPM0t9_jjG9<-+nIMPRbCRy-WGSGmR5n7PDIxZ}_z5Uy*KAZaz3Vu4fQJlZS$P315GezYaf}3u-g9PtpLa3>VMkwHtKO<+sr^v@O{8ua&U#MY{`cI2<^P)OV#V?yt@Ay zK*%ex1b^c;S2EbrJ#hqMmvAPpvf9l$+f}i_1)`kPY9Yd=MpCg8=8N0F>#t*T~!f8qZJD*yz1v*8mp^n|;v*I>z2KodM_q7Wo6qvL<$^ zW0;MqlaW2$WS6e9HaXEp&5drmm+NK9&N60)XLNXLe!7kYxwTA8W~W{)NjduJrTV#o zJH`&+z(ifi+KsN?^mSJSKaNRIK_dw=oEP*w;^<|20)v{B)Y<+isN`yjhvHcvsEy)o z6~fi8P$zq@0+|-{Gx-9e6a3Pwa>cN&4gl&#vTiyg19S?EHQ|WzLSI=hzyz7AIqG5? z(Y1EIf~mqkT3O8kXxn>_+!gXVau50_%VI0GLa32rNHpRA9UQK8Fds7EaMio+dc6{- zo=xn|)(ks><^y5@imijnkIaAMJ1JLa@=$x8VM9>Yf&rf+i$(8cKPJ6E!J7~EMmfSW z!oC0{33_{ggY5w_WJJdWYAgo^hrY|ej_B}~Yy@SsVmjT{-~>hfTJXD~8&-C!bf8z_ z?o!2wE(~3BRq*4SP>URE>RbZh2>KL=aLNkgdBuj{cjb{*gdxMDxK4baY`US^h6)O5 z+?>Xv&d3~Es0%M*5a#}9=QKJ62-*7R{6$4WsT{cg$I){TGI>s3-A(r9_pa}4OOdGx z48AL4lQHR%MJ)qg9K~~_Y&cAmr=TOl(@^5y9A|A~elHv0T-hW2)_r^RCT|T>>e6hz z&iK`l_yCSoMss&o9G&9Fj7j#c6L;+`BYXOXeF7?g9MDzkPu@<#SIErN0liEaKt9?CSC5PT1;k{4 zUeDwdD4FL~UCwmc=5=gbsC*rrwsHxKK=6oa|w{KdHQQ7j>lTP1fcF5a?n=K?FNBKIqE#EC?kSS(GCJV7$7)ATFJk3|Ii<2pO)1 z7qrc2_vDc=JjHh?uoh^Phjq!J*iSK*y=S5{(NWgnU2aR{jg;ew7`9N9r23bCul%=itiASmVSsmd*ymc!8z#^ zwNMn-ckfP}QD08*P!xt>y^z%+WN(a3nwJZ^Cy1MVuNESZpgDA!a#*r}tI*}u!={rC zwbpfKT}D6%BV^=^6U|dQFqxsIjC64_s`~dbBZg>8$xNN->UsC>$4-u9rJM?9t%<8X zsiyb5t>2@#P|a+F;6!mImMutR*QLt42y`L%MxM@be%8lue1@0rldhMR{t6Cs8Cbajgai6)K*OJ=9t_5OkIX<&vTshU?o1$(amgHYc*~BXCjy79FFMy{OdPyGiJ8zhaK{mRWDJnYuKA@a zb4+8GOaRIoywhLKZ3vBrWB5YTI=61)UIJr-mpL83e43z$ii{Hz5~ zfJ-R^OXrOzo~dc?^cIb)g5RA=e)qjCuuZMd2ijxgVCcKYboTyH7WE-C;2Fnob}Wzj zzJff84`PNWp>%&oXZiDJR`96t-~AkpT}|sKHE4XmB3a6`96(S5T)qU5lnwZ~v)fbl zAehT21gEnvPL*W{+MKe?E_Fj0k1Wi*JTFHfdZu82n!H1=Qme}$?`P>x0Yre;=}uP4 z2`J27g5rAs2Ec?-F%CASF;R)Y{Pzxc$eE!!gI!y{1zu+`N?9P5^=*~9+{0;B%4%p) zHSBCnalhUiZqNMgHr%`K&xrh3(8I#Kdys?o7tA$ps9|zaJybS$+h>0n=cQqVk)ifb z@G=4v+}c|kp8bR_9w6lJn7uP+gk~=t=ilxj)UY8-0K8-_>N9s_+5#0P?oax?cjVTL z2+?Y?KNO)7LB@{WlQ9c+sR^<#bu^S93iRs!01n^%{WyxuUc9p(_taP-cxWvB?7pv& zXTG#+Y)VH_oe6$vEK>ieH%H3`G=Xri9F@-6*_!`|JOw;~)pjLs88~|aQ~gYimP1xY zRQpR^$(%eBg|6{MmSQiZCZZhfQB$QO^BB2?lV`)|)^-cV$oJQ-;qQ&zX*IGgnUvro zfT)MBWtckfjRT-`7>V)7NPBg|G(uvZl#+698K0oe|LZ{BI_KDWXp8}>)cNRJK!)-L zphfOz_(QM!dUWt3bkW*?9UR<49Y+`W-TXZ==J<849#V=IC_FTbMgi1RC@|-a3Vv!c zjQrjH;lRk_%!wYrtB!6pm(-#JBzq-+E_N+&2n@1=D>FaO(OF2hZBgQs1=uq+%vLAV z$<>GR9>oB3*(}{c-|=70#TDeq0$XH@)ae@3ih`o@ZBLMOU3uK23|<}3y=~`Es}+O< zeAKQ$XU=MSetewODpM59Mw+H{{sI$fj5*I3NM(;`W%a+Uz1#w)gHv>B%kF)@&aMFx z2VAH-0$l?5G{}Es@MAa@6CLOEMd+yZrHb!%2X)2#(SOjrb1|=`W3CwA)%Rc^92P3h z9=-r76pd4Q7>EwHD;@FGbGZ9{_BnDyIvEJ6}P+JUFTktd*dWJ&b_YT=m^hb=&;EvXkrW*Sj|2$Ug;-2n_TUevmpA)iJM&j5^iEcTzGJk=tv*!CbO z@xiia09ifFnVjw~@ad>DUvfq%qDUnwGG5u2+T94yaOw-$*;*mN$&0$#Cz);43I#p@ z$M&oMj6Hp|bwYQy@uwSi*ft*-{JgC}y^qqM2?&?7<m%E6b2GD>aG8fX{r| z%nysB8HDq3Z|fq{=CEbt0EdiW^z~-#*f?p9&_-*11Kn6>0YDzGM=!1d#;8vjhdQyE zo=n$s>(`*6fAbgYZM9L0^gY=qd7SlE#<2aP7m1pKQYFBt(~ z%thcfFO;w6>V78&*{3XYq>)J(f`11(WoR=Q-+NbQ`}P1UfD3fxl}b~m`#duEX|=|s zQw)kifjFkE1FRu?D1{Iik_CD(Cx)N#FekqYLbH{nHCztEiuP5u{z+_}2sC{oh^hGd$ z=rJ+&U3n7=>JN>DsseH~T=6YXJZepV;xuPy_|*6SW}EXJe&4c00)l3UE6-#_WukHU zE0mxhVa@<}#?R^I^+_^CbxuJ~JyJ7=mocME1(P!yvIP#Awslia?KPS7lu7VHWwIB+ zneFhgPOagat)GMhctPu$znY)ADhAG2FbF-MVLJ@k+c}_`pJp;XAjkK5zAJMTOPnnV zAWyx;Ko#hA1op;&9G7o1QYS{hqM` z6%@Ti%JuaSuD~MraaLNnXPndQ*gQiWPG&IEq@eX&i!*AIqw#@CQ74>1Z;jMy%+p%z zy^Y$v1!q(fM=*sVXNB>A>(y9*1`b&biwt{Ct2ZnGNfwQ66wK(D+8^gBBbNy}XVdRw zRe~r)Qp{rC#968%SD!BM|$Ypn&2(JGac8lc%F>h||{TX`dN3MZgFR z2Ut0Mgp373*&>HekJKZ5AAsk~ZJjt0xbjk3a}!|C`V-@2gKS44fyQ-iCtyfF(4zj0 z4zVDp+^gfd-goH+S&~<;#wY0VLxL_H83D&+qgjWH`4(Ab{q~BUF2Cd8 zAMt^dOblY=kfpW+Owe2WFM;RvAq| zHs*3l97BzmDT{V)2vujK4gTJSz_`zDrrjF8;yUBy4AB%&WiM#CmyAu9qMy2HWyaCb zacI{Wkh>!?#( z27rp@IGy&A`|Bd)$Yh4;=(hegij%F{krsC}^xBx{FWOA4$-T`%-B#m8z3wP&fiLf* z>y3T%_p%)sj-V$%&_VS^l%{M>P>-F^Eg(atCxbFZx~ij=9QZHa1*T-LzcNdGmIU|R%wYc*0Ywj~55ob40Y2)`!()cD9+SEst> zh!4VOkgGAFyu}qVHWx=C4t*XK{3sCWLu~+>usM{V(Ft3KNUZ{D<*Wn~n=P+?!~2$y zAWjOc@H-o9b!e$mL4u=b&#O~(S23O|94@LN?*LG~p$2|^=IYh(y)R;xcy$ib77Z4R~GShqBWSTi6{7A>nV zE1?$=gg^faN1XxsHr~+(BA_j*;h$MDAZooH8Q{Y8uGS}PDUtW zvj*nH9@qjZcP3c7_qSh?8n58u-?t9DrYAB!?4JPX`jPp`_%I2WL7+=;)^H^I7OaQs z%a00vo+Ay0q||9RLusm7)0Tr_1k!v$K|7$X2=?li+^#7M>Pz;-2u9v2P~XE@l8gbm z9dSAq69ue>g;p5(&WMsTSdJZnhMxVKJUJ>#&6#)>r4KbDD;rV3k>}?cYsV=-u$~L} z2)ec<>=~9$E@-#i!Z7pf_F71j(a4NsgZ^!O8I0g8%ZEPId`26F&Wz`Z?{d~k3Tz2# z<|t*>f)htJlO>Og$95&b&2u;$+1FZkBYI6OhCZQ5)db0#!xbQ89Xcgtg+PdV3XZZP zdMI!LD%MI}ueJ;Hs%vDHJv|zkQ+Jt0n$CEBeXJT_fMVyEHFyYc zbXP_~=YT%1-qNVW4{8JwNYTbyK@hM3q9qO^o$<4Cb$#A2uYPM=LH5+K%~{>y%Op7D z#8>laYyMq4047kw<|fM=$@tvgIOz|HGpwP8DA~HRjN7-?Z_4CR!Os9fwHde!fI{zO zRkA#b!5ML&0t6~&Huyo26qX{79!2Ckx=V4%!$@M0GGxqgdI4(>+4&0Rg(^6E=u6;Yx%htuUK_cLSj~b{eF>SL0HGW}$2nSA6gkg2u2ILyX#u8eNk9Ygw)6#v)Bq!( z2*^N>fFY34#~fOW>Xd;1Mq1?2(!iQdZ&_4*l8gTbgauE(?=c9Y^U8JVzM93@f{e4a z72~DT96R}P-0iEd_zqc~Y+Nu`?{go1gzw`Au^H@uGba<*$bvcZ`b{RlfoG^elCk^B z(#)A$hAF-QAy^|>svvu`-YxiJ>SX(S-Kl(@j9q z-x0t2u$mv)=k3xKT$Jw>H7Pjs$GFgPYBFe+S!L(waL}9tL_ZqLWTpb(Fp^jb{=Nf+ zFpA!Xqt}ceSUzQqiDHpAr-rJy0%bBL9lF_r7X=rH8JU19Gx2-qR}kjVtP{r~Sf=H= zC&w#)%bHu@1XdgZf^+zS%6c2MsfZy9LE#QEoSJDeAEzvgUY*0MQclD*k0rcNgl z)XfKs2FUUa*a6O6wlAnE9iYWzmUUl%|FhW~d*nV>2YLPp5LE~B?6&65pK$WFU|@N& zx33OFu93BQ#S=Zpz}Svsj~l?x?#TpI3fRjAeIIzijwpZdedMA32|NOXfDK?^&6O#x zJiH;@^=L{g!cYKdlmo*gm`MPv&DuT813k&cBtRp~8vpb@OS8_}q1;)TjDD>)V zMmsCd-t`LIxN|ib$X75va%iyHnx+9LO^t<fjo^(5=ufS{5xN%aRqKWjR#MLRV41 zy}8%FCj&KR!Q>^p;X@F}=JTV7eMUYUH-MmaC8G(bv8J3ndQXt!r~x1}CZ|N-IVsN1 z?*$Oo(0leM^OJ3{^X%JVuYQs#y2kn_ozSbRDf-BPqZMR1=`BEksx_W~4o@0AD!O@RoS*=1!%(74awv=2R{f5@?lWW z0b1aUvO|(K`pOzSTv496SWplJ{yqtY$%{eO$9^g{H6G#NXyxIl;6D)M^v3tW-d2gC==kp)><&)t5Q)8|)wDspD98u8gpzPVL>5 z0i&A*4MEc0XSOOJUg#V7zm33%YZc(vb|ll#?)^7e7%fU9d?d$JdJ>4-)ZK$5ezkF9>~Oulb!^c-rJDel=4 zhliaJ0A#Y+CZO&vqf!rhRCb##XdR{I)&uYY8@FQ6_T$RdFrC!1XT))Ka^t|-gy1^!x3)@V=jL(R)_WqiG)!~Mw8 zK4dJEgkq~}w0<^bK!-kBoXoqQJA$8k>U4s7pc~Ygy4iEc0vMM9GI|e++H-2SZ;EV- z#z=~;5dhz;sfLkmIV0!@3RVEuSTa(7>@MU@7X+D8Mh3}X(K6Q3`f>=y&$zG1&TpE= zq1#%2>nSrwXI;HcWC>uYFWFOw_T%WZ$nVknP`}y`JyttH&5rITJtT;YFXi<#oHZL! zAKl6l*ao{0thX9u+%Lx&+D5^-lM&wmsIt|WEadE5^Ck(0J!`@-j*-ACXaU)rcaHO8 z>jL^#+dun~NehPlWMlp>`|kLkHu%y5eGHmLG>=>fe#~8il7LM2NBkdo3w{6&K;&=@ z^sx+@ZioXT;4T@TI-jO9Yu^JNo^5|C9g}Pgz31_c;Kxa#W3=z$x6xuy?MTEwtFR;A z53M3g+k3I6CL44PT45xOhQuKij$p4Nm9xvc=AOFAWkg=@)@wK*;0K+8`bK4q)ILY$ zg&9Gw(l1mHP=w}TKc2N#-#{}9di0EAQ2RPl2Ok~l+I0Y~+OX_HX=5)iacF!%PHAd` zwcpDQp?CD3Oiy4(b-8vV=$x6$)^`PDbv3>KZHLky2{M9*wemf4V()^1y=fSdtAe;O z0SZ^1Z5mmm{wDxun^I54C|zKYz4(qAA73aSqB?uB%X|EQAa)^J90`2Jg<8kD34lY} z%O+%kEm$Z3 zbjVdrE)+(~wC*&t!n^hD1xNK^?|aZSidr23?L?;mmYxys-BYF{<5R~Go{|0ESyH`2M;6{TN+qC6DjTEp^M^+2dNz&UePhM`I7}dMdEa7QEm=d z03^IKPU8wi&OOi(Qghv0TYF_(gZD-&^|mdzuZ}E1Z_7ENa8Ljgfy2A1Ta9zpny)6} zG@PsMd!@Wz^1TEe$X$&Vnvc$mI>5{wrDd&TOZ3EjIIVWQIDwqbW8ahvlpSGC)XoJ& z!R9G#33~x>$%;lPF){@D0MG25HBU&LO`x|lRdJZlp+u5(BYQrL595qwx;)cW17ZB%mNMdA-*ek(HhbI<7fMa$#+Ix>{#^ zy5IFoj0V0m=g~t{GX~+wf*({1!DlOa8qcP_GRHjToA&_@H6@5$;yOPNph1`6mhh3DiSYAxXl zY~ztt05SZTCX^9S+}_9c=@L4WujJ&_L1puTi$I7f+>$HiDx2R0P$25=k`hYM$v$eA zJ>TW90<@)UKHFRNEUwM?Mh~}kPdf^9rOOflLi-EV{D$c1J7`ZWxRhCklm)~AQ+h`K zoRnK(S$3!W`Vln+ZO|x_(IeLO6h;RoL$u)b)#xl6<;Le-|LZprfMkJ?FlV3>krR>) z(sxcv5Y!Dzud;{D|EVpbj!;zU$0Ic1bCo(uR&7NFXTR*|N9F@)$_50Ev*2&^xmR5$ z00J}G>CtO~H5y#@Hngv78Hh|?`@YhUfQmM@=^G`A0_Ky|1=+MfqgKX``W_$!M5D$r zX|kjv2T{z*M8Ne-&(;95w^c#!gAQi(>|PKuSLGs2MY9>7rXt_N%%PG6XWP^GMWD3% zxhwd|mIOT?T|VjqYl5Im1WJLPqHv%6MO{H%aDjS_Ii3kpP!hv|b~sYbgz`TpP;r5% zp7ky03};|HF$btgwQcngfC`o8BO~O%)QfXw<7k%joCTo%DF8T>cqa3~Q~<$fL$uUO z3w~J>Yi!Li0P42Dj?xJx0FV|KFiC!Lc4>f+2AI#k04TM2-QFCx%ndl8L%m? zqYGE|Y(J*)0c9gyrMGNy#}8Xz?ZHxfD8N3Cme)3kyiC=AN6x~0&Q9U(v2nH<2AqB& zt5z?%bN|`h^LbnDPmg5}RI4IB23VJXmJnmu0nM<&M6 zt7X~}AQKU^09=_pha8ZUS7-r4s7-XB;I~#%@g0H2kH6>C7czIxdVA5MWr*d_yr^Mk zYXdxRh#A0mWDn@tIAxM_i7#`%5jKQ8)XjBa3#@=cUWMgMWp=0uXh<*b$o!xjhprlw z9}6xuZ6~J&AWdZykc{a62>NkWVF(mQ549=sqaL8N9K{7?pfmjl@R0t?l#SljcgPr)_~9q*d|MnF7yVjS#0 z)Z<`#P4v$p92iDTe}d^yv&6K1m$&`RPB=5U|U%mKS1Ht_p zDDK+do&K=a9fV_6U>0a(RWdEX)K3uA&}0X7o`I`Fs;%L*amr38V9aZXEvGYB7(6}7 zSMi#1*asyD?!B;bYgq1w*H*}NAN=;nM$y4(p1OLt6KO|-}e7bHPSAB^~+~3o80S-h9#h( z%hn&k4~^S`AU+X2ik@_aagNH8gZ%&iAOJ~3K~x))5NU+L2Flb%k{y0U=cwAMK3Z*U_*Pcxdlpo{mqlt8Iy0|ft?pdN ziJ6yeB7&aGR_%g9Qe*%jHIEehb2OU0QZiW7mxB3g_IlN-JnlY%ANIk)4{PsyqwCtv z{my=`pnCS}WE%fBvhVA0GkSf}5ebMJHtqA1GO;yg4-1BZw9gw`kdw9S@$~;A%{oeA z-jpLoXzp9n9YN8S8#KHvD8p3zTJYn*Ik_R;^oZn^BC!p!(o_LVH>jH5*5-sNmC613+-4?ix?-ZnbfNKC2OJm*moxK<5gF524L0!E$QiHXZ!^!Q%A8bT6;>@STEPv?x6b}u%2q9S_^*m zY2fFjtwS#bJg^R^K^$&g8zlIN-n}<1)Q{qn{a8#CqedGUp+IQ!qu}WG0%0%3)_Ekg zmXScN9QsJW>`k3~p<$h1P8+9mQgfN=Rsb{~TR>z{c{NP$Id}aY*r34bo)p~qglLW& zv^ygsjSeUbonRvc?z`sndf(#`NX;*&)6_aFFrq_q2ml|#*>Otrn0?>98TVkSp)cRb9Ih^XTXoH`64Vq2XqW%V@UwN2sR180h0&(1zy)iNZ0vvhC?3SA5 zM2xf-3p5tfoV4X`btX{=TL>&Nbb3d?R$FojV65R{)Q3g*Zd3DidM?MFhr9zA-> z{8IpzRX^8xKUWvXIib?kSve;_kA7!Qp>Z>O=vX!my+iSPCxslDE58s5Uk7)+XH|_{ zBLk2G@S(RkN34O)Kn%|eSUNJkt?%TtCNit{Vj4dupSLHF+ntQpm2;Z87Z5A+qC@-~ zMl5WN`y>v~Cy4|frMzJiJ{=Ocustn!;akNB_XLbvyLMlD?=&;2*U_E5ctX#yWKO?9 zV`3M!j%$=8@Y~+LLf7&_;9sEZC3M6DJ>c_;L54M)m2-&NF3UnUj(5Au36_T=QdsVB0 z78&y+oua^tinF*j;kR#@o}A9`<&MOX^^(0zP{YV`_!y5aRdf~fhbk7Rt}uS5fO>&%5AIH+!)tm)J^ztod!Ax13QQIVn`8TXa#WL~1gImO zbI;*T43M(SOs1e|0n!^mh`sq!Rt6(mk^Nl}O!uA%;bSj)1^eE(AN_ldTLS@l3iYnr z7)sV4B>XaCi1=d+4g|+aiBCt_!Vh9np;I8X7MXjHbk^Ps#;LPXfzu!y?E45M=qbsO z-wV1Ny$^@{=t4Y0)5(NRP}tpjsqT^a&3q@FRrcecdMMSE^_jfgnZs1?J8FQvIYIsm z6LJ^$Akv(Jct;(#H=fboYtTY#YAh0{(1bD#f$7RO9nd)rh@8|^WK3vEh-FP=>rE7rH}^^pE^7 z16W0XivFyaL)BbUxS_6n9R&jn^3NsmeskWkN-R0)JiEV6eX zMvyXg0o?Q03d+`jA>xtir)zu*>w)Q0(|!MuP3{nMoQdo}RM#YOr-6211_dVE zr#xzj5aIFQb&df|chviI6WU9u=-pB#3`=ba9rNg> zi>*Zc>^WhI*+EM zUn8JqW_<)?NfYYQ26n(lAfp$a+p}}QO^J=($pp<;oN=Etapm+Ffr^Z`-kUiyZnbc| z2aad^>x|2S_Jm^rAa_{-f%dMS8PKDzReV)vv$aC1J)%r^jnVn0ltmC^*jF3T-ncnG z8<8o304PJc+^wA#>;TjrLk5aEu*S%wYv$~;Npf#H;)YoOJZGaQ_ zybT+*gO#~++%ja&M?D7Z%Bi8B_CDw@0f|FiqpD_QvUR;a1i%pMgl*yg@A5seZ**9% zvzgCC!`Y^#PK7Nx~#Fr7GRjo%HY)@WqJUrU~jBImGXu9Fz4l?-c+d4ucjLeg60U9WaJDj*S zYFSIN5AD(@+-!_>0==yz_OEhUI^Q@3pbyfd0}fX}>0fDNt!yA$r{vh;B4BV5PNZn% zj*{mb?49BOTYEDH+1ZtKOnv|rg=zy1Wi%Y`mQLjG2J*XOP2Ha}BnNA0eMU0U5q;dc zM&Rdku^{%e$~d;{(fH`p`z;Qe9nI8DGX}v{5LFr=Z^2!YkhKMT61eyYbR8h%IlxEW zA?exm2`lD7w}1sF>fGg1WN(`G03g6N@6KmwSiM-S=*{Y0LqaT``E~|CR0g@Q)T6!-lq1;#0O`xl6+}#@w06@vmojsajc3!z2?WpE}Ugqep&>cp{L34(jg$x88 z6!6A@EAZ!#bio8218J%oIc82^;bh1kg#(Rh$k{qx@96yN?-?gYCr|?%?MsLSW1Vo? z%AI2<7`K_SE>?9X*``!TOfnHWDxv_pmd~h4j@7oY9g`T=uLXTe(QDQtN{T*A{*4zKV?pUb8Ww_ zK}E9z_q_9C`vU47b7YtRF6rJGdG|j4RvHJu82E)79W8jvd<5YB^RB;GQq94 zN1U3Q1w^-rz9KdQw7(BJHh6UuDJ;XXKS<&APJVxOGU;IB6ck1YnRArd>hwcvwgE+I z4t1b!*N{GkZN7@yd+2X=tXtRP^%;*-UuHJhGt|sm{nEIB7Hg_`VlS)J?7$HVxYqX$ z^lrX_4J5}n&NkBM2$RKeMs(F0a~_a72at6JZa4*oW?pnwV3Tb@syb_do&;iamvKU# zTN`!HtaWTk%Q++tB@5a$5U`H645-0z4%V(+6SXEm9MZ1W*8EYa8V1Ov1sLw_8oIof z+0rM^;Pg2jK~^ISJGuh2jL6WM8iTG*b)L1ZW7$$(7Q1&({y5yRI>8lF z;Qx(5C#g-;GA#5Pov~)^n(#jYH7AX^0m5bjbV68oh z5zVh7AGp2y?J2rGm5{I*{0RSxnx!{&*QYVdlIcI0i7({LPoazjYj$c*0;+MFudOTs zq`+uT-=$eBMS#eqq!wP_BRmV?K^9d+M_r+fObiwC)E`P>fhmEp6DZ@>G$4>b5RAC3 zr4TshLg?tmHKz~3K_3=RgU{VB-XvEB1{v*Te#Y*t7L-Ib!>L(64uS&dhEfmU>TXwbusEkpUcMTHgU0bx{bAk%bD(zEe&=YYF+1BRSA%S&Z76wFLCm zoDntoXs$*Quq}28#QX4L^i=ayY>f{vH;j$BlDB}TW0#Lmf^iMqBg5z$ zprbqmjL2k1>Yc;$Fc7>dp+ePY4-ZSdgaQ~$Y65sIF7yi}ci zJj%ye1)b((atLvhwqsln5u+yPwLpQ#=QtP=ML*)SojGUIC$y+5%Aac= zMkN!4p3q@y%1Qyy3&tVKqfq8d`Hv{K@o=aVYU{A?E7lh(bg~2_iY@2`<*jF;KL8R& z4NPQHEyvEO``M%O=r0GypnR9X3LF4ljhwB4@vgn6?ua~OBZ4;P>rV_z^whx;YUrFi z6t6zn>X~r@q$na=A%MJG!^v?n=8pQR!4-LF`k^x%jKH;52SoP@bgr%Sfy_8C6r6^o zBf2&!H_y^-s+OrvwWccqgF2wVli+BsG6%r{kc-nqMXF_!v#gqpMfLzBuupE;r$^QR zk-&rA^o&|J_(^)?haA=z8qcDm*n=%w?#Y7>_6*)a#QKEbl%PPUMWwZ7+<>)epXmVuIESz#Q2PX0FDS@B>0g@>HSM8B?_Z@35g9KOv03W(Q#^izC z6#O_a4j+p5cUcs$z?lIuwezm)J{Sc~hhb{YxvHj(&P*Lh4TQr~lSQLx91Arh8*Rax z`8oYZHUx0m#$o*CrCuv23etY!q-7sU0D>iXU}@IgdYyG}FZ8*40l#bSnS{y(9UHo@ z>@IC}L8itja)fKmR|1n79GRi`$qOjdtAH7y%c*bqH+>NhtusBLhc%68gFXN#0Ol1t z*}~vC)(Imsy7Aw9WQnL&L5nXvvH>0-mBC_n1Y&FeeerKP#8)U;Y`wP*JqWP4X78kx zqqeyAJ+!g_XxkJ!BRe3#Sm|x;v#hi0=r{e7fC$n#uM-1dZGDFwTN`?uGg>d*X<)%E zvQ%{R^nfb`_vm|t_EgtnNLK`twK^a|7z^Gr52GEU9~ z!iK=l1Qbr4Q`DeTZ zpPsszqP_886Ep?@M4Yv3Z;cK|ouPo}rr?=I74vZ~4n(%tc7t*{0-yVPUhiFy5ITT{ zBIAJ8GCR#67$2pND`nHlPJqHlteyQTP}xhSHl7XJ)?Rk2c0`x!eRgzCAoU{?$)4W2 zV=%4vWYE_7WQOQQ!N+}NjidT&4U|;?7Hc%i8llJq3_3|i%$IDiCjhkUl3rQkwGaCi z{4~2vzv8E-&>O!eE5TMxj^2^2d1!9YoYew5dW=d2PU&cVFZ=fsV2WY}<|Gfd)Gj?J zC%7D(`-}P-#b!j56VH4nmD3Z9nh!L`$vIQ?Y&T@@d44aOfabMUAK8~Q@{C*~pv&5D z_-B-tj@l-`320P;0?E!j6Fg*D=EUICtz=og$H+K%w7m>e0CXQ)3Q#oy5IumBWj0rW zApu+FAk!96iFK4+nFnWf6&<{$L)L;5)z)4I3~MO!@d0W$%ex3-J8 zmt(#JM2B>kYd)#1>BaBWTh;PpVOuo2?+F6NwpK#gvmfK3zw|mU zXpJ6|jqKZ7I%K9>eF(-Z>owO$1wZzrzG{3aOUQg>-fI18KDO<+U6YGiF0d$=-_o@j zI&H?Oz2s}n7ow8&K!kU0YUcR!uEI5$QDmr7W<*Jj?#~)s56%&S^d|>#CyixH6jyM8 zxX*$Npe1|Y)Jf4hY6N+qs%Jsn5NO*hA$t)t)vnNA0;O!5{MA=98lnBqj zYGqZNAzk1Qwx}C)kN~Idhyu@c3}clwnyaj!m(lI%1Jo@WHE$VBU58xzp6l3&j9W0d zly<5fCa4%}#9`*Xf@`!YeV2pbs2K{>yrrlz75la{$K0~G&ESm7cr*rRV3>7eis>>K#;@D17c3Yu zzFxL9+K{xjt^y#c5~`I6`4j5*|B$jQMpoY%8y)w1!AAoD=SmiN=bg1et*B*R1%?Ec6WPgVL4_OIEJ%As%2@ALYm~wkKzx#DE>h^@@{j zJWpmIt75!cAcL;h8z%U%7Xb;S3pAm5*(ODD4_%yB>a@BogVh|Pmdf^J(XBJh zW^-Ad4_O`62Z5N}t$)u>dOAPzdoq+M*>+)_ud=(nF$jLyK9&=KH2%=*Bd6Zf&qAf5 zy8(%38~n1r1*%dUhA_1)i`Ylg-kC+8xfac#R=@yICu_)ra}oTYZ*&htv)2jB;X$2{ zsp}xWwNpBb)3qEHups+O2jk2fj$Es@f&NniX}hpS?uT+gnF%_AOfPd3{2;$88zt;_ z)J>+aN1iL&Wb2r;09{ECDmkw_I&xp%!8TxJuH1Y30b{u; z^Rroz<0k-g3dJ#b&hM6D+aHAmga zMr8(dKoOYzJ3-2P)wt*w-BAmYxycY^;2d*}@NEj#;3EhKc*bz%d`#J??2j`QtYZgP zW)+%RG?$qUL%CwXD7C#P0+pid7B8))z)qC%iaPI+&8iD09#1J&ahG8%z*w1&{iNfs;k*$z;5yw*J88c959AuT#FJvb&Q$L)ptW-V9?={PC@PZxYfL+mH_YfS-)f$_>K&9;9 z+Fm`dCvyx)=9Htn$kTYPvTMPQYy^vuQO zIacNt3U?;><>UxKfH6XoT8bGMCxjBK=_m*kVuD1DI_weQAGyZ7bE1t-!M%bi1CRxx zvjii?;3EhMUTEH&y0YgC7?5laD%7med&|K)uiaSaD?t;V@Bg%1bA0NFGmcHx!7yYV zcLzUm0vI^w|I6OJ<66=*T>%~kK6AiF!e9yr3?v*RYzD$8aKXUE#AgD`03Q!M{q^cU zyWXnG$V=_LPrqkNM}0Z9tMU>VYsHGltZII#GLM{z1t#(n)p0U8<51Cqc@lZaQ5hQ! z8W5N(@~3~365Dw~+BjcP#|leL``wEZ*MH6j(Za})7_y}tiM7O;B9a`cDn>v4pX{fP z2$FeH=mPKoJf|yiHIE9nd`I-dHb|$|BS+!dDj3|2yLE!Z`go?cAqk}Vo$talX4xFx z+fzq=*9L&4O4`_r`WIu)PAEU-1SvFjcVJ=d`Kde$0pYkseImeD!K*Kt?AK2w@dAh6ap!j=*@exrgdWGaNNpKt&njv=^=7oKkMhsdMxgFL{--Z(&`(|$yK@{{KE3jC}g5+_G1s@3Pa^g^$1`e2?!E^NTPvXOqZ zNX57TpLY92uRXhduXxCQUVkD^Pks<)&s2VHON%Lw=> zFBjeA#PLX=93I`*qQ{=Fb52AE&RJn+@6P+>OunNA4oE~NCP+2g?18j*lR~PIZ18Vy>TDm zLa@kOib+~hWsWgL0H=?Bhus5VK!SK6V)6)nhfp93z~k(tvekuVUbP9}V){9Rob9`R zz$?c#oe`$|Uxkq9hvF*F67>Seodl!pcfgOjk+`3F9GW7+~pYZ{F8^0`-B-mP+hs$vr0Y6|Slm})&E(oLAaC#1X-Q88{>pOS)-bUT;WLMC z@ty%sa%)&8>5jZ}cZx#A@I_gkn zJomMkmxH=1RbOp?>!?U&h!zkAd=|K<001I0c~2q7$+;qGB39rB47GPxv;+(g0d_7L z;l#~%N3=|O&go-;hEq}QpMNx?q(YQy7W<>1dT=_9JmDh72Hi&a_n3c$Q zb(|1MijWgsfFPg1Z-{iwF+$VZxXmUxezqurq_hB|6@_7>Uy6B1pLs+4Q{%?J@tXpk zR$|rnyk&kSLZ{xiFYw#?4!?E~N5Ieb0G!0M#_62Be0eXH-(zzI9s{;)8#<*s+2G`9n-x-?21CZo9z9eyEkcam*EZqxPV?2XRdQV)fqKsCbgl3l;90o(2>dZbm2eycspONKA7CfP7@JuKX8uXJ zfJT0o6R^jQO_=x9Vu6z3-du#hV7%mcteXskgegAB;RZeCKGFtKYh;@AT?9;G_q-l) z8hO?e*P73(HU|7Sc4PvPvj$ddS}}yYltTbgjp!ISiV-5wwgs^wiCT{&b?U;aKYWyS z1mLW3Kl0Crj`2gjtaSj8tzOm!$&)ni9->H*41j-R({?j3=FM0tIuQUoF>cBCkyzzn zV-x-#L9)+xCg%uDeV;lbMX_RQx3)3^es1V{3;1{0RaHAScJo(Kt|#J z?EaS^W#l9xk%)>*&e(OU`9X`wf^k2CKNE>CXo+}E4cjHBarT@5!}9x7PcS+poJBOqko}D2t77r(jlprxX zfzLD92?xV2I67k^BDEekfZm?4-kd%4d+inptJo%OQaa9#1yitrM2ePo^hE@Pd@0IE zWwX02TUVj>_H(I z)nv9=V7J^}&Qz3TDU7pSVDQa=R2S9HnPis$6B-@%H*eY*r<54j5M9%!z_|1Y} zI{{%usXzo2*bRArY$$Zi%S0J~6VD9}knkPON{)=?Z(-y-%^Ae!bR^Rmn8mz0;i<0V z*iz*f00erNKGw(JXWy(|HRfH{kp=YylU|9oEr9f!1I2RfZ_D|9yV^T*pX8tsH1m?J z1T!{OdA=w>E{mEW4Zz+>%Ou09#AQwZHU~>NShd|=yYosQYmcKM$DN%aYOQkCyIziJ zZfr6)UMl)1EAFpIPT7153Vet>8+C=!boavNUVmqPZ%&L2@TF>0_nQG8TV1TNw)&bv zf+WjrJ`H|}npM4+TR~D39(_+yQ1Jc~vY^vBy(+++Abv#C=k6n<`8v_;7Mn&;STdhT#;Q!qcvg zC)z6qMH*HOE%GDN9ln326+*{F(fU~X->Dn=|%boMe? zMwWsMhBM-vNlzwMo@WF!M<#yfwW`VJ+apIa?RY+tK$5YLIp|#{uyCLvcYjtH@{ay| z>OE|?Kmg@KDlA_f)x1~(wn-opPcD8@m1s(?R&_I3??{9wDcXcAooy4E9eZ{!_h-Fw zkbqZ_(h>alCuCY%jpeIJm5M{r8$Sfl?v5jD$0BbsZ*yTP-{qY}lB=nm>bM&}br}K< zU}C$~if_!J{L}(+=kd^b1kkfQgXBAUv?0k<^bbHEInt~hxEfVVQQqxKJwMA(2_z#->93QC@d2r2HO%vt9M!EvtS zM@iUfH&lF%0xesE1^m)z)HpgWzmDn}{$le5jL5bE%n-=6)qb421g4NXxetpHvWq%M zlolYJ*Ptd}CpyXNEL8kd9H~X}3MpY_td8GB97weop|WH}8I=XL+6D^(%g)&EaBMkL z*E}m#es|U9>KLtlpCe$yBt!YpID5Ed4=8ySo{ouDLd1q>df<}H!rRmHmQb>j|BF9(M zl1kq%uUU=!L@!tXofb1-d=A*nqD^@(P)kHe`xe@g1`MK)r~!bIdcu;iU-xfy^QF#q zzAT9=Ni5vn5eZe>YTP9MMa1L~%uEr$isP$1Th2$79mlid@LjfKO95HO{I;h6Roe5X zU1L1VDZ66pJ+{qp%BOJt?a^_w4wCC4wyrErOYtOaX(l|WS6adw?OivkP; z#JI@MQ+=+EAL9$V_Nfm9SdwMnxbFl}NCB*>M8K0FCO z`;P&WSjac}{Iuqs+!BXlelX@$z$M|z1psp_^U+e}nSp-scZ`R%fnX>Cdj+WyX_!;; zQMMDzJQr|UyVivWX4W=De3Sq(7+^ZK#oEX85oPudIA+$L`;ciBTX4=)lpTu3h{=eG z6q$(r5Ds8K*#Y>7{X4-=KdgCxCJIzpjA+<+4{X!`AYc?65uAwMffiJYye$N1-r0eB z%H>k}M)Uq;VE~9cKQ4J1j8*WX(E>Qm+Q6z(186Zi_m=>*c&);asxX!vUF8ZS{_ic9z`{Rbopi=;CY7QGsfkL~4WM5Tbu z(QVphOtP6@gh!%9RE(3kC;L_i36dj~k_ywR?V1-pLtfPw%}U?Z=l!^D1^j@W{e0NH zN+KVXeiHS{m%|VwTRB7k85zRAoiEAguc8A32mt)dFxQcRu%VIxSb(FfgMk~1T@xl+ z;JloAZ)}i;Cjk)PIut;(X5nIj6+^!oU*nOD)AGRP{fQGMM&|dO*OK*Y+O_59RfRyD z|LU3%HL9F;`qHdzbFL0U=oS5_3!oTrg3d%G{jawFY|d?$&?XUDb^m3>cC?!hv_Fl% zQ@oZ>z($~8ZSZTeIoL{DD%Y?N${MMdeF{c=kYUOf!eq`>?o))SbqG#-5xI-8dI?)+7p*qRZ_eUoDZrqK5>Q@!7_BQ4HbE9)rz24%L z3oxH5(h!)Hh|MBLCgg3&aPDWGcRHME-#+0w(w|oyaV9&r4CtFPODP1cL(S&?nc@m_ z2PD{D&h?xbL-$E>1X=TLZLoFMuyX(+M>^tkEA6va5DB47i7B_F%$VQRMCm>m_(5(PkA}cQ+cq`=oGF5TpYA&k!DZ~x`+k{wt(YE zDn@EC$idCZHdP~`(PJHcBy&euhbTv(2d3OBYN)m;*C7eUYu7@(dp;wVpm#EbIkSiv z{OtI%Elkou-{donID0prma#|2`RVJ81?QOUAS=Y;*j9E2RFf;SKFRm~Poz0&&&V9o z3Ak2N7a+zFdL@$l{@sVYA<*)RY>?`q4`i^>_8*^gx%o)F)W9uq?XXK)$3q@}7)A0f8L4>-1`NHB8M zS){fc0R)J$KZf?Z%Si7g!D5$}Q35=}I^=WYHH^XNaXuB}c;z+Nx=4+amXk$FER3Ad zI%1d{nxYF5t_791Kd_5efcY!Ot@147LUEWs5xZUaKM}kAgrXU_9Qj*S*T~Cg(SbY= zup&K)kY?6H#sYwGh)88`?_JLDR3)r14w$eR+nfOKj7&(XY(uK zvrYg5$(EdI4(?9$(N6_o@@S%@SNONIT_GJ}i_jtg3SZPY2sRY82srFfWH;6-|4Ri@ zrAq13Zo$sg8&TYwA5}we^+N5laa8C8Fxg%9MON0+@-?gAXR%?4!hJfgC}+*_j}52={^Q>q&+Y%+$* zIs3)Px|phYR<16maV8JTA6P(s6zy=nt`|`w2A}qpi=J)l{ypcX64UWs(giEvlC~Lh zW3AHBdbWNr?@_=YI{_baD>CT;*4@}3QR)HAJwMP>4|0qdIWR98=17&ybJPg+XnXR? zD`SFqYr|?3nLg)D^pq}s&zOs%qS%lObqgC+p01Qhgk6GE| zj*04&Lu+I7A^>5ufsF*>8b-hY$m_{n_??nqMJKxq^==Rtu?5c&RnK5N-Va+gaR9L0 z^T($KaDzDG(I~rLh;`2QPN~?KE(U$ul!t!{%{+To9L{b@miF62uOC}6i zAc=`uo-F>V*e8;}SLvguRJ0B1q?vGJ^rln?AdDs8kDKLgHz6r;sx-i zR_0su3J!|sqT@}i1F zz#?x<8hwRr9mma~@PJQV4^ZbY0;(2*=ro;*dL%$VBt^8N5&DdsAf{Bd94DuZ0LQ=O z`V=@>!z5up*08o!4_8MB04epW`W^kS20UM`@a3;U+W~$$Arc^4s?t>aVJm~M8tcRS zIYQeA7%%B8@5;j%T%)|+B6%tD|18jPDuabLn+w2Nu_P?cX$}?RpE2N1`p%i%yxJLI zq-0s80zz{{>gmaFuNZ3%Uyhu-hcGHwd4(fP->g?_)&4Z9 z2j(wYU!6xJiS&g`S{IclK$Iuqb3I>hj4sTzId)#ED2ty!n1LWU{mDZxv`ytQK-V`B z3Zl?fYf`WPiRiTA!^nxs`sG7kQQB`UI50$z03OMAc(0cmJn6>yC}h*N^EJ)@_S@4Qm4gcGTsFk3J^F= zuNYZr1ID9obn+(`;wzl;S9yl=a_7p56ck2aj>iL<**C{2I!{#|hDw2`IH{+{Li-eX zi5vm|l|!&s+QorepSC4&exem@eU|(k+oH--wIJtCrmTP|DbU*C46jlL#)^Llp;6dF zx-*aV6_b#qO{xyNGKLf^H38-Zu~qDWpd9-obt1QUcS@2zigW_*a-smp_`jm?CF6Hh zJuVVOE=ZT7>Kg)@tufU~W}s^=QUnD=BU>XXbJx9QH~8g&SS^Dw;r^Z%p8|%2){(}# zjePI|Y!b^^Ev``%!gxqBJ(@a$SsS;HD z&?^}6JW@9)52*pRK#Dzx@_{EJ9qbVS1BcP|wqY~+BpS+`L z+_${~?J4k^8T@yANB=9#wAVIe&dw#o=0**tckl1t|2_h81mqieR&w2l;|2usN9Kv- zbasv_vc{2$GG2K&vbHHqkb@)Va+Xp8Dkh!tItqlo?>_bylDq%`CrkEqzbj|HVsC&$ z#0LyWlGW&1#3xVd&(VGYA7h7na-{NxNVW=PvNAvel$<+)By#f|xodv{KVtzjNtgbP z43o)|!@lzo*%l!By8}P=1YGzD^Pr;ET&tB(D40UOmGNKsE?=k*+EpPS?X!$I$yc#U zWzGdd_7vuYxTABv($8Pt{kwzTmO=cvxa2vM0>7$!c~{#%?LJtyJ)oi$Or12uF^Q<< zT}Yj(b2--$;7dQrpeo$#d*Uob2pq3_i@c}-u94H>^h97JuUF*?fv+e;G^2n=6s1ja znTceu>l}c<@%yA8i8B|qaJD&!SU)&@6_ror)`3g5GI>tbp(&-8?-Mm}o-^{7zDr>k z6ClEFQuS+Yjj2D)YsMu7TOv+iL^fq(sZ1Vehc{;^Ad$Dd14_9y#V#a!&!IpdCL&h3 zODUmO9BO~H<`pQBJxAWiVE#zAHo#x)0X#krAyFCYXXJ(DTYc3x`0X1`dw%2|s#4Fs zC;u6D;;d9`I`{zdOaX|6g2BrlaT=VPlQdRjA`up6CFfxANz?;dc^muOMDL;pa-@O~ z`9iq~`&TQ>cE^k)q7fO8EOR6l=WVPwbZznPd^l8q=SMCbSSmjAZxJt0<*2K9nQA|@ z)h1_>s_3mf+p>2LIW?z3srsI&_|t!~sgp}Y6Qbpw1P-A1KJ6y8TC>JwHt$LDR7@rJ z+yhOZD@`IoHmBO)lqhq9I3r~I$U8pf!1jj9_LQ_wo>0ZSwOKvnL++Ek*nXkz<1L?W z@Y^@+a-1CUtDNJ$mcRE-7QZMAa~JhF09u}fB6-w%3#Ug}Poy#Z^m8avB74}rBK@)l8Pf;TYRNpuqkp{U}lu^yk+*t^M zV1u{kkUK}DX#0QV21#bxG&-&T1L4&OSq;q7u0?=cp$VWBh;}kDZIMOgnIMP4zHFC^HP#>rO z{DZ1f()A@7`3Aok6Z!tm&Jh4C91v-d>~$u~u~SCwPlXFR^0e5uy-c172=Df{Sx^pI z7lo;kROWD8B6z;KP4Bs|Hyfj0Knl8 z9MsI44mdl-HS%l-f+$xJQw4n5x#PS=F47hXQDzhc)w;F{h&;8U^5Oh#HF1oa{gtCf z(N&%?dJWlHv6X#{y$II5tw-Y~{UGI2Eg(aZ%oVx0@|>%FAWu#KBK6z)!VUqTDqw3y zWQ|;$&dE3Ujhe^jTrXNO!5j{`Va15v(JRs&xyz%LRkQ*IZBtNXj4F}e*)usc+dHsfPFKXC>Xie+^k*Xtq(B5idK8&f ztEM?Cr$Wi?0?&~gllI%@0Bl4koSu6CuKzV*KQ?%a+#F3tPA55z=8{Doidhtl*v3`0 zVe&iR0|weY3fwF9b@pA7D|Y3J%W2#obZtpPHX$UU!)vpsC(jXm<=h$!+ScS_1f zT-cUgn$6tW?N$|r8v9lc;XLnEXSGZq}8WI_C%<@rkA{G{z!NdYTfWeSv z-bnGzap1fp$+3S7aMl6O_8~{IRbSMJQCi@f6qfsBd-F;!&+%M2E#Os+Dvo2KtXvK= zZ)xBl$hZJVkwdRg<8F)rnd90>h)6-t0dklMj^tQHpTMH(^hN)oSk8?EjrfV&MCA%e z^2)Rko3OqR8crO+@h2&K}*s;$-9Ukw}TT0fN8T*^}VMF$+J>%E@<6+Mjqo z3tCiUfvXbZEI1ccj+iP(hV?Q6@|6n6>Y{u1crjiE$#}_nRk`Gy?dGU}ALoEwdmWJ3I^}$5~+tw2mCBplPRjkq=4g0-ekOGd%mH9 zihGy<03ZNKL_t&^oVuvv6LKAuUQseqoPc~h1%4K5j?CkX&AScJR}8n(cIzCgw*{e< zCOrqJ%JbMax#E2DK1h-((wm|KKp>)WNHuw$OqG}K_MD}@Db`^xu9d@a6kJXeaiR)& zOLd}Z&Fc1wcFYt#iPl7WoVX}f0g9@}5$CMrAGuKWPXexhx^^hGk-`AJ?>-J%Pb-V~ z?{W=B&JeM}ln-;hn662bs}UVA)PMK06rOZ58yUQETpfF7p<}wUuaSCXd-E(#5>VJe zU{kN{1As(z<1VK~?#xR?-PZzF5W%r>{414lwsUau$*++PMJsZjh}MqxEQ*drPL4AK z*ydV}PDDn*kaIMCm7)^SD#yi#045vrjRO!RRg=o40p$D43+c8BIIaC?Gh$(zMkHVo zs>o!dkEi!OF07l9-8S zeCE;OnPI*=#(3l&WGahAvU+4c*vK=UxK?y+jLC)auc9VViLpmKl8>EzcD4!tInPOC z>ELTo6{4_W!|a4=z@FHRvUX14-*(?wyeJ~LazM0uaFSFAMJql)2|+u1f8EuXkn_oUKvNW0Au9@Q*p`BwSDf*A zH=qCE=PwoDREmBStRZJo7?tfuB6d+OsdT2V>qBFOxkP zy#-Ji#MuQ_`JPHSk|1WH)EhvErm#>B%m43U?v?gbu94U$C(zU-hV97;!#QrIw?MI8 z?03gl16ZKTQP~Pmc_mGyPq{{c0$G>CsqPCJx&Kqw<}LT`uiZH!3sJFu&VpVkIwHAo z3`kGA*;};ld8=;>aUUP|0W9oD1cgLV5-QQyQ)BDCfWtW2@9CH{ks|QmNAe=&oOhbF zAj)#$59hnGai7v6>XAe8Y}Jd}!cP5P6#%u>_sFzBTJBK0?m%Dr0Rckwl$2hbH(Pnw zHF><^OMs9_oN`c6od6Ku%U4w*%d{KOByS@{d}G!hCBPi1`UTj>c@p#>+EkRkyk~GF z@)N>B`>J77Ct&w=%8*GIm>4FBxf?J{(w_`7Z=BvC{p@PLc5|qVQOKSMniG!U07n3Y zt?rVSv21L~A|`)SOPH(u2Iia@raO{Tsoww9*IA5YE+k3>IMXL0&Y5#ibvd%#VD}h{eAqA|fqY@~>{--D?j)O@y@}mEKi7L{ z?##HSAEIs!Su||DDKz6ujhP5jKCv2g`#wNGAgxvNdiS1B^Q(`4sYcvA$c6ijf}ioy zM?R=BK725nLoRx9W!qfaazvO;cLHO`>7}(6+a@FytmJwd8R5gY+LmZAjH5_l97g#BqRr&sd#oAy-k69eU4ZK<-6ilM`}(CvY&h5o5i34uBwE$(yY> z^Il(G`Fk7YIZXTMW-1P;6Tk>L%gb%!%oP*JZ>^qzXuE`Ho84G*h#uQgJmBzaj$>x4 zz>aa2BUJby(o-OVP|FP}z`3%K$jw0Gzb)D)KR`iIHBENrX!$qg`!=wPRz?brjB(!8 zXfLCFX(tlnUXer117Zsds5=!|c*l5O-D4E|5GQ^IsP!U6{v>CBio~jYRYgoLML?{N zBgtV0e7A!#jJpV0^{hygk9Te=Dc#uf?Y|U)74S203|1b2!5%v!Dp9V@Xn@XDK8k}k za3jg(Q3J?H02co-QjIepcQ91O?)*L4{m9Amqiw2OuWhPkIYtwSO=5}0I`6~6hK%tJ z*-HMwCRC9C35IbqTFj}sfw|W&5(y^!CxIVliG7-%>iLH4I3bGG0S1kL06KD{g-i|= zl>n<10-`d{m?JYtlruQlk{q(Xi~Quy-jO%vhd3zx^HXt*WKvrckTvUc<>UGCLbg+g z;*ntaEOVkrNQ4O#lV`6y%RP~7ML!BO>?afqaK4;BumkX zYEqSDu^z)-n+yG3c`HV2@g6@Kg^@CudooJwNL`5j)xTC0ue8f0&wkBgXKO#=7SoFa$lZgCSxK42&1zj=^ zW+o3?$rDt@=-t;S8bJheD$7iJ0#2N)aaJwKPAy(zCMv6d!qu~_L-$rq%JF(zguF86 zPExhUi{b%jD}@>}ecbsS60T^K%~mQ6d(T$Q%howt(isA54U!fGo6 z$+`T?p9drNj)^i@HqlCib830}_ex%&(#E@Mj5FgT0{|mZmAr`L^vGh&GXQigL2@W90P*mV_rD~QZ$=4*XAZC!F=-ESeK;cU6Q}Ps(uv>=gi4O4T^C1 zkDN@x_GkT73IR#2_KO<(cgfAi`4zD6jr>c6?AvA{imj+Ph>8Gb)Ic_~z(}BSJqeG6v{;b+9y88+ zbYTK{#*IZ(58!2>*oysjq8tSv?}}E8D|U)OsoW#YVDTdAk-3v2BxhpxzRTF{fAJ?n zR_@*2PnDHZIRF)Tn{=Zvfiy~P8g&BXT8qZ>6$A7(xs${6eKf)xwU62BMdRKy;YcWQ z%WOLpZ7A0l#Uq74Dum5=tyThBr`jmWP;`)}Qb7RFC0&_!{(wUk9rmQG*)d!F9(zDE z^no+o6{*U-A_U~K5MAR&VkO&goSrQYTlFDVedQMsY-?)PW>&}X_~r zP753#&`4{ zh#sebAQ_XHkBFLcKuVO{t9Dd$WZn268na{Fwue(U-D1=lWC8~L{$uH=QSJ_W2=ng*>iJP zvJzqrga+Q*bSg(gHb81rf38ZvoCpaQz)3`_8e=cUS~MkJ40I6=Wy@@5WZ~=_@7#-8 zkvDx?J5&Mdhn$EI^v3Y4P5NkUuy=BsQ%(FE)75A5BQG>N*X=VC@mmKinCh4OmVH}D zFvWw+N|sxdTc4N*g(OH5BHDZRT;AT^wuAE}?VCe=HE-4v;*Q90v{$OeD+&7(V|RDY zQSd{`NaQ{6v!2PI)|M-j+bnQN{9tB^XbNrA|5j<(E z|6wBKk?bd1b!K^xsDhMvd{+~x4#PD76$YPNAsNX1dZ^zs6wU>^Ru*l-W|*`HQ1l2a zNT91yRIklX{vLZ4$*JTdg(-%(vjIj0d|bCW7wH$ElgktdvJK45|Cw(;3|&5&O=&OU z@~$x_!C1iL6wJ{U0nw3icoOC8RujN3XTml`xfn8MBEn~@{yn-c>dI~ueW^YKuE#kv z?tUllgOrfuM1!Q#UA|$LJ#&Nr+?cid6SK#TT~nIO8JV5U_`4tD%I_f;9H(($+j81K zk)QH=bFxcL-PP}>?=uR1fP_DwQrty;h^&ZOrT0j25<+GlAO9pOS0JRa+L}QItwrR} z8Z@7XBPB*2_-y|<{{rg}od0c-MQOlb_TwJeGlyl#4*`awY{0o$baH3F590+$J`7NF z2gGa?}O#1OkX9M z+#ush4p4E6lSg))B-6H+4T)yWk&k&du8DSR_b}!bPkZ{wOrJ4*HmahJ1XzuzEMO(+ zV_ zkCibz`!4Vk5myflkUz7{s#hQ-f-}w}%#q?sWRN;E!#%&1y=>WkUHsX7n>Ylv`Er%02M_F+}+0O!pFK#pNz${MCa z8Z83FBy5CyVy{uaFNG_!5d_HvgLXWW@cJvAPkCnW43qQ4uFNB+YZ1t^afFQ9m;p(r zzW|_Jd;UfiZ_Z3aj%J8Uo<&hWTo5#XUbO>&z&7RKNGj37(R8C9b`#4hf zkWbDgbA3lZ*qJR{v!rHspWFMXEJgqjQ)_Wo8xb*MBBHKDy`pacKu`8Wx{yZ||0BK~ zSn)ydM5?JRHZ*^7)6^gZl}MU>nf}k2yPhM;w08VX+D4xMTX z_FPumD2%Dd_frUfwP~xC$Q@A2t&%^9)3oH$c`WlWyKX*eLj`~x!bmYf2c=oNKv z3LLJ8Nff-xA*!53{E#xh*A~nm8Y(}rWk3}fPk#b*2xCZO=7W=Ii!$>6QC=e3S5Mg( zou^k^Pwv$IwrbULok(T^xw6$sU1hQsydqO0}#bH+G`62 zo3zzHA=-)};(2_52noTg$djaDa-;FSTN9)22~6LuSLeI>q0-1dI~0XY^HH{D83Vtw zj@u*RtN~;}yAVm~5>eu>$ny&PT42oLAx}C2hy&EwRk_czb;LbQ=+hhB0lHFeVXq|V zsskgVGDs|&5q!cTnQ=TMT#+C7+MHTMZC~^c5h63$S19ta*ecFtragDx!AcdGV0Q9h z7R8;6f*ErhWEcCi02hWx_5h{;#yn;d?J)xM9Q%w^LHeG2=Za!*>>HWR;sxZ#en`rD z7BvJYo{^0!0&=ykIW|QsoW*Q`&h9xKy&roNEwe$z7VVrl0}@H+2rKp}0_F#RXe)nH zqo@obs+Bi&jP~t#y>-d{9J#1UUKJ|EEp-s=TXBb|NS{|L_C1Fh!LL;Ukthh(#+^SE zamk;WuMxkig4!B42S}nKtRIz{KksLb*@JeA1`$PLgVb2}3g(QBicwPbZ#xF=!0&A0 zOolyXDsDVzB_Yh&8a$PABBzS6t{4-?3HeRzu1HO;3~OY7y^`ydwmgQNk4a6 z9)N@-v*L~?kD}}K6DL3ZH_|pBWI>x@&G^&SYn1P$N)fE&{>=ZoTGUu8=qI8^I`q-Y=8)4u6!&T{B=d@aI$v_JBvb!#iw-TBE?8DhlxQ^fha(omJZRZ3i3Tm{Oe*l=$HlkPl8BU2J ze;dD1@H2=yD-R?BRQ)y+0h(Becey2?(KFQQclSgFM3Wq2RchJM zm!0=eEhQ=@2lfh|K4p&+AVy}8586M27Xerh78i*d7|KnuFL`Uu{%qj^Hx3i9le^ev z@@f{Wg@i%wjQA?^C%Qq_0Cz7ZS-GEUY+;aQ;M`WDgz7VQU#D=wxNy8AxAueWQzs}f zce1Ye*fu+0gJ(Vx*vqGJ@TwbE?F3OIql&UBdHpDX z{OX-O&43@@Dlh_=h$$dbu;pEp$Y@?(Og(X|8GA7QiglzAkXZJvFO-hIi2g$d6JLZ{j6hKHAE=K=!85^ z{-a7c$l_}5L`?FAWJGe}*>#G&L{-L0wcsm1fKPCdP2tD(A%4JFbtYR^z$Xgk;8(U@ zkq+5hHi`H0`ap*)t7zyh2R{RTB0dtQ16Xn>2|uggP9Htf7?D&(bR=rv2!!QoVH+UK zi@yJYGqd0q0F*~bxoI_l&OkL-p5^!g&78(yvN4_B;Exz2-Ph}S$ez6dhmre|f%ONQ ze(Hc)QjbbSj@^XY)QJu50>F{}e(JSHTi$6qukN#oMY&b-WaUi5YWw8GY*zsutHlx3 zXYRg^+->^@B701`DC*&8IdRVMEP4^yle#(5yCd`16X25~xqB1LS^t0npFm0B%Q$3& z8(0HUO2SzrC#XKi{PvLWH;bQ(6}`=a7ma<8b3geh98oTkJV z0ZKmg?wNeA9J7e5N+z|1vgk+j3*^lS@)NMNHh@0a+TSTRB3JVz?ZI!l_ViHf8SpzE z@uX-#>G;`kGG~S%nJh{&5bb^(`v!rjPSfMDdf>pUNL zC|)52SBe7pYLcsQ2IyDzCrU@Q{*4+#XW{GxQ39G|&#Up_Im49}!OtQ)`w znEn3rnIqumTAHeD2?jT%u#8a7iw4_%Ff65}oViFPny~vQmp9NhE=MZl?8yCa zhk>uMRDdfi7H!JWRVSdbR1GpicV99}B{|MeWJ=_zSeq=88a-xZoD zTCn)#7~Ag|JEYzy$cEVw38`|2S9x@b&zF>uvw3yicwjD?ZQmAp507j&jl*KOg9x z95f{-MIdt0{3QZSx>T%Tenc;T571fv0*vh6Jo;Mlqmq76*i0RU`)Ma4&rkA~J-@4e zNCYYJE>fg8q}sk}cgUZ0fZ+QseBlcP80=h*&%FdvZE(akkO$x`aJt;AKLUPGUX>lg zX^(TV5m8ur)Wrdu$FisA`6qOf$4ErjcuN?uZ2vD8A@JH(jiC86`A3zVlrDv9 z0*oA@VqDq2NLS92zYBpd-vIfR3|7HUltOFeScTl_BqnCS8Ap=O8bGFV{Fm}uj$P@v z?*qD2F8$}9#z@+GdLb(B79s+tY$nU`E3K>}mO``?x;I*}kJKA_HrJoTMP^il`x7K#ZfZ z4$ZwHjw>gbgR(JulKEH67xOLptat&D?QOZ?-vFlX86SS;j`(usqAlwYK^K`>cVy)m zKp|locV+h4OvQP> zt4Hq?AigUHhahZMgc|`t&|yVy&a&nlSRlHS!xj1YJNemM#CA#2eoqAxlnKuGc?1d0 z+>(_F_~m_eqKadcp#=!_NfAlR13t$CLFGg(p2J}Sp={iR+^#j@J-KGZ3FU1LK#HtT z9sKGuEi8RaAy3a>jHd}hByu7_PNSFi1dbLQaMWH416U?$OF{tP7AUqT%A_aEq7$mWBno;>qsHX)p2bc5IIX8gbMQ& z!B3h1pjaQ?8ndcy@Jk{v03y=h%*l7s4M=_t$eytP_X2vr!TqdFYuDC^)<^J9%J&^M zfxHMbtY<{HN2IljUo$S&KOZCz5sl@b?$Ndj5c~j<-ac-Ai?1O+BPCY^K_tdb5wFS{ z*|piB8Wb{^VH`x@)&jLKzD>V@q~a%m1ma@6ZH?&GLsY;|Lpb;|)`Yp}ydU5Qov{Xs z(uB9h=~<)zi`HO}0d$bGb61u;I(f(I>Cz-ZlBC6-K>;!*gyCZpvzycde#S!7)dN56 zvwz5*8XGnP#u%!N)$*jYeR79=G{#7h-+dXn=o0ve>^MY*$C2e=WaB#f){51!{{H^@ z2-vnE;^#ccPNXk3hA3I=3OcZQ_U2E-Q?#In#k#_hUBihZm7F`!bd4wxXjE);y(iDy z!Foj!N&X=MIs4K7k;M|}SucL1UHsS+hICu|{28#2TQXK62PDGSq=Is#2Lb@GouwzZSv`1Bc}<|IYQ{-1B* z2t_^$NswLZByZuc-i;q}?*A3E0GypCxgaT`I8jaxa~81xzN_3=UI!=YLS7N$k`w<~ zk?Q_HMgUTMVfdL9vpo`~Ee4h9Ok2G~XME^Yd-*xw2%IWgD6|XsiReUp`3}4G9Jxbv z4+{JgU;2N=m`J0Dy#lVw;3o{F;|e)BeF;g(-dkXtyzi0$7zhBUCPGKt4xqJfMcX(7 z%-Hixk_o{oBx8ljvqzp`lfa0hF~L>FMlvR88V8Fa@6t1&sy!`U5{MjM_PLNEj4fF# zEK9_PF#=3RpOZ}7&*JaR#mIPmU;FwI2&-jV?3kl*@`Xt5c(6QRK!W6t$)KFO>#fnR zy0zhI#Pu~l93n@JAX-z@5sovy2&wfW+EYl9szLq%aR)Rz_st^0qA$cgd0PY=DCVGY zQK#d?L@D|zSSjK!)3&PMXy={5kD zjf(27t|gBeXTWb~K&8e5_?btT;@-wXj*mUV4?a=Khph`b_+Z6o%t#CX03ZNKL_t)H zWjn9Ro>v2CvNR5hGN~44i@NshVW?N<#65kw2=K7*<>XXr8B9i*qj3x(w#cYvK|%yc zrVvFk_PY~nJPS}UaASwHWAE9VYG0#vahh^UcoNdz=Il~gG*rLnr(znA;#6Q6V!ajE|2+eDO= zKnM7#jS#VixEM=g000$jsgMWs@}nZ`A@y(-{Cr>J;-P1#PjbOfA^x4D$jOVCb~ z?wmg|5Xn;+F*yXQ*;(|0ahV9^%vj!CKRF_@i^<~17_9w{7+{Wj%YHtF6lNP>4k$7@ z5~uNX8id8{dlr+qhz#Z=44^!F;=}CX@jcP2zG2@M`z*OwX~UoJUCvC30CBUHDiYoVsIF==*!7WzQ1#gAgm&9 zdDswb{)nGTUKRjo@7caw0O&efozw>C2hgK30mQr$Re#8({-h)!yGs8>i^pOh&(|(e zv1|Do5GOLFoTM#omDCXM1DJBu#y~m;VG-SvIZ5660CyB! zMma0n?kf289)v*{Y#Q<%+DkeM+4JJg-hC^-XV@4orl4|;fs&0-R!(=ORD9%_f9kdDi`q3Z z^<{4y5xo{2-czj*XaDX-aP@IIr{CrdKWhXev1FJgJ0vvfqxGFa6}yykB^(0yA|-GYpbM`Tet!? zP7P{XkiAeBD-#xTnB|I{n^}kkEYV8ZF!7ABvUjFBxtN&=k;Lu2(<=AmB;_L*w0F^6 zmHq-gMK7tKvIxkx9BcbhRSXc=aX7}1Vfo%&g1p+lv+MG937|`|IdiHO7s5k+!BpjZ zkFsZ8)X4!E1JZbM8KOm%z~nou{uQP9K$z1q-XnxTj!CYCY{teB7*Y|3u|w*Ww>Fjv zI5<*jhT<*HI~#k~DhA*TId!D3cZTJPJ>0F<02@_F+VRO7On|i?zLf+T85DTs#nWmqtQ|x@vMO6~ zt%4}gF+##ek`m9znrCE-*sk#*-}ApD`QCW9;K$eS-BMT97Tht%)%@Y<_^*H;nbH8Y zhf^OP!q|k|s?&N$<@he<55=dDym`2YlMd{N9@3i}iChW&xHsq{hKhYKaFSGIPfQpP z2I|MrM)t^vb}-S_5alcYYg;|axrp}U@ff=3R$n=80K#ee6X*bpC)mFHq|*Dy*=NN} z0A5=;YRvT54tY|n5&&YISUYDK>6Rn4Z%LUm=Rr2DR?&{kpKGZXR0rb}K<;_VC%(J{z@8sAm4{fi^{=r|tniN}b{^3YqoKCm_rGI7MTrO)KCh;xM?q3Y$tL&`!hSP$m5pf^eRk zHAfpqy6agMkA;IxSy0vEgcvIDAYszsNt}oQ@bqequrQKsa(~*)DFbk_fyK(H>MO!v zA&>?{;~Wr%B=OC8??_g+W2RJGLY%CH)G*E?SrOR+UkvYW`7G?)c#CdA z>dwXuTW6Ox#{&Y<-%hoowS}CxVyuiK02FO;aB_~;9JQkIR`8W|$>#0XV^`L_@e%QA zOFKr04#|@mAup}{WW6OPdeZPz!J8}3+DW*t#>q3YFHh8qaGVjZ6wzg4J#vLyp4kW> zMW(0@=5v+EsaoY5koVrHUce8)XtRf}` zZm|MG3){UikNyONB0-x^MUy~v=i(F9Dbr@im>lPS+^2~Qki%QahojLZ>=Y=9mVgET zGA5#6Ac_dcPsrDpCu3}^07>`AqCp#zM-ioQmPhH{I08BLR-F?uz56 zMb;E@PTDjkYBKl$?P9;iK&k}UBLTOEZnw`up0wZh5%1N)7i66;R@afay6T(tgTPQv z_&kJLAS0^h)0S=ePXs>;5@R7nlA?eF(6B&&M&(r|J!A8GYy=a+HY+DFFisH};{<5g zl5q7b&V_+;zM?xhJRqPCo-2ZKPxs;ENMbEGVE&2^IE5J*S@dJC+hb0e)u= zP#-Z(V}VF0LJd${8W9A7D^LeFtm~V&XNCV;0NS{=_0&#V{bzJN_lY)_!tj)M?Qll zUdiQ{zQ0Sbz2z-Svwx zl3>Y<9EpE>ehUcx4qWBM0Bv$%95a>;tSl}Jje%qTsRE|e2N1IdiKAAeUomeGa!D~Z{sDOp(sjpf-&oV`(jw2>?9yEt%N;r2P|>uIY;vN9MLZ) z+uQ!qvp2tI2NVWC!f9i|oWK#(I9y;3sDY3O@QI`Dj1v-IodIDHCr~yfKu8LJJWfh} z^4#8xoi!srgj^aU>k_aj`etj$a5gA>q(BBw7!X+MGK-OPK)GWK>|SF$4LRnCklAnTXc*u z1AVq5A>T&x07ZL&pImI(Le}Fzj?TjZS8AVAk9sy$`MoGkJ2^UlLP0n>EQE|xM|{j7 zfEtyDL<*u6^MVL)pd1dzmo;S!l-*lzq8d3)(!XaRTmT=DLlT|<-?QD ziOcoIPaoK*yeQ)OgiYmnh>9^ZcTeSAfs=6-?Oq+x$Vc#xY(u)jnn#}fpLN&UAkLPp zO%YgyO!w@WkM_*eE}UIYsYCJ*R1vNIZH=J+B=Ey-00*a#7diqHYzM`R^&sDLOZozWa#&Rj3g-6MQaybCGW+_0T@+)Epr8o3UGjn zgm-&v(wTvgOBgl>1^Bc_)Fpxz0RF&*BeFn^g-BA{$h-`H8{<0+g!~8j4ogQUw8eO|(I1CFcH}ta zGWEka%U_5{Tc-nf5FK)wYb)m%_MC;^vpeI?*%{Yt_-((d55`(*Zyq=z_J@#}YZ92bX0N~ySh69uN-DPIs^>UX`ro^TEh@|)$5KJeSNlFhAdY;o zJ$(U=PXn_xLRAorJ`n+nV9kwnV{R${8x<_4#PEwf0wAx8@Uw@zw>R|WD8HvLQGH0C zSL>Ru;nVqW{skHBwX^#CAJ_d!;HRt`qY!bV44fnKPAJiuMT)I*vgCo8LI9x2spOqe zqpUh5%A`z2CvwAB0R%}#feL2@U`SRRi2Z|}0~kdqqCyg-!UiBudOB+79Hf160OzXG zj>SHcAO=HY1GN;FdhQS-FkSNJ_4i!kW@-W8_P~|AA z?=GwKjZCbF!hD(^ZEYneju7$lO!gsXGPA{iQzSQ$F4>&^iYyRC_D6#95#1@UAcJcg zCoiJ#cT%`$=jlS1@lzRDH|C=rg+4|0&?d@nTn;y#?DAevsWnG9)|3 zh`p;q9M$?UeTyGJacq?$m)-ON)y*W_h z98h;Z5wrGcD`0aSkOlUxwGcRO`6>&IoCw@8zpbqAFfp8_>OYYmsVw~ijG|bC38AtP zpVTY50)~JA@Bs_}u9}yf0dHh$XO%4?hw!MDRi&t+xdlIcU`OTvnW>(kcxI#K2Kk7r zPZsAZfFRpvGr&(SNF+!GX20f-6pRo6=v`57ZymM27afb#0spax$$HR_-MQnt_Gu4U zpE|I#Df{pca-gHV_&n?X>9Ix{Lg;Kg>K$6ro3p%n>Mr{0-DBzZe**YruMxIq!Jg&% zk{2^rGY$#E=Lk3$xq_?HHAW|cY=%*%@`>cc*#ey$m&K84GY}vVgq4#IZCC}ya#28u z)5&21%DsW4d!2zFhE9eRm2vg}S3gB)94(eCXT|9Q0dgSrNABWWTk;?Z1Xuus3 zSKM3QL{sj^8Hpr4n{#q6fP)buEc%&BLf4Q#fiFkO;qE+tk>sl_z`}F2QB-4rr-%t_ z7Y*x=J{toLo&*%f%I?gWF$SEfUZ098vVYKA=M5mSIdjHFfG<*`oin!Xe&!$rEy#*U zJ{5Y|M9=9O6Z41QATPjQJIwhj0cLdFz505@5?Lin?~p%{Mfp}XKw7W7C1FROkzhG^ z(kDrKRQYP#z{cd#Nwrs7Eq1i|@*aNz_;FsCFh~2u8_YR&(V2-N~f5J1i8$Zr{Q`x}jwO3)n3 zr*GzL_kP6KjrD45LKKe9gxrY0AVjO+!xltJ>_aNSbIqAHAZhFa0TTsy9`fY*t{16) zfBtC%j3XHqQDVdPxXwmu)`Pqzf7A|JDx_)pKg>OM*)4M2?qp&daA25k-W*obF+HRrRmVD`6$CFvuksrSU zh>8e|i3-p}`ywJhn20=Y6$g^Q(;Sc_+k%)C;RlD-v<8Gm!c@saS59x^+UWDXVJhz57A!O=E<`t|IaZ5U4kOKKo{ zdhgnf&`M(<%RrM9{Z6~GmZ&3qZeD%#>0|$w_RWGHwrjEbaM*q<7EDndijxqzOuc8R zIEp~RQBRzbBA3wumb=H0DMSe(FcBZ7zcb>ydp1A^GUi6b9f=JfaQgOIakv~XK*Gl5 zsAh=a~nC9rFVG)X4qzL!Q9uqOU)|e_zFy{KJ*v0cz z))^bJw44?IW$OxoIHZ)B8z<~o?vql0q|8LB#bxm5Wo*M*rx1wxsR<%H{j<$R@r`ld z#LeAT13q*0>NZ-e5R-inB+B0{_Xc%U4$}MsQA7d|id=va$;;xrd+%2E3$+W8 zTuLG&mB|Yz#39{^?DUJQ3oO|LaPuc%v~Yl}dwB_|F}FubM9I!Xkw}PqqOl>LR{KnT z6}6LJ&p?RX>MuYhu(cFjS$mWg zHg8Smy?ay;ksjN8RbfkIEC92Y?8AnS;D5+&%r zEidw!ey<(+3c%aq1J{$P042bFr%cszCh-HubtE#ezteg{JP;e;M{1Xgw*PW8Z`Etd ztA4LojGgZ~=zgT#dA4+e4<&`9$+pSLBy&m@yW=OSL~o=GJFW$Q0v&4%9@xrJd3D{6 zXD{Dl2K+1nMq^`T&Yx86hS|%Ha7-c=GMz;;lAoz`2&0x~!pKFOJHlEwKpNv2`Ym3rYaBgk&6<`D;8iQ~rq#D&8*_UL zQy_F_U-}KK6#V$u>n4XOYST~mQRJeH2%ziC*WCtuPK~V^lc!(nQ&~IhHRhYc6@efc z<_Fn9R*@C$6`3P2_W3FLB1z|6EUDA3PW07IaTWC6b3+XY6)wQ@aT#lJ|| zgv7Bi73)c}RLEWBSx;X>5s?<)I~46nbEF2~>1Qw9e+K+aTuRsDAhBhUA1BA@k?5RI zVnB8-dJB$>W^wK~EuK>+_sLaqepoIkVmC|YR5?OSk5feo6bQ7ZGKh@qqY-JmvV1uP z1axdHC-vqvJe-7_7su!K=GTT=PLAXO7!*Ck;Q=fQ*c{pSMW(g4DMdS;m0Sj?kkjRS zNk1GhJ2EF2B~qiJO~H)05p@6`_p0X5fU$j%#`KEJc%FzHdzD|*W=`HSfj4^wqKXs{ zKmX1=+50K_yR#SIN2Yy;lf8=Y5g2ia}bP9J>a*BtiKUfFQckHX!*l6U5#)Jy9PA zuW-d2dah^~@L~9VCkg@-WRB!?NuDAlK#xq=@<6^N4+4=Rpy%KL00r~_oQt!`_B7fX$o#7b zSPT7XenhI2gkyE+wnaQ}BLu^onmco9Zp>-qHEYb+%Uz}!H~x^pF0cXD(x{|s%92|}MczCbHW5IJ^B7oHwAf_jzGVkN! zm}WMK>Z`>q(r^YSa3MdMAdC75&`aBmi71#e)soEYbp({wmVkpX}d6>+Lqwdfr1sN}REmKJqVi6|&T=3>*-AmrX*5W5c2sEx+ntN1!Z z2)UpVSXX%q&Td6*spT`^=YfEYLm&kyL}>RjktRuc6r*uz`&ZYJ&0UvYty@IWu;$7BE$wnf`|~`YmFhm2qZH6c1d&= z{B)EhzL2+yn$Z6h+HQ6syd!ZTh6WleAuY5 zR{X;;00+4Vghsiwxn{W9ECK+09K32q3)f;MpOU>rk_ZxDmv;lIoM`q5>MKVik_0y9 z))Hx5gXu7+0o?F001BWNklyLYtfQuR&;OuTy3#J zIOU`iPrais73jrwlcQ$VCXw%F+OqQG&=0^@f6eNh9Kw<(VyfH!_0A!m3V0p!>VGtPAvmzmh zYlS8$2r|YZCyrgN*BFbCICyyr^ByJ#3<00tlgvcwz}ugB6Gm%y7Mytnik_ng!?=ii z0kBBrmH7`0+_NbfSI;HquJgQ$`+A81WR8yoE2v?Yws$+ zZ0AyrJBn|vZ4q@~m zh3i!}lNfW*`RsZ$z9e;y&;45Ij1AdB0{}$j^6O`BHRpV_gN!eg@akfh!f^da%~%7J zkLp-iXSPTH{1nwyo|S8;JL)NrUw*rnP8zxQ?rRmO3Ah|pm|`01jXxr@Teo*_i2v1| z9pL9?oR!Vt947gbBVRf2boYRL+Wka;Bw13Q2+zlUDu69FBT7{Wv;FPGHv?e-U{lBp zqv9Au+t`)GD0d~&)^5yMWUn%`-PFqQ14+O|{*)&a87hqNJ*q&vxFQ*nt=lsW!xH7z zNb8gYp!|vrv74_^wB|6DI8`1995a06&N9N$e8Und2Q85UtV!7(yJgwC3w|`B0Bm6{Je=|RB52# zNXfXzCq=`@@uq~aCG`Pt=J+yaYgZaYQDpaIv0dP&ktU7dks@*`{ws{-t3D(9%P>%m z-Gatm($;MYZSM(S5t;V)TB} z2KKmC-Pt*+LMR0J2HHw}12nxX&asBO?yTR|NLHSef%kir! z6h(<_?#`cl_ZTQNAZt6hheIW)Vc8-#kr`tIZng-Joq!?dtFjKG#A4++ec$ioUi25x zF>JYF0EfZ)V88NefHjNQT2+!BSIC2-rf@s$Qi33zd9>e#W34pi%8RvK=O6KQQlhd702rTNbAT! zNGChaA?v+bE_0)$tW!883x_s)0v9b9dk6hE)cuArJ(l zEr8IzXZC}P%Jo@$2)5i_TSP@!5*@0tzB_jCN87)_Z}$|A-A@@h5J?igXXImd-*+`e z2E;JY6u6N7v>jUn2u==>dtjgn6BN&oA1q>pJ=s&GV21R`$>gwZk$~@zeMJbOEsjq0 z764SvELsGd7~#_&&YJuw$`c84+7_AO5ml2_=kjzrukN2Wo*4hP@2C3NNYMo;oxDA= z&(PP|7D-EguJT#7*B~cI+Swb%5h&54!VrZWz|lOD@wLr&Y;j?GB23Z6yVfH@$lg`2 zR;o9VO2_Qkf+X^*+Na8Dpn{~5J>R7`@dZ>R1O$j5PlKXDNyQisK+TQ-om5e4OMHzv z^ZGMtfryyBAUuDO!N0-pUGC{0&n3gitH~cdQC_^GcZyiZnQR64Fg9$Akuh5BCQYPT zRnAhi9XSO919YUQc0;k!bdjDUyGlfC&OHF2b2Le#wtUEkl0SivA{x(l)w!qon|BZz zM@*7b_AUo8GMDl`NC`*3d*9YbJ94eD6oq2!2+wGQ0iX~g^M4j`vlp_RVh4qHXN4jv zhkf5^HLWB@xiDT77{yqst3{WsG)qz?sR2;r3s92ZN9Eg*u@l+IlLPdgL>ur!6i1G1 z0~W?pggH7VBYo*zi!_ToBi-^ZfZ06dby;myxKxXjkwUHz6a{$*fa{P|q|dnVE9QwW z`R%y9Z}96)%d@{H?Wu$mIeiL4KlT{oW|)9a^{Iu%36P5z6lXx@WRP+#z{%!j8}}_- zfJVB>d+~CA#%oK3b54OFDKUG|I5UPzvLl5mKvAVf9)7hmx0rms0_bIIv443~5zMQ{ z>ukj!NumomshLxskRP@Jyw0K;wgkM~`)q%v=abCIXQI3oOgLTv@ewPJ$Y>< z^wuXrAu6MUuxC-qQ=lPok>5fVdWA0mKT#rerc&)mfw8XqD6W~Y@5si+z*?P+l#vU* zgVK`&J@_5lr6^5#m7C|ON8o$R0~?n*5gAg7C{Y3lsR|Jy`Pv*J5|jZcnP2wz4Svsp zTkr0q4Q$h7eS(uZYp?evs^V0p&H-Uhn6<3QR7lkXB;vd`oFbEFw*4Z{Dn%MSoxc zWU6__D_fMGb8awVB6lQFhQjkdJQ^8LK9ftzkFg>{w8agJ-elT(o#&J`z#TBU&Vfxo%HfoXLn-{-nXa-Nhv#9^MBYrLPlAzmryh#jga$V zZCBxx<%7s!KoWQ!?Mc)jx+JTHps{l&8L2=thR2WRi53yFQSj)G*gvjFzTJLVe&Q;} zDCHpHQ%PF^GvnhpLtqaGMn2X&`Izt0E>ZEW!zWa^%GpwQvOP-M0IkD7kSB6x=8saO z-+&ECCgqYv9hh;He)Fm|sU`}*H~5Xr`UBUJr}9djPj&DXh{Z*s6@6jEfZCq`4f9i7 zb(Cc|E7AlxgyH%=+35T8{0MMRq83bWHvzH zRbu8PPyN=noar2VBabR}0eZkw zzkd`LeuH0SYM#3WQ&r*g3DVS6FF6)@2O#L|Kp(jX44RaLMV$dR`GK)nyucm1e)@El z-7{r@VT(@Ou-DKc_2FbW1EtoSBS)}H`q|Y7pra5WW51e{nQa$m`LBM;mB4DpCw?n- z=ij0uhZ7)TY_mNnNp+xtD>=}%;Kuv{MDNm6z(P*-@v1J-BboFpQmpntE?fm7vZxX> z`NZn?jAZMn2{ocwyMO)nNo6W_ek~WuHzR;(v%^rUdCz}AO#zd8;sQ6cY_8a_0%y9p;!gczy691mj z?tgmyjuQOXGvm)oDV_4tlRU68g$QyljPjHFcpMFR5zdd4V$mQd7A7XjX>w@Zgke9U zMT-qrPUEPL`udf?Kx7UC+ZRr+-??@Ng)W>dSzMvi(-qAkpqBZkl?WUOO@1z$?D;;0 zSkxDiqN>fb&s$Y&uaK5dNU`#K+L7-frHGuUsxlu6QK&YG(2!ZV zwOQ%<*nT-a#2P^p(Y0ffx1*%c4cSCun==j&ll%1k zrJv@XRAoPyMMDZx?JBR-_F3OVfC?oPU9eG78|P4QDl_&n`WEI_uMh8$~5o>5bX;0yjU>A#FjBGzp*2_fm^Onkg*u*OUYjspHNNlgy8Gs4`bd zMv+pt$mr9-FQ=R51QdA;IvpLNHni$>2B34K?j!})7} z8}a|MpT!ewL^Wwo`fuBaB$3LI0sdx{xKkbwXoWTU#$MSSP%zIGb>?gg0UsbC^NXT( zzfc=-AUCtY_K^7G*hOp7Dj6RE0?;$|_7=*WssI%gwyIfxPcdG%j^au13p>(L2A8tm z_NApg<5hKK66o|v7Mo;)LB>$Ns>GR=KAM1~eJjDn9PEw3hO?zH}W1)*Jrzje51;E^8p-HhFZ^Ze)+!na_E3y zsk`6tDex1a(bp{&IUk)hasT`$;?sF6jwPLO5{j2#VmS;@frxwCgsL)2CDMo?(wi{| zfJp{oEGp7C2W-j&DAmX880jvZyJ{TY*UgWBxwZLKq{G4IyNd+^$ z{HC!b*P1J;RocPU`7h}kCnfQ>)&Tz{(gcS5WG|JYje?As{#9mzf3-f0t2b<1DFbX( zkVEpc-9c5gZ5sNFtjYNuzbj=yTDIr$*8ZLXKeD8#iiCtg8blKV?J*J!td@pL)H5~` zBrVtE0zOU(^T9BoJ&>wS7DH0dfW?snWf&)5iW9KVfg%YeFXo+XFpyxUfL8wRY~L080zh(voT_$+zfB|wcwww#_Ty5 zRgTA;agJ&Nk|9=@I+a6V0Z@5Ij!b(}ohhmz%~?+h%dm6nR}`WB)EA15=nrYMemK*V zna_^fr+rVK5dwCjuRC9I+uOcieA%RTe#$$Fx{b3oR8+H!rRQkBpg|;v00Q*veG`4I zg86aYjG4$*5X4Uduj3xa^pCQDFzK6qMRJuwu+2pKfW19_c`en|5qSuLz)HT>0q3{D z&=cT?afqle6ZtaCL&LE_`=y*z0Ql@Zsw{G43*aP0axQXmp5xy3pwWaYRcx39 zxl|>e0S2VlM|H#J>;g3|CU-UoJ^S3h!}n5TVtnPNfXbDF;0P2sSzZNlNr*t+7?W%aK_NDI^j7A$Fug?|78NfAt6WDx8pBu(4k{LF8wB_%o;W=aicq z@5P?K&tKg;TWk~&QPhFpJBg)2?0c<9M5yq_Rt`l;)Dh9tj+gfWJz!>Ahd%`u$lTR? zFtdLcC@Zq@5y)5<k&D#-6FZBtEPLut?e zOs+w>vFIIk{9!FU9-7}~ho5g;VrYRm5E;Kg10GLJI{wnR`UkTN#8 z+c%{+Mh%5$kwd8zWdE6Gu@Moa+#FC6+=%8#;XN`5FcGhuo+N0>2`|UBn3rTLfaJH^ z-@6BY4ruw0F+x*p@-EpKYXz2&oP*-zRI70&5}F3r z2^Pw6+c$;ZS-MElgs5I~PXKD7b~(MPXJafT7^}x%?(!noHGP|5th^-h%dGf?hT1=c z_#iN6udBJbHRqC7>~J{04!m7xOZ!!J>&?>U+6z{J9yaQkSHNbCSUXgV_8pIT(?yhn zZ}s5!Ny?^Y|9f`A%cd!P$!*jlAW3pp-HOG<78y6HgFVioHBx`s{MKEN9kaKC%{jcv?O_s#KA6{0m+#Qvkk6%0!c{p*E{eP z3zg5yW=P?*h>-)q_H`ITsure@wrrrZ<-&onqSVzFG4^awq~Tc{Gyqp90KCtfp#G6` zRXJf$h{K;yK+qeb+25;JWN$Vkk5v4MYygvuw!jk++8J$Gka7>oK!uZYCut<-1z z%`r_tQ2vsgIOswC+&YjZAWvCC*1+Ex1XV!tAtW>TUXIb2WBkU*nwE#0iDYJNarJx2 zS!q9iH**%~OdCAcYsaJm_-bVBuBb$$NO42(C>1Jzr49JV@8g^y2wpN4VVq#J*S!XhH+!d(wkfuH-0 zY{KP`ux}H^Vg8q*{JJt}D*J5eBx{)@&YBdgEeX#hq&Y}=A<0@&f~dwg-R&3SFcTT1 z!b@J$ej=OoC6@EyJULVjxjnLrv3%9M4c4j%!#Gt5P{soZL#!wfY-0C*PRBRNEt*?J zII2KxhFv*4V52sKhkCavRi+(n4P`-VggOM<+LG-mMQ#SCLZkO8g8k zl(Xa)*hRY+?8CbATXW?2NOyi-ecmtG5coOI)>fSyEOItp2)Zx=4&WmP-R0_Z4nPU1^R6nukd5!k ze?6nJq1e4di5v$Yz^?PA@+T)u-&GPOx=>i4@Ielg`_MM6=AehQEe+RZ3u0#MtaXnx; z&arusf0IvE`B}*skJyQgxMWQ8MIIsv^%keC1MC7pG4IxiHKT3jm$D*{XdjxjW)1xv z0MHzZf{_B_q5{&o$Nt+Kku}4SiwY4B$JLRa)e3xa6ewzCE1bBf?;SZ-WP)#0Qz0-o zd+{&(Hy5df@7eRndKtMk*p;f;;dbl>KND!5l<*TMVGzn{87qhEhat*mFl5PAQP5qb zWi~`&coLa;f0qdY7%J1;U!KI~>h(Z-UeCpxUq;qXWj%L6b@nC;XNKBY1Nyxns!L$8LN4w)x zNa7+FQC@reQ?3;OlIwvt64iT$+mp84yLU?M*%*nMjai3ml3gKxwldwFlbLN&WMgDS zv6}MtJJ9zXHZGcSpoQ81YwSs)klbVbY~TNAoH*#KL*dz>JfC!t&FJrvv{iy?2b-0u z+4UN#o}Ik>_q)Ll+mb&a_i)IPsT^%&HO`5}oo=*@mBlYQs7I5^H5a7CI*Q3wYB zNJxepO%5YI8%$dpY_$;a`IuZeH5=%k{AjBrwrAx;2mN7a76hQuuK+iOFWME&h{Aw8 zIZU+1QOIY=BQa3lJyu6mSWwHH0IPYzm^oGs%3S94A)XsYMUF9EyQ8Gp@ptmRF%r4W zIJVw?tJ!w>o_m`^Q3}%6J6R*ol79gd?ENYyP9B#Iur`p*cR9G339fbKT?@HE29!baM*&3?YxVEutMQ)-%%FFIoD+ z0GI+T;yF?4hF)P?DOuio*SS>@bx++YZ(B;`&&ri4**#?@d3(6~QnF-|0*NgQ_V01d zX8};aMJ;d`6j2QZ#n8Xqd5dtHn~*a{rVd)EOF_wu9X-r(2uik&7$?KvL>bjn4$pW6 zY*cFMhp1Yew$@Mp=BQ-aoYhLkwM)j?N4FaMc8%lgK5DOYdxpkhGqUn4DqqHq9#u~V z;@-IiM|0P-qsGs^F*fW{7C~nPuIN~fPeW&tlgvj)badP4Dr^)$7VKB*vit>#7z@QW z?PPlR6f71WWR1-Mhz(N$B>J{KY!+bc*UD$n+u0-C`a<&i=P$tfImgHH~>_cEIPChL-8Fd*?1TlM=207F4+P~bhZX|G`BdZWQCj>IcqqQ zNuy@TUwz;mH5Hq%If&mDpNoW9IAE$L_aMYrgaIyax7<(^In z66k*n#N9V#&|CF=r;VUZcY%c*;bm?)a_q>LT=^IJYtC#4bJp4|KZ@=JIQ2(V{Ku@1 zI=WuqGbZ%@U+#U_YdCDpToqXo%5MXII1Bdc; z=%L^Q1qLJAL^o(!(ETPmajh&%X3|q(IjmZ(0kz0!GPK=U6ci`mp)9rEYFYqzK!?Am zw9=zWI1WHUZB)S2{E+4qf0q@YlsFjyodJ>oM+k|kF)|WPhe4$=pgjb4RjKHVxiL!3 zHum^HzFPP>6=xsr2)fnrp@UI?KuqP3;Oc$9!*x0yQDy96_xsjX=g*PLvgjyAXJ%aV z*4eC@g8*F)Us=R`Mx~L_c=ZhZHO{f0BfY7TDQ%^IZh-95;yS%Ohx4mVlcTB8bX(laZyUo=(ol#QbH+Y7xGTNn5gDXv@fsQ)WEdx?4jhJUCEVMhg4@LDd@9 z9b-XvV*==h#+N_S7ht9HQ;i)!dWyZ6k*V6dGKB!R@={;4I=cnrusL*CIb%mtj|@`w zgl+ny7s?85k_3SL2_QbRe(kk3j_dmL@9_P2s}FhC=XM4^3y6l1$;q}Tm_T#pkT^=2 zn?kojv<{=Qy)CKL30630pJ`8Y$?4~6c~W(bK)SA0;JVf+a2ATxo~LWlUO{6$LsewN z!J}|0&Rmc|(F!gMY~`eW4nP3(Hf&j=@v80E0%3oR%olJ_LpkeiZG)mLO>=?vc=Ht~ zjm=&j4G7i1e5I#(*O)Fv4I6oThk&~~t8T|3$g8KS6_M4S>C2%JN&+&P(P0rg8tnJ$fMXYiA~`L=*gU7@%#!Ly=02QT|WcQRtMp8CL% zLZbI%XB?bU&Y=+5Me9^Kbb%3K1yuCQ z2!VRhq-TWgT}9&p78DKLqkJG>&LyvsfnsI73|YoIq8cfRz>FT%&58cuWXRh+^3uyY zib^t+4b^gN2@%X!IzI2r`JJED=}Irqcokr_I#$4zzF1Fe zL=IL^H&;Huq;Npa-euRe58bIjx<5J>dxUz^6R@MZ7!$+p=|6C(J`PwLv+)D!JA&-2 zoIPKV*Qm#@^>ZZ;whG|9GGOzix|FeLY;5FXX6L=jFMmAFoce{cg zM5RlK;y9s1W+hu0y%C!;SKLLgn8=DlqI5t3W%d68W3@PL?KCEFW-@kEG$(-O(8O}b>11O*2g=FF z?CHb~6yF*v8Dj+igx&kNZuqoEKMJg%7Xd~T;|TD~4#t{cG1TnGZ z8I!%I4x89K2)JsX^E|ZZ(_5f2);1%>SoQMb z8*&Ic9e-5@22jep^$1)AKjTyLcYU_$@Wp&t@6Y&bK9Fnys#%cjPzU83UBFm4&-6wX zTi8kmT1V)+f*$Y5IFD(^2$CrE!MI%R4CfQGuwA( z36?rLWtad16s^mR0p>XZhsBn~q9_F`U5;vNK9dZaLzKl)2ted4*d95EP?kD4)sfU> zIaLAHxGQr$b3E3J({aj)3>7`On_hA*p>YF0F{<4GVdPj}`FAA-`e5EW4{4wWC~LMz zudoSM=v)xgjm8S;gL*%dEguX00fS{BnT1?nJ_N#7*hQR`v*qaYh1)fGX`54BdkX34Bjv#2xsAK_`T<#!n0Ev?3sJAnNn=yv=S~37KjN2Ttw=`QsaxGahJadV0$VB_M zz8{T)v8`sU2IReSEUUUO`ke9R)T#bj zy5opHK;9R+@#z;`dk#j64fC72o34r_`zt5kZ0^nW2526=wHJT8Zw3LId2urr& zj8ELMx*w`THrO}H2u=b53dZx$5`Az*1wu&1fgV(=KvNz$9nKh9m1XKsMH%V@H4lv; z&;uSB3Zrx~skXcvV0(>q8lS)=>MK~jFB@L zT2oGh(O6So9G{=fM_q~0$iDr~=Z|b6sP^pq$(&enHr`M`=A8TcH{aDY5wyuZHQOgn z|5poK$I^~u-MA&d{25#YQ-|7Tm$)jg8kX@21!djAJN%fgfm_<=hOPV`Zk z1kkq5XGw}ALpg~3^Sf0&eQI3+T*(nO3IoTU*f8cUulmvvFNwk~$yiSrs~y45qH)~L zoAf||jFS~8DpZ*)2g))ThK;s@wiI?-VQZXVj50BFA1B(jcXMD0@V=lF-9R}o`bg<0 z0QwWvAWO*mvjiEA5Q?B+p6mZ1j=OXNM{A)ptjMIuN2jX*CAjCjT4(lvRoR`H-(A;Nf1aFWJb8W8N*$AL!ysX3te5)YRa1tnn;$~$ z9lcTrv%%L|A0?nW;3Tg>y8@xICrJdIn5w5ev{-;a4k=0SGmo}5tR$wSrE!S79}RvC z+kyxAgR_mBl@4w6Z0aH@1~s>8{`py%&=LVWhNC4jc}9XVFOWaXNX?{JTm zn#t(Cx*$1wjK~w2`RMtd_IGxwj>$iufUEW*=&6}Y1lXl|lrCyMGSj(thg$J$V~_mE zMSwMj{0*`vM@ZDX801VA$dJiO0C$o-bn5%8mKD^PW6yTUup;N5Yvv`OiHvjPKxV1! z`KNvUC)f)HOQ}K=-6&w7<&;`9%CTh$03a%hW@n?%lL-6eAJWv(_cdU0bT=x`0OeSu zQ3i;y;WPOJH0FrH1au`anyP$GFF|GOPp>H7BhHw2yC0Gd7ejy)Op7wssM+$czA-xi z*@or{nSjWg?FBO^pHo$URmdc0X}|3XGL$%Hr@ISkczDiRJxp-SLC%mWv?4>KaFD^w zo-bn%Onv*3HKF!)BVYlFVxfl7Xu9=)hn>dV5)+u(k*<)5Of3BaG09{cZ)!6mw^-BGd9kP+oa(!*I1yDVe zZN~ICy6oD#KhMu+O)kBpav%gStkF*JJF`#Y6I6go{t1f%bZediBvt^eUCMT+Mn(hVRB#1&hl+fR$vrw5d*M2$~ zhA{|+ln!cIr4W-1&jf>6H=~&ay+MhMH#M=@`&?bGQO15i2Ystow)@{0hGq~bl^mf* zMlpl--9uNEbrTG6@vYLK!|8$GdUk-o&iVe_>%Iikr<5I(7J6Dd^=GUI+mLMlZ~osm z-9fFT_L=L?MkTn>5mcUULD%PjPk<@^-#(Xf&zsxbH_sES)Pr*ROfn(BS=I#v8!Ipy zux!l!o&(}NFTvFBWMJw?YHMe&QZiR8h?+XEfJqS~`#?0iGD!`FcRxo?iONw+Yl@jfOtV zpYHgQ@7_Usin!8f8Jpv{ECjSNiyXE3LRl7DjR>c$n@tVQWKatJuA7wNnlL(2_JZ0I z_yo!-y)dhgJFmy>3wVN$E=Wx(Bc)t=x|dgTv1__2>q($;jb~<~ee1vSsxRZ@D>7#P(ow(Tn_Sm6MHz1b zxo73IV0s0BXzlW6HX%p}Kpe3k190!6_Kg#G^>&;bG1dcm>tSw!f-Ds~1`uFj$PWW1 z8zR%nxcFcJ&%F5FA$9n?O8&(Y68sX}_MSyacZy5+W(unqZ?R)A435J3|0jaSlWUuLr9~Uj5O>A_#iD|BimAP!Dcc$W z1LExLw}hT$@X+gwJQu|F{``qEO5oG=;5 zjARtPI3EFvj`(+`TeTgt`{Wc5KZlm|Z|<3EN@)Hou!S~F7q9uG<2T*D`PX&?iIZ_G=tN8=)|>|>U+q*OBN!$;4# z`*%8M+XX*`$pTKWfJ^@KZszCnIibY@r~&DiR2;4#jb0dNK$HiA;(W3p`L59Z?4O6^ zbjVU1NC~ag?-OEZYJswM-MaP*jtc3mTscOy3ZK`(3N5P}*uo*0zT?Zh$RD*X zFr$ST6X(^|jxtWV2bhq9%$$*N3^Ou$$DE&j<}1nqPtV~y-JgD@1SF{Gt)P#0_W5Q0 z){@<0hh+S+TwRh%F)RN26>?4Hej9My4SohDX zW42i>(vW22h(x-M5dwb3Fwy0bL`9`Q=qM>dK6tGXdrVPc>QNwJ|xb#L8(BntQaF z0|{EeJ@Zp(qR7d79Ghi5Y`XScIeT|zEq<IqEa-dz&AQT8!H7NQwPd0G zm6SC9&{K_qN>f-2HN^h4Lua#~|DMIRb(69aEFb#;HU;2slM(&|zvq?p6Q5w+(SnYZ z6WGw3M>PaU({<=lC&p0jY5-#>f|8SKG%k6@QepZ+faU?gI&}tu%{he((DMa2fl4N- zp2-2ENrTaH5)7Dw_?NHj)cthfqD}=28LK8Pt<;dNW-Kxg_-ymgYHg1yNAjtLuRNh6 zS3L&+5X_Y)9JIjsRoAp%3i2mAdXi4eZ%uPjV!vW!e%(00AMd(3&G=HRpk*`7>~P77S9A;?$_BlIT< zlu;T-I{DDRnzn4&F-OkCz9?Uivi)A>Vf&51K~88Q_facxgq1nklx&`>4&^C55u9ZC z&^^S?Noq(E3}p+l^VtIy$e3)k*ORqpkOjvo3${IptUpZ_Ps#Z1eNma1iq*Zzp5M}& zY&P}lYztu<0cWdV=Lr0G7LY06dN-=MB*U}?&E7j(CO!@r{sh0fYWuxE4>@w&>T?d% zMS~tGDLs)n$#NX`#Iao&5ND|NX4{H@AXx0^PHUwNY1$)c`v!-bY)?(j9wjK(8Gulz zy<2Ii?^n#cw2<3RrO}6z@c#h}Q~PGkQ}C~D4(99xe4DTV8ci3RwoJgLYVwz9s`EN>@Z+4`I~SvSwlx60 zbVz$sL+JGn8sgMYWQ4#YfMtIuFsWe-Ya}cDC@}OB{HE6Sx4by5&VnEsOdIu)l0uSR z^CAmGZJeF*&I!t*(1o%jh<5hCgNmRP-i-m>DX>DHXh`!wQTi4DN7<%~&h{MCsbiox za>ub9Wx-@16V!D_7K;83SVyNiGf^O3+2dN7@5(jiCbJj#WbA6a&Ob!)0x%qtz$ciS z^XPyBK*0UfnVi~#O0%}~B^0Q80zPDf@&-&sYp^o6-{CVdar#P!em6N~?;#+ZLkd1> z&3=O4M=i(O217w*G@PTR2z13!W=CHbY~J#%aNb`B`J+Fey}Pe~IunRz*!(NtsNKml zoMq~F5VQbP%{0@{Bby-u0YKJrRl9<4oxHDW)Ww+ zmbG6<0DXeyFiy@|a20eIrcBe}wvKR{eP3Z4{A80lAkl%N#tm5@8qs0K4gi*UqDviG zE;D{&?lVe=a{AY=Ae1+Ic*PfICfm#W(3og%RF%e^vrYWu?zDW_tN)4YTA8`SY)5wAqQM3E)zP?-VGhVcljh>9nd6ela zdbhLr9h3uohZ2M8HAS4&uQ-17F%2M^O|n%&<|PQA#GW!}&vlr(I-3m3-aA1@4bGXe zv(H6e+RMlpIc%Kc=Hx3UxzI=NUGpy|;lN!%K^FA{)jOkOUPa>-FnMpJpY2U_>W&WI z)?TccG3&}jfm+}8@M=Gkxvby)`nQZ5mkbhX0GP-ia{|Y2nKjHTM0c$QA=xk+5%_j@ zK;IbJUwjms!k*Q3=|z7o@UG{)?LOZv_}QQ3+&PFTZ(`Sop!UM?eOj}@+ZOi5g9Q^A zgMDCRdKLsYOcWX&5&$`STPI{=HnuP*)JKAU?6LewEKICurLpbxR$QK!jSUMzGPlM(>P$$7l5e z0GrP3Wg~n-wVbfy`H$Y?y9Gb{SiH{(&C`9}M^Y?1Dq~`W*tZI5NV&|7zIa zd>LpJxmU)Z&ZTn>wPRB>M+;TI6WLeBy?PDA%khz`gLJRn&8VdrI#d@RAM!t|7p{&c zpF_){7S-e!j?L)mbh3@rOe?`p5a+lB2Q+Fm_!*lz7ur+?sD2iP;+-d`kP{~*L)Hug zka%5K@3??R`z2ALPPxg(WVWWnz}X4ve(w;0yt1laONTEDxULBRbw8(n?6k$ZI#m6< zEEdHp+a=38=M}4$0_gU<0T_4XVSlC|Qr#D*o{Jqhs?}EHku!f$pq{PCYv#a<_8F;@ z(~}%DFZelhVTHM=jQ{YO?~wU9MSz19=opjWLy=^F79d{)X>qix`x}I{f+nQ;GD;nb zPEPo%FXZDmAxaCe$ULF@PsjkR;S)ia!D>|pGBj}Xvg91InN~)w#-v+RcJNez94&`_ zGcI*Tbt(-jsLxe2D)?DT`~0lyO7Phnh6!-*ZNckx_R197dkdDj$`pQDpn2x$o zbsP#%*(=%J8?cly%6ixo8K3DI8Q9k;Q}j8R6TJW&)#Wuoy#oxe4{KsfdEe(qe#Q*Q z(C_k_!7px_D`n7_Kr2&1yae^ngAngz7i-<*Z`wW-Mgm{ zsRcXPhph|1K-EmI1)t(=FV-P1%QZgqG8RH}%~h!-zJ?!=r0@f-|IZ0u|4WBHE%-6E zylokxkbN*Z&PcbBjx|E!1UWlGv{|?Pg4Q@@nFyz*?s0`qEGCM>$rt3oKp>jD8Q8M~ zUVEjyY?lKtrlZ54XAN_7Jw?xXlu&c);L#Z9EcC06MIa$9?YS=}#5h)s*LujVWCmyn z0Z|8-XEP#BQIIfBL3a4*aR2}y07*naRM_Tb24)+=U25k@HZn8W3u@Jx2r~Bcp=PTf zr@ybY=S=95rWHXzQ`PMFfg%kIYJCh?z+vFCL3E@O)xXo_%8ORbRe(f~_G7hQkF3$9 zz~9PTvZsv=3$*Omd?l;I9$_2WLo~u7@aw)klbxbTbMS=! zm++Juay}{eiRc22=+EK%vRH&6%aUzDVH_A9yy z2LU#3Ru7_rTq%x&nbj5Tfg|YEfKpL#*T||gotO)GaIBnks9t;WD8CF?-OIRf@#!Fg z&M1nubTu2Ny{~*Jc3T(d8LdTm(JlQOlz|9HOolPa5LU)PR~d!%gf=x`c%uTU1YlWl z%*N3Nzu9ij%te-^jh&OXHr9{MmW^>mC>uUwf276^nJWaHFKC>DwXS6DUv`MPn*|zd z8$cmjf%NIuTlHXAcF&IJkU62K`Hmw{4A|-V)m!jR+WKs1(dq0^lhx6dle5oB8qkZH zcUFBtdvCG?j%3N|z%w;b{?<{6d^DW{y!Z?qVDvr!TT##1`9@ z1Lp(g%>-(qni!yUO(AMpXI*+DMWLwbAI`DVnI+@9iyTMKJo-DsAbU96UbL-1 zHn9pu`rs$)zuN45Hg;4ygO)Xf{`_qUc-Ru1U=t&-1D(4!ikdCW&}4V#=kxJ%SRp}P*#xjWYOnxe1VBtmg`zdL?2Dv> zd`N|gT$z{g#}@x>a;rpGG=W{P+VyqSMJm|x!F-0qf;7kE}=C zO#rlkcIN0PN=cFb-xqx&AQQIV5w!7nR$C8&5-CSJWEz3gr5&iH3O%l7#Zc7;J`9ck!6hdj{rGw|*@ zHE#BaP9+!eVP8J$U3p3cyE9x_kl=^Lo$WR^W`{TMdBEc;Sggug@&Z7}>SWz?OyKjg z%#+`h!TBAa&u@t#{Fy|9jsX&yrP3(mo<5&1G8Z^~mb@!K?2ixc41OG}ePNVABMS5= z)fPn5-s}Ura=yAKIcWQm&|7Uv&v;CfU}hJMz&J=_AzVfWML?}bx+$T3u!gAjt|=gP*L=*aSRsQupMj&@}Io*_BM#MP5uA z2Z8}%r@A`X#;$r75UK_*dq)SO?SLryi^|&doQe+QaBf?dWEX7*DjQQ*=7TUo{krj& zx{GCpN-t>OfB&*8K8j4~led2W5%d*M+r^adL!tLp&P(M7`B63L)iOav#;ySj*pzIH zK1qo9DeEu0(>+gy^h_xyzJ)F-FZmnU**1kSa2@|;{9;YEdH`SOX$>zU2I4QqzBBl_ z7l*_Fb0(0J7GoP<(=iEQpKX9;Aka6eh!Jx7724r!G2BlU2aOXn0YN=DW{YuVa8QS= zN+)5S&-u$TAYp<0DaA2n2+2ZQV1;dnIh}ZnDwG@pMG?C;`^wZ*GzF>8#W>V+1TG5y z=_g8D85a5kr?0U@utO~}Ec4?)SHC!7HBpqi%pRg%p*`($)72<|s>N!MvOcc@OEdH5 zq*3IuAP$C2a!OblvV9^Ld8RKqj)EgAKpAaKzhC)P521_tIgQ` z-9Z3+6dfTeSzg|1Vf-okn4ivZzQ=yH)|cFwCtoT!(AO0oge@`tvm@&6jIIAHJC(o$ zg!_Bq4IRiE=II@ug%zM9{sq>7U0EYp3v6^WHNM;@G;@y9n;QSl;OD`RlLbN%GW_fh z+uQr;sp%;C#ad>*0_XiU6{oD)3IbZQm?3FVUsp*cDKo`S+V%dC8aTbD%;QqvZB>`Hk4jLD%AWvgMJ8A5Y#W6sRnZuU_GAh4^l2ADekz&g>Qr|@7 z$rNR>dFiD4>kLJoemW%=g$Ar-Qff7TjCw5^n9S}pCXgLxq7eY9R-af2elm4gpKnN( zW2Jk*%S`Qi%77Oxro*xuwxEVe4>CSF^9p_7cVsa#Kbba)c$Jc05Wz3U>zTkLUjz&b zSOSZ2c{4|j&r86THK}_7@Ur6(r708S#Q8FT^e&h;4q(``eOG;AD<5+-9)9D=Q<%t? z59R-lw$Suz1~jCP!)L9F44eP8CTx^Ev39a;evAJ4=JRIv8vc6z&fq6%qZW0%K}eiA zXN6)kI7+4Y#J(HO1;RWsH0d!4N&SzrmT@^Razxp=uQZ#W@fuI=HnNiye?6Vw! z0O`3pn2f#cih`JQJu-}TbN!0(9eu{VeF;>M5Y(t1g*I07O>ti569ZIRVo)5HdYsHo zYqoJGI79X_8gwn12OwZHl!}t6AFj|RyXHJ|AB{U$0T~0s-4*=krQk!@<0Bj%dj(#s>nq1%{xUpk%|{4i zvOXP!oHn0<1qk>B=m8@^W9F?Pz^VYqR{1f$a3y1l&;W8t#p(%4C`0}$%_C0%9htS} zD86juw~us)yu}Q)Qwf!%NQNkQqfGt3uVjn*Km9N@w}bE&;Bo|F62y!WM7OP zude>#XA_`w90h7lBtJqh41-frCqS9na|216T&O!^r?6^ZjEHmBjc7lbOhA@dp>K>y zosToc(?c9OOHsG2qFPKrJ7-z$Rvf@U@YR*--g(84W*Zbu&aPxkC}lNB*`C1evzlEX zdXzE60U|gR^76B$7@vc*$%Yd&$M4XPL1F0u)as-P;KO>E17J{YZ$7Xzj!^JZKU8Do zgvoI>_@T?~i3~WhW}0*a(kGaLmB1tGQ`<3pQDy3pw2jD{*cfuEDW9In}p z;Aap5mEZuCb0UPRfkn0?iu;|+BnXS4p|NBxXJ;}R8+uL_=-fo9u$r6TCe;;SIUEzD z#FSaBWu+-2b1-Itf(H9~qbv$~V>nN|wLoU$`Dii$&HSMpG#V$7O|7z2g>+Od+K((y zcEATZG^Zw@ZyBA89Fi6IP&@*>U?@vLD?gFN?lPkGJ^&7*Kzknxu|!`@J{Wk!O7T%gK}dig2OGEn7rqBrm(f=@mG?u+8M%Cj%xwn+Iyvn>F6T1= z96C7@kY=98zmTE0fMJqENL-Y%Dt#PjI^xr>08zVzg)Z@R$qxPN8`wBx8Sex?*_om) zC6R%tuUTBd2c^QH_|o+QJ#p%Jv$uhw;6&@ICK#V5JQ1C97hGjB_977^US8$`Va(78 zM{i~bqVUWkfy)R5KbhYX!H+?5?y?X;DvGJ_3p@x^P%%U1RPtbn`{^uA#j#{wP zSf#=2C^%bxPS?H8j*z2g7y(%qAe#42u26z2b8bIl&7KN+?Q>**f}a3HpZIz{RD9sG z1w+6c(D!c(w)8EK(aI5$@dN&)&j8EeacOsgABDH2K~zN(rVUu8#)(KhQ7n)&C2zZ; z2+8MBdfB|3`kFwh$SL5-a?nz^T?X~|H zipp8$FaU~?<`m67=IuFgBCh3-1b>K#<3|~jg=Ut>&u7py?nSPguwcpIwI~nr^Bhey z?)3^os2FVabZUoYFyzC4%%AR{w_T%#CP3xfNWly6;(SpcIq^Qvtt*|n&$&-909$r?1Qby zaCA+&sL$RsPo``y?fRS-u*q4W+XA3C`*i4$t@#RkPX3u`>nA&mgm(tg-=~{iJP#O= z4RF3^y3d!%*x3-ED~ms}74niX17h@nvzEyo9nOpaQwNse+H0(SC!l_c{f%^Iw*R}sK#{G ztTR#&PF*$zAdr)JaIg%^JsFLI0?@7;RL~FyEHiP9?2}=V9b*zKAtiFO$g=O8#7}{M zk7RtPInU>8$n_O9mR2S?0!^@z(P}K>Y#BrXowXMfAU5EHF+gs91_Cp8 z=UAKh^?KgFW!(Mfm5xng@^73wJ@YWewQ6fG2puV08IvHQM8^6g(KkT+>atry1Zk|GdWNV z9_X7Z>f%f(I5P!oln%P3TH8R=qIk6%uh3W)*SI-HO>RpI3#qkfcUpxYoJKaA){yn*#t}Shf39-+?$gTOsu_UasUDfhdY}^R}Iga<%Ox{ zmX1>n$Xcf`Z4CaOu2}nIZGPU-hHtK9%n{K)dWt>|>p)Ml2g$!}AT{P365jr6T=@>g z8ruK>>AZRQ*P0tcp2P6jkU#?oYf4i0B^SnTY&$api~%G}?<>HEj?ho2ojiPHuGS_; zRjrPZ-phn+BYNshAgzvCdk&fXvk@$g%+r<>^Hl347gRcXah zOKo0h2C(BN+U*3^T#yv(fgJZ%&mYybsy6m%*U=X;0>noRU-XQ8$Q5g-DH82T?|=;c z!xufHf9wOez&M=wEWV8o#Jn6PV0VL`0Z|%C#kpxpp#Y4zH3-j%Bcnu|n;;k3Qbv*u z!EK;BT2Rgcy{ECD?*^(UfJITrCO84NO4Be53(;;Rs5~#%K+Y%^*|6Z#8dJ~^XUO@X zCGpizlerpeI<=ruPEjFVZHl4@9%?7Hm@sbh<4h=q^^i@PH*msWt&;#?jW}dkj!ckK zgtS(jSuYQ|Ve_{-9cAQXg60^6aa->MmNt0I$oA@5XkMmGHfTI!3aHB7Aqa6~pey5H z(7w(BO^brVddTDPbPY=m?cX{9#lJW4<* z%ok!ed>YqRRGk)gxc&6z!tcGMrURAHXOPQ-Q6CRkXLZA13*>N8T+&z zGrb3QW$>!cqc4>Z_|2K%uHFZTqKJE)Pm@{L2r?A_`7N0|+7!U$-;}8&38yDp?FxQ( z1!@wq0}~MO&yGOz9LPXW7}1ZZAu;k6QF8QxgkXY(sL-Akl7S}MTt%o1UQko;mccSI z$kBZJqsOd`g=K&YMV$^}6!aJv8dR;2lY~&wH0CTglc%7AlJ*P%v8|c*!3VA2zUXI2 zbOx!Nt-Uo;hjc%n;p#2mclGD$^MDnEFWW{jL4o9&hAN1W6aJL#2$>52DO=_YbmivM zp1ZQ*)Kl|a)#JNk048;c(_2}e6H8t(7K{ksEgJw}1Jd&*1~jbNlHUUeoGftJfY-$FT) zYxTX4ZI?GNgE8Y5`C0Nm-N*bX!OsFvDl~%Zz@X32f@T%QgYvs-6{b|EBSEVzxS|0m zAymd0j*Kp~092uS-gS}!mjDcX5Wh0!nOt64!X4&RNw5ma@* zLOBZXWC{JCk_0`n47J!QyKGb)P| z1&0RlYcx^w8|gviSx;O8l%Q|u@s12Z(2? z5tIbEypi0`^Z^(KA_XwMh%;`pWVQ#O%h((gfSIx9SO!VYWpmgWjWumU9s32`bs&0< z?s0xdIYs}%r|RE|PKzrN1x=8$uS$K{b7bSPY5u=ITeUI{r*+B51zdjiayP&y1wUia zAOH=T{8{9WgND}6=tqhytAqL}UAsqzqN2edx^_R^nQ+l03_;>RLr?R?_| z8K3P1Y=3VX4&aJ?kwLvG@EM<17-=|R&uq%?P|HdwY=)fCuVgO!;6!^Mu67Khvqj)i zXK>!$0k~pYIDPfLG_?V+oI2nv;F&XfRbs$O{BBzwa*Uet%i$io69vY`U?%AL%Bf8< zY1@?evY{XQq~J#$G7)qg1%q^t_ToTTG77V57GI?1vMV5k*tmF_uc62|FcQsrN8W|?F$gJICY)kf~h&A5hIL3J1@XF-Pf8w z5=fON$Oll|L3{Rf6Vm~PW@4yK1N!cZDV8}M6qp<-L{DlUu zSv{v$k^+D`Cy8CEPc`_BTDCXp=&xHr4w@wxqmInB0fW+ow>K^dB-jxcMIvND6VgL% zLR~sZ87f4Fj!2-m8n=33d!X&EZZyUt05cF-sSTLsXWZ$&Y{w-~az;>58e2MB!M-JKEb?-mxebkYFJceCq z(5lFZ?dTrnpiuijl5c@Ypa75{Y4j*ZBmkrOa$1hY4b57>A$CE%8cPE7C`q7JWqtJ9 z_^~FkBi-B@xL*A>5e+ANiQqh{^|Lu(S>{JREr7!wnV)~v>#jPZ*+RBP@l$OUq$ERz z&VyY&G^1T-;{iH>UTcA}ZJ9HF2c9+CWsh~g7qOx@m23DbfE>sG!~p=zlW!RsfX?>- zPy%%VuzjfH9{*K&R<3ct06o^IRAMr&f}g(;q#&YEfHTdhE3ZKFIu8XefsWFKB7s(A zOcV!wgCj;W$fPW$V8BUGIzluLC|A%iegeM=WSoM!px~?EEsfqu&zO_O1@x_8cC_D0 z#+FP^=IR>RE2Jin+uLWHy2Mbo0-F0VE=@VshaspNQY-;52fvaJ)Cb*Wb3LTQU1{%5_Rie)fXE9-~dSux!)F& zY!<+iAs%H<96dh-aFYqSwb`X{@MGkh62@o_qrdBK0NOQ~2(D>3F$RCrP49R74ra_Y zpQ~fuM$bF@J0Aq}08YMg{wbf9tqDp}bc7G0Ujh~?9;?N#<-E_)zVB9#%|&ukice?3 zk7E_|AU8pSgQWnRGQm-br}qgNgN2mJLI*NF84|QArDjZ=zU+cg`JLi3M=vYlfP(-+ zOUSlHR0~IAzmGY3=FUyu77Cg+Hcp`(3!ow3qa@5trUyAH(hGcy2dx1$`xzjS`N;y& zRyOc5Mso!afC0~-?ClBmS#tp}r7xf){M=_;;fx@V`rQZUGg)hlq1L>d5&GcWGmTk%O3qd$1YF;j&xksLkB&_zku4v z4oBmj{kyJC^edJ`c6#+CpbM02j2`zkVV>jygrZXO%C_8-&jg;$Q4@_o(1ObBHReNi z?zxot7%#aCIH+j0?Pmc+&+4k?b*M5|*5Nlk4Mq$d3%t@Q3NMH9{~H zFv%(}?%`OIX6#V>-vO`Mf3_&2r!*I^p^9^Qa4eU&q#)7VJ zOpXjtca*FNdZ1t&LHKQBh9+c5epgC;n+HQBUYi5q+6SesLFsq5AZuF}#4NCmOml>y z&52@Ke#dzIKPMspaykqUmBUd{Do8!`8JRE{$?7N-$_dKM)`wOp$&NBs zI$*DqAGN}$82^f4Wdo}@kP$k#gycpR`S9PvltBDI3-D$=)o`=1e{~4fm&1~!x#!Nn z0pQ9^pmnDPIeY=bko{}uBtectYqwgULH%C6uciLbrh=o)3AM=~V=Dwh`s-U}^6D?t zD~E56BfYeC^w(S*lF&PGW0xJer_9a$1QxcYflUblwJIp~TbF#6uTlTR&g^`zo9u2b_;gWv=e z0t`Z+y-iS01f9Hqwb&?)j=3FLy4%!M3I&nlc5Y;!I8 zTb)H8?|`^IQYXHh7R-qIZ7*ldJbeh@W*t?mz zup7*h3>_PEc7z>v%Z6}%WasmZ1GtcgV7ID$62L!ZfjsgWqn4qH&ytC|mcR0|gu$G} z2j5sRvM+u0!O#CgZKyP9GGpT~8L@>;mO_y{#GW#L%eiaPYYNY)n)u!NQ6`aW)E*(3 zlfdiL5DT~Z3}c0g7Gbp>OmOQiiDCu|8+>hfdLj5HJ17%bBf{Z?=KPrnlyVny$(v&$LI3!2_OH5Ontp zz`I&II)YK5KOB~fK%FaN6m(IebgVsj$(qQD)FJbG_p*+Hi-4hCqoD%}BPd{v(5lsp zV5D<1e^2nk?z9I^pWQhXO3sU%barndiIT8W#;t3{ph)M+^NfKnyvs^YG3`S zQJJeXHg4;@v)j`>>8H3Li>vwpe-nW0W&i>hP-YtGhG*nkY?4Iii_oMc^DCdxo8Xtl z^Z!s9iVZhUdDARnLL8-sam23Wh@{X`eTJTQl`#epoFiC4xmF4)i zszgwP;LaHtJIY2dwc!^+pK&SzQ(mt$^SOS0#*`ObI$SsVja-LDgg!Zb0Us43Gl#gz zJbQ&?MjSEc!ujNwGUF4B&{Pahu;hd@cH_22cd0abBM3lajE=Lc)DMk~!B`7pL(#TJ zq2;Vg&P%qzKyqmJjPrZyT4+;nPy=HRy}{F40MR_v!vIQaRz=0eZA}@vKtxZV`aAm8 z%fh-@KcEUwlC|Z)=A5$c_bt<-p+d8n;FkTb){3rLAI{y}-II;-DP$wdJafuVt&#ht z=4VqoMy2v)YZMw$Ah)l0wv=*Y=jdg2>wY6gUm0Vr0cZhFft^3QI<*K$3)N_ycll`k z2Mc9$`{}V_2a^)`$i(MXYT9U4^Y!+PY8?2boTwTP_OoCIy`#mn;d77z8^j5v$PNfi z%FF?yH_#>ux;SP|i-YwyNL}rWaCd$gr%ZvdQfT!r6BcL%K^%6Rr)$kY8g8CWQh_pj zaa8J-_+x0Hic&Hc&L}~cY&d`whs0s1+fiOwK@g^~Lo?7BV`YTqWiz|~S5PKv%>#ZX zTQmo>13E+I#fhb>4i%@4K}M+2orsT2&|A9wFaq?&-lkFTLmR0jsaJBY=o*euu%MIV zDM;in1KBRU(y2D{#_*l`*WQb*kY!rpjh*e#Hz=I5)Ipmfz3dQuD46wc1GpL^y`XRG zO7lzAc~|GnCdi*$tp&;-2;&q{=bFjrPJ6(!o&b8r;ihh6jMh`I0G_R*|JU^4J~_hg zF3_sZtGy231qd~S=wqnZs__E`np>>dS!ZWuJoG}~Wg}z~hM@A<(KY;`paaP36BuPb z8VQvbG{mqYlr&1-=PPnK8xNL74U|31)Dr2QOmVgTsoW!8$#^Te^@~aLAIObTr<+r{ z&yf=d#|*K`J~UTwY=R#ejzU0m8bjJml|IAK$__a&PI<>c$-Thy_5%UHz7iA+;h7Uf z^G$gzCTC2z98NZrTWA5GBCMmu4$=~Q30|ks%G(eqj6jvwon$;59YiD3bvlIgur}xn zflp1)|62oyN7iIMf;=Zi4val#`Jz(gOV;=Ir4|XLy!jb)E6ho z`EU~GB+vJAPHfM?)D+$V@1XeHTfmitkdr14jVOZP?EWREA&{qTCv_I!LgNRN=zg+Q zf0IRdj-Z12;#_1HvQBFNnadiD&Ck%EOatl$PU3LThwd-fT)jPGcD-!EHV<-U=tp~- z+7o3s1kTgmG7U0_j_NQ85y-- zqmyoOD7feP&b}o!z?lnp0uz0w7iws_WUV8(eeKnu#4IcXh)c{??saz<%X;MAc2&X7=_`U;fF6a_v=OheYdbB|)UADV%q({esb_nyrSMXSS;qadF&JaIbaMc3L)+wU15-4HAV zZu8=7Im;G&F>u>7&~fTavJhDWu#mt+KAtJy_?>4lKwu{UhHm%9oolb0VLnHm?1b)n zjvxl~sB3u+=SHTos2IOS6~?J1E8|uZLk-E!trvOu&XIOU@-=>Q=WOrRozB*ePGtX= z;N_bRT1&cVZCdAY6#V!GpVK92y>t}<*Xq^gEHjyH_L;Gz(Y3|~@BwDCb;q2D!}p8aYfUI8T(wYJpG=n45?L)a^j3P7+!Y{<^c*EozvR-Siu(mnRzU;YvB0CwrI+B8-I zIFZcA^jw$n!bpZ!f5%Wsboj+8xB#l?cDjRSpAX23GnxS_!IN(#kN-)-3xm$_ShB$E zO$mjV*T}~}p;41d>hABpp$!7&*eHpCL0YAQMrUXJg}?<4(ZAnsl-r>IC?2P?@|ui( zSR55J58=paQ9}Zlg_o&WL~moo#koh2O7R=cYrRb!tS-)OE!f9F7em%Mg|uAt)SiFwhpb`RB2@T1E+;(N} z0e1A`DBy7R7&_1OOcb`@4|r7rR8`hMs{})K3w&DZD|(l$VyWoIs&A&3<^fn#`WP^m z5|{soLrN0~gp%ydgk>|*Qj0C{`St(^l;QS@Y%($}iw%tsuqKAl+Y_q7?XT0Z2|=g5 z_h>QIWQ@n6j~X!A`-jTSDJW1a#i!^RT_`rk&B2Sb zqci{pIuKm}kO*{woPAePe29(VLDxRRNm1&cA5;SQCtwJGP%pz%4=}#=wJWP@(0`8H z%%cx>{dHs{TX!vrjozUKfd)Y^&LMR)asZ;#qjY_m>pS=TF(O@aXivZkxIsq)jm#>_xUmcL5CR0VD|+>i+r4>&F0>)B?>lhcyeH zJ}-MD6S~S5?5uUo$^<)s1p=-d<93JQW1liS^5Hktk?4f^u`|Ih$pHJ7feF0I4t$3( zylVaR4zLxz3u8eByMk}K27oC)l`S9SLmmLV;MUgxQOL3|badNHRb5wW!1m}>wF8_V z$JG5d2h}>Opi54kGqqTn45amhr}ih1Sa3>>vf_A6k^-1GCky>^R2HYSt}+7Ke0QFhAg6nmK?$DCIRnXg5pz^wvl4B!YTJ!c>&LVKKJdp2oxVY7b) zDuPmtBOPNFT=26#92KXE&JaxUjyCJ$`kbbL2DLVvkh#cOIjG&}uR1^1siDYBp*PvF zJ(tjVkg01RYyn>IAX`XLpqbq+Ff*>owd_WRow|v@0CZ%#hwPuhTSFNYBga0lA%R5Q zE?IizS+BT;V|2g+1g%rk+~^d*tEo+3Z-XDo+FAggX>8&j$RclJ(Imntq2bwz=B#(> z8;~mV=BLbWHTyeSkJgtSW$9@$L4#t6=<`f%?2Znwc`OoNAq&JTJ+ThrhCnYq2r~4a zp9ZwqiC~32;CBRmF@_!qewD1PmjSSa1){S@r|_J~Oz*_sSP%l?40CQLM{mHWF%Fj@ zry+*&Krm=JSqKCn`;p}_at>BNWY}t7Pf{FcCyqoGbX3c;5HcqjnT}R9h#Bfg@I%|= zl`n#dpvM`IQJ>8Q-T8a=Wci)ID?raG8|5)>vgAmUfy!WIMx3pnq3!_1>H@TufB?Y3 z5p%lMBhSu}LH-{q-Bs^fHB7oBQxNQolhJStIlfJ>Aak``I*5rdf2i4d&dPLkoM)et zN!Yr;iCF{k%)9N_7KhK!QPGYr}q6R?7GcaOhkI@pqokArmJ0$HnN0ZRVX9!tjl z1v=Lx__2TVCK?#x2f);@WkkTr49)x0T-gQrvuCx*r%rM@8$TPA{gIOz{wo@Qa@?E% z!>5h9uy@Hmlxz;x7gy*AyJzd-i$qE3KxR0*7Ict)0cX|jQgi!tZf(#jBNnLa&rn}- zQwUt~(!g3LBYLanNu^~RHYQ4UMN zf~SQ-Gb-A1&Jfe66&OV zS-ZgTPO52SNU{s{O!WdrnN!~xj5R|cSzCr9Fp`7%#Zy%JXuSR3(Kb*u>Ya`VfD9Vy z1u$|l556K6>aa3u*!Ltu5hzsh|6gHm#M zt?WXukdDfB>>YvlD146)(FQ0FNRT6H&#QzS1q({Aqv)xHHFicyi3Pu$ET6H;P9bfb zcmmK&)|Y#v7Rp!zcN7j9@(Q82P9dC8k?EcJGaf;V(xzdCqeUHXCTd^S2pwpwX{+{3 zfh1YsCkH>YrtFDq(ZjOpwq9u6l7%x44$FL3*0X9HGuLrsbd8S4Y^*y24&VVwI39sP z0}^mKL%+|AAFdmzkQ=^=;zDeFZ> z{1rRR>y4B|P@pp)l>F(N%K97a6 zHlL(>^ewehvLQn{2RyMC|MF%0DE6cWDatb5MoA&9Q54 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

    afh#-7FOIpY&$N4FrbR%HATA*=X)fAv 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

    llw55LGCg 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 literal 0 HcmV?d00001 diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_school.imageset/Contents.json b/apps/ios/Shared/Assets.xcassets/wallpaper_school.imageset/Contents.json new file mode 100644 index 0000000000..59c209b134 --- /dev/null +++ b/apps/ios/Shared/Assets.xcassets/wallpaper_school.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "wallpaper_school@1x.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "wallpaper_school@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "wallpaper_school@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_school.imageset/wallpaper_school@1x.png b/apps/ios/Shared/Assets.xcassets/wallpaper_school.imageset/wallpaper_school@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c95ac60b6e6971bfc8cd076001d4ee9706d0415c GIT binary patch literal 91468 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

    8Fp|G%`i#`IxmGgX0WZ4R_jsLQ-YRo;{c^BK0| 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

    m4vRaDjH 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�Gub`ybx+Az{0u+&I3 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 literal 0 HcmV?d00001 diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_travel.imageset/Contents.json b/apps/ios/Shared/Assets.xcassets/wallpaper_travel.imageset/Contents.json new file mode 100644 index 0000000000..4e56988263 --- /dev/null +++ b/apps/ios/Shared/Assets.xcassets/wallpaper_travel.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "wallpaper_travel@1x.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "wallpaper_travel@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "wallpaper_travel@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_travel.imageset/wallpaper_travel@1x.png b/apps/ios/Shared/Assets.xcassets/wallpaper_travel.imageset/wallpaper_travel@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c1d825b86e909eb2fbf1c122defe0dc8deebc239 GIT binary patch literal 30379 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

    4yfDw%7X}J6{oNh`^kM(^ITC~j)Mb@Z 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 P00000NkvXXu0mjfsC7Oa literal 0 HcmV?d00001 diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_travel.imageset/wallpaper_travel@3x.png b/apps/ios/Shared/Assets.xcassets/wallpaper_travel.imageset/wallpaper_travel@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..64ec1373312855069a0f079ea1f8bf6cf55f0955 GIT binary patch literal 80606 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 z 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μy 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%0AZP9GDx(de+*du1H`)3*E!9m(ih_F; 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%0At?Qucb^IfYw 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 CHP}}G literal 0 HcmV?d00001 diff --git a/apps/ios/Shared/ContentView.swift b/apps/ios/Shared/ContentView.swift index acea38e69e..d93625986e 100644 --- a/apps/ios/Shared/ContentView.swift +++ b/apps/ios/Shared/ContentView.swift @@ -14,6 +14,8 @@ struct ContentView: View { @ObservedObject var alertManager = AlertManager.shared @ObservedObject var callController = CallController.shared @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme + @EnvironmentObject var sceneDelegate: SceneDelegate var contentAccessAuthenticationExtended: Bool @@ -51,6 +53,16 @@ struct ContentView: View { } var body: some View { + if #available(iOS 16.0, *) { + allViews() + .scrollContentBackground(.hidden) + } else { + // on iOS 15 scroll view background disabled in SceneDelegate + allViews() + } + } + + @ViewBuilder func allViews() -> some View { ZStack { let showCallArea = chatModel.activeCall != nil && chatModel.activeCall?.callState != .waitCapabilities && chatModel.activeCall?.callState != .invitationAccepted // contentView() has to be in a single branch, so that enabling authentication doesn't trigger re-rendering and close settings. @@ -138,6 +150,17 @@ struct ContentView: View { break } } + .onAppear { + reactOnDarkThemeChanges() + } + .onChange(of: colorScheme) { scheme in + // It's needed to update UI colors when iOS wants to make screenshot after going to background, + // so when a user changes his global theme from dark to light or back, the app will adapt to it + reactOnDarkThemeChanges() + } + .onChange(of: theme.name) { _ in + ThemeManager.adjustWindowStyle() + } } @ViewBuilder private func contentView() -> some View { @@ -224,8 +247,8 @@ struct ContentView: View { .frame(maxWidth: .infinity, maxHeight: .infinity ) .background( Rectangle() - .fill(.background) - ) + .fill(theme.colors.background) + ) } private func mainView() -> some View { diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index 542c7974e2..02a31ecda4 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -47,7 +47,11 @@ final class ChatModel: ObservableObject { @Published var onboardingStage: OnboardingStage? @Published var setDeliveryReceipts = false @Published var v3DBMigration: V3DBMigrationState = v3DBMigrationDefault.get() - @Published var currentUser: User? + @Published var currentUser: User? { + didSet { + ThemeManager.applyTheme(currentThemeDefault.get()) + } + } @Published var users: [UserInfo] = [] @Published var chatInitialized = false @Published var chatRunning: Bool? @@ -422,6 +426,16 @@ final class ChatModel: ObservableObject { } } + func updateCurrentUserUiThemes(uiThemes: ThemeModeOverrides?) { + guard var current = currentUser else { return } + current.uiThemes = uiThemes + let i = users.firstIndex(where: { $0.user.userId == current.userId }) + if let i { + users[i].user = current + } + currentUser = current + } + func addLiveDummy(_ chatInfo: ChatInfo) -> ChatItem { let cItem = ChatItem.liveDummy(chatInfo.chatType) withAnimation { diff --git a/apps/ios/Shared/Model/ImageUtils.swift b/apps/ios/Shared/Model/ImageUtils.swift index 6437597b19..073621caa4 100644 --- a/apps/ios/Shared/Model/ImageUtils.swift +++ b/apps/ios/Shared/Model/ImageUtils.swift @@ -205,6 +205,43 @@ func moveTempFileFromURL(_ url: URL) -> CryptoFile? { } } +func saveWallpaperFile(url: URL) -> String? { + let destFile = URL(fileURLWithPath: generateNewFileName(getWallpaperDirectory().path + "/" + "wallpaper", "jpg", fullPath: true)) + do { + try FileManager.default.copyItem(atPath: url.path, toPath: destFile.path) + return destFile.lastPathComponent + } catch { + logger.error("FileUtils.saveWallpaperFile error: \(error.localizedDescription)") + return nil + } +} + +func saveWallpaperFile(image: UIImage) -> String? { + let hasAlpha = imageHasAlpha(image) + let destFile = URL(fileURLWithPath: generateNewFileName(getWallpaperDirectory().path + "/" + "wallpaper", hasAlpha ? "png" : "jpg", fullPath: true)) + let dataResized = resizeImageToDataSize(image, maxDataSize: 5_000_000, hasAlpha: hasAlpha) + do { + try dataResized!.write(to: destFile) + return destFile.lastPathComponent + } catch { + logger.error("FileUtils.saveWallpaperFile error: \(error.localizedDescription)") + return nil + } +} + +func removeWallpaperFile(fileName: String? = nil) { + do { + try FileManager.default.contentsOfDirectory(atPath: getWallpaperDirectory().path).forEach { + if URL(fileURLWithPath: $0).lastPathComponent == fileName { try FileManager.default.removeItem(atPath: $0) } + } + } catch { + logger.error("FileUtils.removeWallpaperFile error: \(error.localizedDescription)") + } + if let fileName { + WallpaperType.cachedImages.removeValue(forKey: fileName) + } +} + func generateNewFileName(_ prefix: String, _ ext: String, fullPath: Bool = false) -> String { uniqueCombine("\(prefix)_\(getTimestamp()).\(ext)", fullPath: fullPath) } diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index 4751968496..8c90c4b1ac 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -246,14 +246,8 @@ func apiSuspendChat(timeoutMicroseconds: Int) { logger.error("apiSuspendChat error: \(String(describing: r))") } -func apiSetTempFolder(tempFolder: String, ctrl: chat_ctrl? = nil) throws { - let r = chatSendCmdSync(.setTempFolder(tempFolder: tempFolder), ctrl) - if case .cmdOk = r { return } - throw r -} - -func apiSetFilesFolder(filesFolder: String, ctrl: chat_ctrl? = nil) throws { - let r = chatSendCmdSync(.setFilesFolder(filesFolder: filesFolder), ctrl) +func apiSetAppFilePaths(filesFolder: String, tempFolder: String, assetsFolder: String, ctrl: chat_ctrl? = nil) throws { + let r = chatSendCmdSync(.apiSetAppFilePaths(filesFolder: filesFolder, tempFolder: tempFolder, assetsFolder: assetsFolder), ctrl) if case .cmdOk = r { return } throw r } @@ -842,6 +836,21 @@ func apiSetConnectionAlias(connId: Int64, localAlias: String) async throws -> Pe throw r } +func apiSetUserUIThemes(userId: Int64, themes: ThemeModeOverrides?) async -> Bool { + let r = await chatSendCmd(.apiSetUserUIThemes(userId: userId, themes: themes)) + if case .cmdOk = r { return true } + logger.error("apiSetUserUIThemes bad response: \(String(describing: r))") + return false +} + +func apiSetChatUIThemes(chatId: ChatId, themes: ThemeModeOverrides?) async -> Bool { + let r = await chatSendCmd(.apiSetChatUIThemes(chatId: chatId, themes: themes)) + if case .cmdOk = r { return true } + logger.error("apiSetChatUIThemes bad response: \(String(describing: r))") + return false +} + + func apiCreateUserAddress() async throws -> String { let userId = try currentUserId("apiCreateUserAddress") let r = await chatSendCmd(.apiCreateMyAddress(userId: userId)) @@ -1376,8 +1385,7 @@ func initializeChat(start: Bool, confirmStart: Bool = false, dbKey: String? = ni if encryptionStartedDefault.get() { encryptionStartedDefault.set(false) } - try apiSetTempFolder(tempFolder: getTempFilesDirectory().path) - try apiSetFilesFolder(filesFolder: getAppFilesDirectory().path) + try apiSetAppFilePaths(filesFolder: getAppFilesDirectory().path, tempFolder: getTempFilesDirectory().path, assetsFolder: getWallpaperDirectory().deletingLastPathComponent().path) try apiSetEncryptLocalFiles(privacyEncryptLocalFilesGroupDefault.get()) m.chatInitialized = true m.currentUser = try apiGetActiveUser() @@ -1462,8 +1470,7 @@ func startChatWithTemporaryDatabase(ctrl: chat_ctrl) throws -> User? { logger.debug("startChatWithTemporaryDatabase") let migrationActiveUser = try? apiGetActiveUser(ctrl: ctrl) ?? apiCreateActiveUser(Profile(displayName: "Temp", fullName: ""), ctrl: ctrl) try setNetworkConfig(getNetCfg(), ctrl: ctrl) - try apiSetTempFolder(tempFolder: getMigrationTempFilesDirectory().path, ctrl: ctrl) - try apiSetFilesFolder(filesFolder: getMigrationTempFilesDirectory().path, ctrl: ctrl) + try apiSetAppFilePaths(filesFolder: getMigrationTempFilesDirectory().path, tempFolder: getMigrationTempFilesDirectory().path, assetsFolder: getWallpaperDirectory().deletingLastPathComponent().path, ctrl: ctrl) _ = try apiStartChat(ctrl: ctrl) return migrationActiveUser } diff --git a/apps/ios/Shared/SimpleXApp.swift b/apps/ios/Shared/SimpleXApp.swift index 7d69466c07..34c66d6705 100644 --- a/apps/ios/Shared/SimpleXApp.swift +++ b/apps/ios/Shared/SimpleXApp.swift @@ -39,6 +39,7 @@ struct SimpleXApp: App { // so that it's computed by the time view renders, and not on event after rendering ContentView(contentAccessAuthenticationExtended: !authenticationExpired()) .environmentObject(chatModel) + .environmentObject(AppTheme.shared) .onOpenURL { url in logger.debug("ContentView.onOpenURL: \(url)") chatModel.appOpenUrl = url diff --git a/apps/ios/Shared/Theme/Theme.swift b/apps/ios/Shared/Theme/Theme.swift new file mode 100644 index 0000000000..3f7013bad7 --- /dev/null +++ b/apps/ios/Shared/Theme/Theme.swift @@ -0,0 +1,200 @@ +// +// Theme.swift +// SimpleX (iOS) +// +// Created by Avently on 14.06.2024. +// Copyright © 2024 SimpleX Chat. All rights reserved. +// + +import Foundation +import SwiftUI +import SimpleXChat + +var CurrentColors: ThemeManager.ActiveTheme = ThemeManager.currentColors(nil, nil, ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + +var MenuTextColor: Color { if isInDarkTheme() { AppTheme.shared.colors.onBackground.opacity(0.8) } else { Color.black } } +var NoteFolderIconColor: Color { AppTheme.shared.appColors.primaryVariant2 } + +func isInDarkTheme() -> Bool { !CurrentColors.colors.isLight } + +class AppTheme: ObservableObject, Equatable { + static let shared = AppTheme(name: CurrentColors.name, base: CurrentColors.base, colors: CurrentColors.colors, appColors: CurrentColors.appColors, wallpaper: CurrentColors.wallpaper) + + var name: String + var base: DefaultTheme + @ObservedObject var colors: Colors + @ObservedObject var appColors: AppColors + @ObservedObject var wallpaper: AppWallpaper + + init(name: String, base: DefaultTheme, colors: Colors, appColors: AppColors, wallpaper: AppWallpaper) { + self.name = name + self.base = base + self.colors = colors + self.appColors = appColors + self.wallpaper = wallpaper + } + + static func == (lhs: AppTheme, rhs: AppTheme) -> Bool { + lhs.name == rhs.name && + lhs.colors == rhs.colors && + lhs.appColors == rhs.appColors && + lhs.wallpaper == rhs.wallpaper + } + + func updateFromCurrentColors() { + objectWillChange.send() + name = CurrentColors.name + base = CurrentColors.base + colors.updateColorsFrom(CurrentColors.colors) + appColors.updateColorsFrom(CurrentColors.appColors) + wallpaper.updateWallpaperFrom(CurrentColors.wallpaper) + } +} + +struct ThemedBackground: ViewModifier { + @EnvironmentObject var theme: AppTheme + var grouped: Bool = false + + func body(content: Content) -> some View { + content + .background( + theme.base == DefaultTheme.SIMPLEX + ? LinearGradient( + colors: [ + grouped + ? theme.colors.background.lighter(0.4).asGroupedBackground(theme.base.mode) + : theme.colors.background.lighter(0.4), + grouped + ? theme.colors.background.darker(0.4).asGroupedBackground(theme.base.mode) + : theme.colors.background.darker(0.4) + ], + startPoint: .topLeading, + endPoint: .bottomTrailing + ) + : LinearGradient( + colors: [], + startPoint: .topLeading, + endPoint: .bottomTrailing + ) + ) + .background( + theme.base == DefaultTheme.SIMPLEX + ? Color.clear + : grouped + ? theme.colors.background.asGroupedBackground(theme.base.mode) + : theme.colors.background + ) + } +} + +var systemInDarkThemeCurrently: Bool { + return UITraitCollection.current.userInterfaceStyle == .dark +} + +func reactOnDarkThemeChanges() { + if currentThemeDefault.get() == DefaultTheme.SYSTEM_THEME_NAME && CurrentColors.colors.isLight == systemInDarkThemeCurrently { + // Change active colors from light to dark and back based on system theme + ThemeManager.applyTheme(DefaultTheme.SYSTEM_THEME_NAME) + } +} + +extension ThemeWallpaper { + public func importFromString() -> ThemeWallpaper { + if preset == nil, let image { + // Need to save image from string and to save its path + if let data = Data(base64Encoded: dropImagePrefix(image)), + let parsed = UIImage(data: data), + let filename = saveWallpaperFile(image: parsed) { + var copy = self + copy.image = nil + copy.imageFile = filename + return copy + } else { + return ThemeWallpaper() + } + } else { + return self + } + } + + func withFilledWallpaperBase64() -> ThemeWallpaper { + let aw = toAppWallpaper() + let type = aw.type + let preset: String? = if case let WallpaperType.preset(filename, _) = type { filename } else { nil } + let scale: Float? = if case let WallpaperType.preset(_, scale) = type { scale } else { if case let WallpaperType.image(_, scale, _) = type { scale } else { 1.0 } } + let scaleType: WallpaperScaleType? = if case let WallpaperType.image(_, _, scaleType) = type { scaleType } else { nil } + let image: String? = if case WallpaperType.image = type, let image = type.uiImage { resizeImageToStrSize(image, maxDataSize: 5_000_000) } else { nil } + return ThemeWallpaper ( + preset: preset, + scale: scale, + scaleType: scaleType, + background: aw.background?.toReadableHex(), + tint: aw.tint?.toReadableHex(), + image: image, + imageFile: nil + ) + } +} + +extension ThemeModeOverride { + func removeSameColors(_ base: DefaultTheme, colorsToCompare tc: ThemeColors) -> ThemeModeOverride { + let wallpaperType = WallpaperType.from(wallpaper) ?? WallpaperType.empty + let w: ThemeWallpaper + switch wallpaperType { + case let WallpaperType.preset(filename, scale): + let p = PresetWallpaper.from(filename) + w = ThemeWallpaper( + preset: filename, + scale: scale ?? wallpaper?.scale, + scaleType: nil, + background: p?.background[base]?.toReadableHex(), + tint: p?.tint[base]?.toReadableHex(), + image: nil, + imageFile: nil + ) + case WallpaperType.image: + w = ThemeWallpaper( + preset: nil, + scale: nil, + scaleType: WallpaperScaleType.fill, + background: Color.clear.toReadableHex(), + tint: Color.clear.toReadableHex(), + image: nil, + imageFile: nil + ) + default: + w = ThemeWallpaper() + } + let wallpaper: ThemeWallpaper? = if let wallpaper { + ThemeWallpaper( + preset: wallpaper.preset, + scale: wallpaper.scale != w.scale ? wallpaper.scale : nil, + scaleType: wallpaper.scaleType != w.scaleType ? wallpaper.scaleType : nil, + background: wallpaper.background != w.background ? wallpaper.background : nil, + tint: wallpaper.tint != w.tint ? wallpaper.tint : nil, + image: wallpaper.image, + imageFile: wallpaper.imageFile + ) + } else { + nil + } + return ThemeModeOverride( + mode: self.mode, + colors: ThemeColors( + primary: colors.primary != tc.primary ? colors.primary : nil, + primaryVariant: colors.primaryVariant != tc.primaryVariant ? colors.primaryVariant : nil, + secondary: colors.secondary != tc.secondary ? colors.secondary : nil, + secondaryVariant: colors.secondaryVariant != tc.secondaryVariant ? colors.secondaryVariant : nil, + background: colors.background != tc.background ? colors.background : nil, + surface: colors.surface != tc.surface ? colors.surface : nil, + title: colors.title != tc.title ? colors.title : nil, + primaryVariant2: colors.primaryVariant2 != tc.primaryVariant2 ? colors.primary : nil, + sentMessage: colors.sentMessage != tc.sentMessage ? colors.sentMessage : nil, + sentQuote: colors.sentQuote != tc.sentQuote ? colors.sentQuote : nil, + receivedMessage: colors.receivedMessage != tc.receivedMessage ? colors.receivedMessage : nil, + receivedQuote: colors.receivedQuote != tc.receivedQuote ? colors.receivedQuote : nil + ), + wallpaper: wallpaper + ) + } +} diff --git a/apps/ios/Shared/Theme/ThemeManager.swift b/apps/ios/Shared/Theme/ThemeManager.swift new file mode 100644 index 0000000000..55f9a08878 --- /dev/null +++ b/apps/ios/Shared/Theme/ThemeManager.swift @@ -0,0 +1,303 @@ +// +// ThemeManager.swift +// SimpleX (iOS) +// +// Created by Avently on 03.06.2024. +// Copyright © 2024 SimpleX Chat. All rights reserved. +// + +import Foundation +import SwiftUI +import SimpleXChat + +class ThemeManager { + struct ActiveTheme: Equatable { + let name: String + let base: DefaultTheme + let colors: Colors + let appColors: AppColors + var wallpaper: AppWallpaper = AppWallpaper(background: nil, tint: nil, type: .empty) + + func toAppTheme() -> AppTheme { + AppTheme(name: name, base: base, colors: colors, appColors: appColors, wallpaper: wallpaper) + } + } + + private static func systemDarkThemeColors() -> (Colors, DefaultTheme) { + switch systemDarkThemeDefault.get() { + case DefaultTheme.DARK.themeName: (DarkColorPalette, DefaultTheme.DARK) + case DefaultTheme.SIMPLEX.themeName: (SimplexColorPalette, DefaultTheme.SIMPLEX) + case DefaultTheme.BLACK.themeName: (BlackColorPalette, DefaultTheme.BLACK) + default: (SimplexColorPalette, DefaultTheme.SIMPLEX) + } + } + + private static func nonSystemThemeName() -> String { + let themeName = currentThemeDefault.get() + return if themeName != DefaultTheme.SYSTEM_THEME_NAME { + themeName + } else { + systemInDarkThemeCurrently ? systemDarkThemeDefault.get() : DefaultTheme.LIGHT.themeName + } + } + + static func defaultActiveTheme(_ appSettingsTheme: [ThemeOverrides]) -> ThemeOverrides? { + let nonSystemThemeName = nonSystemThemeName() + let defaultThemeId = currentThemeIdsDefault.get()[nonSystemThemeName] + return appSettingsTheme.getTheme(defaultThemeId) + } + + static func defaultActiveTheme(_ perUserTheme: ThemeModeOverrides?, _ appSettingsTheme: [ThemeOverrides]) -> ThemeModeOverride { + let perUserTheme = !CurrentColors.colors.isLight ? perUserTheme?.dark : perUserTheme?.light + if let perUserTheme { + return perUserTheme + } + let defaultTheme = defaultActiveTheme(appSettingsTheme) + return ThemeModeOverride(mode: CurrentColors.base.mode, colors: defaultTheme?.colors ?? ThemeColors(), wallpaper: defaultTheme?.wallpaper) + } + + static func currentColors(_ themeOverridesForType: WallpaperType?, _ perChatTheme: ThemeModeOverride?, _ perUserTheme: ThemeModeOverrides?, _ appSettingsTheme: [ThemeOverrides]) -> ActiveTheme { + let themeName = currentThemeDefault.get() + let nonSystemThemeName = nonSystemThemeName() + let defaultTheme = defaultActiveTheme(appSettingsTheme) + + let baseTheme = switch nonSystemThemeName { + case DefaultTheme.LIGHT.themeName: ActiveTheme(name: DefaultTheme.LIGHT.themeName, base: DefaultTheme.LIGHT, colors: LightColorPalette.clone(), appColors: LightColorPaletteApp.clone(), wallpaper: AppWallpaper(background: nil, tint: nil, type: PresetWallpaper.school.toType(DefaultTheme.LIGHT))) + case DefaultTheme.DARK.themeName: ActiveTheme(name: DefaultTheme.DARK.themeName, base: DefaultTheme.DARK, colors: DarkColorPalette.clone(), appColors: DarkColorPaletteApp.clone(), wallpaper: AppWallpaper(background: nil, tint: nil, type: PresetWallpaper.school.toType(DefaultTheme.DARK))) + case DefaultTheme.SIMPLEX.themeName: ActiveTheme(name: DefaultTheme.SIMPLEX.themeName, base: DefaultTheme.SIMPLEX, colors: SimplexColorPalette.clone(), appColors: SimplexColorPaletteApp.clone(), wallpaper: AppWallpaper(background: nil, tint: nil, type: PresetWallpaper.school.toType(DefaultTheme.SIMPLEX))) + case DefaultTheme.BLACK.themeName: ActiveTheme(name: DefaultTheme.BLACK.themeName, base: DefaultTheme.BLACK, colors: BlackColorPalette.clone(), appColors: BlackColorPaletteApp.clone(), wallpaper: AppWallpaper(background: nil, tint: nil, type: PresetWallpaper.school.toType(DefaultTheme.BLACK))) + default: ActiveTheme(name: DefaultTheme.LIGHT.themeName, base: DefaultTheme.LIGHT, colors: LightColorPalette.clone(), appColors: LightColorPaletteApp.clone(), wallpaper: AppWallpaper(background: nil, tint: nil, type: PresetWallpaper.school.toType(DefaultTheme.LIGHT))) + } + + let perUserTheme = baseTheme.colors.isLight ? perUserTheme?.light : perUserTheme?.dark + let theme = appSettingsTheme.sameTheme(themeOverridesForType ?? perChatTheme?.type ?? perUserTheme?.type ?? defaultTheme?.wallpaper?.toAppWallpaper().type, nonSystemThemeName) ?? defaultTheme + + if theme == nil && perUserTheme == nil && perChatTheme == nil && themeOverridesForType == nil { + return ActiveTheme(name: themeName, base: baseTheme.base, colors: baseTheme.colors, appColors: baseTheme.appColors, wallpaper: baseTheme.wallpaper) + } + let presetWallpaperTheme: ThemeColors? = if let themeOverridesForType, case let WallpaperType.preset(filename, _) = themeOverridesForType { + PresetWallpaper.from(filename)?.colors[baseTheme.base] + } else if let wallpaper = perChatTheme?.wallpaper { + if let preset = wallpaper.preset { PresetWallpaper.from(preset)?.colors[baseTheme.base] } else { nil } + } else if let wallpaper = perUserTheme?.wallpaper { + if let preset = wallpaper.preset { PresetWallpaper.from(preset)?.colors[baseTheme.base] } else { nil } + } else { + if let preset = theme?.wallpaper?.preset { PresetWallpaper.from(preset)?.colors[baseTheme.base] } else { nil } + } + + let themeOrEmpty = theme ?? ThemeOverrides(base: baseTheme.base) + let colors = themeOrEmpty.toColors(themeOrEmpty.base, perChatTheme?.colors, perUserTheme?.colors, presetWallpaperTheme) + return ActiveTheme( + name: themeName, + base: baseTheme.base, + colors: colors, + appColors: themeOrEmpty.toAppColors(themeOrEmpty.base, perChatTheme?.colors, perChatTheme?.type, perUserTheme?.colors, perUserTheme?.type, presetWallpaperTheme), + wallpaper: themeOrEmpty.toAppWallpaper(themeOverridesForType, perChatTheme, perUserTheme, colors.background) + ) + } + + static func currentThemeOverridesForExport(_ themeOverridesForType: WallpaperType?, _ perChatTheme: ThemeModeOverride?, _ perUserTheme: ThemeModeOverrides?) -> ThemeOverrides { + let current = currentColors(themeOverridesForType, perChatTheme, perUserTheme, themeOverridesDefault.get()) + let wType = current.wallpaper.type + let wBackground = current.wallpaper.background + let wTint = current.wallpaper.tint + let w: ThemeWallpaper? = if case WallpaperType.empty = wType { + nil + } else { + ThemeWallpaper.from(wType, wBackground?.toReadableHex(), wTint?.toReadableHex()).withFilledWallpaperBase64() + } + return ThemeOverrides( + themeId: "", + base: current.base, + colors: ThemeColors.from(current.colors, current.appColors), + wallpaper: w + ) + } + + static func applyTheme(_ theme: String) { + currentThemeDefault.set(theme) + CurrentColors = currentColors(nil, nil, ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + AppTheme.shared.updateFromCurrentColors() + let tint = UIColor(CurrentColors.colors.primary) + if SceneDelegate.windowStatic?.tintColor != tint { + SceneDelegate.windowStatic?.tintColor = tint + } +// applyNavigationBarColors(CurrentColors.toAppTheme()) + } + + static func adjustWindowStyle() { + let style = switch currentThemeDefault.get() { + case DefaultTheme.LIGHT.themeName: UIUserInterfaceStyle.light + case DefaultTheme.SYSTEM_THEME_NAME: UIUserInterfaceStyle.unspecified + default: UIUserInterfaceStyle.dark + } + if SceneDelegate.windowStatic?.overrideUserInterfaceStyle != style { + SceneDelegate.windowStatic?.overrideUserInterfaceStyle = style + } + } + +// static func applyNavigationBarColors(_ theme: AppTheme) { +// let baseColors = switch theme.base { +// case DefaultTheme.LIGHT: LightColorPaletteApp +// case DefaultTheme.DARK: DarkColorPaletteApp +// case DefaultTheme.SIMPLEX: SimplexColorPaletteApp +// case DefaultTheme.BLACK: BlackColorPaletteApp +// } +// let isDefaultColor = baseColors.title == theme.appColors.title +// +// let title = UIColor(theme.appColors.title) +// if !isDefaultColor && UINavigationBar.appearance().titleTextAttributes?.first as? UIColor != title { +// UINavigationBar.appearance().titleTextAttributes = [.foregroundColor: title] +// UINavigationBar.appearance().largeTitleTextAttributes = [.foregroundColor: title] +// } else { +// UINavigationBar.appearance().titleTextAttributes = nil +// UINavigationBar.appearance().largeTitleTextAttributes = nil +// } +// } + + static func changeDarkTheme(_ theme: String) { + systemDarkThemeDefault.set(theme) + CurrentColors = currentColors(nil, nil, ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + AppTheme.shared.updateFromCurrentColors() + } + + static func saveAndApplyThemeColor(_ baseTheme: DefaultTheme, _ name: ThemeColor, _ color: Color? = nil, _ pref: CodableDefault<[ThemeOverrides]>? = nil) { + let nonSystemThemeName = baseTheme.themeName + let pref = pref ?? themeOverridesDefault + let overrides = pref.get() + let themeId = currentThemeIdsDefault.get()[nonSystemThemeName] + let prevValue = overrides.getTheme(themeId) ?? ThemeOverrides(base: baseTheme) + pref.set(overrides.replace(prevValue.withUpdatedColor(name, color?.toReadableHex()))) + var themeIds = currentThemeIdsDefault.get() + themeIds[nonSystemThemeName] = prevValue.themeId + currentThemeIdsDefault.set(themeIds) + applyTheme(currentThemeDefault.get()) + } + + static func applyThemeColor(name: ThemeColor, color: Color? = nil, pref: Binding) { + pref.wrappedValue = pref.wrappedValue.withUpdatedColor(name, color?.toReadableHex()) + } + + static func saveAndApplyWallpaper(_ baseTheme: DefaultTheme, _ type: WallpaperType?, _ pref: CodableDefault<[ThemeOverrides]>?) { + let nonSystemThemeName = baseTheme.themeName + let pref = pref ?? themeOverridesDefault + let overrides = pref.get() + let theme = overrides.sameTheme(type, baseTheme.themeName) + var prevValue = theme ?? ThemeOverrides(base: baseTheme) + prevValue.wallpaper = if let type { + if case WallpaperType.empty = type { + nil as ThemeWallpaper? + } else { + ThemeWallpaper.from(type, prevValue.wallpaper?.background, prevValue.wallpaper?.tint) + } + } else { + nil + } + pref.set(overrides.replace(prevValue)) + var themeIds = currentThemeIdsDefault.get() + themeIds[nonSystemThemeName] = prevValue.themeId + currentThemeIdsDefault.set(themeIds) + applyTheme(nonSystemThemeName) + } + + static func copyFromSameThemeOverrides(_ type: WallpaperType?, _ lowerLevelOverride: ThemeModeOverride?, _ pref: Binding) -> Bool { + let overrides = themeOverridesDefault.get() + let sameWallpaper: ThemeWallpaper? = if let wallpaper = lowerLevelOverride?.wallpaper, lowerLevelOverride?.type?.sameType(type) == true { + wallpaper + } else { + overrides.sameTheme(type, CurrentColors.base.themeName)?.wallpaper + } + guard let sameWallpaper else { + if let type { + var w: ThemeWallpaper = ThemeWallpaper.from(type, nil, nil) + w.scale = nil + w.scaleType = nil + w.background = nil + w.tint = nil + pref.wrappedValue = ThemeModeOverride(mode: CurrentColors.base.mode, wallpaper: w) + } else { + // Make an empty wallpaper to override any top level ones + pref.wrappedValue = ThemeModeOverride(mode: CurrentColors.base.mode, wallpaper: ThemeWallpaper()) + } + return true + } + var type = sameWallpaper.toAppWallpaper().type + if case let WallpaperType.image(filename, scale, scaleType) = type, sameWallpaper.imageFile == filename { + // same image file. Needs to be copied first in order to be able to remove the file once it's not needed anymore without affecting main theme override + if let filename = saveWallpaperFile(url: getWallpaperFilePath(filename)) { + type = WallpaperType.image(filename, scale, scaleType) + } else { + logger.error("Error while copying wallpaper from global overrides to chat overrides") + return false + } + } + var prevValue = pref.wrappedValue + var w = ThemeWallpaper.from(type, nil, nil) + w.scale = nil + w.scaleType = nil + w.background = nil + w.tint = nil + prevValue.colors = ThemeColors() + prevValue.wallpaper = w + pref.wrappedValue = prevValue + return true + } + + static func applyWallpaper(_ type: WallpaperType?, _ pref: Binding) { + var prevValue = pref.wrappedValue + prevValue.wallpaper = if let type { + ThemeWallpaper.from(type, prevValue.wallpaper?.background, prevValue.wallpaper?.tint) + } else { + nil + } + pref.wrappedValue = prevValue + } + + static func saveAndApplyThemeOverrides(_ theme: ThemeOverrides, _ pref: CodableDefault<[ThemeOverrides]>? = nil) { + let wallpaper = theme.wallpaper?.importFromString() + let nonSystemThemeName = theme.base.themeName + let pref: CodableDefault<[ThemeOverrides]> = pref ?? themeOverridesDefault + let overrides = pref.get() + var prevValue = overrides.getTheme(nil, wallpaper?.toAppWallpaper().type, theme.base) ?? ThemeOverrides(base: theme.base) + if let imageFile = prevValue.wallpaper?.imageFile { + try? FileManager.default.removeItem(at: getWallpaperFilePath(imageFile)) + } + prevValue.base = theme.base + prevValue.colors = theme.colors + prevValue.wallpaper = wallpaper + pref.set(overrides.replace(prevValue)) + currentThemeDefault.set(nonSystemThemeName) + var currentThemeIds = currentThemeIdsDefault.get() + currentThemeIds[nonSystemThemeName] = prevValue.themeId + currentThemeIdsDefault.set(currentThemeIds) + applyTheme(nonSystemThemeName) + } + + static func resetAllThemeColors(_ pref: CodableDefault<[ThemeOverrides]>? = nil) { + let nonSystemThemeName = nonSystemThemeName() + let pref: CodableDefault<[ThemeOverrides]> = pref ?? themeOverridesDefault + let overrides = pref.get() + guard let themeId = currentThemeIdsDefault.get()[nonSystemThemeName], + var prevValue = overrides.getTheme(themeId) + else { return } + prevValue.colors = ThemeColors() + prevValue.wallpaper?.background = nil + prevValue.wallpaper?.tint = nil + pref.set(overrides.replace(prevValue)) + applyTheme(currentThemeDefault.get()) + } + + static func resetAllThemeColors(_ pref: Binding) { + var prevValue = pref.wrappedValue + prevValue.colors = ThemeColors() + prevValue.wallpaper?.background = nil + prevValue.wallpaper?.tint = nil + pref.wrappedValue = prevValue + } + + static func removeTheme(_ themeId: String?) { + var themes = themeOverridesDefault.get().map { $0 } + themes.removeAll(where: { $0.themeId == themeId }) + themeOverridesDefault.set(themes) + } +} diff --git a/apps/ios/Shared/Views/Call/AudioDevicePicker.swift b/apps/ios/Shared/Views/Call/AudioDevicePicker.swift index 3d846c7b68..be41741ab5 100644 --- a/apps/ios/Shared/Views/Call/AudioDevicePicker.swift +++ b/apps/ios/Shared/Views/Call/AudioDevicePicker.swift @@ -2,7 +2,7 @@ // MPVolumeView.swift // SimpleX (iOS) // -// Created by Stanislav on 24.04.2024. +// Created by Avently on 24.04.2024. // Copyright © 2024 SimpleX Chat. All rights reserved. // diff --git a/apps/ios/Shared/Views/Call/IncomingCallView.swift b/apps/ios/Shared/Views/Call/IncomingCallView.swift index 4647995b28..4960281d72 100644 --- a/apps/ios/Shared/Views/Call/IncomingCallView.swift +++ b/apps/ios/Shared/Views/Call/IncomingCallView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct IncomingCallView: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @ObservedObject var cc = CallController.shared var body: some View { @@ -43,7 +44,7 @@ struct IncomingCallView: View { cc.endCall(invitation: invitation) } - callButton("Ignore", "multiply", .accentColor) { + callButton("Ignore", "multiply", .primary) { cc.activeCallInvitation = nil } @@ -63,7 +64,7 @@ struct IncomingCallView: View { .padding(.horizontal, 16) .padding(.vertical, 12) .frame(maxWidth: .infinity) - .background(Color(uiColor: .tertiarySystemGroupedBackground)) + .modifier(ThemedBackground()) .onAppear { dismissAllSheets() } } @@ -76,7 +77,7 @@ struct IncomingCallView: View { .frame(width: 24, height: 24) Text(text) .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } .frame(minWidth: 44) }) diff --git a/apps/ios/Shared/Views/Chat/ChatInfoToolbar.swift b/apps/ios/Shared/Views/Chat/ChatInfoToolbar.swift index 140b609902..26749ed3ce 100644 --- a/apps/ios/Shared/Views/Chat/ChatInfoToolbar.swift +++ b/apps/ios/Shared/Views/Chat/ChatInfoToolbar.swift @@ -9,10 +9,9 @@ import SwiftUI import SimpleXChat -let chatImageColorLight = Color(red: 0.9, green: 0.9, blue: 0.9) -let chatImageColorDark = Color(red: 0.2, green: 0.2, blue: 0.2) struct ChatInfoToolbar: View { @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme @ObservedObject var chat: Chat var imageSize: CGFloat = 32 @@ -26,9 +25,7 @@ struct ChatInfoToolbar: View { ChatInfoImage( chat: chat, size: imageSize, - color: colorScheme == .dark - ? chatImageColorDark - : chatImageColorLight + color: Color(uiColor: .tertiaryLabel) ) .padding(.trailing, 4) VStack { @@ -41,14 +38,14 @@ struct ChatInfoToolbar: View { } } } - .foregroundColor(.primary) + .foregroundColor(theme.colors.onBackground) .frame(width: 220) } private var contactVerifiedShield: Text { (Text(Image(systemName: "checkmark.shield")) + Text(" ")) .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .baselineOffset(1) .kerning(-2) } @@ -57,5 +54,6 @@ struct ChatInfoToolbar: View { struct ChatInfoToolbar_Previews: PreviewProvider { static var previews: some View { ChatInfoToolbar(chat: Chat(chatInfo: ChatInfo.sampleData.direct, chatItems: [])) + .environmentObject(CurrentColors.toAppTheme()) } } diff --git a/apps/ios/Shared/Views/Chat/ChatInfoView.swift b/apps/ios/Shared/Views/Chat/ChatInfoView.swift index f5abfe9c58..ed589ec083 100644 --- a/apps/ios/Shared/Views/Chat/ChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatInfoView.swift @@ -36,14 +36,14 @@ func localizedInfoRow(_ title: LocalizedStringKey, _ value: LocalizedStringKey) } } -@ViewBuilder func smpServers(_ title: LocalizedStringKey, _ servers: [String]) -> some View { +@ViewBuilder func smpServers(_ title: LocalizedStringKey, _ servers: [String], _ secondaryColor: Color) -> some View { if servers.count > 0 { HStack { Text(title).frame(width: 120, alignment: .leading) Button(serverHost(servers[0])) { UIPasteboard.general.string = servers.joined(separator: ";") } - .foregroundColor(.secondary) + .foregroundColor(secondaryColor) .lineLimit(1) } } @@ -90,6 +90,7 @@ enum SendReceipts: Identifiable, Hashable { struct ChatInfoView: View { @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @Environment(\.dismiss) var dismiss: DismissAction @ObservedObject var chat: Chat @State var contact: Contact @@ -143,7 +144,7 @@ struct ChatInfoView: View { .listRowSeparator(.hidden) if let customUserProfile = customUserProfile { - Section("Incognito") { + Section(header: Text("Incognito").foregroundColor(theme.colors.secondary)) { HStack { Text("Your random profile") Spacer() @@ -161,6 +162,11 @@ struct ChatInfoView: View { connStats.ratchetSyncAllowed { synchronizeConnectionButton() } + NavigationLink { + ChatWallpaperEditorSheet(chat: chat) + } label: { + Label("Chat theme", systemImage: "photo") + } // } else if developerTools { // synchronizeConnectionButtonForce() // } @@ -183,13 +189,15 @@ struct ChatInfoView: View { } } header: { Text("Address") + .foregroundColor(theme.colors.secondary) } footer: { Text("You can share this address with your contacts to let them connect with **\(contact.displayName)**.") + .foregroundColor(theme.colors.secondary) } } if contact.ready && contact.active { - Section("Servers") { + Section(header: Text("Servers").foregroundColor(theme.colors.secondary)) { networkStatusRow() .onTapGesture { alert = .networkStatusAlert @@ -211,8 +219,8 @@ struct ChatInfoView: View { || connStats.ratchetSyncSendProhibited ) } - smpServers("Receiving via", connStats.rcvQueuesInfo.map { $0.rcvServer }) - smpServers("Sending via", connStats.sndQueuesInfo.map { $0.sndServer }) + smpServers("Receiving via", connStats.rcvQueuesInfo.map { $0.rcvServer }, theme.colors.secondary) + smpServers("Sending via", connStats.sndQueuesInfo.map { $0.sndServer }, theme.colors.secondary) } } } @@ -223,7 +231,7 @@ struct ChatInfoView: View { } if developerTools { - Section(header: Text("For console")) { + Section(header: Text("For console").foregroundColor(theme.colors.secondary)) { infoRow("Local name", chat.chatInfo.localDisplayName) infoRow("Database ID", "\(chat.chatInfo.apiId)") Button ("Debug delivery") { @@ -241,6 +249,7 @@ struct ChatInfoView: View { } } } + .modifier(ThemedBackground(grouped: true)) .navigationBarHidden(true) } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) @@ -292,7 +301,7 @@ struct ChatInfoView: View { if contact.verified { ( Text(Image(systemName: "checkmark.shield")) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .font(.title2) + Text(" ") + Text(contact.profile.displayName) @@ -332,7 +341,7 @@ struct ChatInfoView: View { setContactAlias() } .multilineTextAlignment(.center) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } private func setContactAlias() { @@ -370,6 +379,7 @@ struct ChatInfoView: View { ) .navigationBarTitleDisplayMode(.inline) .navigationTitle("Security code") + .modifier(ThemedBackground(grouped: true)) } label: { Label( contact.verified ? "View security code" : "Verify security code", @@ -386,6 +396,7 @@ struct ChatInfoView: View { currentFeaturesAllowed: contactUserPrefsToFeaturesAllowed(contact.mergedPreferences) ) .navigationBarTitle("Contact preferences") + .modifier(ThemedBackground(grouped: true)) .navigationBarTitleDisplayMode(.large) } label: { Label("Contact preferences", systemImage: "switch.2") @@ -434,11 +445,11 @@ struct ChatInfoView: View { HStack { Text("Network status") Image(systemName: "info.circle") - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) .font(.system(size: 14)) Spacer() Text(chatModel.contactNetworkStatus(contact).statusString) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) serverImage() } } @@ -446,7 +457,7 @@ struct ChatInfoView: View { private func serverImage() -> some View { let status = chatModel.contactNetworkStatus(contact) return Image(systemName: status.imageName) - .foregroundColor(status == .connected ? .green : .secondary) + .foregroundColor(status == .connected ? .green : theme.colors.secondary) .font(.system(size: 12)) } @@ -565,6 +576,148 @@ struct ChatInfoView: View { } } +struct ChatWallpaperEditorSheet: View { + @Environment(\.dismiss) var dismiss + @EnvironmentObject var theme: AppTheme + @State private var globalThemeUsed: Bool = false + @State var chat: Chat + @State private var themes: ThemeModeOverrides + + init(chat: Chat) { + self.chat = chat + self.themes = if case let ChatInfo.direct(contact) = chat.chatInfo, let uiThemes = contact.uiThemes { + uiThemes + } else if case let ChatInfo.group(groupInfo) = chat.chatInfo, let uiThemes = groupInfo.uiThemes { + uiThemes + } else { + ThemeModeOverrides() + } + } + + var body: some View { + let preferred = themes.preferredMode(!theme.colors.isLight) + let initialTheme = preferred ?? ThemeManager.defaultActiveTheme(ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + ChatWallpaperEditor( + initialTheme: initialTheme, + themeModeOverride: initialTheme, + applyToMode: themes.light == themes.dark ? nil : initialTheme.mode, + globalThemeUsed: $globalThemeUsed, + save: { applyToMode, newTheme in + await save(applyToMode, newTheme, $chat) + } + ) + .navigationTitle("Chat theme") + .modifier(ThemedBackground(grouped: true)) + .navigationBarTitleDisplayMode(.inline) + .onAppear { + globalThemeUsed = preferred == nil + } + .onChange(of: theme.base.mode) { _ in + globalThemeUsed = themesFromChat(chat).preferredMode(!theme.colors.isLight) == nil + } + .onChange(of: ChatModel.shared.chatId) { _ in + dismiss() + } + } + + private func themesFromChat(_ chat: Chat) -> ThemeModeOverrides { + if case let ChatInfo.direct(contact) = chat.chatInfo, let uiThemes = contact.uiThemes { + uiThemes + } else if case let ChatInfo.group(groupInfo) = chat.chatInfo, let uiThemes = groupInfo.uiThemes { + uiThemes + } else { + ThemeModeOverrides() + } + } + + private static var updateBackendTask: Task = Task {} + private func save( + _ applyToMode: DefaultThemeMode?, + _ newTheme: ThemeModeOverride?, + _ chat: Binding + ) async { + let unchangedThemes: ThemeModeOverrides = themesFromChat(chat.wrappedValue) + var wallpaperFiles = Set([unchangedThemes.light?.wallpaper?.imageFile, unchangedThemes.dark?.wallpaper?.imageFile]) + var changedThemes: ThemeModeOverrides? = unchangedThemes + let light: ThemeModeOverride? = if let newTheme { + ThemeModeOverride(mode: DefaultThemeMode.light, colors: newTheme.colors, wallpaper: newTheme.wallpaper?.withFilledWallpaperPath()) + } else { + nil + } + let dark: ThemeModeOverride? = if let newTheme { + ThemeModeOverride(mode: DefaultThemeMode.dark, colors: newTheme.colors, wallpaper: newTheme.wallpaper?.withFilledWallpaperPath()) + } else { + nil + } + + if let applyToMode { + switch applyToMode { + case DefaultThemeMode.light: + changedThemes?.light = light + case DefaultThemeMode.dark: + changedThemes?.dark = dark + } + } else { + changedThemes?.light = light + changedThemes?.dark = dark + } + if changedThemes?.light != nil || changedThemes?.dark != nil { + let light = changedThemes?.light + let dark = changedThemes?.dark + let currentMode = CurrentColors.base.mode + // same image file for both modes, copy image to make them as different files + if var light, var dark, let lightWallpaper = light.wallpaper, let darkWallpaper = dark.wallpaper, let lightImageFile = lightWallpaper.imageFile, let darkImageFile = darkWallpaper.imageFile, lightWallpaper.imageFile == darkWallpaper.imageFile { + let imageFile = if currentMode == DefaultThemeMode.light { + darkImageFile + } else { + lightImageFile + } + let filePath = saveWallpaperFile(url: getWallpaperFilePath(imageFile)) + if currentMode == DefaultThemeMode.light { + dark.wallpaper?.imageFile = filePath + changedThemes = ThemeModeOverrides(light: changedThemes?.light, dark: dark) + } else { + light.wallpaper?.imageFile = filePath + changedThemes = ThemeModeOverrides(light: light, dark: changedThemes?.dark) + } + } + } else { + changedThemes = nil + } + wallpaperFiles.remove(changedThemes?.light?.wallpaper?.imageFile) + wallpaperFiles.remove(changedThemes?.dark?.wallpaper?.imageFile) + wallpaperFiles.forEach(removeWallpaperFile) + + let changedThemesConstant = changedThemes + ChatWallpaperEditorSheet.updateBackendTask.cancel() + ChatWallpaperEditorSheet.updateBackendTask = Task { + do { + try await Task.sleep(nanoseconds: 300_000000) + if await apiSetChatUIThemes(chatId: chat.id, themes: changedThemesConstant) { + if case var ChatInfo.direct(contact) = chat.wrappedValue.chatInfo { + contact.uiThemes = changedThemesConstant + await MainActor.run { + ChatModel.shared.updateChatInfo(ChatInfo.direct(contact: contact)) + chat.wrappedValue = Chat.init(chatInfo: ChatInfo.direct(contact: contact)) + themes = themesFromChat(chat.wrappedValue) + } + } else if case var ChatInfo.group(groupInfo) = chat.wrappedValue.chatInfo { + groupInfo.uiThemes = changedThemesConstant + + await MainActor.run { + ChatModel.shared.updateChatInfo(ChatInfo.group(groupInfo: groupInfo)) + chat.wrappedValue = Chat.init(chatInfo: ChatInfo.group(groupInfo: groupInfo)) + themes = themesFromChat(chat.wrappedValue) + } + } + } + } catch { + // canceled task + } + } + } +} + func switchAddressAlert(_ switchAddress: @escaping () -> Void) -> Alert { Alert( title: Text("Change receiving address?"), diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CICallItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CICallItemView.swift index e3913431f5..3b3e1b3899 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CICallItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CICallItemView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct CICallItemView: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @ObservedObject var chat: Chat var chatItem: ChatItem var status: CICallStatus @@ -22,7 +23,7 @@ struct CICallItemView: View { switch status { case .pending: if sent { - Image(systemName: "phone.arrow.up.right").foregroundColor(.secondary) + Image(systemName: "phone.arrow.up.right").foregroundColor(theme.colors.secondary) } else { acceptCallButton() } @@ -35,7 +36,7 @@ struct CICallItemView: View { case .error: missedCallIcon(sent).foregroundColor(.orange) } - CIMetaView(chat: chat, chatItem: chatItem, showStatus: false, showEdited: false) + CIMetaView(chat: chat, chatItem: chatItem, metaColor: theme.colors.secondary, showStatus: false, showEdited: false) .padding(.bottom, 8) .padding(.horizontal, 12) } @@ -52,7 +53,7 @@ struct CICallItemView: View { @ViewBuilder private func endedCallIcon(_ sent: Bool) -> some View { HStack { Image(systemName: "phone.down") - Text(durationText(duration)).foregroundColor(.secondary) + Text(durationText(duration)).foregroundColor(theme.colors.secondary) } } @@ -70,7 +71,7 @@ struct CICallItemView: View { Label("Answer call", systemImage: "phone.arrow.down.left") } } else { - Image(systemName: "phone.arrow.down.left").foregroundColor(.secondary) + Image(systemName: "phone.arrow.down.left").foregroundColor(theme.colors.secondary) } } } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIChatFeatureView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIChatFeatureView.swift index 5c9ea0f6d8..c41039a4ef 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIChatFeatureView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIChatFeatureView.swift @@ -12,6 +12,7 @@ import SimpleXChat struct CIChatFeatureView: View { @EnvironmentObject var m: ChatModel @ObservedObject var chat: Chat + @EnvironmentObject var theme: AppTheme var chatItem: ChatItem @Binding var revealed: Bool var feature: Feature @@ -66,10 +67,10 @@ struct CIChatFeatureView: View { private func featureInfo(_ ci: ChatItem) -> FeatureInfo? { switch ci.content { - case let .rcvChatFeature(feature, enabled, param): FeatureInfo(feature, enabled.iconColor, param) - case let .sndChatFeature(feature, enabled, param): FeatureInfo(feature, enabled.iconColor, param) - case let .rcvGroupFeature(feature, preference, param, role): FeatureInfo(feature, preference.enabled(role, for: chat.chatInfo.groupInfo?.membership).iconColor, param) - case let .sndGroupFeature(feature, preference, param, role): FeatureInfo(feature, preference.enabled(role, for: chat.chatInfo.groupInfo?.membership).iconColor, param) + case let .rcvChatFeature(feature, enabled, param): FeatureInfo(feature, enabled.iconColor(theme.colors.secondary), param) + case let .sndChatFeature(feature, enabled, param): FeatureInfo(feature, enabled.iconColor(theme.colors.secondary), param) + case let .rcvGroupFeature(feature, preference, param, role): FeatureInfo(feature, preference.enabled(role, for: chat.chatInfo.groupInfo?.membership).iconColor(theme.colors.secondary), param) + case let .sndGroupFeature(feature, preference, param, role): FeatureInfo(feature, preference.enabled(role, for: chat.chatInfo.groupInfo?.membership).iconColor(theme.colors.secondary), param) default: nil } } @@ -81,7 +82,7 @@ struct CIChatFeatureView: View { if let param = f.param { HStack { i - chatEventText(Text(param)).lineLimit(1) + chatEventText(Text(param), theme.colors.secondary).lineLimit(1) } } else { i @@ -93,7 +94,7 @@ struct CIChatFeatureView: View { Image(systemName: icon ?? feature.iconFilled) .foregroundColor(iconColor) .scaleEffect(feature.iconScale) - chatEventText(chatItem) + chatEventText(chatItem, theme.colors.secondary) } .padding(.horizontal, 6) .padding(.vertical, 4) @@ -104,6 +105,6 @@ struct CIChatFeatureView: View { struct CIChatFeatureView_Previews: PreviewProvider { static var previews: some View { let enabled = FeatureEnabled(forUser: false, forContact: false) - CIChatFeatureView(chat: Chat.sampleData, chatItem: ChatItem.getChatFeatureSample(.fullDelete, enabled), revealed: Binding.constant(true), feature: ChatFeature.fullDelete, iconColor: enabled.iconColor) + CIChatFeatureView(chat: Chat.sampleData, chatItem: ChatItem.getChatFeatureSample(.fullDelete, enabled), revealed: Binding.constant(true), feature: ChatFeature.fullDelete, iconColor: enabled.iconColor(.secondary)) } } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIFeaturePreferenceView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIFeaturePreferenceView.swift index e52a92a3c6..752f599c8d 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIFeaturePreferenceView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIFeaturePreferenceView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct CIFeaturePreferenceView: View { @ObservedObject var chat: Chat + @EnvironmentObject var theme: AppTheme var chatItem: ChatItem var feature: ChatFeature var allowed: FeatureAllowed @@ -19,7 +20,7 @@ struct CIFeaturePreferenceView: View { var body: some View { HStack(alignment: .center, spacing: 4) { Image(systemName: feature.icon) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .scaleEffect(feature.iconScale) if let ct = chat.chatInfo.contact, allowed != .no && ct.allowsFeature(feature) && !ct.userAllowsFeature(feature) { @@ -40,17 +41,17 @@ struct CIFeaturePreferenceView: View { private func featurePreferenceView(acceptText: LocalizedStringKey? = nil) -> some View { var r = Text(CIContent.preferenceText(feature, allowed, param) + " ") .fontWeight(.light) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) if let acceptText { r = r + Text(acceptText) .fontWeight(.medium) - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) + Text(" ") } r = r + chatItem.timestampText .fontWeight(.light) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) return r.font(.caption) } } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift index 6def90ebe9..414da5371a 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIFileView.swift @@ -11,7 +11,7 @@ import SimpleXChat struct CIFileView: View { @EnvironmentObject var m: ChatModel - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme let file: CIFile? let edited: Bool @@ -30,12 +30,12 @@ struct CIFileView: View { Text(file.fileName) .lineLimit(1) .multilineTextAlignment(.leading) - .foregroundColor(.primary) + .foregroundColor(theme.colors.onBackground) Text(prettyFileSize + metaReserve) .font(.caption) .lineLimit(1) .multilineTextAlignment(.leading) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } } else { Text(metaReserve) @@ -170,7 +170,7 @@ struct CIFileView: View { case .sndWarning: fileIcon("doc.fill", innerIcon: "exclamationmark.triangle.fill", innerIconSize: 10) case .rcvInvitation: if fileSizeValid(file) { - fileIcon("arrow.down.doc.fill", color: .accentColor) + fileIcon("arrow.down.doc.fill", color: theme.colors.primary) } else { fileIcon("doc.fill", color: .orange, innerIcon: "exclamationmark", innerIconSize: 12) } @@ -182,7 +182,7 @@ struct CIFileView: View { progressView() } case .rcvAborted: - fileIcon("doc.fill", color: .accentColor, innerIcon: "exclamationmark.arrow.circlepath", innerIconSize: 12) + fileIcon("doc.fill", color: theme.colors.primary, innerIcon: "exclamationmark.arrow.circlepath", innerIconSize: 12) case .rcvComplete: fileIcon("doc.fill") case .rcvCancelled: fileIcon("doc.fill", innerIcon: "xmark", innerIconSize: 10) case .rcvError: fileIcon("doc.fill", innerIcon: "xmark", innerIconSize: 10) diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIGroupInvitationView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIGroupInvitationView.swift index 2f92f778c3..62e9852853 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIGroupInvitationView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIGroupInvitationView.swift @@ -11,7 +11,7 @@ import SimpleXChat struct CIGroupInvitationView: View { @EnvironmentObject var chatModel: ChatModel - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme @ObservedObject var chat: Chat var chatItem: ChatItem var groupInvitation: CIGroupInvitation @@ -42,7 +42,7 @@ struct CIGroupInvitationView: View { .overlay(DetermineWidth()) ( Text(chatIncognito ? "Tap to join incognito" : "Tap to join") - .foregroundColor(inProgress ? .secondary : chatIncognito ? .indigo : .accentColor) + .foregroundColor(inProgress ? theme.colors.secondary : chatIncognito ? .indigo : theme.colors.primary) .font(.callout) + Text(" ") + ciMetaText(chatItem.meta, chatTTL: nil, encrypted: nil, transparent: true, showStatus: false, showEdited: false, showViaProxy: showSentViaProxy) @@ -65,11 +65,11 @@ struct CIGroupInvitationView: View { } } - CIMetaView(chat: chat, chatItem: chatItem, showStatus: false, showEdited: false) + CIMetaView(chat: chat, chatItem: chatItem, metaColor: theme.colors.secondary, showStatus: false, showEdited: false) } .padding(.horizontal, 12) .padding(.vertical, 6) - .background(chatItemFrameColor(chatItem, colorScheme)) + .background(chatItemFrameColor(chatItem, theme)) .cornerRadius(18) .textSelection(.disabled) .onPreferenceChange(DetermineWidth.Key.self) { frameWidth = $0 } @@ -99,7 +99,7 @@ struct CIGroupInvitationView: View { private func groupInfoView(_ action: Bool) -> some View { var color: Color if action && !inProgress { - color = chatIncognito ? .indigo : .accentColor + color = chatIncognito ? .indigo : theme.colors.primary } else { color = Color(uiColor: .tertiaryLabel) } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift index 5aacc335ab..9c12653343 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIImageView.swift @@ -11,7 +11,6 @@ import SimpleXChat struct CIImageView: View { @EnvironmentObject var m: ChatModel - @Environment(\.colorScheme) var colorScheme let chatItem: ChatItem var preview: UIImage? let maxWidth: CGFloat diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIInvalidJSONView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIInvalidJSONView.swift index 40ed8bc76c..f9802089df 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIInvalidJSONView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIInvalidJSONView.swift @@ -9,6 +9,7 @@ import SwiftUI struct CIInvalidJSONView: View { + @EnvironmentObject var theme: AppTheme var json: String @State private var showJSON = false @@ -44,6 +45,7 @@ func invalidJSONView(_ json: String) -> some View { } .frame(maxHeight: .infinity) .padding() + .modifier(ThemedBackground()) } struct CIInvalidJSONView_Previews: PreviewProvider { diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CILinkView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CILinkView.swift index 4c12c7312a..0f7ea9a716 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CILinkView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CILinkView.swift @@ -10,7 +10,7 @@ import SwiftUI import SimpleXChat struct CILinkView: View { - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme let linkPreview: LinkPreview var body: some View { @@ -32,7 +32,7 @@ struct CILinkView: View { Text(linkPreview.uri.absoluteString) .font(.caption) .lineLimit(1) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } .padding(.horizontal, 12) .frame(maxWidth: .infinity, alignment: .leading) diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIMemberCreatedContactView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIMemberCreatedContactView.swift index da82ed4dd2..463695ddb7 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIMemberCreatedContactView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIMemberCreatedContactView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct CIMemberCreatedContactView: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme var chatItem: ChatItem var body: some View { @@ -43,12 +44,12 @@ struct CIMemberCreatedContactView: View { r = r + Text(openText) .fontWeight(.medium) - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) + Text(" ") } r = r + chatItem.timestampText .fontWeight(.light) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) return r.font(.caption) } @@ -56,11 +57,11 @@ struct CIMemberCreatedContactView: View { if let member = chatItem.memberDisplayName { return Text(member + " " + chatItem.content.text + " ") .fontWeight(.light) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } else { return Text(chatItem.content.text + " ") .fontWeight(.light) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } } } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIMetaView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIMetaView.swift index 24c2c07962..66b810cf2f 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIMetaView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIMetaView.swift @@ -11,8 +11,9 @@ import SimpleXChat struct CIMetaView: View { @ObservedObject var chat: Chat + @EnvironmentObject var theme: AppTheme var chatItem: ChatItem - var metaColor = Color.secondary + var metaColor: Color var paleMetaColor = Color(UIColor.tertiaryLabel) var showStatus = true var showEdited = true @@ -63,6 +64,7 @@ func ciMetaText( chatTTL: Int?, encrypted: Bool?, color: Color = .clear, + primaryColor: Color = .accentColor, transparent: Bool = false, sent: SentCheckmark? = nil, showStatus: Bool = true, @@ -85,7 +87,7 @@ func ciMetaText( r = r + statusIconText("arrow.forward", color.opacity(0.67)).font(.caption2) } if showStatus { - if let (icon, statusColor) = meta.statusIcon(color) { + if let (icon, statusColor) = meta.statusIcon(color, primaryColor) { let t = Text(Image(systemName: icon)).font(.caption2) let gap = Text(" ").kerning(-1.25) let t1 = t.foregroundColor(transparent ? .clear : statusColor.opacity(0.67)) @@ -112,15 +114,16 @@ private func statusIconText(_ icon: String, _ color: Color) -> Text { } struct CIMetaView_Previews: PreviewProvider { + static let metaColor = Color.secondary static var previews: some View { Group { - CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directSnd, .now, "https://simplex.chat", .sndSent(sndProgress: .complete))) - CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directSnd, .now, "https://simplex.chat", .sndSent(sndProgress: .partial))) - CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directSnd, .now, "https://simplex.chat", .sndRcvd(msgRcptStatus: .ok, sndProgress: .complete))) - CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directSnd, .now, "https://simplex.chat", .sndRcvd(msgRcptStatus: .ok, sndProgress: .partial))) - CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directSnd, .now, "https://simplex.chat", .sndRcvd(msgRcptStatus: .badMsgHash, sndProgress: .complete))) - CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directSnd, .now, "https://simplex.chat", .sndSent(sndProgress: .complete), itemEdited: true)) - CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getDeletedContentSample()) + CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directSnd, .now, "https://simplex.chat", .sndSent(sndProgress: .complete)), metaColor: metaColor) + CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directSnd, .now, "https://simplex.chat", .sndSent(sndProgress: .partial)), metaColor: metaColor) + CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directSnd, .now, "https://simplex.chat", .sndRcvd(msgRcptStatus: .ok, sndProgress: .complete)), metaColor: metaColor) + CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directSnd, .now, "https://simplex.chat", .sndRcvd(msgRcptStatus: .ok, sndProgress: .partial)), metaColor: metaColor) + CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directSnd, .now, "https://simplex.chat", .sndRcvd(msgRcptStatus: .badMsgHash, sndProgress: .complete)), metaColor: metaColor) + CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, .directSnd, .now, "https://simplex.chat", .sndSent(sndProgress: .complete), itemEdited: true), metaColor: metaColor) + CIMetaView(chat: Chat.sampleData, chatItem: ChatItem.getDeletedContentSample(), metaColor: metaColor) } .previewLayout(.fixed(width: 360, height: 100)) } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIRcvDecryptionError.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIRcvDecryptionError.swift index da9d5e7d50..e127ca86cf 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIRcvDecryptionError.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIRcvDecryptionError.swift @@ -13,6 +13,7 @@ let decryptErrorReason: LocalizedStringKey = "It can happen when you or your con struct CIRcvDecryptionError: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @ObservedObject var chat: Chat var msgDecryptError: MsgDecryptError var msgCount: UInt32 @@ -114,18 +115,18 @@ struct CIRcvDecryptionError: View { } ( Text(Image(systemName: "exclamationmark.arrow.triangle.2.circlepath")) - .foregroundColor(syncSupported ? .accentColor : .secondary) + .foregroundColor(syncSupported ? theme.colors.primary : theme.colors.secondary) .font(.callout) + Text(" ") + Text("Fix connection") - .foregroundColor(syncSupported ? .accentColor : .secondary) + .foregroundColor(syncSupported ? theme.colors.primary : theme.colors.secondary) .font(.callout) + Text(" ") + ciMetaText(chatItem.meta, chatTTL: nil, encrypted: nil, transparent: true, showViaProxy: showSentViaProxy) ) } .padding(.horizontal, 12) - CIMetaView(chat: chat, chatItem: chatItem) + CIMetaView(chat: chat, chatItem: chatItem, metaColor: theme.colors.secondary) .padding(.horizontal, 12) } .onTapGesture(perform: { onClick() }) @@ -145,7 +146,7 @@ struct CIRcvDecryptionError: View { + ciMetaText(chatItem.meta, chatTTL: nil, encrypted: nil, transparent: true, showViaProxy: showSentViaProxy) } .padding(.horizontal, 12) - CIMetaView(chat: chat, chatItem: chatItem) + CIMetaView(chat: chat, chatItem: chatItem, metaColor: theme.colors.secondary) .padding(.horizontal, 12) } .onTapGesture(perform: { onClick() }) diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIVideoView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIVideoView.swift index 055a235970..c31c4a0da9 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIVideoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIVideoView.swift @@ -13,7 +13,6 @@ import Combine struct CIVideoView: View { @EnvironmentObject var m: ChatModel - @Environment(\.colorScheme) var colorScheme private let chatItem: ChatItem private let preview: UIImage? @State private var duration: Int diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIVoiceView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIVoiceView.swift index 4d950a0d99..ad15d0d342 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIVoiceView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIVoiceView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct CIVoiceView: View { @ObservedObject var chat: Chat + @EnvironmentObject var theme: AppTheme var chatItem: ChatItem let recordingFile: CIFile? let duration: Int @@ -72,7 +73,7 @@ struct CIVoiceView: View { playbackState: $playbackState, playbackTime: $playbackTime ) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } private func playbackSlider() -> some View { @@ -89,10 +90,11 @@ struct CIVoiceView: View { allowMenu = true } } + .tint(theme.colors.primary) } private func metaView() -> some View { - CIMetaView(chat: chat, chatItem: chatItem) + CIMetaView(chat: chat, chatItem: chatItem, metaColor: theme.colors.secondary) } } @@ -118,7 +120,7 @@ struct VoiceMessagePlayerTime: View { struct VoiceMessagePlayer: View { @EnvironmentObject var chatModel: ChatModel - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme var chatItem: ChatItem var recordingFile: CIFile? var recordingTime: TimeInterval @@ -216,26 +218,26 @@ struct VoiceMessagePlayer: View { startPlayback(recordingSource) } } label: { - playPauseIcon("play.fill") + playPauseIcon("play.fill", theme.colors.primary) } case .playing: Button { audioPlayer?.pause() playbackState = .paused } label: { - playPauseIcon("pause.fill") + playPauseIcon("pause.fill", theme.colors.primary) } case .paused: Button { audioPlayer?.play() playbackState = .playing } label: { - playPauseIcon("play.fill") + playPauseIcon("play.fill", theme.colors.primary) } } } - private func playPauseIcon(_ image: String, _ color: Color = .accentColor) -> some View { + private func playPauseIcon(_ image: String, _ color: Color/* = .accentColor*/) -> some View { ZStack { Image(systemName: image) .resizable() @@ -244,7 +246,7 @@ struct VoiceMessagePlayer: View { .foregroundColor(color) .padding(.leading, image == "play.fill" ? 4 : 0) .frame(width: 56, height: 56) - .background(showBackground ? chatItemFrameColor(chatItem, colorScheme) : .clear) + .background(showBackground ? chatItemFrameColor(chatItem, theme) : .clear) .clipShape(Circle()) if recordingTime > 0 { ProgressCircle(length: recordingTime, progress: $playbackTime) @@ -261,11 +263,12 @@ struct VoiceMessagePlayer: View { } } } label: { - playPauseIcon(icon) + playPauseIcon(icon, theme.colors.primary) } } private struct ProgressCircle: View { + @EnvironmentObject var theme: AppTheme var length: TimeInterval @Binding var progress: TimeInterval? @@ -273,7 +276,7 @@ struct VoiceMessagePlayer: View { Circle() .trim(from: 0, to: ((progress ?? TimeInterval(0)) / length)) .stroke( - Color.accentColor, + theme.colors.primary, style: StrokeStyle(lineWidth: 3) ) .rotationEffect(.degrees(-90)) @@ -288,7 +291,7 @@ struct VoiceMessagePlayer: View { .frame(width: size, height: size) .foregroundColor(Color(uiColor: .tertiaryLabel)) .frame(width: 56, height: 56) - .background(showBackground ? chatItemFrameColor(chatItem, colorScheme) : .clear) + .background(showBackground ? chatItemFrameColor(chatItem, theme) : .clear) .clipShape(Circle()) } @@ -296,7 +299,7 @@ struct VoiceMessagePlayer: View { ProgressView() .frame(width: 30, height: 30) .frame(width: 56, height: 56) - .background(showBackground ? chatItemFrameColor(chatItem, colorScheme) : .clear) + .background(showBackground ? chatItemFrameColor(chatItem, theme) : .clear) .clipShape(Circle()) } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/DeletedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/DeletedItemView.swift index 4763707421..54356c5a6e 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/DeletedItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/DeletedItemView.swift @@ -10,21 +10,21 @@ import SwiftUI import SimpleXChat struct DeletedItemView: View { - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme @ObservedObject var chat: Chat var chatItem: ChatItem var body: some View { HStack(alignment: .bottom, spacing: 0) { Text(chatItem.content.text) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .italic() - CIMetaView(chat: chat, chatItem: chatItem) + CIMetaView(chat: chat, chatItem: chatItem, metaColor: theme.colors.secondary) .padding(.horizontal, 12) } .padding(.leading, 12) .padding(.vertical, 6) - .background(chatItemFrameColor(chatItem, colorScheme)) + .background(chatItemFrameColor(chatItem, theme)) .cornerRadius(18) .textSelection(.disabled) } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift index f57e45fed0..250d9d5636 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct EmojiItemView: View { @ObservedObject var chat: Chat + @EnvironmentObject var theme: AppTheme var chatItem: ChatItem var body: some View { @@ -18,7 +19,7 @@ struct EmojiItemView: View { emojiText(chatItem.content.text) .padding(.top, 8) .padding(.horizontal, 6) - CIMetaView(chat: chat, chatItem: chatItem) + CIMetaView(chat: chat, chatItem: chatItem, metaColor: theme.colors.secondary) .padding(.bottom, 8) .padding(.horizontal, 12) } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/FramedCIVoiceView.swift b/apps/ios/Shared/Views/Chat/ChatItem/FramedCIVoiceView.swift index af5c917dc8..59fabb3901 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/FramedCIVoiceView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/FramedCIVoiceView.swift @@ -12,6 +12,7 @@ import SwiftUI import SimpleXChat struct FramedCIVoiceView: View { + @EnvironmentObject var theme: AppTheme var chatItem: ChatItem let recordingFile: CIFile? let duration: Int @@ -42,7 +43,7 @@ struct FramedCIVoiceView: View { playbackState: $playbackState, playbackTime: $playbackTime ) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .frame(width: 50, alignment: .leading) if .playing == playbackState || (playbackTime ?? 0) > 0 || !allowMenu { playbackSlider() diff --git a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift index f8c5f3a4da..db1a74e213 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift @@ -9,17 +9,10 @@ import SwiftUI import SimpleXChat -let notesChatColorLight = Color(.sRGB, red: 0.27, green: 0.72, blue: 1, opacity: 0.21) -let notesChatColorDark = Color(.sRGB, red: 0.27, green: 0.72, blue: 1, opacity: 0.19) -let sentColorLight = Color(.sRGB, red: 0.27, green: 0.72, blue: 1, opacity: 0.12) -let sentColorDark = Color(.sRGB, red: 0.27, green: 0.72, blue: 1, opacity: 0.17) -private let sentQuoteColorLight = Color(.sRGB, red: 0.27, green: 0.72, blue: 1, opacity: 0.11) -private let sentQuoteColorDark = Color(.sRGB, red: 0.27, green: 0.72, blue: 1, opacity: 0.09) - struct FramedItemView: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @EnvironmentObject var scrollModel: ReverseListScrollModel - @Environment(\.colorScheme) var colorScheme @ObservedObject var chat: Chat var chatItem: ChatItem var preview: UIImage? @@ -28,7 +21,7 @@ struct FramedItemView: View { @State var msgWidth: CGFloat = 0 var imgWidth: CGFloat? = nil var videoWidth: CGFloat? = nil - @State var metaColor = Color.secondary + @State private var useWhiteMetaColor: Bool = false @State var showFullScreenImage = false @Binding var allowMenu: Bool @State private var showSecrets = false @@ -73,18 +66,16 @@ struct FramedItemView: View { .padding(chatItem.content.msgContent != nil ? 0 : 4) .overlay(DetermineWidth()) } - .onPreferenceChange(MetaColorPreferenceKey.self) { metaColor = $0 } if chatItem.content.msgContent != nil { - CIMetaView(chat: chat, chatItem: chatItem, metaColor: metaColor) + CIMetaView(chat: chat, chatItem: chatItem, metaColor: useWhiteMetaColor ? Color.white : theme.colors.secondary) .padding(.horizontal, 12) .padding(.bottom, 6) .overlay(DetermineWidth()) .accessibilityLabel("") } } - .background(chatItemFrameColorMaybeImageOrVideo(chatItem, colorScheme)) - .background(Color(.systemBackground)) + .background(chatItemFrameColorMaybeImageOrVideo(chatItem, theme)) .cornerRadius(18) .onPreferenceChange(DetermineWidth.Key.self) { msgWidth = $0 } @@ -121,10 +112,12 @@ struct FramedItemView: View { if text == "" && !chatItem.meta.isLive { Color.clear .frame(width: 0, height: 0) - .preference( - key: MetaColorPreferenceKey.self, - value: .white - ) + .onAppear { + useWhiteMetaColor = true + } + .onDisappear { + useWhiteMetaColor = false + } } else { ciMsgContentView(chatItem) } @@ -134,10 +127,12 @@ struct FramedItemView: View { if text == "" && !chatItem.meta.isLive { Color.clear .frame(width: 0, height: 0) - .preference( - key: MetaColorPreferenceKey.self, - value: .white - ) + .onAppear { + useWhiteMetaColor = true + } + .onDisappear { + useWhiteMetaColor = false + } } else { ciMsgContentView(chatItem) } @@ -176,12 +171,13 @@ struct FramedItemView: View { .font(.caption) .lineLimit(1) } - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .padding(.horizontal, 12) .padding(.top, 6) .padding(.bottom, pad || (chatItem.quotedItem == nil && chatItem.meta.itemForwarded == nil) ? 6 : 0) .overlay(DetermineWidth()) .frame(minWidth: msgWidth, alignment: .leading) + .background(chatItemFrameContextColor(chatItem, theme)) if let mediaWidth = maxMediaWidth(), mediaWidth < maxWidth { v.frame(maxWidth: mediaWidth, alignment: .leading) } else { @@ -233,7 +229,7 @@ struct FramedItemView: View { // if enable this always, size of the framed voice message item will be incorrect after end of playback .overlay { if case .voice = chatItem.content.msgContent {} else { DetermineWidth() } } .frame(minWidth: msgWidth, alignment: .leading) - .background(chatItemFrameContextColor(chatItem, colorScheme)) + .background(chatItemFrameContextColor(chatItem, theme)) if let mediaWidth = maxMediaWidth(), mediaWidth < maxWidth { v.frame(maxWidth: mediaWidth, alignment: .leading) @@ -248,7 +244,7 @@ struct FramedItemView: View { VStack(alignment: .leading, spacing: 2) { Text(sender) .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .lineLimit(1) ciQuotedMsgTextView(qi, lines: 2) } @@ -347,13 +343,6 @@ func isRightToLeft(_ s: String) -> Bool { return false } -private struct MetaColorPreferenceKey: PreferenceKey { - static var defaultValue = Color.secondary - static func reduce(value: inout Color, nextValue: () -> Color) { - value = nextValue() - } -} - func onlyImageOrVideo(_ ci: ChatItem) -> Bool { if case let .image(text, _) = ci.content.msgContent { return ci.meta.itemDeleted == nil && !ci.meta.isLive && ci.quotedItem == nil && ci.meta.itemForwarded == nil && text == "" @@ -363,22 +352,22 @@ func onlyImageOrVideo(_ ci: ChatItem) -> Bool { return false } -func chatItemFrameColorMaybeImageOrVideo(_ ci: ChatItem, _ colorScheme: ColorScheme) -> Color { +func chatItemFrameColorMaybeImageOrVideo(_ ci: ChatItem, _ theme: AppTheme) -> Color { onlyImageOrVideo(ci) ? Color.clear - : chatItemFrameColor(ci, colorScheme) + : chatItemFrameColor(ci, theme) } -func chatItemFrameColor(_ ci: ChatItem, _ colorScheme: ColorScheme) -> Color { +func chatItemFrameColor(_ ci: ChatItem, _ theme: AppTheme) -> Color { ci.chatDir.sent - ? (colorScheme == .light ? sentColorLight : sentColorDark) - : Color(uiColor: .tertiarySystemGroupedBackground) + ? theme.appColors.sentMessage + : theme.appColors.receivedMessage } -func chatItemFrameContextColor(_ ci: ChatItem, _ colorScheme: ColorScheme) -> Color { +func chatItemFrameContextColor(_ ci: ChatItem, _ theme: AppTheme) -> Color { ci.chatDir.sent - ? (colorScheme == .light ? sentQuoteColorLight : sentQuoteColorDark) - : Color(uiColor: .quaternarySystemFill) + ? theme.appColors.sentQuote + : theme.appColors.receivedQuote } struct FramedItemView_Previews: PreviewProvider { diff --git a/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift index 1aa0093c9a..de71b1fa08 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct IntegrityErrorItemView: View { @ObservedObject var chat: Chat + @EnvironmentObject var theme: AppTheme var msgError: MsgErrorType var chatItem: ChatItem @@ -54,6 +55,7 @@ struct IntegrityErrorItemView: View { struct CIMsgError: View { @ObservedObject var chat: Chat + @EnvironmentObject var theme: AppTheme var chatItem: ChatItem var onTap: () -> Void @@ -62,7 +64,7 @@ struct CIMsgError: View { Text(chatItem.content.text) .foregroundColor(.red) .italic() - CIMetaView(chat: chat, chatItem: chatItem) + CIMetaView(chat: chat, chatItem: chatItem, metaColor: theme.colors.secondary) .padding(.horizontal, 12) } .padding(.leading, 12) diff --git a/apps/ios/Shared/Views/Chat/ChatItem/MarkedDeletedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/MarkedDeletedItemView.swift index cb0b61f537..b81f113d22 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/MarkedDeletedItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/MarkedDeletedItemView.swift @@ -11,7 +11,7 @@ import SimpleXChat struct MarkedDeletedItemView: View { @EnvironmentObject var m: ChatModel - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme @ObservedObject var chat: Chat var chatItem: ChatItem @Binding var revealed: Bool @@ -19,10 +19,10 @@ struct MarkedDeletedItemView: View { var body: some View { (Text(mergedMarkedDeletedText).italic() + Text(" ") + chatItem.timestampText) .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .padding(.horizontal, 12) .padding(.vertical, 6) - .background(chatItemFrameColor(chatItem, colorScheme)) + .background(chatItemFrameColor(chatItem, theme)) .cornerRadius(18) .textSelection(.disabled) } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/MsgContentView.swift b/apps/ios/Shared/Views/Chat/ChatItem/MsgContentView.swift index 11e94cb2c9..999f99b294 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/MsgContentView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/MsgContentView.swift @@ -26,6 +26,7 @@ private func typing(_ w: Font.Weight = .light) -> Text { struct MsgContentView: View { @ObservedObject var chat: Chat + @EnvironmentObject var theme: AppTheme var text: String var formattedText: [FormattedText]? = nil var sender: String? = nil @@ -65,7 +66,7 @@ struct MsgContentView: View { } private func msgContentView() -> Text { - var v = messageText(text, formattedText, sender, showSecrets: showSecrets) + var v = messageText(text, formattedText, sender, showSecrets: showSecrets, secondaryColor: theme.colors.secondary) if let mt = meta { if mt.isLive { v = v + typingIndicator(mt.recent) @@ -79,7 +80,7 @@ struct MsgContentView: View { return (recent ? typingIndicators[typingIdx] : noTyping) .font(.body.monospaced()) .kerning(-2) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } private func reserveSpaceForMeta(_ mt: CIMeta) -> Text { @@ -87,7 +88,7 @@ struct MsgContentView: View { } } -func messageText(_ text: String, _ formattedText: [FormattedText]?, _ sender: String?, icon: String? = nil, preview: Bool = false, showSecrets: Bool) -> Text { +func messageText(_ text: String, _ formattedText: [FormattedText]?, _ sender: String?, icon: String? = nil, preview: Bool = false, showSecrets: Bool, secondaryColor: Color) -> Text { let s = text var res: Text if let ft = formattedText, ft.count > 0 && ft.count <= 200 { @@ -102,7 +103,7 @@ func messageText(_ text: String, _ formattedText: [FormattedText]?, _ sender: St } if let i = icon { - res = Text(Image(systemName: i)).foregroundColor(Color(uiColor: .tertiaryLabel)) + Text(" ") + res + res = Text(Image(systemName: i)).foregroundColor(secondaryColor) + Text(" ") + res } if let s = sender { diff --git a/apps/ios/Shared/Views/Chat/ChatItemForwardingView.swift b/apps/ios/Shared/Views/Chat/ChatItemForwardingView.swift index f90653534c..1814419623 100644 --- a/apps/ios/Shared/Views/Chat/ChatItemForwardingView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItemForwardingView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct ChatItemForwardingView: View { @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @Environment(\.dismiss) var dismiss var ci: ChatItem @@ -38,6 +39,7 @@ struct ChatItemForwardingView: View { } } } + .modifier(ThemedBackground()) .alert(item: $alert) { $0.alert } } @@ -45,7 +47,7 @@ struct ChatItemForwardingView: View { VStack(alignment: .leading) { if !chatsToForwardTo.isEmpty { List { - searchFieldView(text: $searchText, focussed: $searchFocused) + searchFieldView(text: $searchText, focussed: $searchFocused, theme.colors.onBackground, theme.colors.secondary) .padding(.leading, 2) let s = searchText.trimmingCharacters(in: .whitespaces).localizedLowercase let chats = s == "" ? chatsToForwardTo : chatsToForwardTo.filter { foundChat($0, s) } @@ -54,8 +56,13 @@ struct ChatItemForwardingView: View { .disabled(chatModel.deletedChats.contains(chat.chatInfo.id)) } } + .modifier(ThemedBackground(grouped: true)) } else { - emptyList() + ZStack { + emptyList() + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .modifier(ThemedBackground()) } } } @@ -106,10 +113,10 @@ struct ChatItemForwardingView: View { private func emptyList() -> some View { Text("No filtered chats") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .frame(maxWidth: .infinity) } - + @ViewBuilder private func forwardListChatView(_ chat: Chat) -> some View { let prohibited = prohibitedByPref(chat) Button { @@ -139,7 +146,7 @@ struct ChatItemForwardingView: View { ChatInfoImage(chat: chat, size: 30) .padding(.trailing, 2) Text(chat.chatInfo.chatViewName) - .foregroundColor(prohibited ? .secondary : .primary) + .foregroundColor(prohibited ? theme.colors.secondary : theme.colors.onBackground) .lineLimit(1) if chat.chatInfo.incognito { Spacer() @@ -147,7 +154,7 @@ struct ChatItemForwardingView: View { .resizable() .scaledToFit() .frame(width: 22, height: 22) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } } .frame(maxWidth: .infinity, alignment: .leading) @@ -181,5 +188,5 @@ private func canForwardToChat(_ chat: Chat) -> Bool { ci: ChatItem.getSample(1, .directSnd, .now, "hello"), fromChatInfo: .direct(contact: Contact.sampleData), composeState: Binding.constant(ComposeState(message: "hello")) - ) + ).environmentObject(CurrentColors.toAppTheme()) } diff --git a/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift b/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift index f5da473fd6..a55b07495a 100644 --- a/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift @@ -12,7 +12,7 @@ import SimpleXChat struct ChatItemInfoView: View { @EnvironmentObject var chatModel: ChatModel @Environment(\.dismiss) var dismiss - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme var ci: ChatItem @Binding var chatItemInfo: ChatItemInfo? @State private var selection: CIInfoTab = .history @@ -101,12 +101,14 @@ struct ChatItemInfoView: View { Label("History", systemImage: "clock") } .tag(CIInfoTab.history) + .modifier(ThemedBackground()) if let qi = ci.quotedItem { quoteTab(qi) .tabItem { Label("In reply to", systemImage: "arrowshape.turn.up.left") } .tag(CIInfoTab.quote) + .modifier(ThemedBackground()) } if let forwardedFromItem = chatItemInfo?.forwardedFromChatItem { forwardedFromTab(forwardedFromItem) @@ -114,6 +116,7 @@ struct ChatItemInfoView: View { Label(local ? "Saved" : "Forwarded", systemImage: "arrowshape.turn.up.forward") } .tag(CIInfoTab.forwarded) + .modifier(ThemedBackground()) } } .onAppear { @@ -123,6 +126,7 @@ struct ChatItemInfoView: View { } } else { historyTab() + .modifier(ThemedBackground()) } } @@ -212,7 +216,7 @@ struct ChatItemInfoView: View { } else { Text("No history") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .frame(maxWidth: .infinity) } } @@ -227,7 +231,7 @@ struct ChatItemInfoView: View { textBubble(itemVersion.msgContent.text, itemVersion.formattedText, nil) .padding(.horizontal, 12) .padding(.vertical, 6) - .background(chatItemFrameColor(ci, colorScheme)) + .background(chatItemFrameColor(ci, theme)) .cornerRadius(18) .contextMenu { if itemVersion.msgContent.text != "" { @@ -258,18 +262,19 @@ struct ChatItemInfoView: View { } else { Text("no text") .italic() - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } } private struct TextBubble: View { + @EnvironmentObject var theme: AppTheme var text: String var formattedText: [FormattedText]? var sender: String? = nil @State private var showSecrets = false var body: some View { - toggleSecrets(formattedText, $showSecrets, messageText(text, formattedText, sender, showSecrets: showSecrets)) + toggleSecrets(formattedText, $showSecrets, messageText(text, formattedText, sender, showSecrets: showSecrets, secondaryColor: theme.colors.secondary)) } } @@ -296,7 +301,7 @@ struct ChatItemInfoView: View { textBubble(qi.text, qi.formattedText, qi.getSender(nil)) .padding(.horizontal, 12) .padding(.vertical, 6) - .background(quotedMsgFrameColor(qi, colorScheme)) + .background(quotedMsgFrameColor(qi, theme)) .cornerRadius(18) .contextMenu { if qi.text != "" { @@ -320,10 +325,10 @@ struct ChatItemInfoView: View { .frame(maxWidth: maxWidth, alignment: .leading) } - func quotedMsgFrameColor(_ qi: CIQuote, _ colorScheme: ColorScheme) -> Color { + func quotedMsgFrameColor(_ qi: CIQuote, _ theme: AppTheme) -> Color { (qi.chatDir?.sent ?? false) - ? (colorScheme == .light ? sentColorLight : sentColorDark) - : Color(uiColor: .tertiarySystemGroupedBackground) + ? theme.appColors.sentMessage + : theme.appColors.receivedMessage } @ViewBuilder private func forwardedFromTab(_ forwardedFromItem: AChatItem) -> some View { @@ -358,7 +363,7 @@ struct ChatItemInfoView: View { Divider().padding(.top, 32) Text("Recipient(s) can't see who this message is from.") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } } } @@ -372,23 +377,23 @@ struct ChatItemInfoView: View { VStack(alignment: .leading) { Text("you") .italic() - .foregroundColor(.primary) + .foregroundColor(theme.colors.onBackground) Text(forwardedFromItem.chatInfo.chatViewName) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .lineLimit(1) } } else if case let .groupRcv(groupMember) = forwardedFromItem.chatItem.chatDir { VStack(alignment: .leading) { Text(groupMember.chatViewName) - .foregroundColor(.primary) + .foregroundColor(theme.colors.onBackground) .lineLimit(1) Text(forwardedFromItem.chatInfo.chatViewName) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .lineLimit(1) } } else { Text(forwardedFromItem.chatInfo.chatViewName) - .foregroundColor(.primary) + .foregroundColor(theme.colors.onBackground) .lineLimit(1) } } @@ -418,7 +423,7 @@ struct ChatItemInfoView: View { } } else { Text("No delivery information") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } } } @@ -442,10 +447,10 @@ struct ChatItemInfoView: View { Spacer() if sentViaProxy == true { Image(systemName: "arrow.forward") - .foregroundColor(.secondary).opacity(0.67) + .foregroundColor(theme.colors.secondary).opacity(0.67) } let v = Group { - if let (icon, statusColor) = status.statusIcon(Color.secondary) { + if let (icon, statusColor) = status.statusIcon(theme.colors.secondary, theme.colors.primary) { switch status { case .sndRcvd: ZStack(alignment: .trailing) { diff --git a/apps/ios/Shared/Views/Chat/ChatItemView.swift b/apps/ios/Shared/Views/Chat/ChatItemView.swift index a0c8254496..4cb97112ca 100644 --- a/apps/ios/Shared/Views/Chat/ChatItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItemView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct ChatItemView: View { @ObservedObject var chat: Chat + @EnvironmentObject var theme: AppTheme var chatItem: ChatItem var maxWidth: CGFloat = .infinity @Binding var revealed: Bool @@ -95,6 +96,7 @@ struct ChatItemView: View { struct ChatItemContentView: View { @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @ObservedObject var chat: Chat var chatItem: ChatItem @Binding var revealed: Bool @@ -124,14 +126,14 @@ struct ChatItemContentView: View { case .sndGroupEvent: eventItemView() case .rcvConnEvent: eventItemView() case .sndConnEvent: eventItemView() - case let .rcvChatFeature(feature, enabled, _): chatFeatureView(feature, enabled.iconColor) - case let .sndChatFeature(feature, enabled, _): chatFeatureView(feature, enabled.iconColor) + case let .rcvChatFeature(feature, enabled, _): chatFeatureView(feature, enabled.iconColor(theme.colors.secondary)) + case let .sndChatFeature(feature, enabled, _): chatFeatureView(feature, enabled.iconColor(theme.colors.secondary)) case let .rcvChatPreference(feature, allowed, param): CIFeaturePreferenceView(chat: chat, chatItem: chatItem, feature: feature, allowed: allowed, param: param) case let .sndChatPreference(feature, _, _): - CIChatFeatureView(chat: chat, chatItem: chatItem, revealed: $revealed, feature: feature, icon: feature.icon, iconColor: .secondary) - case let .rcvGroupFeature(feature, preference, _, role): chatFeatureView(feature, preference.enabled(role, for: chat.chatInfo.groupInfo?.membership).iconColor) - case let .sndGroupFeature(feature, preference, _, role): chatFeatureView(feature, preference.enabled(role, for: chat.chatInfo.groupInfo?.membership).iconColor) + CIChatFeatureView(chat: chat, chatItem: chatItem, revealed: $revealed, feature: feature, icon: feature.icon, iconColor: theme.colors.secondary) + case let .rcvGroupFeature(feature, preference, _, role): chatFeatureView(feature, preference.enabled(role, for: chat.chatInfo.groupInfo?.membership).iconColor(theme.colors.secondary)) + case let .sndGroupFeature(feature, preference, _, role): chatFeatureView(feature, preference.enabled(role, for: chat.chatInfo.groupInfo?.membership).iconColor(theme.colors.secondary)) case let .rcvChatFeatureRejected(feature): chatFeatureView(feature, .red) case let .rcvGroupFeatureRejected(feature): chatFeatureView(feature, .red) case .sndModerated: deletedItemView() @@ -158,20 +160,20 @@ struct ChatItemContentView: View { } private func eventItemView() -> some View { - return CIEventView(eventText: eventItemViewText()) + CIEventView(eventText: eventItemViewText(theme.colors.secondary)) } - private func eventItemViewText() -> Text { + private func eventItemViewText(_ secondaryColor: Color) -> Text { if !revealed, let t = mergedGroupEventText { - return chatEventText(t + Text(" ") + chatItem.timestampText) + return chatEventText(t + Text(" ") + chatItem.timestampText, secondaryColor) } else if let member = chatItem.memberDisplayName { return Text(member + " ") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(secondaryColor) .fontWeight(.light) - + chatEventText(chatItem) + + chatEventText(chatItem, secondaryColor) } else { - return chatEventText(chatItem) + return chatEventText(chatItem, secondaryColor) } } @@ -206,7 +208,7 @@ struct ChatItemContentView: View { info.pqEnabled ? Text("Messages, files and calls are protected by **quantum resistant e2e encryption** with perfect forward secrecy, repudiation and break-in recovery.") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .fontWeight(.light) : e2eeInfoNoPQText() } @@ -214,24 +216,24 @@ struct ChatItemContentView: View { private func e2eeInfoNoPQText() -> Text { Text("Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery.") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .fontWeight(.light) } } -func chatEventText(_ text: Text) -> Text { +func chatEventText(_ text: Text, _ secondaryColor: Color) -> Text { text .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(secondaryColor) .fontWeight(.light) } -func chatEventText(_ eventText: LocalizedStringKey, _ ts: Text) -> Text { - chatEventText(Text(eventText) + Text(" ") + ts) +func chatEventText(_ eventText: LocalizedStringKey, _ ts: Text, _ secondaryColor: Color) -> Text { + chatEventText(Text(eventText) + Text(" ") + ts, secondaryColor) } -func chatEventText(_ ci: ChatItem) -> Text { - chatEventText("\(ci.content.text)", ci.timestampText) +func chatEventText(_ ci: ChatItem, _ secondaryColor: Color) -> Text { + chatEventText("\(ci.content.text)", ci.timestampText, secondaryColor) } struct ChatItemView_Previews: PreviewProvider { diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index 7ab4913bf3..34ad68f031 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -15,8 +15,9 @@ private let memberImageSize: CGFloat = 34 struct ChatView: View { @EnvironmentObject var chatModel: ChatModel - @Environment(\.colorScheme) var colorScheme + @State var theme: AppTheme = buildTheme() @Environment(\.dismiss) var dismiss + @Environment(\.colorScheme) var colorScheme @Environment(\.presentationMode) var presentationMode @Environment(\.scenePhase) var scenePhase @State @ObservedObject var chat: Chat @@ -61,7 +62,16 @@ struct ChatView: View { Divider() } ZStack(alignment: .bottomTrailing) { + let wallpaperImage = theme.wallpaper.type.image + let wallpaperType = theme.wallpaper.type + let backgroundColor = theme.wallpaper.background ?? wallpaperType.defaultBackgroundColor(theme.base, theme.colors.background) + let tintColor = theme.wallpaper.tint ?? wallpaperType.defaultTintColor(theme.base) chatItemsList() + .if(wallpaperImage != nil) { view in + view.modifier( + ChatViewBackground(image: wallpaperImage!, imageType: wallpaperType, background: backgroundColor, tint: tintColor) + ) + } floatingButtons(counts: floatingButtonModel.unreadChatItemCounts) } connectingText() @@ -74,7 +84,9 @@ struct ChatView: View { } .padding(.top, 1) .navigationTitle(cInfo.chatViewName) + .background(theme.colors.background) .navigationBarTitleDisplayMode(.inline) + .environmentObject(theme) .onAppear { loadChat(chat: chat) initChatView() @@ -86,6 +98,7 @@ struct ChatView: View { chat = c } initChatView() + theme = buildTheme() } else { dismiss() } @@ -113,6 +126,9 @@ struct ChatView: View { } } } + .onChange(of: colorScheme) { _ in + theme = buildTheme() + } .toolbar { ToolbarItem(placement: .principal) { if case let .direct(contact) = cInfo { @@ -141,6 +157,7 @@ struct ChatView: View { connectionStats = nil customUserProfile = nil connectionCode = nil + theme = buildTheme() }) { ChatInfoView(chat: chat, contact: contact, connectionStats: $connectionStats, customUserProfile: $customUserProfile, localAlias: chat.chatInfo.localAlias, connectionCode: $connectionCode) } @@ -149,8 +166,9 @@ struct ChatView: View { Task { await loadGroupMembers(groupInfo) { showChatInfoSheet = true } } } label: { ChatInfoToolbar(chat: chat) + .tint(theme.colors.primary) } - .appSheet(isPresented: $showChatInfoSheet) { + .appSheet(isPresented: $showChatInfoSheet, onDismiss: { theme = buildTheme() }) { GroupChatInfoView( chat: chat, groupInfo: Binding( @@ -278,7 +296,7 @@ struct ChatView: View { Image(systemName: "magnifyingglass") TextField("Search", text: $searchText) .focused($searchFocussed) - .foregroundColor(.primary) + .foregroundColor(theme.colors.onBackground) .frame(maxWidth: .infinity) Button { @@ -288,7 +306,7 @@ struct ChatView: View { } } .padding(EdgeInsets(top: 7, leading: 7, bottom: 7, trailing: 7)) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .background(Color(.tertiarySystemFill)) .cornerRadius(10.0) @@ -321,8 +339,8 @@ struct ChatView: View { } .map { $0.element } } - - + + private func chatItemsList() -> some View { let cInfo = chat.chatInfo let mergedItems = filtered(chatModel.reversedChatItems) @@ -371,7 +389,7 @@ struct ChatView: View { !contact.nextSendGrpInv { Text("connecting…") .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .padding(.top) } else { EmptyView() @@ -434,7 +452,7 @@ struct ChatView: View { circleButton { unreadCountText(unreadAbove) .font(.callout) - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) } .onTapGesture { scrollModel.scrollToNextPage() @@ -454,7 +472,7 @@ struct ChatView: View { circleButton { unreadCountText(counts.unreadBelow) .font(.callout) - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) } .onTapGesture { if let latestUnreadItem = filtered(chatModel.reversedChatItems).last(where: { $0.isRcvNew }) { @@ -464,7 +482,7 @@ struct ChatView: View { } else if counts.totalBelow > 16 { circleButton { Image(systemName: "chevron.down") - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) } .onTapGesture { scrollModel.scrollToBottom() } } @@ -594,7 +612,7 @@ struct ChatView: View { private struct ChatItemWithMenu: View { @EnvironmentObject var m: ChatModel - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme @ObservedObject var chat: Chat var chatItem: ChatItem var maxWidth: CGFloat @@ -638,7 +656,7 @@ struct ChatView: View { } .onAppear { markRead( - chatItems: range.flatMap { m.reversedChatItems[$0] } + chatItems: range.flatMap { m.reversedChatItems[$0] } ?? [chatItem] ) } @@ -678,7 +696,7 @@ struct ChatView: View { .padding(.top, 7) } HStack(alignment: .top, spacing: 8) { - ProfileImage(imageStr: member.memberProfile.image, size: memberImageSize) + ProfileImage(imageStr: member.memberProfile.image, size: memberImageSize, backgroundColor: theme.colors.background) .onTapGesture { if chatView.membersLoaded { selectedMember = m.getGroupMember(member.groupMemberId) @@ -803,7 +821,7 @@ struct ChatView: View { Text("\(r.totalReacted)") .font(.caption) .fontWeight(r.userReacted ? .bold : .light) - .foregroundColor(r.userReacted ? .accentColor : .secondary) + .foregroundColor(r.userReacted ? theme.colors.primary : theme.colors.secondary) } } .padding(.horizontal, 6) @@ -1306,6 +1324,27 @@ struct ChatView: View { } } +private func buildTheme() -> AppTheme { + if let cId = ChatModel.shared.chatId, let chat = ChatModel.shared.getChat(cId) { + let perChatTheme = if case let .direct(contact) = chat.chatInfo { + contact.uiThemes?.preferredMode(!AppTheme.shared.colors.isLight) + } else if case let .group(groupInfo) = chat.chatInfo { + groupInfo.uiThemes?.preferredMode(!AppTheme.shared.colors.isLight) + } else { + nil as ThemeModeOverride? + } + let overrides = if perChatTheme != nil { + ThemeManager.currentColors(nil, perChatTheme, ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + } else { + nil as ThemeManager.ActiveTheme? + } + let theme = overrides ?? CurrentColors + return AppTheme(name: theme.name, base: theme.base, colors: theme.colors, appColors: theme.appColors, wallpaper: theme.wallpaper) + } else { + return AppTheme.shared + } +} + struct ToggleNtfsButton: View { @ObservedObject var chat: Chat diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeFileView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeFileView.swift index bc6a96aa86..488fe0a65d 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeFileView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeFileView.swift @@ -9,7 +9,7 @@ import SwiftUI struct ComposeFileView: View { - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme let fileName: String let cancelFile: (() -> Void) let cancelEnabled: Bool @@ -33,7 +33,7 @@ struct ComposeFileView: View { .padding(.vertical, 1) .padding(.trailing, 12) .frame(height: 50) - .background(colorScheme == .light ? sentColorLight : sentColorDark) + .background(theme.appColors.sentMessage) .frame(maxWidth: .infinity) .padding(.top, 8) } diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeImageView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeImageView.swift index edaf86912c..52655f1c6a 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeImageView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeImageView.swift @@ -10,7 +10,7 @@ import SwiftUI import SimpleXChat struct ComposeImageView: View { - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme let images: [String] let cancelImage: (() -> Void) let cancelEnabled: Bool @@ -48,7 +48,7 @@ struct ComposeImageView: View { } .padding(.vertical, 1) .padding(.trailing, 12) - .background(colorScheme == .light ? sentColorLight : sentColorDark) + .background(theme.appColors.sentMessage) .frame(maxWidth: .infinity) .padding(.top, 8) } diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeLinkView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeLinkView.swift index cc779851ab..4137370e3f 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeLinkView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeLinkView.swift @@ -40,7 +40,7 @@ func getLinkPreview(url: URL, cb: @escaping (LinkPreview?) -> Void) { } struct ComposeLinkView: View { - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme let linkPreview: LinkPreview? var cancelPreview: (() -> Void)? = nil let cancelEnabled: Bool @@ -62,7 +62,7 @@ struct ComposeLinkView: View { } .padding(.vertical, 1) .padding(.trailing, 12) - .background(colorScheme == .light ? sentColorLight : sentColorDark) + .background(theme.appColors.sentMessage) .frame(maxWidth: .infinity) .padding(.top, 8) } @@ -82,7 +82,7 @@ struct ComposeLinkView: View { Text(linkPreview.uri.absoluteString) .font(.caption) .lineLimit(1) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } .padding(.vertical, 5) .frame(maxWidth: .infinity, minHeight: 60, maxHeight: 60) diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift index 8a0ad9a023..819b337a73 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift @@ -254,6 +254,7 @@ enum UploadContent: Equatable { struct ComposeView: View { @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @ObservedObject var chat: Chat @Binding var composeState: ComposeState @Binding var keyboardVisible: Bool @@ -314,6 +315,7 @@ struct ComposeView: View { .frame(width: 25, height: 25) .padding(.bottom, 12) .padding(.leading, 12) + .tint(theme.colors.primary) if case let .group(g) = chat.chatInfo, !g.fullGroupPreferences.files.on(for: g.membership) { b.disabled(true).onTapGesture { @@ -354,16 +356,16 @@ struct ComposeView: View { keyboardVisible: $keyboardVisible, sendButtonColor: chat.chatInfo.incognito ? .indigo.opacity(colorScheme == .dark ? 1 : 0.7) - : .accentColor + : theme.colors.primary ) .padding(.trailing, 12) - .background(.background) + .background(theme.colors.background) .disabled(!chat.userCanSend) if chat.userIsObserver { Text("you are observer") .italic() - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .padding(.horizontal, 12) .onTapGesture { AlertManager.shared.showAlertMsg( @@ -655,7 +657,7 @@ struct ComposeView: View { private func msgNotAllowedView(_ reason: LocalizedStringKey, icon: String) -> some View { HStack { - Image(systemName: icon).foregroundColor(.secondary) + Image(systemName: icon).foregroundColor(theme.colors.secondary) Text(reason).italic() } .padding(12) diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeVoiceView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeVoiceView.swift index 2617bc77bc..4b813d35cb 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeVoiceView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeVoiceView.swift @@ -25,7 +25,7 @@ func voiceMessageTime_(_ time: TimeInterval?) -> String { struct ComposeVoiceView: View { @EnvironmentObject var chatModel: ChatModel - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme var recordingFileName: String @Binding var recordingTime: TimeInterval? @Binding var recordingState: VoiceMessageRecordingState @@ -50,7 +50,7 @@ struct ComposeVoiceView: View { } .padding(.vertical, 1) .frame(height: ComposeVoiceView.previewHeight) - .background(colorScheme == .light ? sentColorLight : sentColorDark) + .background(theme.appColors.sentMessage) .frame(maxWidth: .infinity) .padding(.top, 8) } @@ -80,7 +80,7 @@ struct ComposeVoiceView: View { Button { startPlayback() } label: { - playPauseIcon("play.fill") + playPauseIcon("play.fill", theme.colors.primary) } Text(voiceMessageTime_(recordingTime)) case .playing: @@ -88,7 +88,7 @@ struct ComposeVoiceView: View { audioPlayer?.pause() playbackState = .paused } label: { - playPauseIcon("pause.fill") + playPauseIcon("pause.fill", theme.colors.primary) } Text(voiceMessageTime_(playbackTime)) case .paused: @@ -96,7 +96,7 @@ struct ComposeVoiceView: View { audioPlayer?.play() playbackState = .playing } label: { - playPauseIcon("play.fill") + playPauseIcon("play.fill", theme.colors.primary) } Text(voiceMessageTime_(playbackTime)) } @@ -131,7 +131,7 @@ struct ComposeVoiceView: View { } } - private func playPauseIcon(_ image: String, _ color: Color = .accentColor) -> some View { + private func playPauseIcon(_ image: String, _ color: Color) -> some View { Image(systemName: image) .resizable() .aspectRatio(contentMode: .fit) @@ -147,9 +147,11 @@ struct ComposeVoiceView: View { } label: { Image(systemName: "multiply") } + .tint(theme.colors.primary) } struct SliderBar: View { + @EnvironmentObject var theme: AppTheme var length: TimeInterval @Binding var progress: TimeInterval? var seek: (TimeInterval) -> Void @@ -158,10 +160,12 @@ struct ComposeVoiceView: View { Slider(value: Binding(get: { progress ?? TimeInterval(0) }, set: { seek($0) }), in: 0 ... length) .frame(maxWidth: .infinity) .frame(height: 4) + .tint(theme.colors.primary) } } private struct ProgressBar: View { + @EnvironmentObject var theme: AppTheme var length: TimeInterval @Binding var progress: TimeInterval? @@ -169,7 +173,7 @@ struct ComposeVoiceView: View { GeometryReader { geometry in ZStack { Rectangle() - .fill(Color.accentColor) + .fill(theme.colors.primary) .frame(width: min(CGFloat((progress ?? TimeInterval(0)) / length) * geometry.size.width, geometry.size.width), height: 4) .animation(.linear, value: progress) } diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ContextInvitingContactMemberView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ContextInvitingContactMemberView.swift index acb4f6d3e1..cd6f5961cd 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ContextInvitingContactMemberView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ContextInvitingContactMemberView.swift @@ -9,18 +9,18 @@ import SwiftUI struct ContextInvitingContactMemberView: View { - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme var body: some View { HStack { Image(systemName: "message") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) Text("Send direct message to connect") } .padding(12) .frame(minHeight: 50) .frame(maxWidth: .infinity, alignment: .leading) - .background(colorScheme == .light ? sentColorLight : sentColorDark) + .background(theme.appColors.sentMessage) .padding(.top, 8) } } diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ContextItemView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ContextItemView.swift index 2777d8321c..3c89cbeb85 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ContextItemView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ContextItemView.swift @@ -10,7 +10,7 @@ import SwiftUI import SimpleXChat struct ContextItemView: View { - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme @ObservedObject var chat: Chat let contextItem: ChatItem let contextIcon: String @@ -23,10 +23,10 @@ struct ContextItemView: View { .resizable() .aspectRatio(contentMode: .fit) .frame(width: 16, height: 16) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) if showSender, let sender = contextItem.memberDisplayName { VStack(alignment: .leading, spacing: 4) { - Text(sender).font(.caption).foregroundColor(.secondary) + Text(sender).font(.caption).foregroundColor(theme.colors.secondary) msgContentView(lines: 2) } } else { @@ -40,11 +40,12 @@ struct ContextItemView: View { } label: { Image(systemName: "multiply") } + .tint(theme.colors.primary) } .padding(12) .frame(minHeight: 50) .frame(maxWidth: .infinity) - .background(chatItemFrameColor(contextItem, colorScheme)) + .background(chatItemFrameColor(contextItem, theme)) .padding(.top, 8) } @@ -55,7 +56,7 @@ struct ContextItemView: View { } private func contextMsgPreview() -> Text { - return attachment() + messageText(contextItem.text, contextItem.formattedText, nil, preview: true, showSecrets: false) + return attachment() + messageText(contextItem.text, contextItem.formattedText, nil, preview: true, showSecrets: false, secondaryColor: theme.colors.secondary) func attachment() -> Text { switch contextItem.content.msgContent { diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/NativeTextEditor.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/NativeTextEditor.swift index f2c7221835..ad47b7351a 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/NativeTextEditor.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/NativeTextEditor.swift @@ -28,6 +28,7 @@ struct NativeTextEditor: UIViewRepresentable { func makeUIView(context: Context) -> UITextView { let field = CustomUITextField(height: _height) + field.backgroundColor = .clear field.text = text field.textAlignment = alignment(text) field.autocapitalizationType = .sentences diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift index a180efbd28..a52cc7f71a 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/SendMessageView.swift @@ -13,6 +13,7 @@ private let liveMsgInterval: UInt64 = 3000_000000 struct SendMessageView: View { @Binding var composeState: ComposeState + @EnvironmentObject var theme: AppTheme var sendMessage: (Int?) -> Void var sendLiveMessage: (() async -> Void)? = nil var updateLiveMessage: (() async -> Void)? = nil @@ -49,7 +50,7 @@ struct SendMessageView: View { Text("Voice message…") .font(teFont.italic()) .multilineTextAlignment(.leading) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .padding(.horizontal, 10) .padding(.vertical, 8) .frame(maxWidth: .infinity) @@ -247,6 +248,7 @@ struct SendMessageView: View { } private struct RecordVoiceMessageButton: View { + @EnvironmentObject var theme: AppTheme var startVoiceMessageRecording: (() -> Void)? var finishVoiceMessageRecording: (() -> Void)? @Binding var holdingVMR: Bool @@ -256,7 +258,7 @@ struct SendMessageView: View { var body: some View { Button(action: {}) { Image(systemName: "mic.fill") - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) } .disabled(disabled) .frame(width: 29, height: 29) @@ -309,7 +311,7 @@ struct SendMessageView: View { } } label: { Image(systemName: "mic") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } .disabled(composeState.inProgress) .frame(width: 29, height: 29) @@ -323,7 +325,7 @@ struct SendMessageView: View { Image(systemName: "multiply") .resizable() .scaledToFit() - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) .frame(width: 15, height: 15) } .frame(width: 29, height: 29) @@ -340,7 +342,7 @@ struct SendMessageView: View { Image(systemName: "bolt.fill") .resizable() .scaledToFit() - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) .frame(width: 20, height: 20) } .frame(width: 29, height: 29) @@ -383,7 +385,7 @@ struct SendMessageView: View { } Task { _ = try? await Task.sleep(nanoseconds: liveMsgInterval) - while composeState.liveMessage != nil { + while await composeState.liveMessage != nil { await update() _ = try? await Task.sleep(nanoseconds: liveMsgInterval) } @@ -394,7 +396,7 @@ struct SendMessageView: View { private func finishVoiceMessageRecordingButton() -> some View { Button(action: { finishVoiceMessageRecording?() }) { Image(systemName: "stop.fill") - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) } .disabled(composeState.inProgress) .frame(width: 29, height: 29) diff --git a/apps/ios/Shared/Views/Chat/ContactPreferencesView.swift b/apps/ios/Shared/Views/Chat/ContactPreferencesView.swift index 86acbf6d54..b3fab958bc 100644 --- a/apps/ios/Shared/Views/Chat/ContactPreferencesView.swift +++ b/apps/ios/Shared/Views/Chat/ContactPreferencesView.swift @@ -12,6 +12,7 @@ import SimpleXChat struct ContactPreferencesView: View { @Environment(\.dismiss) var dismiss: DismissAction @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @Binding var contact: Contact @State var featuresAllowed: ContactFeaturesAllowed @State var currentFeaturesAllowed: ContactFeaturesAllowed @@ -66,8 +67,8 @@ struct ContactPreferencesView: View { .frame(height: 36) infoRow("Contact allows", pref.contactPreference.allow.text) } - header: { featureHeader(feature, enabled) } - footer: { featureFooter(feature, enabled) } + header: { featureHeader(feature, enabled).foregroundColor(theme.colors.secondary) } + footer: { featureFooter(feature, enabled).foregroundColor(theme.colors.secondary) } } private func timedMessagesFeatureSection() -> some View { @@ -102,8 +103,8 @@ struct ContactPreferencesView: View { infoRow("Delete after", timeText(pref.contactPreference.ttl)) } } - header: { featureHeader(.timedMessages, enabled) } - footer: { featureFooter(.timedMessages, enabled) } + header: { featureHeader(.timedMessages, enabled).foregroundColor(theme.colors.secondary) } + footer: { featureFooter(.timedMessages, enabled).foregroundColor(theme.colors.secondary) } } private func featureHeader(_ feature: ChatFeature, _ enabled: FeatureEnabled) -> some View { diff --git a/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift b/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift index ed2afb91b3..49239c8fa5 100644 --- a/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift +++ b/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift @@ -21,6 +21,7 @@ struct AddGroupMembersView: View { struct AddGroupMembersViewCommon: View { @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme var chat: Chat @State var groupInfo: GroupInfo var creatingGroup: Bool = false @@ -70,7 +71,7 @@ struct AddGroupMembersViewCommon: View { if (membersToAdd.isEmpty) { Text("No contacts to add") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .padding() .frame(maxWidth: .infinity, alignment: .center) .listRowBackground(Color.clear) @@ -90,16 +91,18 @@ struct AddGroupMembersViewCommon: View { Button { selectedContacts.removeAll() } label: { Text("Clear").font(.caption) } Spacer() Text("\(count) contact(s) selected") + .foregroundColor(theme.colors.secondary) } } else { Text("No contacts selected") .frame(maxWidth: .infinity, alignment: .trailing) + .foregroundColor(theme.colors.secondary) } } } Section { - searchFieldView(text: $searchText, focussed: $searchFocussed) + searchFieldView(text: $searchText, focussed: $searchFocussed, theme.colors.primary, theme.colors.secondary) .padding(.leading, 2) let s = searchText.trimmingCharacters(in: .whitespaces).localizedLowercase let members = s == "" ? membersToAdd : membersToAdd.filter { $0.chatViewName.localizedLowercase.contains(s) } @@ -125,6 +128,7 @@ struct AddGroupMembersViewCommon: View { .onChange(of: selectedContacts) { _ in searchFocussed = false } + .modifier(ThemedBackground(grouped: true)) } private func inviteMembersButton() -> some View { @@ -172,14 +176,14 @@ struct AddGroupMembersViewCommon: View { var iconColor: Color if prohibitedToInviteIncognito { icon = "theatermasks.circle.fill" - iconColor = Color(uiColor: .tertiaryLabel) + iconColor = Color(uiColor: .tertiaryLabel).asAnotherColorFromSecondary(theme) } else { if checked { icon = "checkmark.circle.fill" - iconColor = .accentColor + iconColor = theme.colors.primary } else { icon = "circle" - iconColor = Color(uiColor: .tertiaryLabel) + iconColor = Color(uiColor: .tertiaryLabel).asAnotherColorFromSecondary(theme) } } return Button { @@ -197,7 +201,7 @@ struct AddGroupMembersViewCommon: View { ProfileImage(imageStr: contact.image, size: 30) .padding(.trailing, 2) Text(ChatInfo.direct(contact: contact).chatViewName) - .foregroundColor(prohibitedToInviteIncognito ? .secondary : .primary) + .foregroundColor(prohibitedToInviteIncognito ? theme.colors.secondary : theme.colors.onBackground) .lineLimit(1) Spacer() Image(systemName: icon) @@ -207,7 +211,7 @@ struct AddGroupMembersViewCommon: View { } } -func searchFieldView(text: Binding, focussed: FocusState.Binding) -> some View { +func searchFieldView(text: Binding, focussed: FocusState.Binding, _ onBackgroundColor: Color, _ secondaryColor: Color) -> some View { HStack { Image(systemName: "magnifyingglass") .resizable() @@ -216,7 +220,7 @@ func searchFieldView(text: Binding, focussed: FocusState.Binding) .padding(.trailing, 10) TextField("Search", text: text) .focused(focussed) - .foregroundColor(.primary) + .foregroundColor(onBackgroundColor) .frame(maxWidth: .infinity) Image(systemName: "xmark.circle.fill") .resizable() @@ -228,7 +232,7 @@ func searchFieldView(text: Binding, focussed: FocusState.Binding) focussed.wrappedValue = false } } - .foregroundColor(.secondary) + .foregroundColor(secondaryColor) .frame(height: 36) } diff --git a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift index c22f3f0fed..8fff94871e 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift @@ -13,6 +13,7 @@ let SMALL_GROUPS_RCPS_MEM_LIMIT: Int = 20 struct GroupChatInfoView: View { @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @Environment(\.dismiss) var dismiss: DismissAction @ObservedObject var chat: Chat @Binding var groupInfo: GroupInfo @@ -81,13 +82,19 @@ struct GroupChatInfoView: View { } else { sendReceiptsOptionDisabled() } + NavigationLink { + ChatWallpaperEditorSheet(chat: chat) + } label: { + Label("Chat theme", systemImage: "photo") + } } header: { Text("") } footer: { Text("Only group owners can change group preferences.") + .foregroundColor(theme.colors.secondary) } - Section("\(members.count + 1) members") { + Section(header: Text("\(members.count + 1) members").foregroundColor(theme.colors.secondary)) { if groupInfo.canAddMembers { groupLinkButton() if (chat.chatInfo.incognito) { @@ -99,7 +106,7 @@ struct GroupChatInfoView: View { } } if members.count > 8 { - searchFieldView(text: $searchText, focussed: $searchFocussed) + searchFieldView(text: $searchText, focussed: $searchFocussed, theme.colors.onBackground, theme.colors.secondary) .padding(.leading, 8) } let s = searchText.trimmingCharacters(in: .whitespaces).localizedLowercase @@ -129,12 +136,13 @@ struct GroupChatInfoView: View { } if developerTools { - Section(header: Text("For console")) { + Section(header: Text("For console").foregroundColor(theme.colors.secondary)) { infoRow("Local name", chat.chatInfo.localDisplayName) infoRow("Database ID", "\(chat.chatInfo.apiId)") } } } + .modifier(ThemedBackground(grouped: true)) .navigationBarHidden(true) } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) @@ -210,6 +218,7 @@ struct GroupChatInfoView: View { private struct MemberRowView: View { var groupInfo: GroupInfo @ObservedObject var groupMember: GMember + @EnvironmentObject var theme: AppTheme var user: Bool = false @Binding var alert: GroupChatInfoViewAlert? @@ -220,14 +229,14 @@ struct GroupChatInfoView: View { .padding(.trailing, 2) // TODO server connection status VStack(alignment: .leading) { - let t = Text(member.chatViewName).foregroundColor(member.memberIncognito ? .indigo : .primary) + let t = Text(member.chatViewName).foregroundColor(member.memberIncognito ? .indigo : theme.colors.onBackground) (member.verified ? memberVerifiedShield + t : t) .lineLimit(1) let s = Text(member.memberStatus.shortText) (user ? Text ("you: ") + s : s) .lineLimit(1) .font(.caption) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } Spacer() memberInfo(member) @@ -260,12 +269,12 @@ struct GroupChatInfoView: View { @ViewBuilder private func memberInfo(_ member: GroupMember) -> some View { if member.blocked { Text("blocked") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } else { let role = member.memberRole if [.owner, .admin, .observer].contains(role) { Text(member.memberRole.text) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } } } @@ -276,13 +285,13 @@ struct GroupChatInfoView: View { Button { alert = .blockMemberAlert(mem: member) } label: { - Label("Block member", systemImage: "hand.raised").foregroundColor(.secondary) + Label("Block member", systemImage: "hand.raised").foregroundColor(theme.colors.secondary) } } else { Button { alert = .unblockMemberAlert(mem: member) } label: { - Label("Unblock member", systemImage: "hand.raised.slash").foregroundColor(.accentColor) + Label("Unblock member", systemImage: "hand.raised.slash").foregroundColor(theme.colors.primary) } } } @@ -294,13 +303,13 @@ struct GroupChatInfoView: View { Button { alert = .unblockForAllAlert(mem: member) } label: { - Label("Unblock for all", systemImage: "hand.raised.slash").foregroundColor(.accentColor) + Label("Unblock for all", systemImage: "hand.raised.slash").foregroundColor(theme.colors.primary) } } else { Button { alert = .blockForAllAlert(mem: member) } label: { - Label("Block for all", systemImage: "hand.raised").foregroundColor(.secondary) + Label("Block for all", systemImage: "hand.raised").foregroundColor(theme.colors.secondary) } } } @@ -316,6 +325,14 @@ struct GroupChatInfoView: View { } } } + + private var memberVerifiedShield: Text { + (Text(Image(systemName: "checkmark.shield")) + Text(" ")) + .font(.caption) + .baselineOffset(2) + .kerning(-2) + .foregroundColor(theme.colors.secondary) + } } private func memberInfoView(_ groupMember: GMember) -> some View { @@ -333,6 +350,7 @@ struct GroupChatInfoView: View { creatingGroup: false ) .navigationBarTitle("Group link") + .modifier(ThemedBackground(grouped: true)) .navigationBarTitleDisplayMode(.large) } label: { if groupLink == nil { @@ -350,6 +368,7 @@ struct GroupChatInfoView: View { groupProfile: groupInfo.groupProfile ) .navigationBarTitle("Group profile") + .modifier(ThemedBackground()) .navigationBarTitleDisplayMode(.large) } label: { Label("Edit group profile", systemImage: "pencil") @@ -364,6 +383,7 @@ struct GroupChatInfoView: View { welcomeText: groupInfo.groupProfile.description ?? "" ) .navigationTitle("Welcome message") + .modifier(ThemedBackground(grouped: true)) .navigationBarTitleDisplayMode(.large) } label: { groupInfo.groupProfile.description == nil @@ -518,6 +538,7 @@ func groupPreferencesButton(_ groupInfo: Binding, _ creatingGroup: Bo creatingGroup: creatingGroup ) .navigationBarTitle("Group preferences") + .modifier(ThemedBackground(grouped: true)) .navigationBarTitleDisplayMode(.large) } label: { if creatingGroup { @@ -528,14 +549,6 @@ func groupPreferencesButton(_ groupInfo: Binding, _ creatingGroup: Bo } } -private var memberVerifiedShield: Text { - (Text(Image(systemName: "checkmark.shield")) + Text(" ")) - .font(.caption) - .baselineOffset(2) - .kerning(-2) - .foregroundColor(.secondary) -} - func cantInviteIncognitoAlert() -> Alert { Alert( title: Text("Can't invite contacts!"), diff --git a/apps/ios/Shared/Views/Chat/Group/GroupLinkView.swift b/apps/ios/Shared/Views/Chat/Group/GroupLinkView.swift index c782e2a717..adf5f998a4 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupLinkView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupLinkView.swift @@ -133,6 +133,7 @@ struct GroupLinkView: View { shouldCreate = false } } + .modifier(ThemedBackground(grouped: true)) } private func createGroupLink() { diff --git a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift index a851e3fc1d..deabf1137e 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct GroupMemberInfoView: View { @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @Environment(\.dismiss) var dismiss: DismissAction @State var groupInfo: GroupInfo @ObservedObject var groupMember: GMember @@ -120,12 +121,14 @@ struct GroupMemberInfoView: View { } } header: { Text("Address") + .foregroundColor(theme.colors.secondary) } footer: { Text("You can share this address with your contacts to let them connect with **\(member.displayName)**.") + .foregroundColor(theme.colors.secondary) } } - Section("Member") { + Section(header: Text("Member").foregroundColor(theme.colors.secondary)) { infoRow("Group", groupInfo.displayName) if let roles = member.canChangeRoleTo(groupInfo: groupInfo) { @@ -147,7 +150,7 @@ struct GroupMemberInfoView: View { } if let connStats = connectionStats { - Section("Servers") { + Section(header: Text("Servers").foregroundColor(theme.colors.secondary)) { // TODO network connection status Button("Change receiving address") { alert = .switchAddressAlert @@ -165,8 +168,8 @@ struct GroupMemberInfoView: View { || connStats.ratchetSyncSendProhibited ) } - smpServers("Receiving via", connStats.rcvQueuesInfo.map { $0.rcvServer }) - smpServers("Sending via", connStats.sndQueuesInfo.map { $0.sndServer }) + smpServers("Receiving via", connStats.rcvQueuesInfo.map { $0.rcvServer }, theme.colors.secondary) + smpServers("Sending via", connStats.sndQueuesInfo.map { $0.sndServer }, theme.colors.secondary) } } @@ -177,7 +180,7 @@ struct GroupMemberInfoView: View { } if developerTools { - Section("For console") { + Section(header: Text("For console").foregroundColor(theme.colors.secondary)) { infoRow("Local name", member.localDisplayName) infoRow("Database ID", "\(member.groupMemberId)") Button ("Debug delivery") { @@ -247,6 +250,7 @@ struct GroupMemberInfoView: View { ProgressView().scaleEffect(2) } } + .modifier(ThemedBackground(grouped: true)) } func connectViaAddressButton(_ contactLink: String) -> some View { @@ -326,7 +330,7 @@ struct GroupMemberInfoView: View { if mem.verified { ( Text(Image(systemName: "checkmark.shield")) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .font(.title2) + Text(" ") + Text(mem.displayName) @@ -374,6 +378,7 @@ struct GroupMemberInfoView: View { ) .navigationBarTitleDisplayMode(.inline) .navigationTitle("Security code") + .modifier(ThemedBackground()) } label: { Label( member.verified ? "View security code" : "Verify security code", @@ -423,7 +428,7 @@ struct GroupMemberInfoView: View { Section { if mem.blockedByAdmin { Label("Blocked by admin", systemImage: "hand.raised") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } else if mem.memberSettings.showMessages { blockMemberButton(mem) } else { diff --git a/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift b/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift index 6ae5032be5..2b0d05375b 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift @@ -18,6 +18,7 @@ private let featureRoles: [(role: GroupMemberRole?, text: LocalizedStringKey)] = struct GroupPreferencesView: View { @Environment(\.dismiss) var dismiss: DismissAction @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @Binding var groupInfo: GroupInfo @State var preferences: FullGroupPreferences @State var currentPreferences: FullGroupPreferences @@ -73,7 +74,7 @@ struct GroupPreferencesView: View { private func featureSection(_ feature: GroupFeature, _ enableFeature: Binding, _ enableForRole: Binding? = nil) -> some View { Section { - let color: Color = enableFeature.wrappedValue == .on ? .green : .secondary + let color: Color = enableFeature.wrappedValue == .on ? .green : theme.colors.secondary let icon = enableFeature.wrappedValue == .on ? feature.iconFilled : feature.icon let timedOn = feature == .timedMessages && enableFeature.wrappedValue == .on if groupInfo.canEdit { @@ -111,18 +112,19 @@ struct GroupPreferencesView: View { } if enableFeature.wrappedValue == .on, let enableForRole { HStack { - Text("Enabled for").foregroundColor(.secondary) + Text("Enabled for").foregroundColor(theme.colors.secondary) Spacer() Text( featureRoles.first(where: { fr in fr.role == enableForRole.wrappedValue })?.text ?? "all members" ) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } } } } footer: { Text(feature.enableDescription(enableFeature.wrappedValue, groupInfo.canEdit)) + .foregroundColor(theme.colors.secondary) } .onChange(of: enableFeature.wrappedValue) { enabled in if case .off = enabled { diff --git a/apps/ios/Shared/Views/Chat/Group/GroupWelcomeView.swift b/apps/ios/Shared/Views/Chat/Group/GroupWelcomeView.swift index 00d4f8c37b..9a9002f9dc 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupWelcomeView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupWelcomeView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct GroupWelcomeView: View { @Environment(\.dismiss) var dismiss: DismissAction + @EnvironmentObject var theme: AppTheme @Binding var groupInfo: GroupInfo @State var groupProfile: GroupProfile @State var welcomeText: String @@ -57,7 +58,7 @@ struct GroupWelcomeView: View { } private func textPreview() -> some View { - messageText(welcomeText, parseSimpleXMarkdown(welcomeText), nil, showSecrets: false) + messageText(welcomeText, parseSimpleXMarkdown(welcomeText), nil, showSecrets: false, secondaryColor: theme.colors.secondary) .frame(minHeight: 130, alignment: .topLeading) .frame(maxWidth: .infinity, alignment: .leading) } @@ -70,7 +71,7 @@ struct GroupWelcomeView: View { Group { if welcomeText.isEmpty { TextEditor(text: Binding.constant(NSLocalizedString("Enter welcome message…", comment: "placeholder"))) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .disabled(true) } TextEditor(text: $welcomeText) diff --git a/apps/ios/Shared/Views/Chat/ReverseList.swift b/apps/ios/Shared/Views/Chat/ReverseList.swift index f795b96b03..512aa9196a 100644 --- a/apps/ios/Shared/Views/Chat/ReverseList.swift +++ b/apps/ios/Shared/Views/Chat/ReverseList.swift @@ -90,6 +90,7 @@ struct ReverseList: UIV } cell.transform = .verticalFlip cell.selectionStyle = .none + cell.backgroundColor = .clear return cell } diff --git a/apps/ios/Shared/Views/Chat/VerifyCodeView.swift b/apps/ios/Shared/Views/Chat/VerifyCodeView.swift index 75e31c26ed..7b01fe0300 100644 --- a/apps/ios/Shared/Views/Chat/VerifyCodeView.swift +++ b/apps/ios/Shared/Views/Chat/VerifyCodeView.swift @@ -10,6 +10,7 @@ import SwiftUI struct VerifyCodeView: View { @Environment(\.dismiss) var dismiss: DismissAction + @EnvironmentObject var theme: AppTheme var displayName: String @State var connectionCode: String? @State var connectionVerified: Bool @@ -30,7 +31,7 @@ struct VerifyCodeView: View { HStack { if connectionVerified { Image(systemName: "checkmark.shield") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) Text("\(displayName) is verified") } else { Text("\(displayName) is not verified") @@ -66,6 +67,7 @@ struct VerifyCodeView: View { ScanCodeView(connectionVerified: $connectionVerified, verify: verify) .navigationBarTitleDisplayMode(.large) .navigationTitle("Scan code") + .modifier(ThemedBackground()) } label: { Label("Scan code", systemImage: "qrcode") } @@ -122,5 +124,6 @@ struct VerifyCodeView: View { struct VerifyCodeView_Previews: PreviewProvider { static var previews: some View { VerifyCodeView(displayName: "alice", connectionCode: "12345 67890 12345 67890", connectionVerified: false, verify: {_ in nil}) + .environmentObject(CurrentColors.toAppTheme()) } } diff --git a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift index 73c3c73556..c8a6efd282 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift @@ -26,6 +26,7 @@ private let rowHeights: [DynamicTypeSize: CGFloat] = [ struct ChatListNavLink: View { @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @Environment(\.dynamicTypeSize) private var dynamicTypeSize @ObservedObject var chat: Chat @State private var showContactRequestDialog = false @@ -224,7 +225,7 @@ struct ChatListNavLink: View { } label: { Label("Join", systemImage: chat.chatInfo.incognito ? "theatermasks" : "ipad.and.arrow.forward") } - .tint(chat.chatInfo.incognito ? .indigo : .accentColor) + .tint(chat.chatInfo.incognito ? .indigo : theme.colors.primary) } @ViewBuilder private func markReadButton() -> some View { @@ -234,14 +235,14 @@ struct ChatListNavLink: View { } label: { Label("Read", systemImage: "checkmark") } - .tint(Color.accentColor) + .tint(theme.colors.primary) } else { Button { Task { await markChatUnread(chat) } } label: { Label("Unread", systemImage: "circlebadge.fill") } - .tint(Color.accentColor) + .tint(theme.colors.primary) } } @@ -306,7 +307,7 @@ struct ChatListNavLink: View { Button { Task { await acceptContactRequest(incognito: false, contactRequest: contactRequest) } } label: { Label("Accept", systemImage: "checkmark") } - .tint(.accentColor) + .tint(theme.colors.primary) Button { Task { await acceptContactRequest(incognito: true, contactRequest: contactRequest) } } label: { @@ -346,7 +347,7 @@ struct ChatListNavLink: View { } label: { Label("Name", systemImage: "pencil") } - .tint(.accentColor) + .tint(theme.colors.primary) } .frame(height: rowHeights[dynamicTypeSize]) .appSheet(isPresented: $showContactConnectionInfo) { @@ -354,6 +355,7 @@ struct ChatListNavLink: View { if case let .contactConnection(contactConnection) = chat.chatInfo { ContactConnectionInfo(contactConnection: contactConnection) .environment(\EnvironmentValues.refresh as! WritableKeyPath, nil) + .modifier(ThemedBackground(grouped: true)) } } } diff --git a/apps/ios/Shared/Views/ChatList/ChatListView.swift b/apps/ios/Shared/Views/ChatList/ChatListView.swift index 9471e09d5e..886b7465f3 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct ChatListView: View { @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @Binding var showSettings: Bool @State private var searchMode = false @FocusState private var searchFocussed @@ -86,6 +87,7 @@ struct ChatListView: View { )) } .listStyle(.plain) + .background(theme.colors.background) .navigationBarTitleDisplayMode(.inline) .navigationBarHidden(searchMode) .toolbar { @@ -143,12 +145,14 @@ struct ChatListView: View { searchChatFilteredBySimplexLink: $searchChatFilteredBySimplexLink ) .listRowSeparator(.hidden) + .listRowBackground(Color.clear) .frame(maxWidth: .infinity) } ForEach(cs, id: \.viewId) { chat in ChatListNavLink(chat: chat) .padding(.trailing, -16) .disabled(chatModel.chatRunning != true || chatModel.deletedChats.contains(chat.chatInfo.id)) + .listRowBackground(Color.clear) } .offset(x: -8) } @@ -160,7 +164,7 @@ struct ChatListView: View { } } if cs.isEmpty && !chatModel.chats.isEmpty { - Text("No filtered chats").foregroundColor(.secondary) + Text("No filtered chats").foregroundColor(theme.colors.secondary) } } } @@ -168,7 +172,7 @@ struct ChatListView: View { private func unreadBadge(_ text: Text? = Text(" "), size: CGFloat = 18) -> some View { Circle() .frame(width: size, height: size) - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) } private func onboardingButtons() -> some View { @@ -179,7 +183,7 @@ struct ChatListView: View { p.addLine(to: CGPoint(x: 0, y: 10)) p.addLine(to: CGPoint(x: 8, y: 0)) } - .fill(Color.accentColor) + .fill(theme.colors.primary) .frame(width: 20, height: 10) .padding(.trailing, 12) @@ -189,7 +193,7 @@ struct ChatListView: View { Spacer() Text("You have no chats") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .frame(maxWidth: .infinity) } .padding(.trailing, 6) @@ -202,7 +206,7 @@ struct ChatListView: View { .padding(.vertical, 10) .padding(.horizontal, 20) } - .background(Color.accentColor) + .background(theme.colors.primary) .foregroundColor(.white) .clipShape(RoundedRectangle(cornerRadius: 16)) } @@ -267,7 +271,7 @@ struct SubsStatusIndicator: View { @State private var timer: Timer? = nil @State private var timerCounter = 0 @State private var showServersSummary = false - + @AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false // Constants for the intervals @@ -332,6 +336,7 @@ struct SubsStatusIndicator: View { struct ChatListSearchBar: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @Binding var searchMode: Bool @FocusState.Binding var searchFocussed: Bool @Binding var searchText: String @@ -348,7 +353,7 @@ struct ChatListSearchBar: View { HStack(spacing: 4) { Image(systemName: "magnifyingglass") TextField("Search or paste SimpleX link", text: $searchText) - .foregroundColor(searchShowingSimplexLink ? .secondary : .primary) + .foregroundColor(searchShowingSimplexLink ? theme.colors.secondary : theme.colors.onBackground) .disabled(searchShowingSimplexLink) .focused($searchFocussed) .frame(maxWidth: .infinity) @@ -360,13 +365,13 @@ struct ChatListSearchBar: View { } } .padding(EdgeInsets(top: 7, leading: 7, bottom: 7, trailing: 7)) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .background(Color(.tertiarySystemFill)) .cornerRadius(10.0) if searchFocussed { Text("Cancel") - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) .onTapGesture { searchText = "" searchFocussed = false @@ -417,7 +422,7 @@ struct ChatListSearchBar: View { Image(systemName: showUnreadAndFavorites ? "line.3.horizontal.decrease.circle.fill" : "line.3.horizontal.decrease") .resizable() .scaledToFit() - .foregroundColor(showUnreadAndFavorites ? .accentColor : .secondary) + .foregroundColor(showUnreadAndFavorites ? theme.colors.primary : theme.colors.secondary) .frame(width: showUnreadAndFavorites ? 22 : 16, height: showUnreadAndFavorites ? 22 : 16) .onTapGesture { showUnreadAndFavorites = !showUnreadAndFavorites diff --git a/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift b/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift index 4cfd5ae068..c1156225d8 100644 --- a/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift @@ -11,10 +11,10 @@ import SimpleXChat struct ChatPreviewView: View { @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @ObservedObject var chat: Chat @Binding var progressByTimeout: Bool @State var deleting: Bool = false - @Environment(\.colorScheme) var colorScheme var darkGreen = Color(red: 0, green: 0.5, blue: 0) @AppStorage(DEFAULT_PRIVACY_SHOW_CHAT_PREVIEWS) private var showChatPreviews = true @@ -36,7 +36,7 @@ struct ChatPreviewView: View { (cItem?.timestampText ?? formatTimestampText(chat.chatInfo.chatTs)) .font(.subheadline) .frame(minWidth: 60, alignment: .trailing) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .padding(.top, 4) } .padding(.bottom, 4) @@ -94,9 +94,9 @@ struct ChatPreviewView: View { case let .group(groupInfo): let v = previewTitle(t) switch (groupInfo.membership.memberStatus) { - case .memInvited: v.foregroundColor(deleting ? .secondary : chat.chatInfo.incognito ? .indigo : .accentColor) - case .memAccepted: v.foregroundColor(.secondary) - default: if deleting { v.foregroundColor(.secondary) } else { v } + case .memInvited: v.foregroundColor(deleting ? theme.colors.secondary : chat.chatInfo.incognito ? .indigo : theme.colors.primary) + case .memAccepted: v.foregroundColor(theme.colors.secondary) + default: if deleting { v.foregroundColor(theme.colors.secondary) } else { v } } default: previewTitle(t) } @@ -108,7 +108,7 @@ struct ChatPreviewView: View { private var verifiedIcon: Text { (Text(Image(systemName: "checkmark.shield")) + Text(" ")) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .baselineOffset(1) .kerning(-2) } @@ -133,11 +133,11 @@ struct ChatPreviewView: View { .foregroundColor(.white) .padding(.horizontal, 4) .frame(minWidth: 18, minHeight: 18) - .background(chat.chatInfo.ntfsEnabled || chat.chatInfo.chatType == .local ? Color.accentColor : Color.secondary) + .background(chat.chatInfo.ntfsEnabled || chat.chatInfo.chatType == .local ? theme.colors.primary : theme.colors.secondary) .cornerRadius(10) } else if !chat.chatInfo.ntfsEnabled && chat.chatInfo.chatType != .local { Image(systemName: "speaker.slash.fill") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } else if chat.chatInfo.chatSettings?.favorite ?? false { Image(systemName: "star.fill") .resizable() @@ -151,9 +151,9 @@ struct ChatPreviewView: View { private func messageDraft(_ draft: ComposeState) -> Text { let msg = draft.message - return image("rectangle.and.pencil.and.ellipsis", color: .accentColor) + return image("rectangle.and.pencil.and.ellipsis", color: theme.colors.primary) + attachment() - + messageText(msg, parseSimpleXMarkdown(msg), nil, preview: true, showSecrets: false) + + messageText(msg, parseSimpleXMarkdown(msg), nil, preview: true, showSecrets: false, secondaryColor: theme.colors.secondary) func image(_ s: String, color: Color = Color(uiColor: .tertiaryLabel)) -> Text { Text(Image(systemName: s)).foregroundColor(color) + Text(" ") @@ -172,7 +172,7 @@ struct ChatPreviewView: View { func chatItemPreview(_ cItem: ChatItem) -> Text { let itemText = cItem.meta.itemDeleted == nil ? cItem.text : markedDeletedText() let itemFormattedText = cItem.meta.itemDeleted == nil ? cItem.formattedText : nil - return messageText(itemText, itemFormattedText, cItem.memberDisplayName, icon: attachment(), preview: true, showSecrets: false) + return messageText(itemText, itemFormattedText, cItem.memberDisplayName, icon: attachment(), preview: true, showSecrets: false, secondaryColor: theme.colors.secondary) // same texts are in markedDeletedText in MarkedDeletedItemView, but it returns LocalizedStringKey; // can be refactored into a single function if functions calling these are changed to return same type @@ -206,7 +206,7 @@ struct ChatPreviewView: View { case let .direct(contact): if contact.activeConn == nil && contact.profile.contactLink != nil { chatPreviewInfoText("Tap to Connect") - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) } else if !contact.ready && contact.activeConn != nil { if contact.nextSendGrpInv { chatPreviewInfoText("send direct message") @@ -257,38 +257,38 @@ struct ChatPreviewView: View { case let .direct(contact): if contact.active && contact.activeConn != nil { switch (chatModel.contactNetworkStatus(contact)) { - case .connected: incognitoIcon(chat.chatInfo.incognito) + case .connected: incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary) case .error: Image(systemName: "exclamationmark.circle") .resizable() .scaledToFit() .frame(width: 17, height: 17) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) default: ProgressView() } } else { - incognitoIcon(chat.chatInfo.incognito) + incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary) } case .group: if progressByTimeout { ProgressView() } else { - incognitoIcon(chat.chatInfo.incognito) + incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary) } default: - incognitoIcon(chat.chatInfo.incognito) + incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary) } } } -@ViewBuilder func incognitoIcon(_ incognito: Bool) -> some View { +@ViewBuilder func incognitoIcon(_ incognito: Bool, _ secondaryColor: Color) -> some View { if incognito { Image(systemName: "theatermasks") .resizable() .scaledToFit() .frame(width: 22, height: 22) - .foregroundColor(.secondary) + .foregroundColor(secondaryColor) } else { EmptyView() } diff --git a/apps/ios/Shared/Views/ChatList/ContactConnectionInfo.swift b/apps/ios/Shared/Views/ChatList/ContactConnectionInfo.swift index 42e90232d6..b7e641a338 100644 --- a/apps/ios/Shared/Views/ChatList/ContactConnectionInfo.swift +++ b/apps/ios/Shared/Views/ChatList/ContactConnectionInfo.swift @@ -11,6 +11,7 @@ import SimpleXChat struct ContactConnectionInfo: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @Environment(\.dismiss) var dismiss: DismissAction @State var contactConnection: PendingContactConnection @State private var alert: CCInfoAlert? @@ -48,7 +49,7 @@ struct ContactConnectionInfo: View { Section { if contactConnection.groupLinkId == nil { - settingsRow("pencil") { + settingsRow("pencil", color: theme.colors.secondary) { TextField("Set contact name…", text: $localAlias) .autocapitalization(.none) .autocorrectionDisabled(true) @@ -63,14 +64,15 @@ struct ContactConnectionInfo: View { let connReqInv = contactConnection.connReqInv { SimpleXLinkQRCode(uri: simplexChatLink(connReqInv)) incognitoEnabled() - shareLinkButton(connReqInv) - oneTimeLinkLearnMoreButton() + shareLinkButton(connReqInv, theme.colors.secondary) + oneTimeLinkLearnMoreButton(theme.colors.secondary) } else { incognitoEnabled() - oneTimeLinkLearnMoreButton() + oneTimeLinkLearnMoreButton(theme.colors.secondary) } } footer: { sharedProfileInfo(contactConnection.incognito) + .foregroundColor(theme.colors.secondary) } Section { @@ -82,6 +84,7 @@ struct ContactConnectionInfo: View { } } } + .modifier(ThemedBackground(grouped: true)) if #available(iOS 16, *) { v } else { @@ -149,7 +152,7 @@ struct ContactConnectionInfo: View { HStack(spacing: 6) { Text("Incognito") Image(systemName: "info.circle") - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) .font(.system(size: 14)) } .onTapGesture { @@ -164,23 +167,24 @@ struct ContactConnectionInfo: View { } } -private func shareLinkButton(_ connReqInvitation: String) -> some View { +private func shareLinkButton(_ connReqInvitation: String, _ secondaryColor: Color) -> some View { Button { showShareSheet(items: [simplexChatLink(connReqInvitation)]) } label: { - settingsRow("square.and.arrow.up") { + settingsRow("square.and.arrow.up", color: secondaryColor) { Text("Share 1-time link") } } } -private func oneTimeLinkLearnMoreButton() -> some View { +private func oneTimeLinkLearnMoreButton(_ secondaryColor: Color) -> some View { NavigationLink { AddContactLearnMore(showTitle: false) .navigationTitle("One-time invitation link") + .modifier(ThemedBackground()) .navigationBarTitleDisplayMode(.large) } label: { - settingsRow("info.circle") { + settingsRow("info.circle", color: secondaryColor) { Text("Learn more") } } diff --git a/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift b/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift index d21f347881..bb224b7844 100644 --- a/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift +++ b/apps/ios/Shared/Views/ChatList/ContactConnectionView.swift @@ -12,6 +12,7 @@ import SimpleXChat struct ContactConnectionView: View { @EnvironmentObject var m: ChatModel @ObservedObject var chat: Chat + @EnvironmentObject var theme: AppTheme @State private var localAlias = "" @FocusState private var aliasTextFieldFocused: Bool @State private var showContactConnectionInfo = false @@ -29,7 +30,7 @@ struct ContactConnectionView: View { .resizable() .scaledToFill() .frame(width: 48, height: 48) - .foregroundColor(Color(uiColor: .secondarySystemBackground)) + .foregroundColor(Color(uiColor: .tertiarySystemGroupedBackground).asAnotherColorFromSecondaryVariant(theme)) .onTapGesture { showContactConnectionInfo = true } } .frame(width: 63, height: 63) @@ -41,7 +42,7 @@ struct ContactConnectionView: View { .font(.title3) .bold() .allowsTightening(false) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .padding(.horizontal, 8) .padding(.top, 1) .padding(.bottom, 0.5) @@ -54,14 +55,14 @@ struct ContactConnectionView: View { .padding(.trailing, 8) .padding(.vertical, 4) .frame(minWidth: 60, alignment: .trailing) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } .padding(.bottom, 2) ZStack(alignment: .topTrailing) { Text(contactConnection.description) .frame(maxWidth: .infinity, alignment: .leading) - incognitoIcon(contactConnection.incognito) + incognitoIcon(contactConnection.incognito, theme.colors.secondary) .padding(.top, 26) .frame(maxWidth: .infinity, alignment: .trailing) } diff --git a/apps/ios/Shared/Views/ChatList/ContactRequestView.swift b/apps/ios/Shared/Views/ChatList/ContactRequestView.swift index dacf51a5e8..e36a2f7596 100644 --- a/apps/ios/Shared/Views/ChatList/ContactRequestView.swift +++ b/apps/ios/Shared/Views/ChatList/ContactRequestView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct ContactRequestView: View { @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme var contactRequest: UserContactRequest @ObservedObject var chat: Chat @@ -23,7 +24,7 @@ struct ContactRequestView: View { Text(contactRequest.chatViewName) .font(.title3) .fontWeight(.bold) - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) .padding(.leading, 8) .frame(alignment: .topLeading) Spacer() @@ -32,7 +33,7 @@ struct ContactRequestView: View { .padding(.trailing, 8) .padding(.top, 4) .frame(minWidth: 60, alignment: .trailing) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } .padding(.bottom, 2) diff --git a/apps/ios/Shared/Views/ChatList/UserPicker.swift b/apps/ios/Shared/Views/ChatList/UserPicker.swift index a615f9c118..eeb7bf14f4 100644 --- a/apps/ios/Shared/Views/ChatList/UserPicker.swift +++ b/apps/ios/Shared/Views/ChatList/UserPicker.swift @@ -6,13 +6,10 @@ import SwiftUI import SimpleXChat -private let fillColorDark = Color(uiColor: UIColor(red: 0.11, green: 0.11, blue: 0.11, alpha: 255)) -private let fillColorLight = Color(uiColor: UIColor(red: 0.99, green: 0.99, blue: 0.99, alpha: 255)) - struct UserPicker: View { @EnvironmentObject var m: ChatModel - @Environment(\.colorScheme) var colorScheme @Environment(\.scenePhase) var scenePhase + @EnvironmentObject var theme: AppTheme @Binding var showSettings: Bool @Binding var showConnectDesktop: Bool @Binding var userPickerVisible: Bool @@ -21,9 +18,6 @@ struct UserPicker: View { private let menuButtonHeight: CGFloat = 68 @State var chatViewNameWidth: CGFloat = 0 - var fillColor: Color { - colorScheme == .dark ? fillColorDark : fillColorLight - } var body: some View { VStack { @@ -82,7 +76,7 @@ struct UserPicker: View { .clipShape(RoundedRectangle(cornerRadius: 16)) .background( Rectangle() - .fill(fillColor) + .fill(theme.colors.surface) .cornerRadius(16) .shadow(color: .black.opacity(0.12), radius: 24, x: 0, y: 0) ) @@ -131,13 +125,13 @@ struct UserPicker: View { .padding(.trailing, 12) Text(user.chatViewName) .fontWeight(user.activeUser ? .medium : .regular) - .foregroundColor(.primary) + .foregroundColor(theme.colors.onBackground) .overlay(DetermineWidth()) Spacer() if user.activeUser { Image(systemName: "checkmark") } else if u.unreadCount > 0 { - unreadCounter(u.unreadCount, color: user.showNtfs ? .accentColor : .secondary) + unreadCounter(u.unreadCount, color: user.showNtfs ? theme.colors.primary : theme.colors.secondary) } else if !user.showNtfs { Image(systemName: "speaker.slash") } @@ -145,7 +139,7 @@ struct UserPicker: View { .padding(.trailing) .padding([.leading, .vertical], 12) }) - .buttonStyle(PressedButtonStyle(defaultColor: fillColor, pressedColor: Color(uiColor: .secondarySystemFill))) + .buttonStyle(PressedButtonStyle(defaultColor: theme.colors.surface, pressedColor: Color(uiColor: .secondarySystemFill))) } private func menuButton(_ title: LocalizedStringKey, icon: String, action: @escaping () -> Void) -> some View { @@ -156,13 +150,13 @@ struct UserPicker: View { Spacer() Image(systemName: icon) .symbolRenderingMode(.monochrome) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } .padding(.horizontal) .padding(.vertical, 22) .frame(height: menuButtonHeight) } - .buttonStyle(PressedButtonStyle(defaultColor: fillColor, pressedColor: Color(uiColor: .secondarySystemFill))) + .buttonStyle(PressedButtonStyle(defaultColor: theme.colors.surface, pressedColor: Color(uiColor: .secondarySystemFill))) } } diff --git a/apps/ios/Shared/Views/Database/ChatArchiveView.swift b/apps/ios/Shared/Views/Database/ChatArchiveView.swift index 65913343d5..3ab4ac9a31 100644 --- a/apps/ios/Shared/Views/Database/ChatArchiveView.swift +++ b/apps/ios/Shared/Views/Database/ChatArchiveView.swift @@ -10,6 +10,7 @@ import SwiftUI import SimpleXChat struct ChatArchiveView: View { + @EnvironmentObject var theme: AppTheme var archiveName: String @AppStorage(DEFAULT_CHAT_ARCHIVE_NAME) private var chatArchiveName: String? @AppStorage(DEFAULT_CHAT_ARCHIVE_TIME) private var chatArchiveTime: Double = 0 @@ -20,14 +21,14 @@ struct ChatArchiveView: View { let fileTs = chatArchiveTimeDefault.get() List { Section { - settingsRow("square.and.arrow.up") { + settingsRow("square.and.arrow.up", color: theme.colors.secondary) { Button { showShareSheet(items: [fileUrl]) } label: { Text("Save archive") } } - settingsRow("trash") { + settingsRow("trash", color: theme.colors.secondary) { Button { showDeleteAlert = true } label: { @@ -36,8 +37,10 @@ struct ChatArchiveView: View { } } header: { Text("Chat archive") + .foregroundColor(theme.colors.secondary) } footer: { Text("Created on \(fileTs)") + .foregroundColor(theme.colors.secondary) } } .alert(isPresented: $showDeleteAlert) { diff --git a/apps/ios/Shared/Views/Database/DatabaseEncryptionView.swift b/apps/ios/Shared/Views/Database/DatabaseEncryptionView.swift index 4031c3e00a..be167b92b9 100644 --- a/apps/ios/Shared/Views/Database/DatabaseEncryptionView.swift +++ b/apps/ios/Shared/Views/Database/DatabaseEncryptionView.swift @@ -35,6 +35,7 @@ enum DatabaseEncryptionAlert: Identifiable { struct DatabaseEncryptionView: View { @EnvironmentObject private var m: ChatModel + @EnvironmentObject private var theme: AppTheme @Binding var useKeychain: Bool var migration: Bool @State private var alert: DatabaseEncryptionAlert? = nil @@ -63,7 +64,7 @@ struct DatabaseEncryptionView: View { private func databaseEncryptionView() -> some View { Section { - settingsRow(storedKey ? "key.fill" : "key", color: storedKey ? .green : .secondary) { + settingsRow(storedKey ? "key.fill" : "key", color: storedKey ? .green : theme.colors.secondary) { Toggle("Save passphrase in Keychain", isOn: $useKeychainToggle) .onChange(of: useKeychainToggle) { _ in if useKeychainToggle { @@ -85,7 +86,7 @@ struct DatabaseEncryptionView: View { PassphraseField(key: $newKey, placeholder: "New passphrase…", valid: validKey(newKey), showStrength: true) PassphraseField(key: $confirmNewKey, placeholder: "Confirm new passphrase…", valid: confirmNewKey == "" || newKey == confirmNewKey) - settingsRow("lock.rotation") { + settingsRow("lock.rotation", color: theme.colors.secondary) { Button(migration ? "Set passphrase" : "Update database passphrase") { alert = currentKey == "" ? (useKeychain ? .encryptDatabaseSaved : .encryptDatabase) @@ -102,6 +103,7 @@ struct DatabaseEncryptionView: View { ) } header: { Text(migration ? "Database passphrase" : "") + .foregroundColor(theme.colors.secondary) } footer: { VStack(alignment: .leading, spacing: 16) { if m.chatDbEncrypted == false { @@ -125,6 +127,7 @@ struct DatabaseEncryptionView: View { } } } + .foregroundColor(theme.colors.secondary) .padding(.top, 1) .font(.callout) } @@ -277,6 +280,7 @@ struct DatabaseEncryptionView: View { struct PassphraseField: View { + @EnvironmentObject var theme: AppTheme @Binding var key: String var placeholder: LocalizedStringKey var valid: Bool @@ -287,7 +291,7 @@ struct PassphraseField: View { var body: some View { ZStack(alignment: .leading) { let iconColor = valid - ? (showStrength && key != "" ? PassphraseStrength(passphrase: key).color : .secondary) + ? (showStrength && key != "" ? PassphraseStrength(passphrase: key).color : theme.colors.secondary) : .red Image(systemName: valid ? (showKey ? "eye.slash" : "eye") : "exclamationmark.circle") .resizable() diff --git a/apps/ios/Shared/Views/Database/DatabaseView.swift b/apps/ios/Shared/Views/Database/DatabaseView.swift index 2e0cd7738f..58000a7ee7 100644 --- a/apps/ios/Shared/Views/Database/DatabaseView.swift +++ b/apps/ios/Shared/Views/Database/DatabaseView.swift @@ -41,6 +41,7 @@ enum DatabaseAlert: Identifiable { struct DatabaseView: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @Binding var showSettings: Bool @State private var runChat = false @State private var alert: DatabaseAlert? = nil @@ -82,8 +83,10 @@ struct DatabaseView: View { .disabled(stopped || progressIndicator) } header: { Text("Messages") + .foregroundColor(theme.colors.secondary) } footer: { Text("This setting applies to messages in your current chat profile **\(m.currentUser?.displayName ?? "")**.") + .foregroundColor(theme.colors.secondary) } Section { @@ -105,24 +108,27 @@ struct DatabaseView: View { } } header: { Text("Run chat") + .foregroundColor(theme.colors.secondary) } footer: { if case .documents = dbContainer { Text("Database will be migrated when the app restarts") + .foregroundColor(theme.colors.secondary) } } Section { let unencrypted = m.chatDbEncrypted == false - let color: Color = unencrypted ? .orange : .secondary + let color: Color = unencrypted ? .orange : theme.colors.secondary settingsRow(unencrypted ? "lock.open" : useKeychain ? "key" : "lock", color: color) { NavigationLink { DatabaseEncryptionView(useKeychain: $useKeychain, migration: false) .navigationTitle("Database passphrase") + .modifier(ThemedBackground(grouped: true)) } label: { Text("Database passphrase") } } - settingsRow("square.and.arrow.up") { + settingsRow("square.and.arrow.up", color: theme.colors.secondary) { Button("Export database") { if initialRandomDBPassphraseGroupDefault.get() && !unencrypted { alert = .exportProhibited @@ -131,7 +137,7 @@ struct DatabaseView: View { } } } - settingsRow("square.and.arrow.down") { + settingsRow("square.and.arrow.down", color: theme.colors.secondary) { Button("Import database", role: .destructive) { showFileImporter = true } @@ -140,34 +146,37 @@ struct DatabaseView: View { let title: LocalizedStringKey = chatArchiveTimeDefault.get() < chatLastStartGroupDefault.get() ? "Old database archive" : "New database archive" - settingsRow("archivebox") { + settingsRow("archivebox", color: theme.colors.secondary) { NavigationLink { ChatArchiveView(archiveName: archiveName) .navigationTitle(title) + .modifier(ThemedBackground(grouped: true)) } label: { Text(title) } } } - settingsRow("trash.slash") { + settingsRow("trash.slash", color: theme.colors.secondary) { Button("Delete database", role: .destructive) { alert = .deleteChat } } } header: { Text("Chat database") + .foregroundColor(theme.colors.secondary) } footer: { Text( stopped ? "You must use the most recent version of your chat database on one device ONLY, otherwise you may stop receiving the messages from some contacts." : "Stop chat to enable database actions" ) + .foregroundColor(theme.colors.secondary) } .disabled(!stopped) if case .group = dbContainer, legacyDatabase { - Section("Old database") { - settingsRow("trash") { + Section(header: Text("Old database").foregroundColor(theme.colors.secondary)) { + settingsRow("trash", color: theme.colors.secondary) { Button("Delete old database") { alert = .deleteLegacyDatabase } @@ -182,12 +191,15 @@ struct DatabaseView: View { .disabled(!stopped || appFilesCountAndSize?.0 == 0) } header: { Text("Files & media") + .foregroundColor(theme.colors.secondary) } footer: { if let (fileCount, size) = appFilesCountAndSize { if fileCount == 0 { Text("No received or sent files") + .foregroundColor(theme.colors.secondary) } else { Text("\(fileCount) file(s) with total size of \(ByteCountFormatter.string(fromByteCount: Int64(size), countStyle: .binary))") + .foregroundColor(theme.colors.secondary) } } } @@ -355,6 +367,7 @@ struct DatabaseView: View { Task { do { try await apiDeleteStorage() + try? FileManager.default.createDirectory(at: getWallpaperDirectory(), withIntermediateDirectories: true) do { let config = ArchiveConfig(archivePath: archivePath.path) let archiveErrors = try await apiImportArchive(config: config) diff --git a/apps/ios/Shared/Views/Database/MigrateToAppGroupView.swift b/apps/ios/Shared/Views/Database/MigrateToAppGroupView.swift index ae6af24f53..6d3026f11f 100644 --- a/apps/ios/Shared/Views/Database/MigrateToAppGroupView.swift +++ b/apps/ios/Shared/Views/Database/MigrateToAppGroupView.swift @@ -189,6 +189,7 @@ struct MigrateToAppGroupView: View { Task { do { try apiSaveAppSettings(settings: AppSettings.current.prepareForExport()) + try? FileManager.default.createDirectory(at: getWallpaperDirectory(), withIntermediateDirectories: true) try await apiExportArchive(config: config) await MainActor.run { setV3DBMigration(.exported) } } catch let error { @@ -231,6 +232,7 @@ func exportChatArchive(_ storagePath: URL? = nil) async throws -> URL { if !ChatModel.shared.chatDbChanged { try apiSaveAppSettings(settings: AppSettings.current.prepareForExport()) } + try? FileManager.default.createDirectory(at: getWallpaperDirectory(), withIntermediateDirectories: true) try await apiExportArchive(config: config) if storagePath == nil { deleteOldArchive() diff --git a/apps/ios/Shared/Views/Helpers/ChatInfoImage.swift b/apps/ios/Shared/Views/Helpers/ChatInfoImage.swift index 0180b066ab..844b5ab4d3 100644 --- a/apps/ios/Shared/Views/Helpers/ChatInfoImage.swift +++ b/apps/ios/Shared/Views/Helpers/ChatInfoImage.swift @@ -10,7 +10,7 @@ import SwiftUI import SimpleXChat struct ChatInfoImage: View { - @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var theme: AppTheme @ObservedObject var chat: Chat var size: CGFloat var color = Color(uiColor: .tertiarySystemGroupedBackground) @@ -24,8 +24,7 @@ struct ChatInfoImage: View { case .contactRequest: iconName = "person.crop.circle.fill" default: iconName = "circle.fill" } - let notesColor = colorScheme == .light ? notesChatColorLight : notesChatColorDark - let iconColor = if case .local = chat.chatInfo { notesColor } else { color } + let iconColor = if case .local = chat.chatInfo { theme.appColors.primaryVariant2 } else { color } return ProfileImage( imageStr: chat.chatInfo.image, iconName: iconName, diff --git a/apps/ios/Shared/Views/Helpers/ChatWallpaper.swift b/apps/ios/Shared/Views/Helpers/ChatWallpaper.swift new file mode 100644 index 0000000000..6eef843d37 --- /dev/null +++ b/apps/ios/Shared/Views/Helpers/ChatWallpaper.swift @@ -0,0 +1,102 @@ +// +// ChatWallpaper.swift +// SimpleX (iOS) +// +// Created by Avently on 14.06.2024. +// Copyright © 2024 SimpleX Chat. All rights reserved. +// + +import Foundation +import SwiftUI +import SimpleXChat + +struct ChatViewBackground: ViewModifier { + @EnvironmentObject var theme: AppTheme + var image: Image + var imageType: WallpaperType + var background: Color + var tint: Color + + func body(content: Content) -> some View { + content.background( + Canvas { context, size in + var image = context.resolve(image) + let rect = CGRectMake(0, 0, size.width, size.height) + func repeatDraw(_ imageScale: CGFloat) { + image.shading = .color(tint) + let scale = imageScale * 1.57 // for some reason a wallpaper on iOS looks smaller than on Android + for h in 0 ... Int(size.height / image.size.height / scale) { + for w in 0 ... Int(size.width / image.size.width / scale) { + let rect = CGRectMake(CGFloat(w) * image.size.width * scale, CGFloat(h) * image.size.height * scale, image.size.width * scale, image.size.height * scale) + context.draw(image, in: rect, style: FillStyle()) + } + } + } + context.fill(Path(rect), with: .color(background)) + switch imageType { + case let WallpaperType.preset(filename, scale): + repeatDraw(CGFloat((scale ?? 1) * (PresetWallpaper.from(filename)?.scale ?? 1))) + case let WallpaperType.image(_, scale, scaleType): + let scaleType = scaleType ?? WallpaperScaleType.fill + switch scaleType { + case WallpaperScaleType.repeat: repeatDraw(CGFloat(scale ?? 1)) + case WallpaperScaleType.fill: fallthrough + case WallpaperScaleType.fit: + let scale = scaleType.computeScaleFactor(image.size, size) + let scaledWidth = (image.size.width * scale.0) + let scaledHeight = (image.size.height * scale.1) + context.draw(image, in: CGRectMake(((size.width - scaledWidth) / 2), ((size.height - scaledHeight) / 2), scaledWidth, scaledHeight), style: FillStyle()) + if case WallpaperScaleType.fit = scaleType { + if scaledWidth < size.width { + // has black lines at left and right sides + var x = (size.width - scaledWidth) / 2 + while x > 0 { + context.draw(image, in: CGRectMake((x - scaledWidth), ((size.height - scaledHeight) / 2), scaledWidth, scaledHeight), style: FillStyle()) + x -= scaledWidth + } + x = size.width - (size.width - scaledWidth) / 2 + while x < size.width { + context.draw(image, in: CGRectMake(x, ((size.height - scaledHeight) / 2), scaledWidth, scaledHeight), style: FillStyle()) + + x += scaledWidth + } + } else { + // has black lines at top and bottom sides + var y = (size.height - scaledHeight) / 2 + while y > 0 { + context.draw(image, in: CGRectMake(((size.width - scaledWidth) / 2), (y - scaledHeight), scaledWidth, scaledHeight), style: FillStyle()) + y -= scaledHeight + } + y = size.height - (size.height - scaledHeight) / 2 + while y < size.height { + context.draw(image, in: CGRectMake(((size.width - scaledWidth) / 2), y, scaledWidth, scaledHeight), style: FillStyle()) + y += scaledHeight + } + } + } + context.fill(Path(rect), with: .color(tint)) + } + case WallpaperType.empty: () + } + } + ) + } +} + +extension PresetWallpaper { + public func toType(_ base: DefaultTheme, _ scale: Float? = nil) -> WallpaperType { + let scale = if let scale { + scale + } else if let type = ChatModel.shared.currentUser?.uiThemes?.preferredMode(base.mode == DefaultThemeMode.dark)?.wallpaper?.toAppWallpaper().type, type.sameType(WallpaperType.preset(filename, nil)) { + type.scale + } else if let scale = themeOverridesDefault.get().first(where: { $0.wallpaper != nil && $0.wallpaper!.preset == filename })?.wallpaper?.scale { + scale + } else { + Float(1.0) + } + return WallpaperType.preset( + filename, + scale + ) + } +} diff --git a/apps/ios/Shared/Views/Helpers/ImagePicker.swift b/apps/ios/Shared/Views/Helpers/ImagePicker.swift index fe8d5bbdd4..d7525027e0 100644 --- a/apps/ios/Shared/Views/Helpers/ImagePicker.swift +++ b/apps/ios/Shared/Views/Helpers/ImagePicker.swift @@ -33,6 +33,7 @@ struct LibraryMediaListPicker: UIViewControllerRepresentable { typealias UIViewControllerType = PHPickerViewController var addMedia: (_ content: UploadContent) async -> Void var selectionLimit: Int + var filter: PHPickerFilter = .any(of: [.images, .videos]) var finishedPreprocessing: () -> Void = {} var didFinishPicking: (_ didSelectItems: Bool) async -> Void @@ -148,7 +149,7 @@ struct LibraryMediaListPicker: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> PHPickerViewController { var config = PHPickerConfiguration() - config.filter = .any(of: [.images, .videos]) + config.filter = filter config.selectionLimit = selectionLimit config.selection = .ordered config.preferredAssetRepresentationMode = .current diff --git a/apps/ios/Shared/Views/Helpers/ProfileImage.swift b/apps/ios/Shared/Views/Helpers/ProfileImage.swift index 6b8439504a..0a0aab6253 100644 --- a/apps/ios/Shared/Views/Helpers/ProfileImage.swift +++ b/apps/ios/Shared/Views/Helpers/ProfileImage.swift @@ -12,10 +12,12 @@ import SimpleXChat let defaultProfileImageCorner = 22.5 struct ProfileImage: View { + @EnvironmentObject var theme: AppTheme var imageStr: String? = nil var iconName: String = "person.crop.circle.fill" var size: CGFloat var color = Color(uiColor: .tertiarySystemGroupedBackground) + var backgroundColor: Color? = nil @AppStorage(DEFAULT_PROFILE_IMAGE_CORNER_RADIUS) private var radius = defaultProfileImageCorner var body: some View { @@ -24,10 +26,12 @@ struct ProfileImage: View { let uiImage = UIImage(data: data) { clipProfileImage(Image(uiImage: uiImage), size: size, radius: radius) } else { + let c = color.asAnotherColorFromSecondaryVariant(theme) Image(systemName: iconName) .resizable() - .foregroundColor(color) + .foregroundColor(c) .frame(width: size, height: size) + .background(Circle().fill(backgroundColor != nil ? backgroundColor! : .clear)) } } } @@ -51,6 +55,29 @@ private let radiusFactor = (1 - squareToCircleRatio) / 50 } } + +extension Color { + func asAnotherColorFromSecondary(_ theme: AppTheme) -> Color { + return self + } + + func asAnotherColorFromSecondaryVariant(_ theme: AppTheme) -> Color { + let s = theme.colors.secondaryVariant + let l = theme.colors.isLight + return switch self { + case Color(uiColor: .tertiaryLabel): // ChatView title + l ? s.darker(0.05) : s.lighter(0.2) + case Color(uiColor: .tertiarySystemFill): // SettingsView, ChatInfoView + l ? s.darker(0.065) : s.lighter(0.085) + case Color(uiColor: .quaternaryLabel): // ChatListView user picker + l ? s.darker(0.1) : s.lighter(0.1) + case Color(uiColor: .tertiarySystemGroupedBackground): // ChatListView items, forward view + s.asGroupedBackground(theme.base.mode) + default: self + } + } +} + struct ProfileImage_Previews: PreviewProvider { static var previews: some View { ProfileImage(imageStr: "data:image/png;base64,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", size: 63) diff --git a/apps/ios/Shared/Views/Helpers/ThemeModeEditor.swift b/apps/ios/Shared/Views/Helpers/ThemeModeEditor.swift new file mode 100644 index 0000000000..ae94b4685c --- /dev/null +++ b/apps/ios/Shared/Views/Helpers/ThemeModeEditor.swift @@ -0,0 +1,445 @@ +// +// ThemeModeEditor.swift +// SimpleX (iOS) +// +// Created by Avently on 20.06.2024. +// Copyright © 2024 SimpleX Chat. All rights reserved. +// + +import Foundation +import SwiftUI +import SimpleXChat + +struct UserWallpaperEditor: View { + @EnvironmentObject var theme: AppTheme + var initialTheme: ThemeModeOverride + @State var themeModeOverride: ThemeModeOverride + @State var applyToMode: DefaultThemeMode? + @State var showMore: Bool = false + @Binding var globalThemeUsed: Bool + var save: (DefaultThemeMode?, ThemeModeOverride?) async -> Void + + @State private var showImageImporter: Bool = false + + var body: some View { + List { + let wallpaperType = theme.wallpaper.type + + WallpaperPresetSelector( + selectedWallpaper: wallpaperType, + currentColors: { type in + // If applying for : + // - all themes: no overrides needed + // - specific user: only user overrides for currently selected theme are needed, because they will NOT be copied when other wallpaper is selected + let perUserOverride: ThemeModeOverrides? = wallpaperType.sameType(type) ? ChatModel.shared.currentUser?.uiThemes : nil + return ThemeManager.currentColors(type, nil, perUserOverride, themeOverridesDefault.get()) + }, + onChooseType: onChooseType + ) + .padding(.bottom, 10) + .listRowInsets(.init()) + .listRowBackground(Color.clear) + .modifier(WallpaperImporter(showImageImporter: $showImageImporter, onChooseImage: { image in + if let filename = saveWallpaperFile(image: image) { + _ = onTypeCopyFromSameTheme(WallpaperType.image(filename, 1, WallpaperScaleType.fill)) + } + })) + + WallpaperSetupView( + wallpaperType: themeModeOverride.type, + base: theme.base, + initialWallpaper: theme.wallpaper, + editColor: { name in editColor(name, theme) }, + onTypeChange: onTypeChange + ) + + Section { + if !globalThemeUsed { + ResetToGlobalThemeButton(true, theme.colors.primary) { + themeModeOverride = ThemeManager.defaultActiveTheme(ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + globalThemeUsed = true + Task { + await save(applyToMode, nil) + await MainActor.run { + // Change accent color globally + ThemeManager.applyTheme(currentThemeDefault.get()) + } + } + } + } + + SetDefaultThemeButton(theme.colors.primary) { + globalThemeUsed = false + let lightBase = DefaultTheme.LIGHT + let darkBase = if theme.base != DefaultTheme.LIGHT { theme.base } else if systemDarkThemeDefault.get() == DefaultTheme.DARK.themeName { DefaultTheme.DARK } else if systemDarkThemeDefault.get() == DefaultTheme.BLACK.themeName { DefaultTheme.BLACK } else { DefaultTheme.SIMPLEX } + let mode = themeModeOverride.mode + Task { + // Saving for both modes in one place by changing mode once per save + if applyToMode == nil { + let oppositeMode = mode == DefaultThemeMode.light ? DefaultThemeMode.dark : DefaultThemeMode.light + await save(oppositeMode, ThemeModeOverride.withFilledAppDefaults(oppositeMode, oppositeMode == DefaultThemeMode.light ? lightBase : darkBase)) + } + await MainActor.run { + themeModeOverride = ThemeModeOverride.withFilledAppDefaults(mode, mode == DefaultThemeMode.light ? lightBase : darkBase) + } + await save(themeModeOverride.mode, themeModeOverride) + await MainActor.run { + // Change accent color globally + ThemeManager.applyTheme(currentThemeDefault.get()) + } + } + }.onChange(of: initialTheme.mode) { mode in + themeModeOverride = initialTheme + if applyToMode != nil { + applyToMode = mode + } + } + .onChange(of: theme) { _ in + // Applies updated global theme if current one tracks global theme + if globalThemeUsed { + themeModeOverride = ThemeManager.defaultActiveTheme(ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + globalThemeUsed = true + } + } + } + + if showMore { + let values = [ + (nil, "All modes"), + (DefaultThemeMode.light, "Light mode"), + (DefaultThemeMode.dark, "Dark mode") + ] + Picker("Apply to", selection: $applyToMode) { + ForEach(values, id: \.0) { (_, text) in + Text(text) + } + } + .frame(height: 36) + .onChange(of: applyToMode) { mode in + if let mode, mode != theme.base.mode { + let lightBase = DefaultTheme.LIGHT + let darkBase = if theme.base != DefaultTheme.LIGHT { theme.base } else if systemDarkThemeDefault.get() == DefaultTheme.DARK.themeName { DefaultTheme.DARK } else if systemDarkThemeDefault.get() == DefaultTheme.BLACK.themeName { DefaultTheme.BLACK } else { DefaultTheme.SIMPLEX } + ThemeManager.applyTheme(mode == DefaultThemeMode.light ? lightBase.themeName : darkBase.themeName) + } + } + + CustomizeThemeColorsSection(editColor: { name in editColor(name, theme) }) + + ImportExportThemeSection(perChat: nil, perUser: ChatModel.shared.currentUser?.uiThemes) { imported in + let importedFromString = imported.wallpaper?.importFromString() + let importedType = importedFromString?.toAppWallpaper().type + let currentTheme = ThemeManager.currentColors(nil, nil, nil, themeOverridesDefault.get()) + let type: WallpaperType? = if importedType?.sameType(currentTheme.wallpaper.type) == true { nil } else { importedType } + let colors = ThemeManager.currentThemeOverridesForExport(type, nil, nil).colors + let res = ThemeModeOverride(mode: imported.base.mode, colors: imported.colors, wallpaper: importedFromString).removeSameColors(imported.base, colorsToCompare: colors) + Task { + await MainActor.run { + themeModeOverride = res + } + await save(applyToMode, res) + } + } + } else { + AdvancedSettingsButton(theme.colors.primary) { showMore = true } + } + } + } + + private func onTypeCopyFromSameTheme(_ type: WallpaperType?) -> Bool { + _ = ThemeManager.copyFromSameThemeOverrides(type, nil, $themeModeOverride) + Task { + await save(applyToMode, themeModeOverride) + } + globalThemeUsed = false + return true + } + + private func preApplyGlobalIfNeeded(_ type: WallpaperType?) { + if globalThemeUsed { + _ = onTypeCopyFromSameTheme(type) + } + } + + private func onTypeChange(_ type: WallpaperType?) { + if globalThemeUsed { + preApplyGlobalIfNeeded(type) + // Saves copied static image instead of original from global theme + ThemeManager.applyWallpaper(themeModeOverride.type, $themeModeOverride) + } else { + ThemeManager.applyWallpaper(type, $themeModeOverride) + } + Task { + await save(applyToMode, themeModeOverride) + } + } + + private func currentColors(_ type: WallpaperType?) -> ThemeManager.ActiveTheme { + // If applying for : + // - all themes: no overrides needed + // - specific user: only user overrides for currently selected theme are needed, because they will NOT be copied when other wallpaper is selected + let perUserOverride: ThemeModeOverrides? = theme.wallpaper.type.sameType(type) ? ChatModel.shared.currentUser?.uiThemes : nil + return ThemeManager.currentColors(type, nil, perUserOverride, themeOverridesDefault.get()) + } + + private func onChooseType(_ type: WallpaperType?) { + if let type, case WallpaperType.image = type { + if theme.wallpaper.type.isImage || currentColors(type).wallpaper.type.image == nil { + showImageImporter = true + } else { + _ = onTypeCopyFromSameTheme(currentColors(type).wallpaper.type) + } + } else if themeModeOverride.type != type || theme.wallpaper.type != type { + _ = onTypeCopyFromSameTheme(type) + } else { + onTypeChange(type) + } + } + + private func editColor(_ name: ThemeColor, _ currentTheme: AppTheme) -> Binding { + editColorBinding( + name: name, + wallpaperType: theme.wallpaper.type, + wallpaperImage: theme.wallpaper.type.image, + theme: currentTheme, + onColorChange: { color in + preApplyGlobalIfNeeded(themeModeOverride.type) + ThemeManager.applyThemeColor(name: name, color: color, pref: $themeModeOverride) + Task { await save(applyToMode, themeModeOverride) } + }) + } +} + +struct ChatWallpaperEditor: View { + @EnvironmentObject var theme: AppTheme + @State private var currentTheme: ThemeManager.ActiveTheme + var initialTheme: ThemeModeOverride + @State var themeModeOverride: ThemeModeOverride + @State var applyToMode: DefaultThemeMode? + @State var showMore: Bool = false + @Binding var globalThemeUsed: Bool + var save: (DefaultThemeMode?, ThemeModeOverride?) async -> Void + + @State private var showImageImporter: Bool = false + + init(initialTheme: ThemeModeOverride, themeModeOverride: ThemeModeOverride, applyToMode: DefaultThemeMode? = nil, globalThemeUsed: Binding, save: @escaping (DefaultThemeMode?, ThemeModeOverride?) async -> Void) { + let cur = ThemeManager.currentColors(nil, globalThemeUsed.wrappedValue ? nil : themeModeOverride, ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + self.currentTheme = cur + self.initialTheme = initialTheme + self.themeModeOverride = themeModeOverride + self.applyToMode = applyToMode + self._globalThemeUsed = globalThemeUsed + self.save = save + } + + var body: some View { + List { + WallpaperPresetSelector( + selectedWallpaper: currentTheme.wallpaper.type, + activeBackgroundColor: currentTheme.wallpaper.background, + activeTintColor: currentTheme.wallpaper.tint, + currentColors: currentColors, + onChooseType: onChooseType + ) + .padding(.bottom, 10) + .listRowInsets(.init()) + .listRowBackground(Color.clear) + .modifier(WallpaperImporter(showImageImporter: $showImageImporter, onChooseImage: { image in + if let filename = saveWallpaperFile(image: image) { + _ = onTypeCopyFromSameTheme(WallpaperType.image(filename, 1, WallpaperScaleType.fill)) + } + })) + + WallpaperSetupView( + wallpaperType: themeModeOverride.type, + base: currentTheme.base, + initialWallpaper: currentTheme.wallpaper, + editColor: editColor, + onTypeChange: onTypeChange + ) + + Section { + if !globalThemeUsed { + ResetToGlobalThemeButton(ChatModel.shared.currentUser?.uiThemes?.preferredMode(isInDarkTheme()) == nil, theme.colors.primary) { + themeModeOverride = ThemeManager.defaultActiveTheme(ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + globalThemeUsed = true + Task { + await save(applyToMode, nil) + } + } + } + + SetDefaultThemeButton(theme.colors.primary) { + globalThemeUsed = false + let lightBase = DefaultTheme.LIGHT + let darkBase = if currentTheme.base != DefaultTheme.LIGHT { currentTheme.base } else if systemDarkThemeDefault.get() == DefaultTheme.DARK.themeName { DefaultTheme.DARK } else if systemDarkThemeDefault.get() == DefaultTheme.BLACK.themeName { DefaultTheme.BLACK } else { DefaultTheme.SIMPLEX } + let mode = themeModeOverride.mode + Task { + // Saving for both modes in one place by changing mode once per save + if applyToMode == nil { + let oppositeMode = mode == DefaultThemeMode.light ? DefaultThemeMode.dark : DefaultThemeMode.light + await save(oppositeMode, ThemeModeOverride.withFilledAppDefaults(oppositeMode, oppositeMode == DefaultThemeMode.light ? lightBase : darkBase)) + } + await MainActor.run { + themeModeOverride = ThemeModeOverride.withFilledAppDefaults(mode, mode == DefaultThemeMode.light ? lightBase : darkBase) + } + await save(themeModeOverride.mode, themeModeOverride) + } + } + .onChange(of: initialTheme) { initial in + if initial.mode != themeModeOverride.mode { + themeModeOverride = initial + currentTheme = ThemeManager.currentColors(nil, globalThemeUsed ? nil : themeModeOverride, ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + if applyToMode != nil { + applyToMode = initial.mode + } + } + } + .onChange(of: currentTheme) { _ in + // Applies updated global theme if current one tracks global theme + if globalThemeUsed { + themeModeOverride = ThemeManager.defaultActiveTheme(ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + globalThemeUsed = true + } + } + .onChange(of: themeModeOverride) { override in + currentTheme = ThemeManager.currentColors(nil, globalThemeUsed ? nil : override, ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + } + } + + if showMore { + let values = [ + (nil, "All modes"), + (DefaultThemeMode.light, "Light mode"), + (DefaultThemeMode.dark, "Dark mode") + ] + Picker("Apply to", selection: $applyToMode) { + ForEach(values, id: \.0) { (_, text) in + Text(text) + } + } + .frame(height: 36) + .onChange(of: applyToMode) { mode in + if let mode, mode != currentTheme.base.mode { + let lightBase = DefaultTheme.LIGHT + let darkBase = if currentTheme.base != DefaultTheme.LIGHT { currentTheme.base } else if systemDarkThemeDefault.get() == DefaultTheme.DARK.themeName { DefaultTheme.DARK } else if systemDarkThemeDefault.get() == DefaultTheme.BLACK.themeName { DefaultTheme.BLACK } else { DefaultTheme.SIMPLEX } + ThemeManager.applyTheme(mode == DefaultThemeMode.light ? lightBase.themeName : darkBase.themeName) + } + } + + CustomizeThemeColorsSection(editColor: editColor) + + ImportExportThemeSection(perChat: themeModeOverride, perUser: ChatModel.shared.currentUser?.uiThemes) { imported in + let importedFromString = imported.wallpaper?.importFromString() + let importedType = importedFromString?.toAppWallpaper().type + let currentTheme = ThemeManager.currentColors(nil, nil, ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + let type: WallpaperType? = if importedType?.sameType(currentTheme.wallpaper.type) == true { nil } else { importedType } + let colors = ThemeManager.currentThemeOverridesForExport(type, nil, ChatModel.shared.currentUser?.uiThemes).colors + let res = ThemeModeOverride(mode: imported.base.mode, colors: imported.colors, wallpaper: importedFromString).removeSameColors(imported.base, colorsToCompare: colors) + Task { + await MainActor.run { + themeModeOverride = res + } + await save(applyToMode, res) + } + } + } else { + AdvancedSettingsButton(theme.colors.primary) { showMore = true } + } + } + } + + private func onTypeCopyFromSameTheme(_ type: WallpaperType?) -> Bool { + let success = ThemeManager.copyFromSameThemeOverrides(type, ChatModel.shared.currentUser?.uiThemes?.preferredMode(!currentTheme.colors.isLight), $themeModeOverride) + if success { + Task { + await save(applyToMode, themeModeOverride) + } + globalThemeUsed = false + } + return success + } + + private func preApplyGlobalIfNeeded(_ type: WallpaperType?) { + if globalThemeUsed { + _ = onTypeCopyFromSameTheme(type) + } + } + + private func onTypeChange(_ type: WallpaperType?) { + if globalThemeUsed { + preApplyGlobalIfNeeded(type) + // Saves copied static image instead of original from global theme + ThemeManager.applyWallpaper(themeModeOverride.type, $themeModeOverride) + } else { + ThemeManager.applyWallpaper(type, $themeModeOverride) + } + Task { + await save(applyToMode, themeModeOverride) + } + } + + private func currentColors(_ type: WallpaperType?) -> ThemeManager.ActiveTheme { + // If applying for : + // - all themes: no overrides needed + // - specific user: only user overrides for currently selected theme are needed, because they will NOT be copied when other wallpaper is selected + let perChatOverride: ThemeModeOverride? = type?.sameType(themeModeOverride.type) == true ? themeModeOverride : nil + return ThemeManager.currentColors(type, perChatOverride, ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + } + + private func onChooseType(_ type: WallpaperType?) { + if let type, case WallpaperType.image = type { + if (themeModeOverride.type?.isImage == true && !globalThemeUsed) || currentColors(type).wallpaper.type.image == nil { + showImageImporter = true + } else if !onTypeCopyFromSameTheme(currentColors(type).wallpaper.type) { + showImageImporter = true + } + } else if globalThemeUsed || themeModeOverride.type != type || themeModeOverride.type != type { + _ = onTypeCopyFromSameTheme(type) + } else { + onTypeChange(type) + } + } + + private func editColor(_ name: ThemeColor) -> Binding { + editColorBinding( + name: name, + wallpaperType: themeModeOverride.type, + wallpaperImage: themeModeOverride.type?.image, + theme: currentTheme.toAppTheme(), + onColorChange: { color in + preApplyGlobalIfNeeded(themeModeOverride.type) + ThemeManager.applyThemeColor(name: name, color: color, pref: $themeModeOverride) + currentTheme = ThemeManager.currentColors(nil, globalThemeUsed ? nil : themeModeOverride, ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + Task { await save(applyToMode, themeModeOverride) } + }) + } +} + +private func ResetToGlobalThemeButton(_ app: Bool, _ primaryColor: Color, _ onClick: @escaping () -> Void) -> some View { + Button { + onClick() + } label: { + Text(app ? "Reset to app theme" : "Reset to user theme") + .foregroundColor(primaryColor) + } +} + +private func SetDefaultThemeButton(_ primaryColor: Color, _ onClick: @escaping () -> Void) -> some View { + Button { + onClick() + } label: { + Text("Set default theme") + .foregroundColor(primaryColor) + } +} + +private func AdvancedSettingsButton(_ primaryColor: Color, _ onClick: @escaping () -> Void) -> some View { + Button { + onClick() + } label: { + HStack { + Image(systemName: "chevron.down") + Text("Advanced settings") + }.foregroundColor(primaryColor) + } +} diff --git a/apps/ios/Shared/Views/Helpers/ViewModifiers.swift b/apps/ios/Shared/Views/Helpers/ViewModifiers.swift new file mode 100644 index 0000000000..7e2655f4f7 --- /dev/null +++ b/apps/ios/Shared/Views/Helpers/ViewModifiers.swift @@ -0,0 +1,19 @@ +// +// ViewModifiers.swift +// SimpleX (iOS) +// +// Created by Avently on 12.06.2024. +// Copyright © 2024 SimpleX Chat. All rights reserved. +// + +import SwiftUI + +extension View { + @ViewBuilder func `if`(_ condition: @autoclosure () -> Bool, transform: (Self) -> Content) -> some View { + if condition() { + transform(self) + } else { + self + } + } +} diff --git a/apps/ios/Shared/Views/LocalAuth/PasscodeEntry.swift b/apps/ios/Shared/Views/LocalAuth/PasscodeEntry.swift index 46ce66678a..609943bcb6 100644 --- a/apps/ios/Shared/Views/LocalAuth/PasscodeEntry.swift +++ b/apps/ios/Shared/Views/LocalAuth/PasscodeEntry.swift @@ -10,6 +10,7 @@ import SwiftUI struct PasscodeEntry: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme var width: CGFloat var height: CGFloat @Binding var password: String @@ -140,11 +141,11 @@ struct PasscodeEntry: View { ZStack { Circle() .frame(width: h, height: h) - .foregroundColor(Color(uiColor: .systemBackground)) + .foregroundColor(AppTheme.shared.colors.background) label() } } - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .frame(width: size, height: h) } } diff --git a/apps/ios/Shared/Views/LocalAuth/PasscodeView.swift b/apps/ios/Shared/Views/LocalAuth/PasscodeView.swift index 9e0d7f38b5..ca30fa5ce8 100644 --- a/apps/ios/Shared/Views/LocalAuth/PasscodeView.swift +++ b/apps/ios/Shared/Views/LocalAuth/PasscodeView.swift @@ -29,7 +29,7 @@ struct PasscodeView: View { } .padding(.horizontal, 40) .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(Color(uiColor: .systemBackground)) + .background(AppTheme.shared.colors.background) } private func verticalPasscodeView(_ g: GeometryProxy) -> some View { diff --git a/apps/ios/Shared/Views/Migration/MigrateFromDevice.swift b/apps/ios/Shared/Views/Migration/MigrateFromDevice.swift index 645de4c3f8..ec2ce883c5 100644 --- a/apps/ios/Shared/Views/Migration/MigrateFromDevice.swift +++ b/apps/ios/Shared/Views/Migration/MigrateFromDevice.swift @@ -53,6 +53,7 @@ private enum MigrateFromDeviceViewAlert: Identifiable { struct MigrateFromDevice: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @Environment(\.dismiss) var dismiss: DismissAction @Binding var showSettings: Bool @Binding var showProgressOnSettings: Bool @@ -177,6 +178,7 @@ struct MigrateFromDevice: View { List { Section {} header: { Text("Stopping chat") + .foregroundColor(theme.colors.secondary) } } progressView() @@ -188,14 +190,16 @@ struct MigrateFromDevice: View { Section { Text(reason) Button(action: stopChat) { - settingsRow("stop.fill") { + settingsRow("stop.fill", color: theme.colors.secondary) { Text("Stop chat").foregroundColor(.red) } } } header: { Text("Error stopping chat") + .foregroundColor(theme.colors.secondary) } footer: { Text("In order to continue, chat should be stopped.") + .foregroundColor(theme.colors.secondary) .font(.callout) } } @@ -214,14 +218,16 @@ struct MigrateFromDevice: View { List { Section { Button(action: { migrationState = .archiving }) { - settingsRow("tray.and.arrow.up") { - Text("Archive and upload").foregroundColor(.accentColor) + settingsRow("tray.and.arrow.up", color: theme.colors.secondary) { + Text("Archive and upload").foregroundColor(theme.colors.primary) } } } header: { Text("Confirm upload") + .foregroundColor(theme.colors.secondary) } footer: { Text("All your contacts, conversations and files will be securely encrypted and uploaded in chunks to configured XFTP relays.") + .foregroundColor(theme.colors.secondary) .font(.callout) } } @@ -232,6 +238,7 @@ struct MigrateFromDevice: View { List { Section {} header: { Text("Archiving database") + .foregroundColor(theme.colors.secondary) } } progressView() @@ -246,10 +253,11 @@ struct MigrateFromDevice: View { List { Section {} header: { Text("Uploading archive") + .foregroundColor(theme.colors.secondary) } } let ratio = Float(uploadedBytes) / Float(totalBytes) - MigrateFromDevice.largeProgressView(ratio, "\(Int(ratio * 100))%", "\(ByteCountFormatter.string(fromByteCount: uploadedBytes, countStyle: .binary)) uploaded") + MigrateFromDevice.largeProgressView(ratio, "\(Int(ratio * 100))%", "\(ByteCountFormatter.string(fromByteCount: uploadedBytes, countStyle: .binary)) uploaded", theme.colors.primary) } .onAppear { startUploading(totalBytes, archivePath) @@ -262,14 +270,16 @@ struct MigrateFromDevice: View { Button(action: { migrationState = .uploadProgress(uploadedBytes: 0, totalBytes: totalBytes, fileId: 0, archivePath: archivePath, ctrl: nil) }) { - settingsRow("tray.and.arrow.up") { - Text("Repeat upload").foregroundColor(.accentColor) + settingsRow("tray.and.arrow.up", color: theme.colors.secondary) { + Text("Repeat upload").foregroundColor(theme.colors.primary) } } } header: { Text("Upload failed") + .foregroundColor(theme.colors.secondary) } footer: { Text("You can give another try.") + .foregroundColor(theme.colors.secondary) .font(.callout) } } @@ -283,6 +293,7 @@ struct MigrateFromDevice: View { List { Section {} header: { Text("Creating archive link") + .foregroundColor(theme.colors.secondary) } } progressView() @@ -293,13 +304,13 @@ struct MigrateFromDevice: View { List { Section { Button(action: { cancelMigration(fileId, ctrl) }) { - settingsRow("multiply") { + settingsRow("multiply", color: theme.colors.secondary) { Text("Cancel migration").foregroundColor(.red) } } Button(action: { finishMigration(fileId, ctrl) }) { - settingsRow("checkmark") { - Text("Finalize migration").foregroundColor(.accentColor) + settingsRow("checkmark", color: theme.colors.secondary) { + Text("Finalize migration").foregroundColor(theme.colors.primary) } } } footer: { @@ -307,9 +318,10 @@ struct MigrateFromDevice: View { Text("**Warning**: the archive will be removed.") Text("Choose _Migrate from another device_ on the new device and scan QR code.") } + .foregroundColor(theme.colors.secondary) .font(.callout) } - Section("Show QR code") { + Section(header: Text("Show QR code").foregroundColor(theme.colors.secondary)) { SimpleXLinkQRCode(uri: link) .padding() .background( @@ -322,7 +334,7 @@ struct MigrateFromDevice: View { .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) } - Section("Or securely share this file link") { + Section(header: Text("Or securely share this file link").foregroundColor(theme.colors.secondary)) { shareLinkView(link) } .listRowInsets(EdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 10)) @@ -334,22 +346,24 @@ struct MigrateFromDevice: View { List { Section { Button(action: { alert = .startChat() }) { - settingsRow("play.fill") { + settingsRow("play.fill", color: theme.colors.secondary) { Text("Start chat").foregroundColor(.red) } } Button(action: { alert = .deleteChat() }) { - settingsRow("trash.fill") { - Text("Delete database from this device").foregroundColor(.accentColor) + settingsRow("trash.fill", color: theme.colors.secondary) { + Text("Delete database from this device").foregroundColor(theme.colors.primary) } } } header: { Text("Migration complete") + .foregroundColor(theme.colors.secondary) } footer: { VStack(alignment: .leading, spacing: 16) { Text("You **must not** use the same database on two devices.") Text("**Please note**: using the same database on two devices will break the decryption of messages from your connections, as a security protection.") } + .foregroundColor(theme.colors.secondary) .font(.callout) } } @@ -379,7 +393,7 @@ struct MigrateFromDevice: View { .truncationMode(.middle) } - static func largeProgressView(_ value: Float, _ title: String, _ description: LocalizedStringKey) -> some View { + static func largeProgressView(_ value: Float, _ title: String, _ description: LocalizedStringKey, _ primaryColor: Color) -> some View { ZStack { VStack { Text(description) @@ -389,7 +403,7 @@ struct MigrateFromDevice: View { Text(title) .font(.system(size: 54)) .bold() - .foregroundColor(.accentColor) + .foregroundColor(primaryColor) Text(description) .font(.title3) @@ -398,7 +412,7 @@ struct MigrateFromDevice: View { Circle() .trim(from: 0, to: CGFloat(value)) .stroke( - Color.accentColor, + primaryColor, style: StrokeStyle(lineWidth: 27) ) .rotationEffect(.degrees(180)) @@ -590,6 +604,7 @@ struct MigrateFromDevice: View { } private struct PassphraseConfirmationView: View { + @EnvironmentObject var theme: AppTheme @Binding var migrationState: MigrationFromState @State private var useKeychain = storeDBPassphraseGroupDefault.get() @State private var currentKey: String = "" @@ -612,15 +627,17 @@ private struct PassphraseConfirmationView: View { verifyingPassphrase = false } }) { - settingsRow(useKeychain ? "key" : "lock", color: .secondary) { + settingsRow(useKeychain ? "key" : "lock", color: theme.colors.secondary) { Text("Verify passphrase") } } .disabled(verifyingPassphrase || currentKey.isEmpty) } header: { Text("Verify database passphrase") + .foregroundColor(theme.colors.secondary) } footer: { Text("Confirm that you remember database passphrase to migrate it.") + .foregroundColor(theme.colors.secondary) .font(.callout) } .onAppear { diff --git a/apps/ios/Shared/Views/Migration/MigrateToDevice.swift b/apps/ios/Shared/Views/Migration/MigrateToDevice.swift index e290537b46..107785e336 100644 --- a/apps/ios/Shared/Views/Migration/MigrateToDevice.swift +++ b/apps/ios/Shared/Views/Migration/MigrateToDevice.swift @@ -91,6 +91,7 @@ private enum MigrateToDeviceViewAlert: Identifiable { struct MigrateToDevice: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @Environment(\.dismiss) var dismiss: DismissAction @AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false @Binding var migrationState: MigrationToState? @@ -180,7 +181,7 @@ struct MigrateToDevice: View { private func pasteOrScanLinkView() -> some View { ZStack { List { - Section("Scan QR code") { + Section(header: Text("Scan QR code").foregroundColor(theme.colors.secondary)) { ScannerInView(showQRCodeScanner: $showQRCodeScanner) { resp in switch resp { case let .success(r): @@ -197,7 +198,7 @@ struct MigrateToDevice: View { } } if developerTools { - Section("Or paste archive link") { + Section(header: Text("Or paste archive link").foregroundColor(theme.colors.secondary)) { pasteLinkView() } } @@ -226,6 +227,7 @@ struct MigrateToDevice: View { List { Section {} header: { Text("Downloading link details") + .foregroundColor(theme.colors.secondary) } } progressView() @@ -240,10 +242,11 @@ struct MigrateToDevice: View { List { Section {} header: { Text("Downloading archive") + .foregroundColor(theme.colors.secondary) } } let ratio = Float(downloadedBytes) / Float(max(totalBytes, 1)) - MigrateFromDevice.largeProgressView(ratio, "\(Int(ratio * 100))%", "\(ByteCountFormatter.string(fromByteCount: downloadedBytes, countStyle: .binary)) downloaded") + MigrateFromDevice.largeProgressView(ratio, "\(Int(ratio * 100))%", "\(ByteCountFormatter.string(fromByteCount: downloadedBytes, countStyle: .binary)) downloaded", theme.colors.primary) } } @@ -254,14 +257,16 @@ struct MigrateToDevice: View { try? FileManager.default.removeItem(atPath: archivePath) migrationState = .linkDownloading(link: link) }) { - settingsRow("tray.and.arrow.down") { - Text("Repeat download").foregroundColor(.accentColor) + settingsRow("tray.and.arrow.down", color: theme.colors.secondary) { + Text("Repeat download").foregroundColor(theme.colors.primary) } } } header: { Text("Download failed") + .foregroundColor(theme.colors.secondary) } footer: { Text("You can give another try.") + .foregroundColor(theme.colors.secondary) .font(.callout) } } @@ -277,6 +282,7 @@ struct MigrateToDevice: View { List { Section {} header: { Text("Importing archive") + .foregroundColor(theme.colors.secondary) } } progressView() @@ -292,14 +298,16 @@ struct MigrateToDevice: View { Button(action: { migrationState = .archiveImport(archivePath: archivePath) }) { - settingsRow("square.and.arrow.down") { - Text("Repeat import").foregroundColor(.accentColor) + settingsRow("square.and.arrow.down", color: theme.colors.secondary) { + Text("Repeat import").foregroundColor(theme.colors.primary) } } } header: { Text("Import failed") + .foregroundColor(theme.colors.secondary) } footer: { Text("You can give another try.") + .foregroundColor(theme.colors.secondary) .font(.callout) } } @@ -333,8 +341,8 @@ struct MigrateToDevice: View { Button(action: { migrationState = .migration(passphrase: passphrase, confirmation: confirmation, useKeychain: useKeychain) }) { - settingsRow("square.and.arrow.down") { - Text(button).foregroundColor(.accentColor) + settingsRow("square.and.arrow.down", color: theme.colors.secondary) { + Text(button).foregroundColor(theme.colors.primary) } } } else { @@ -342,8 +350,10 @@ struct MigrateToDevice: View { } } header: { Text(header) + .foregroundColor(theme.colors.secondary) } footer: { Text(footer) + .foregroundColor(theme.colors.secondary) .font(.callout) } } @@ -354,6 +364,7 @@ struct MigrateToDevice: View { List { Section {} header: { Text("Migrating") + .foregroundColor(theme.colors.secondary) } } progressView() @@ -364,6 +375,7 @@ struct MigrateToDevice: View { } struct OnionView: View { + @EnvironmentObject var theme: AppTheme @State var appSettings: AppSettings @State private var onionHosts: OnionHosts = .no var finishMigration: (AppSettings) -> Void @@ -380,18 +392,20 @@ struct MigrateToDevice: View { appSettings.networkConfig = updated finishMigration(appSettings) }) { - settingsRow("checkmark") { - Text("Apply").foregroundColor(.accentColor) + settingsRow("checkmark", color: theme.colors.secondary) { + Text("Apply").foregroundColor(theme.colors.primary) } } } header: { Text("Confirm network settings") + .foregroundColor(theme.colors.secondary) } footer: { Text("Please confirm that network settings are correct for this device.") + .foregroundColor(theme.colors.secondary) .font(.callout) } - Section("Network settings") { + Section(header: Text("Network settings").foregroundColor(theme.colors.secondary)) { Picker("Use .onion hosts", selection: $onionHosts) { ForEach(OnionHosts.values, id: \.self) { Text($0.text) } } @@ -475,6 +489,7 @@ struct MigrateToDevice: View { chatInitControllerRemovingDatabases() } try await apiDeleteStorage() + try? FileManager.default.createDirectory(at: getWallpaperDirectory(), withIntermediateDirectories: true) do { let config = ArchiveConfig(archivePath: archivePath) let archiveErrors = try await apiImportArchive(config: config) @@ -566,6 +581,7 @@ struct MigrateToDevice: View { } private struct PassphraseEnteringView: View { + @EnvironmentObject var theme: AppTheme @Binding var migrationState: MigrationToState? @State private var useKeychain = true @State var currentKey: String @@ -577,7 +593,7 @@ private struct PassphraseEnteringView: View { ZStack { List { Section { - settingsRow("key", color: .secondary) { + settingsRow("key", color: theme.colors.secondary) { Toggle("Save passphrase in Keychain", isOn: $useKeychain) } @@ -606,13 +622,14 @@ private struct PassphraseEnteringView: View { verifyingPassphrase = false } }) { - settingsRow("key", color: .secondary) { + settingsRow("key", color: theme.colors.secondary) { Text("Open chat") } } .disabled(verifyingPassphrase || currentKey.isEmpty) } header: { Text("Enter passphrase") + .foregroundColor(theme.colors.secondary) } footer: { VStack(alignment: .leading, spacing: 16) { if useKeychain { @@ -623,6 +640,7 @@ private struct PassphraseEnteringView: View { Text("**Warning**: Instant push notifications require passphrase saved in Keychain.") } } + .foregroundColor(theme.colors.secondary) .font(.callout) .padding(.top, 1) .onTapGesture { keyboardVisible = false } diff --git a/apps/ios/Shared/Views/NewChat/AddContactLearnMore.swift b/apps/ios/Shared/Views/NewChat/AddContactLearnMore.swift index 45eb783326..5e6d44f686 100644 --- a/apps/ios/Shared/Views/NewChat/AddContactLearnMore.swift +++ b/apps/ios/Shared/Views/NewChat/AddContactLearnMore.swift @@ -30,6 +30,7 @@ struct AddContactLearnMore: View { } .listRowBackground(Color.clear) } + .modifier(ThemedBackground()) } } diff --git a/apps/ios/Shared/Views/NewChat/AddGroupView.swift b/apps/ios/Shared/Views/NewChat/AddGroupView.swift index 4b272f4caa..5c8a88bd8f 100644 --- a/apps/ios/Shared/Views/NewChat/AddGroupView.swift +++ b/apps/ios/Shared/Views/NewChat/AddGroupView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct AddGroupView: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @Environment(\.dismiss) var dismiss: DismissAction @AppStorage(GROUP_DEFAULT_INCOGNITO, store: groupDefaults) private var incognitoDefault = false @State private var chat: Chat? @@ -70,7 +71,7 @@ struct AddGroupView: View { ZStack(alignment: .center) { ZStack(alignment: .topTrailing) { - ProfileImage(imageStr: profile.image, size: 128, color: Color(uiColor: .secondarySystemGroupedBackground)) + ProfileImage(imageStr: profile.image, size: 128) if profile.image != nil { Button { profile.image = nil @@ -95,7 +96,7 @@ struct AddGroupView: View { Section { groupNameTextField() Button(action: createGroup) { - settingsRow("checkmark", color: .accentColor) { Text("Create group") } + settingsRow("checkmark", color: theme.colors.primary) { Text("Create group") } } .disabled(!canCreateProfile()) IncognitoToggle(incognitoEnabled: $incognitoDefault) @@ -104,6 +105,7 @@ struct AddGroupView: View { sharedGroupProfileInfo(incognitoDefault) Text("Fully decentralized – visible only to members.") } + .foregroundColor(theme.colors.secondary) .frame(maxWidth: .infinity, alignment: .leading) .onTapGesture(perform: hideKeyboard) } @@ -144,6 +146,7 @@ struct AddGroupView: View { profile.image = nil } } + .modifier(ThemedBackground(grouped: true)) } func groupNameTextField() -> some View { @@ -156,7 +159,7 @@ struct AddGroupView: View { Image(systemName: "exclamationmark.circle").foregroundColor(.red) } } else { - Image(systemName: "pencil").foregroundColor(.secondary) + Image(systemName: "pencil").foregroundColor(theme.colors.secondary) } textField("Enter group name…", text: $profile.displayName) .focused($focusDisplayName) diff --git a/apps/ios/Shared/Views/NewChat/NewChatView.swift b/apps/ios/Shared/Views/NewChat/NewChatView.swift index 4b1f72345a..df50bf9df2 100644 --- a/apps/ios/Shared/Views/NewChat/NewChatView.swift +++ b/apps/ios/Shared/Views/NewChat/NewChatView.swift @@ -10,6 +10,7 @@ import SwiftUI import SimpleXChat import CodeScanner import AVFoundation +import SimpleXChat struct SomeAlert: Identifiable { var alert: Alert @@ -37,6 +38,7 @@ enum NewChatOption: Identifiable { struct NewChatView: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @State var selection: NewChatOption @State var showQRCodeScanner = false @State private var invitationUsed: Bool = false @@ -89,7 +91,7 @@ struct NewChatView: View { .background( // Rectangle is needed for swipe gesture to work on mostly empty views (creatingLinkProgressView and retryButton) Rectangle() - .fill(Color(uiColor: .systemGroupedBackground)) + .fill(theme.base == DefaultTheme.LIGHT ? theme.colors.background.asGroupedBackground(theme.base.mode) : theme.colors.background) ) .animation(.easeInOut(duration: 0.3333), value: selection) .gesture(DragGesture(minimumDistance: 20.0, coordinateSpace: .local) @@ -108,7 +110,7 @@ struct NewChatView: View { } ) } - .background(Color(.systemGroupedBackground)) + .modifier(ThemedBackground(grouped: true)) .onChange(of: invitationUsed) { used in if used && !(m.showingInvitation?.connChatUsed ?? true) { m.markShowingInvitationUsed() @@ -202,6 +204,7 @@ struct NewChatView: View { private struct InviteView: View { @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @Binding var invitationUsed: Bool @Binding var contactConnection: PendingContactConnection? var connReqInvitation: String @@ -209,7 +212,7 @@ private struct InviteView: View { var body: some View { List { - Section("Share this 1-time invite link") { + Section(header: Text("Share this 1-time invite link").foregroundColor(theme.colors.secondary)) { shareLinkView() } .listRowInsets(EdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 10)) @@ -220,6 +223,7 @@ private struct InviteView: View { IncognitoToggle(incognitoEnabled: $incognitoDefault) } footer: { sharedProfileInfo(incognitoDefault) + .foregroundColor(theme.colors.secondary) } } .onChange(of: incognitoDefault) { incognito in @@ -256,7 +260,7 @@ private struct InviteView: View { } private func qrCodeView() -> some View { - Section("Or show this code") { + Section(header: Text("Or show this code").foregroundColor(theme.colors.secondary)) { SimpleXLinkQRCode(uri: connReqInvitation, onShare: setInvitationUsed) .padding() .background( @@ -279,6 +283,7 @@ private struct InviteView: View { private struct ConnectView: View { @Environment(\.dismiss) var dismiss: DismissAction + @EnvironmentObject var theme: AppTheme @Binding var showQRCodeScanner: Bool @Binding var pastedLink: String @Binding var alert: NewChatViewAlert? @@ -286,10 +291,10 @@ private struct ConnectView: View { var body: some View { List { - Section("Paste the link you received") { + Section(header: Text("Paste the link you received").foregroundColor(theme.colors.secondary)) { pasteLinkView() } - Section("Or scan QR code") { + Section(header: Text("Or scan QR code").foregroundColor(theme.colors.secondary)) { ScannerInView(showQRCodeScanner: $showQRCodeScanner, processQRCode: processQRCode) } } @@ -483,6 +488,7 @@ func strHasSingleSimplexLink(_ str: String) -> FormattedText? { } struct IncognitoToggle: View { + @EnvironmentObject var theme: AppTheme @Binding var incognitoEnabled: Bool @State private var showIncognitoSheet = false @@ -490,13 +496,13 @@ struct IncognitoToggle: View { ZStack(alignment: .leading) { Image(systemName: incognitoEnabled ? "theatermasks.fill" : "theatermasks") .frame(maxWidth: 24, maxHeight: 24, alignment: .center) - .foregroundColor(incognitoEnabled ? Color.indigo : .secondary) + .foregroundColor(incognitoEnabled ? Color.indigo : theme.colors.secondary) .font(.system(size: 14)) Toggle(isOn: $incognitoEnabled) { HStack(spacing: 6) { Text("Incognito") Image(systemName: "info.circle") - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) .font(.system(size: 14)) } .onTapGesture { diff --git a/apps/ios/Shared/Views/Onboarding/CreateProfile.swift b/apps/ios/Shared/Views/Onboarding/CreateProfile.swift index 0ee6baa765..a62f609833 100644 --- a/apps/ios/Shared/Views/Onboarding/CreateProfile.swift +++ b/apps/ios/Shared/Views/Onboarding/CreateProfile.swift @@ -27,6 +27,7 @@ enum UserProfileAlert: Identifiable { struct CreateProfile: View { @Environment(\.dismiss) var dismiss + @EnvironmentObject var theme: AppTheme @State private var displayName: String = "" @FocusState private var focusDisplayName @State private var alert: UserProfileAlert? @@ -45,6 +46,8 @@ struct CreateProfile: View { } header: { HStack { Text("Your profile") + .foregroundColor(theme.colors.secondary) + let name = displayName.trimmingCharacters(in: .whitespaces) let validName = mkValidName(name) if name != validName { @@ -62,10 +65,12 @@ struct CreateProfile: View { Text("Your profile, contacts and delivered messages are stored on your device.") Text("The profile is only shared with your contacts.") } + .foregroundColor(theme.colors.secondary) .frame(maxWidth: .infinity, alignment: .leading) } } .navigationTitle("Create your profile") + .modifier(ThemedBackground(grouped: true)) .alert(item: $alert) { a in userProfileAlert(a, $displayName) } .onAppear() { DispatchQueue.main.asyncAfter(deadline: .now() + 1) { @@ -78,6 +83,7 @@ struct CreateProfile: View { struct CreateFirstProfile: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @Environment(\.dismiss) var dismiss @State private var displayName: String = "" @FocusState private var focusDisplayName @@ -89,9 +95,9 @@ struct CreateFirstProfile: View { .font(.largeTitle) .bold() Text("Your profile, contacts and delivered messages are stored on your device.") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) Text("The profile is only shared with your contacts.") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .padding(.bottom) } .padding(.bottom) diff --git a/apps/ios/Shared/Views/Onboarding/HowItWorks.swift b/apps/ios/Shared/Views/Onboarding/HowItWorks.swift index fdd73d2632..c1975765d2 100644 --- a/apps/ios/Shared/Views/Onboarding/HowItWorks.swift +++ b/apps/ios/Shared/Views/Onboarding/HowItWorks.swift @@ -44,6 +44,7 @@ struct HowItWorks: View { .lineLimit(10) .padding() .frame(maxHeight: .infinity, alignment: .top) + .modifier(ThemedBackground()) } } diff --git a/apps/ios/Shared/Views/Onboarding/SetNotificationsMode.swift b/apps/ios/Shared/Views/Onboarding/SetNotificationsMode.swift index 3bbd7a5c94..7681a42a77 100644 --- a/apps/ios/Shared/Views/Onboarding/SetNotificationsMode.swift +++ b/apps/ios/Shared/Views/Onboarding/SetNotificationsMode.swift @@ -78,6 +78,7 @@ struct SetNotificationsMode: View { } struct NtfModeSelector: View { + @EnvironmentObject var theme: AppTheme var mode: NotificationsMode @Binding var selection: NotificationsMode @State private var tapped = false @@ -87,7 +88,7 @@ struct NtfModeSelector: View { VStack(alignment: .leading, spacing: 4) { Text(mode.label) .font(.headline) - .foregroundColor(selection == mode ? .accentColor : .secondary) + .foregroundColor(selection == mode ? theme.colors.primary : theme.colors.secondary) Text(ntfModeDescription(mode)) .lineLimit(10) .font(.subheadline) @@ -95,11 +96,11 @@ struct NtfModeSelector: View { .padding(12) } .frame(maxWidth: .infinity, alignment: .leading) - .background(Color(uiColor: tapped ? .secondarySystemFill : .systemBackground)) + .background(tapped ? Color(uiColor: .secondarySystemFill) : theme.colors.background) .clipShape(RoundedRectangle(cornerRadius: 18)) .overlay( RoundedRectangle(cornerRadius: 18) - .stroke(selection == mode ? Color.accentColor : Color(uiColor: .secondarySystemFill), lineWidth: 2) + .stroke(selection == mode ? theme.colors.primary : Color(uiColor: .secondarySystemFill), lineWidth: 2) ) ._onButtonGesture { down in tapped = down diff --git a/apps/ios/Shared/Views/Onboarding/SimpleXInfo.swift b/apps/ios/Shared/Views/Onboarding/SimpleXInfo.swift index 94e281be7d..ee5a618e68 100644 --- a/apps/ios/Shared/Views/Onboarding/SimpleXInfo.swift +++ b/apps/ios/Shared/Views/Onboarding/SimpleXInfo.swift @@ -79,7 +79,7 @@ struct SimpleXInfo: View { MigrateToDevice(migrationState: $m.migrationState) } .navigationTitle("Migrate here") - .background(colorScheme == .light ? Color(uiColor: .tertiarySystemGroupedBackground) : .clear) + .modifier(ThemedBackground(grouped: true)) } } .sheet(isPresented: $showHowItWorks) { diff --git a/apps/ios/Shared/Views/Onboarding/WhatsNewView.swift b/apps/ios/Shared/Views/Onboarding/WhatsNewView.swift index 86e14b74f7..74390c97e1 100644 --- a/apps/ios/Shared/Views/Onboarding/WhatsNewView.swift +++ b/apps/ios/Shared/Views/Onboarding/WhatsNewView.swift @@ -444,6 +444,7 @@ func shouldShowWhatsNew() -> Bool { struct WhatsNewView: View { @Environment(\.dismiss) var dismiss: DismissAction + @EnvironmentObject var theme: AppTheme @State var currentVersion = versionDescriptions.count - 1 @State var currentVersionNav = versionDescriptions.count - 1 var viaSettings = false @@ -455,7 +456,7 @@ struct WhatsNewView: View { VStack(alignment: .leading, spacing: 16) { Text("New in \(v.version)") .font(.title) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .frame(maxWidth: .infinity) .padding(.vertical) ForEach(v.features, id: \.icon) { f in @@ -499,7 +500,7 @@ struct WhatsNewView: View { HStack(alignment: .center, spacing: 4) { Image(systemName: icon) .symbolRenderingMode(.monochrome) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .frame(minWidth: 30, alignment: .center) Text(title).font(.title3).bold() } diff --git a/apps/ios/Shared/Views/RemoteAccess/ConnectDesktopView.swift b/apps/ios/Shared/Views/RemoteAccess/ConnectDesktopView.swift index c749e09ca8..30d200b6e3 100644 --- a/apps/ios/Shared/Views/RemoteAccess/ConnectDesktopView.swift +++ b/apps/ios/Shared/Views/RemoteAccess/ConnectDesktopView.swift @@ -12,6 +12,7 @@ import CodeScanner struct ConnectDesktopView: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @Environment(\.dismiss) var dismiss: DismissAction var viaSettings = false @AppStorage(DEFAULT_DEVICE_NAME_FOR_REMOTE_ACCESS) private var deviceName = UIDevice.current.name @@ -167,7 +168,7 @@ struct ConnectDesktopView: View { private func connectDesktopView(showScanner: Bool = true) -> some View { List { - Section("This device name") { + Section(header: Text("This device name").foregroundColor(theme.colors.secondary)) { devicesView() } if showScanner { @@ -178,18 +179,19 @@ struct ConnectDesktopView: View { } } .navigationTitle("Connect to desktop") + .modifier(ThemedBackground(grouped: true)) } private func connectingDesktopView(_ session: RemoteCtrlSession, _ rc: RemoteCtrlInfo?) -> some View { ZStack { List { - Section("Connecting to desktop") { + Section(header: Text("Connecting to desktop").foregroundColor(theme.colors.secondary)) { ctrlDeviceNameText(session, rc) ctrlDeviceVersionText(session) } if let sessCode = session.sessionCode { - Section("Session code") { + Section(header: Text("Session code").foregroundColor(theme.colors.secondary)) { sessionCodeText(sessCode) } } @@ -202,14 +204,15 @@ struct ConnectDesktopView: View { ProgressView().scaleEffect(2) } + .modifier(ThemedBackground(grouped: true)) } private func searchingDesktopView() -> some View { List { - Section("This device name") { + Section(header: Text("This device name").foregroundColor(theme.colors.secondary)) { devicesView() } - Section("Found desktop") { + Section(header: Text("Found desktop").foregroundColor(theme.colors.secondary)) { Text("Waiting for desktop...").italic() Button { disconnectDesktop() @@ -219,14 +222,15 @@ struct ConnectDesktopView: View { } } .navigationTitle("Connecting to desktop") + .modifier(ThemedBackground(grouped: true)) } @ViewBuilder private func foundDesktopView(_ session: RemoteCtrlSession, _ rc: RemoteCtrlInfo, _ compatible: Bool) -> some View { let v = List { - Section("This device name") { + Section(header: Text("This device name").foregroundColor(theme.colors.secondary)) { devicesView() } - Section("Found desktop") { + Section(header: Text("Found desktop").foregroundColor(theme.colors.secondary)) { ctrlDeviceNameText(session, rc) ctrlDeviceVersionText(session) if !compatible { @@ -246,6 +250,7 @@ struct ConnectDesktopView: View { } } .navigationTitle("Found desktop") + .modifier(ThemedBackground(grouped: true)) if compatible && connectRemoteViaMulticastAuto { v.onAppear { confirmKnownDesktop(rc) } @@ -256,12 +261,12 @@ struct ConnectDesktopView: View { private func verifySessionView(_ session: RemoteCtrlSession, _ rc: RemoteCtrlInfo?, _ sessCode: String) -> some View { List { - Section("Connected to desktop") { + Section(header: Text("Connected to desktop").foregroundColor(theme.colors.secondary)) { ctrlDeviceNameText(session, rc) ctrlDeviceVersionText(session) } - Section("Verify code with desktop") { + Section(header: Text("Verify code with desktop").foregroundColor(theme.colors.secondary)) { sessionCodeText(sessCode) Button { verifyDesktopSessionCode(sessCode) @@ -275,6 +280,7 @@ struct ConnectDesktopView: View { } } .navigationTitle("Verify connection") + .modifier(ThemedBackground(grouped: true)) } private func ctrlDeviceNameText(_ session: RemoteCtrlSession, _ rc: RemoteCtrlInfo?) -> Text { @@ -296,13 +302,13 @@ struct ConnectDesktopView: View { private func activeSessionView(_ session: RemoteCtrlSession, _ rc: RemoteCtrlInfo) -> some View { List { - Section("Connected desktop") { + Section(header: Text("Connected desktop").foregroundColor(theme.colors.secondary)) { Text(rc.deviceViewName) ctrlDeviceVersionText(session) } if let sessCode = session.sessionCode { - Section("Session code") { + Section(header: Text("Session code").foregroundColor(theme.colors.secondary)) { sessionCodeText(sessCode) } } @@ -312,9 +318,11 @@ struct ConnectDesktopView: View { } footer: { // This is specific to iOS Text("Keep the app open to use it from desktop") + .foregroundColor(theme.colors.secondary) } } .navigationTitle("Connected to desktop") + .modifier(ThemedBackground(grouped: true)) } private func sessionCodeText(_ code: String) -> some View { @@ -333,15 +341,15 @@ struct ConnectDesktopView: View { } } } - + private func scanDesctopAddressView() -> some View { - Section("Scan QR code from desktop") { + Section(header: Text("Scan QR code from desktop").foregroundColor(theme.colors.secondary)) { ScannerInView(showQRCodeScanner: $showQRCodeScanner, processQRCode: processDesktopQRCode, scanMode: .oncePerCode) } } private func desktopAddressView() -> some View { - Section("Desktop address") { + Section(header: Text("Desktop address").foregroundColor(theme.colors.secondary)) { if sessionAddress.isEmpty { Button { sessionAddress = UIPasteboard.general.string ?? "" @@ -354,7 +362,7 @@ struct ConnectDesktopView: View { Text(sessionAddress).lineLimit(1) Spacer() Image(systemName: "multiply.circle.fill") - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .onTapGesture { sessionAddress = "" } } } @@ -369,7 +377,7 @@ struct ConnectDesktopView: View { private func linkedDesktopsView() -> some View { List { - Section("Desktop devices") { + Section(header: Text("Desktop devices").foregroundColor(theme.colors.secondary)) { ForEach(remoteCtrls, id: \.remoteCtrlId) { rc in remoteCtrlView(rc) } @@ -380,7 +388,7 @@ struct ConnectDesktopView: View { } } - Section("Linked desktop options") { + Section(header: Text("Linked desktop options").foregroundColor(theme.colors.secondary)) { Toggle("Verify connections", isOn: $confirmRemoteSessions) Toggle("Discover via local network", isOn: $connectRemoteViaMulticast) if connectRemoteViaMulticast { @@ -389,6 +397,7 @@ struct ConnectDesktopView: View { } } .navigationTitle("Linked desktops") + .modifier(ThemedBackground(grouped: true)) } private func remoteCtrlView(_ rc: RemoteCtrlInfo) -> some View { diff --git a/apps/ios/Shared/Views/TerminalView.swift b/apps/ios/Shared/Views/TerminalView.swift index 94a8937db6..d209ced128 100644 --- a/apps/ios/Shared/Views/TerminalView.swift +++ b/apps/ios/Shared/Views/TerminalView.swift @@ -106,6 +106,7 @@ struct TerminalView: View { } .navigationViewStyle(.stack) .navigationTitle("Chat console") + .modifier(ThemedBackground()) } func scrollToBottom(_ proxy: ScrollViewProxy, animation: Animation = .default) { @@ -121,6 +122,7 @@ struct TerminalView: View { return ScrollView { Text(s.prefix(maxItemSize)) .padding() + .frame(maxWidth: .infinity) } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { @@ -130,6 +132,7 @@ struct TerminalView: View { } } .onDisappear { terminalItem = nil } + .modifier(ThemedBackground()) } func consoleSendMessage() { diff --git a/apps/ios/Shared/Views/UserSettings/AdvancedNetworkSettings.swift b/apps/ios/Shared/Views/UserSettings/AdvancedNetworkSettings.swift index e8bb6c6444..6dda7bf799 100644 --- a/apps/ios/Shared/Views/UserSettings/AdvancedNetworkSettings.swift +++ b/apps/ios/Shared/Views/UserSettings/AdvancedNetworkSettings.swift @@ -24,6 +24,7 @@ enum NetworkSettingsAlert: Identifiable { } struct AdvancedNetworkSettings: View { + @EnvironmentObject var theme: AppTheme @State private var netCfg = NetCfg.defaults @State private var currentNetCfg = NetCfg.defaults @State private var cfgLoaded = false @@ -69,10 +70,11 @@ struct AdvancedNetworkSettings: View { Text("TCP_KEEPINTVL") Text("TCP_KEEPCNT") } - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } } header: { Text("") + .foregroundColor(theme.colors.secondary) } footer: { HStack { Button { diff --git a/apps/ios/Shared/Views/UserSettings/AppSettings.swift b/apps/ios/Shared/Views/UserSettings/AppSettings.swift index 299c96626a..8c68d70526 100644 --- a/apps/ios/Shared/Views/UserSettings/AppSettings.swift +++ b/apps/ios/Shared/Views/UserSettings/AppSettings.swift @@ -44,6 +44,11 @@ extension AppSettings { if let val = androidCallOnLockScreen { def.setValue(val.rawValue, forKey: ANDROID_DEFAULT_CALL_ON_LOCK_SCREEN) } if let val = iosCallKitEnabled { callKitEnabledGroupDefault.set(val) } if let val = iosCallKitCallsInRecents { def.setValue(val, forKey: DEFAULT_CALL_KIT_CALLS_IN_RECENTS) } + if let val = uiProfileImageCornerRadius { def.setValue(val, forKey: DEFAULT_PROFILE_IMAGE_CORNER_RADIUS) } + if let val = uiColorScheme { def.setValue(val, forKey: DEFAULT_CURRENT_THEME) } + if let val = uiDarkColorScheme { def.setValue(val, forKey: DEFAULT_SYSTEM_DARK_THEME) } + if let val = uiCurrentThemeIds { def.setValue(val, forKey: DEFAULT_CURRENT_THEME_IDS) } + if let val = uiThemes { def.setValue(val.skipDuplicates(), forKey: DEFAULT_THEME_OVERRIDES) } } public static var current: AppSettings { @@ -69,6 +74,11 @@ extension AppSettings { c.androidCallOnLockScreen = AppSettingsLockScreenCalls(rawValue: def.string(forKey: ANDROID_DEFAULT_CALL_ON_LOCK_SCREEN)!) c.iosCallKitEnabled = callKitEnabledGroupDefault.get() c.iosCallKitCallsInRecents = def.bool(forKey: DEFAULT_CALL_KIT_CALLS_IN_RECENTS) + c.uiProfileImageCornerRadius = def.float(forKey: DEFAULT_PROFILE_IMAGE_CORNER_RADIUS) + c.uiColorScheme = currentThemeDefault.get() + c.uiDarkColorScheme = systemDarkThemeDefault.get() + c.uiCurrentThemeIds = currentThemeIdsDefault.get() + c.uiThemes = themeOverridesDefault.get() return c } } diff --git a/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift b/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift index b91d2c9369..209f25496d 100644 --- a/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift +++ b/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift @@ -7,12 +7,17 @@ // import SwiftUI +import SimpleXChat +import Yams -let defaultAccentColor = CGColor.init(red: 0, green: 0.533, blue: 1, alpha: 1) +let colorModesLocalized: [LocalizedStringKey] = ["System", "Light", "Dark"] +let colorModesNames: [DefaultThemeMode?] = [nil, DefaultThemeMode.light, DefaultThemeMode.dark] -let interfaceStyles: [UIUserInterfaceStyle] = [.unspecified, .light, .dark] +let darkThemesLocalized: [LocalizedStringKey] = ["Dark", "SimpleX", "Black"] +let darkThemesNames: [String] = [DefaultTheme.DARK.themeName, DefaultTheme.SIMPLEX.themeName, DefaultTheme.BLACK.themeName] -let interfaceStyleNames: [LocalizedStringKey] = ["System", "Light", "Dark"] +let darkThemesWithoutBlackLocalized: [LocalizedStringKey] = ["Dark", "SimpleX"] +let darkThemesWithoutBlackNames: [String] = [DefaultTheme.DARK.themeName, DefaultTheme.SIMPLEX.themeName] let appSettingsURL = URL(string: UIApplication.openSettingsURLString)! @@ -20,12 +25,30 @@ struct AppearanceSettings: View { @EnvironmentObject var m: ChatModel @Environment(\.colorScheme) var colorScheme @EnvironmentObject var sceneDelegate: SceneDelegate + @EnvironmentObject var theme: AppTheme @State private var iconLightTapped = false @State private var iconDarkTapped = false - @State private var userInterfaceStyle = getUserInterfaceStyleDefault() - @State private var uiTintColor = getUIAccentColorDefault() + @State private var colorMode: DefaultThemeMode? = { + if currentThemeDefault.get() == DefaultTheme.SYSTEM_THEME_NAME { nil as DefaultThemeMode? } else { CurrentColors.base.mode } + }() + @State private var darkModeTheme: String = UserDefaults.standard.string(forKey: DEFAULT_SYSTEM_DARK_THEME) ?? DefaultTheme.DARK.themeName @AppStorage(DEFAULT_PROFILE_IMAGE_CORNER_RADIUS) private var profileImageCornerRadius = defaultProfileImageCorner + @State var themeUserDestination: (Int64, ThemeModeOverrides?)? = { + if let currentUser = ChatModel.shared.currentUser, let uiThemes = currentUser.uiThemes, uiThemes.preferredMode(!CurrentColors.colors.isLight) != nil { + (currentUser.userId, uiThemes) + } else { + nil + } + }() + + @State var perUserTheme: ThemeModeOverride = { + ChatModel.shared.currentUser?.uiThemes?.preferredMode(!CurrentColors.colors.isLight) ?? ThemeModeOverride(mode: CurrentColors.base.mode) + }() + + @State var showImageImporter: Bool = false + @State var customizeThemeIsOpen: Bool = false + var body: some View { VStack{ List { @@ -39,15 +62,111 @@ struct AppearanceSettings: View { } } - Section("App icon") { - HStack { - updateAppIcon(image: "icon-light", icon: nil, tapped: $iconLightTapped) - Spacer().frame(width: 16) - updateAppIcon(image: "icon-dark", icon: "DarkAppIcon", tapped: $iconDarkTapped) + Section { + ThemeDestinationPicker(themeUserDestination: $themeUserDestination, themeUserDest: themeUserDestination?.0, customizeThemeIsOpen: $customizeThemeIsOpen) + + WallpaperPresetSelector( + selectedWallpaper: theme.wallpaper.type, + currentColors: currentColors, + onChooseType: onChooseType + ) + .padding(.bottom, 10) + .listRowInsets(.init()) + .listRowBackground(Color.clear) + .modifier(WallpaperImporter(showImageImporter: $showImageImporter, onChooseImage: { image in + if let filename = saveWallpaperFile(image: image) { + if themeUserDestination == nil, case let WallpaperType.image(filename, _, _) = theme.wallpaper.type { + removeWallpaperFile(fileName: filename) + } else if let type = perUserTheme.type, case let WallpaperType.image(filename, _, _) = type { + removeWallpaperFile(fileName: filename) + } + onTypeChange(WallpaperType.image(filename, 1, WallpaperScaleType.fill)) + } + })) + + if case let WallpaperType.image(filename, _, _) = theme.wallpaper.type, (themeUserDestination == nil || perUserTheme.wallpaper?.imageFile != nil) { + Button { + if themeUserDestination == nil { + let defaultActiveTheme = ThemeManager.defaultActiveTheme(themeOverridesDefault.get()) + ThemeManager.saveAndApplyWallpaper(theme.base, nil, themeOverridesDefault) + ThemeManager.removeTheme(defaultActiveTheme?.themeId) + removeWallpaperFile(fileName: filename) + } else { + removeUserThemeModeOverrides($themeUserDestination, $perUserTheme) + } + saveThemeToDatabase(themeUserDestination) + } label: { + Text("Remove image") + .foregroundColor(theme.colors.primary) + } + .listRowBackground(Color.clear) + } + + Picker("Color mode", selection: $colorMode) { + ForEach(Array(colorModesNames.enumerated()), id: \.element) { index, mode in + Text(colorModesLocalized[index]) + } + } + .frame(height: 36) + Picker("Dark mode colors", selection: $darkModeTheme) { + if theme.base == .BLACK || themeOverridesDefault.get().contains(where: { $0.base == .BLACK }) { + ForEach(Array(darkThemesNames.enumerated()), id: \.element) { index, darkTheme in + Text(darkThemesLocalized[index]) + } + } else { + ForEach(Array(darkThemesWithoutBlackNames.enumerated()), id: \.element) { index, darkTheme in + Text(darkThemesLocalized[index]) + } + } + } + .frame(height: 36) + + NavigationLink { + let userId = themeUserDestination?.0 + if let userId { + UserWallpaperEditorSheet(userId: userId) + .onAppear { + customizeThemeIsOpen = true + } + } else { + CustomizeThemeView(onChooseType: onChooseType) + .navigationTitle("Customize theme") + .modifier(ThemedBackground(grouped: true)) + .onAppear { + customizeThemeIsOpen = true + } + } + } label: { + Text("Customize theme") + } + } header: { + Text("Themes") + .foregroundColor(theme.colors.secondary) + } + .onChange(of: profileImageCornerRadius) { _ in + saveThemeToDatabase(nil) + } + .onChange(of: colorMode) { mode in + guard let mode else { + ThemeManager.applyTheme(DefaultTheme.SYSTEM_THEME_NAME) + return + } + if case DefaultThemeMode.light = mode { + ThemeManager.applyTheme(DefaultTheme.LIGHT.themeName) + } else if case DefaultThemeMode.dark = mode { + ThemeManager.applyTheme(systemDarkThemeDefault.get()) + } + } + .onChange(of: darkModeTheme) { darkTheme in + ThemeManager.changeDarkTheme(darkTheme) + if currentThemeDefault.get() == DefaultTheme.SYSTEM_THEME_NAME { + ThemeManager.applyTheme(currentThemeDefault.get()) + } else if currentThemeDefault.get() != DefaultTheme.LIGHT.themeName { + ThemeManager.applyTheme(systemDarkThemeDefault.get()) } } - Section("Profile images") { + Section(header: Text("Profile images").foregroundColor(theme.colors.secondary)) { HStack(spacing: 16) { if let img = m.currentUser?.image, img != "" { ProfileImage(imageStr: img, size: 60) @@ -61,37 +180,91 @@ struct AppearanceSettings: View { step: 2.5 ) } - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) } - Section { - Picker("Theme", selection: $userInterfaceStyle) { - ForEach(interfaceStyles, id: \.self) { style in - Text(interfaceStyleNames[interfaceStyles.firstIndex(of: style) ?? 0]) - } + Section(header: Text("App icon").foregroundColor(theme.colors.secondary)) { + HStack { + updateAppIcon(image: "icon-light", icon: nil, tapped: $iconLightTapped) + Spacer().frame(width: 16) + updateAppIcon(image: "icon-dark", icon: "DarkAppIcon", tapped: $iconDarkTapped) } - .frame(height: 36) - ColorPicker("Accent color", selection: $uiTintColor, supportsOpacity: false) - } header: { - Text("Colors") - } footer: { - Button { - uiTintColor = defaultAccentColor - setUIAccentColorDefault(defaultAccentColor) - } label: { - Text("Reset colors").font(.callout) - } - } - .onChange(of: userInterfaceStyle) { _ in - sceneDelegate.window?.overrideUserInterfaceStyle = userInterfaceStyle - setUserInterfaceStyleDefault(userInterfaceStyle) - } - .onChange(of: uiTintColor) { _ in - sceneDelegate.window?.tintColor = UIColor(cgColor: uiTintColor) - setUIAccentColorDefault(uiTintColor) } } } + .onAppear { + customizeThemeIsOpen = false + } + } + + private func updateThemeUserDestination() { + if let dest = themeUserDestination { + var (userId, themes) = dest + themes = themes ?? ThemeModeOverrides() + if case DefaultThemeMode.light = perUserTheme.mode { + themes?.light = perUserTheme + } else { + themes?.dark = perUserTheme + } + themeUserDestination = (userId, themes) + } + } + + private func onTypeCopyFromSameTheme(_ type: WallpaperType?) -> Bool { + if themeUserDestination == nil { + ThemeManager.saveAndApplyWallpaper(theme.base, type, themeOverridesDefault) + } else { + var wallpaperFiles = Set([perUserTheme.wallpaper?.imageFile]) + _ = ThemeManager.copyFromSameThemeOverrides(type, nil, $perUserTheme) + wallpaperFiles.remove(perUserTheme.wallpaper?.imageFile) + wallpaperFiles.forEach(removeWallpaperFile) + updateThemeUserDestination() + } + saveThemeToDatabase(themeUserDestination) + return true + } + + private func onTypeChange(_ type: WallpaperType?) { + if themeUserDestination == nil { + ThemeManager.saveAndApplyWallpaper(theme.base, type, themeOverridesDefault) + } else { + ThemeManager.applyWallpaper(type, $perUserTheme) + updateThemeUserDestination() + } + saveThemeToDatabase(themeUserDestination) + } + + private func currentColors(_ type: WallpaperType?) -> ThemeManager.ActiveTheme { + // If applying for : + // - all themes: no overrides needed + // - specific user: only user overrides for currently selected theme are needed, because they will NOT be copied when other wallpaper is selected + let perUserOverride: ThemeModeOverrides? = themeUserDestination == nil + ? nil + : theme.wallpaper.type.sameType(type) + ? m.currentUser?.uiThemes + : nil + return ThemeManager.currentColors(type, nil, perUserOverride, themeOverridesDefault.get()) + } + + private func onChooseType(_ type: WallpaperType?) { + // don't have image in parent or already selected wallpaper with custom image + if let type, case WallpaperType.image = type { + if case WallpaperType.image = theme.wallpaper.type, themeUserDestination?.1 != nil { + showImageImporter = true + } else if currentColors(type).wallpaper.type.image == nil { + showImageImporter = true + } else if currentColors(type).wallpaper.type.image != nil, case WallpaperType.image = theme.wallpaper.type, themeUserDestination == nil { + showImageImporter = true + } else if themeUserDestination == nil { + onTypeChange(currentColors(type).wallpaper.type) + } else { + _ = onTypeCopyFromSameTheme(currentColors(type).wallpaper.type) + } + } else if (themeUserDestination != nil && themeUserDestination?.1?.preferredMode(!CurrentColors.colors.isLight)?.type != type) || theme.wallpaper.type != type { + _ = onTypeCopyFromSameTheme(type) + } else { + onTypeChange(type) + } } private var currentLanguage: String { @@ -117,6 +290,734 @@ struct AppearanceSettings: View { } } +struct ChatThemePreview: View { + @EnvironmentObject var theme: AppTheme + var base: DefaultTheme + var wallpaperType: WallpaperType? + var backgroundColor: Color? + var tintColor: Color? + var withMessages: Bool = true + + var body: some View { + let themeBackgroundColor = theme.colors.background + let backgroundColor = backgroundColor ?? wallpaperType?.defaultBackgroundColor(theme.base, theme.colors.background) + let tintColor = tintColor ?? wallpaperType?.defaultTintColor(theme.base) + let view = VStack { + if withMessages { + let alice = ChatItem.getSample(1, CIDirection.directRcv, Date.now, NSLocalizedString("Good afternoon!", comment: "message preview")) + HStack { + ChatItemView(chat: Chat.sampleData, chatItem: alice, revealed: Binding.constant(false)) + Spacer() + } + HStack { + Spacer() + ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, CIDirection.directSnd, Date.now, NSLocalizedString("Good morning!", comment: "message preview"), quotedItem: CIQuote.getSample(alice.id, alice.meta.itemTs, alice.content.text, chatDir: alice.chatDir)), revealed: Binding.constant(false)) + .frame(alignment: .trailing) + } + } else { + Rectangle().fill(.clear) + } + } + .padding(10) + .frame(maxWidth: .infinity) + + if let wallpaperType, let wallpaperImage = wallpaperType.image, let backgroundColor, let tintColor { + view.modifier(ChatViewBackground(image: wallpaperImage, imageType: wallpaperType, background: backgroundColor, tint: tintColor)) + } else { + view.background(themeBackgroundColor) + } + } +} + +struct WallpaperPresetSelector: View { + @EnvironmentObject var theme: AppTheme + var selectedWallpaper: WallpaperType? + var activeBackgroundColor: Color? = nil + var activeTintColor: Color? = nil + var currentColors: (WallpaperType?) -> ThemeManager.ActiveTheme + var onChooseType: (WallpaperType?) -> Void + let width: Double = 80 + let height: Double = 80 + let backgrounds = PresetWallpaper.allCases + + private let cornerRadius: Double = 22.5 + + var baseTheme: DefaultTheme { theme.base } + + var body: some View { + VStack { + ChatThemePreview( + base: theme.base, + wallpaperType: selectedWallpaper, + backgroundColor: activeBackgroundColor ?? theme.wallpaper.background, + tintColor: activeTintColor ?? theme.wallpaper.tint + ) + .environmentObject(currentColors(selectedWallpaper).toAppTheme()) + ScrollView(.horizontal, showsIndicators: false) { + HStack { + BackgroundItem(nil) + ForEach(backgrounds, id: \.self) { background in + BackgroundItem(background) + } + OwnBackgroundItem(selectedWallpaper) + } + } + } + } + + func plus() -> some View { + Image(systemName: "plus") + .tint(theme.colors.primary) + .frame(width: 25, height: 25) + } + + func BackgroundItem(_ background: PresetWallpaper?) -> some View { + let checked = (background == nil && (selectedWallpaper == nil || selectedWallpaper?.isEmpty == true)) || selectedWallpaper?.samePreset(other: background) == true + let type = background?.toType(baseTheme, checked ? selectedWallpaper?.scale : nil) + let overrides = currentColors(type).toAppTheme() + return ZStack { + if let type { + ChatThemePreview( + base: baseTheme, + wallpaperType: type, + backgroundColor: checked ? activeBackgroundColor ?? overrides.wallpaper.background : overrides.wallpaper.background, + tintColor: checked ? activeTintColor ?? overrides.wallpaper.tint : overrides.wallpaper.tint, + withMessages: false + ) + .environmentObject(overrides) + } else { + Rectangle().fill(overrides.colors.background) + } + } + .frame(width: CGFloat(width), height: CGFloat(height)) + .clipShape(RoundedRectangle(cornerRadius: width / 100 * cornerRadius)) + .overlay(RoundedRectangle(cornerRadius: width / 100 * cornerRadius) + .strokeBorder(checked ? theme.colors.primary.opacity(0.8) : theme.colors.onBackground.opacity(isInDarkTheme() ? 0.2 : 0.1), lineWidth: 1) + ) + .onTapGesture { + onChooseType(background?.toType(baseTheme)) + } + } + + func OwnBackgroundItem(_ type: WallpaperType?) -> some View { + let overrides = currentColors(WallpaperType.image("", nil, nil)) + let appWallpaper = overrides.wallpaper + let backgroundColor = appWallpaper.background + let tintColor = appWallpaper.tint + let wallpaperImage = appWallpaper.type.image + let checked = if let type, case WallpaperType.image = type, wallpaperImage != nil { true } else { false } + let borderColor = if let type, case WallpaperType.image = type { theme.colors.primary.opacity(0.8) } else { theme.colors.onBackground.opacity(0.1) } + return ZStack { + if checked || wallpaperImage != nil { + ChatThemePreview( + base: baseTheme, + wallpaperType: checked ? type : appWallpaper.type, + backgroundColor: checked ? activeBackgroundColor ?? backgroundColor : backgroundColor, + tintColor: checked ? activeTintColor ?? tintColor : tintColor, + withMessages: false + ) + .environmentObject(currentColors(type).toAppTheme()) + } else { + plus() + } + } + .frame(width: width, height: height) + .clipShape(RoundedRectangle(cornerRadius: width / 100 * cornerRadius)) + .overlay(RoundedRectangle(cornerRadius: width / 100 * cornerRadius) + .strokeBorder(borderColor, lineWidth: 1) + ) + .onTapGesture { + onChooseType(WallpaperType.image("", nil, nil)) + } + } +} + +struct CustomizeThemeView: View { + @EnvironmentObject var theme: AppTheme + var onChooseType: (WallpaperType?) -> Void + @State private var showFileImporter = false + + var body: some View { + List { + let wallpaperImage = theme.wallpaper.type.image + let wallpaperType = theme.wallpaper.type + let baseTheme = theme.base + + let editColor: (ThemeColor) -> Binding = { name in + editColorBinding( + name: name, + wallpaperType: wallpaperType, + wallpaperImage: wallpaperImage, + theme: theme, + onColorChange: { color in + updateBackendTask.cancel() + updateBackendTask = Task { + if (try? await Task.sleep(nanoseconds: 200_000000)) != nil { + ThemeManager.saveAndApplyThemeColor(baseTheme, name, color) + saveThemeToDatabase(nil) + } + } + }) + } + WallpaperPresetSelector( + selectedWallpaper: wallpaperType, + currentColors: { type in + ThemeManager.currentColors(type, nil, nil, themeOverridesDefault.get()) + }, + onChooseType: onChooseType + ) + .listRowInsets(.init()) + .listRowBackground(Color.clear) + + if case let WallpaperType.image(filename, _, _) = theme.wallpaper.type { + Button { + let defaultActiveTheme = ThemeManager.defaultActiveTheme(themeOverridesDefault.get()) + ThemeManager.saveAndApplyWallpaper(baseTheme, nil, themeOverridesDefault) + ThemeManager.removeTheme(defaultActiveTheme?.themeId) + removeWallpaperFile(fileName: filename) + saveThemeToDatabase(nil) + } label: { + Text("Remove image") + .foregroundColor(theme.colors.primary) + } + .listRowBackground(Color.clear) + } + + Section { + WallpaperSetupView( + wallpaperType: wallpaperType, + base: baseTheme, + initialWallpaper: theme.wallpaper, + editColor: { name in + editColor(name) + }, + onTypeChange: { type in + ThemeManager.saveAndApplyWallpaper(baseTheme, type, themeOverridesDefault) + updateBackendTask.cancel() + updateBackendTask = Task { + if (try? await Task.sleep(nanoseconds: 200_000000)) != nil { + saveThemeToDatabase(nil) + } + } + } + ) + } header: { + Text("Chat colors") + .foregroundColor(theme.colors.secondary) + } + + CustomizeThemeColorsSection(editColor: editColor) + + let currentOverrides = ThemeManager.defaultActiveTheme(themeOverridesDefault.get()) + let canResetColors = theme.base.hasChangedAnyColor(currentOverrides) + if canResetColors { + Button { + ThemeManager.resetAllThemeColors() + saveThemeToDatabase(nil) + } label: { + Text("Reset colors").font(.callout).foregroundColor(theme.colors.primary) + } + } + + ImportExportThemeSection(perChat: nil, perUser: nil, save: { theme in + ThemeManager.saveAndApplyThemeOverrides(theme) + saveThemeToDatabase(nil) + }) + } + /// When changing app theme, user overrides are hidden. User overrides will be returned back after closing Appearance screen, see ThemeDestinationPicker() + .interactiveDismissDisabled(true) + } +} + +struct ImportExportThemeSection: View { + @EnvironmentObject var theme: AppTheme + var perChat: ThemeModeOverride? + var perUser: ThemeModeOverrides? + var save: (ThemeOverrides) -> Void + @State private var showFileImporter = false + + var body: some View { + Section { + Button { + let overrides = ThemeManager.currentThemeOverridesForExport(nil, perChat, perUser) + do { + let encoded = try encodeThemeOverrides(overrides) + var lines = encoded.split(separator: "\n") + // Removing theme id without using custom serializer or data class + lines.remove(at: 0) + let theme = lines.joined(separator: "\n") + let tempUrl = getTempFilesDirectory().appendingPathComponent("simplex.theme") + try? FileManager.default.removeItem(at: tempUrl) + if FileManager.default.createFile(atPath: tempUrl.path, contents: theme.data(using: .utf8)) { + showShareSheet(items: [tempUrl]) + } + } catch { + AlertManager.shared.showAlertMsg(title: "Error", message: "Error exporting theme: \(error.localizedDescription)") + } + } label: { + Text("Export theme").foregroundColor(theme.colors.primary) + } + Button { + showFileImporter = true + } label: { + Text("Import theme").foregroundColor(theme.colors.primary) + } + .fileImporter( + isPresented: $showFileImporter, + allowedContentTypes: [.data/*.plainText*/], + allowsMultipleSelection: false + ) { result in + if case let .success(files) = result, let fileURL = files.first { + do { + var fileSize: Int? = nil + if fileURL.startAccessingSecurityScopedResource() { + let resourceValues = try fileURL.resourceValues(forKeys: [.fileSizeKey]) + fileSize = resourceValues.fileSize + } + if let fileSize = fileSize, + // Same as Android/desktop + fileSize <= 5_500_000 { + if let string = try? String(contentsOf: fileURL, encoding: .utf8), let theme: ThemeOverrides = decodeYAML("themeId: \(UUID().uuidString)\n" + string) { + save(theme) + logger.error("Saved theme from file") + } else { + logger.error("Error decoding theme file") + } + fileURL.stopAccessingSecurityScopedResource() + } else { + fileURL.stopAccessingSecurityScopedResource() + let prettyMaxFileSize = ByteCountFormatter.string(fromByteCount: 5_500_000, countStyle: .binary) + AlertManager.shared.showAlertMsg( + title: "Large file!", + message: "Currently maximum supported file size is \(prettyMaxFileSize)." + ) + } + } catch { + logger.error("Appearance fileImporter error \(error.localizedDescription)") + } + } + } + } + } +} + +struct UserWallpaperEditorSheet: View { + @Environment(\.dismiss) var dismiss + @EnvironmentObject var theme: AppTheme + @State var userId: Int64 + @State private var globalThemeUsed: Bool = false + + @State private var themes = ChatModel.shared.currentUser?.uiThemes ?? ThemeModeOverrides() + + var body: some View { + let preferred = themes.preferredMode(!theme.colors.isLight) + let initialTheme = preferred ?? ThemeManager.defaultActiveTheme(ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + UserWallpaperEditor( + initialTheme: initialTheme, + themeModeOverride: initialTheme, + applyToMode: themes.light == themes.dark ? nil : initialTheme.mode, + globalThemeUsed: $globalThemeUsed, + save: { applyToMode, newTheme in + updateBackendTask.cancel() + updateBackendTask = Task { + let themes = ChatModel.shared.currentUser?.uiThemes ?? ThemeModeOverrides() + let initialTheme = themes.preferredMode(!theme.colors.isLight) ?? ThemeManager.defaultActiveTheme(ChatModel.shared.currentUser?.uiThemes, themeOverridesDefault.get()) + + await save( + applyToMode, + newTheme, + themes, + userId, + realtimeUpdate: + initialTheme.wallpaper?.preset != newTheme?.wallpaper?.preset || + initialTheme.wallpaper?.imageFile != newTheme?.wallpaper?.imageFile || + initialTheme.wallpaper?.scale != newTheme?.wallpaper?.scale || + initialTheme.wallpaper?.scaleType != newTheme?.wallpaper?.scaleType + ) + } + } + ) + .navigationTitle("Profile theme") + .modifier(ThemedBackground(grouped: true)) + .onAppear { + globalThemeUsed = preferred == nil + } + .onChange(of: theme.base.mode) { _ in + globalThemeUsed = (ChatModel.shared.currentUser?.uiThemes ?? ThemeModeOverrides()).preferredMode(!theme.colors.isLight) == nil + } + .onChange(of: ChatModel.shared.currentUser?.userId) { _ in + dismiss() + } + } + + private func save( + _ applyToMode: DefaultThemeMode?, + _ newTheme: ThemeModeOverride?, + _ themes: ThemeModeOverrides?, + _ userId: Int64, + realtimeUpdate: Bool + ) async { + let unchangedThemes: ThemeModeOverrides = themes ?? ThemeModeOverrides() + var wallpaperFiles = Set([unchangedThemes.light?.wallpaper?.imageFile, unchangedThemes.dark?.wallpaper?.imageFile]) + var changedThemes: ThemeModeOverrides? = unchangedThemes + let light: ThemeModeOverride? = if let newTheme { + ThemeModeOverride(mode: DefaultThemeMode.light, colors: newTheme.colors, wallpaper: newTheme.wallpaper?.withFilledWallpaperPath()) + } else { + nil + } + let dark: ThemeModeOverride? = if let newTheme { + ThemeModeOverride(mode: DefaultThemeMode.dark, colors: newTheme.colors, wallpaper: newTheme.wallpaper?.withFilledWallpaperPath()) + } else { + nil + } + + if let applyToMode { + switch applyToMode { + case DefaultThemeMode.light: + changedThemes?.light = light + case DefaultThemeMode.dark: + changedThemes?.dark = dark + } + } else { + changedThemes?.light = light + changedThemes?.dark = dark + } + if changedThemes?.light != nil || changedThemes?.dark != nil { + let light = changedThemes?.light + let dark = changedThemes?.dark + let currentMode = CurrentColors.base.mode + // same image file for both modes, copy image to make them as different files + if var light, var dark, let lightWallpaper = light.wallpaper, let darkWallpaper = dark.wallpaper, let lightImageFile = lightWallpaper.imageFile, let darkImageFile = darkWallpaper.imageFile, lightWallpaper.imageFile == darkWallpaper.imageFile { + let imageFile = if currentMode == DefaultThemeMode.light { + darkImageFile + } else { + lightImageFile + } + let filePath = saveWallpaperFile(url: getWallpaperFilePath(imageFile)) + if currentMode == DefaultThemeMode.light { + dark.wallpaper?.imageFile = filePath + changedThemes = ThemeModeOverrides(light: changedThemes?.light, dark: dark) + } else { + light.wallpaper?.imageFile = filePath + changedThemes = ThemeModeOverrides(light: light, dark: changedThemes?.dark) + } + } + } else { + changedThemes = nil + } + wallpaperFiles.remove(changedThemes?.light?.wallpaper?.imageFile) + wallpaperFiles.remove(changedThemes?.dark?.wallpaper?.imageFile) + wallpaperFiles.forEach(removeWallpaperFile) + + let oldThemes = ChatModel.shared.currentUser?.uiThemes + let changedThemesConstant = changedThemes + if realtimeUpdate { + await MainActor.run { + ChatModel.shared.updateCurrentUserUiThemes(uiThemes: changedThemesConstant) + } + } + do { + try await Task.sleep(nanoseconds: 200_000000) + } catch { + return + } + if !realtimeUpdate { + await MainActor.run { + ChatModel.shared.updateCurrentUserUiThemes(uiThemes: changedThemesConstant) + } + } + + if await !apiSetUserUIThemes(userId: userId, themes: changedThemesConstant) { + await MainActor.run { + // If failed to apply for some reason return the old themes + ChatModel.shared.updateCurrentUserUiThemes(uiThemes: oldThemes) + } + } + } +} + +struct ThemeDestinationPicker: View { + @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme + @Binding var themeUserDestination: (Int64, ThemeModeOverrides?)? + @State var themeUserDest: Int64? + @Binding var customizeThemeIsOpen: Bool + + var body: some View { + let values = [(nil, "All profiles")] + m.users.filter { $0.user.activeUser }.map { ($0.user.userId, $0.user.chatViewName)} + + if values.contains(where: { (userId, text) in userId == themeUserDestination?.0 }) { + Picker("Apply to mode", selection: $themeUserDest) { + ForEach(values, id: \.0) { (_, text) in + Text(text) + } + } + .frame(height: 36) + .onChange(of: themeUserDest) { userId in + themeUserDest = userId + if let userId { + themeUserDestination = (userId, m.users.first { $0.user.userId == userId }?.user.uiThemes) + } else { + themeUserDestination = nil + } + if let userId, userId != m.currentUser?.userId { + changeActiveUser(userId, viewPwd: nil) + } + } + .onChange(of: themeUserDestination == nil) { isNil in + if isNil { + // Easiest way to hide per-user customization. + // Otherwise, it would be needed to make global variable and to use it everywhere for making a decision to include these overrides into active theme constructing or not + m.currentUser?.uiThemes = nil + } else { + m.updateCurrentUserUiThemes(uiThemes: m.users.first(where: { $0.user.userId == m.currentUser?.userId })?.user.uiThemes) + } + } + .onDisappear { + // Skip when Appearance screen is not hidden yet + if customizeThemeIsOpen { return } + // Restore user overrides from stored list of users + m.updateCurrentUserUiThemes(uiThemes: m.users.first(where: { $0.user.userId == m.currentUser?.userId })?.user.uiThemes) + themeUserDestination = if let currentUser = m.currentUser, let uiThemes = currentUser.uiThemes { + (currentUser.userId, uiThemes) + } else { + nil + } + } + } else { + EmptyView() + .onAppear { + themeUserDestination = nil + themeUserDest = nil + } + } + } +} + +struct CustomizeThemeColorsSection: View { + @EnvironmentObject var theme: AppTheme + var editColor: (ThemeColor) -> Binding + + var body: some View { + Section { + picker(.primary, editColor) + picker(.primaryVariant, editColor) + picker(.secondary, editColor) + picker(.secondaryVariant, editColor) + picker(.background, editColor) + picker(.surface, editColor) + //picker(.title, editColor) + picker(.primaryVariant2, editColor) + } header: { + Text("Interface colors") + .foregroundColor(theme.colors.secondary) + } + } +} + +func editColorBinding(name: ThemeColor, wallpaperType: WallpaperType?, wallpaperImage: Image?, theme: AppTheme, onColorChange: @escaping (Color?) -> Void) -> Binding { + Binding(get: { + let baseTheme = theme.base + let wallpaperBackgroundColor = theme.wallpaper.background ?? wallpaperType?.defaultBackgroundColor(baseTheme, theme.colors.background) ?? Color.clear + let wallpaperTintColor = theme.wallpaper.tint ?? wallpaperType?.defaultTintColor(baseTheme) ?? Color.clear + return switch name { + case ThemeColor.wallpaperBackground: wallpaperBackgroundColor + case ThemeColor.wallpaperTint: wallpaperTintColor + case ThemeColor.primary: theme.colors.primary + case ThemeColor.primaryVariant: theme.colors.primaryVariant + case ThemeColor.secondary: theme.colors.secondary + case ThemeColor.secondaryVariant: theme.colors.secondaryVariant + case ThemeColor.background: theme.colors.background + case ThemeColor.surface: theme.colors.surface + case ThemeColor.title: theme.appColors.title + case ThemeColor.primaryVariant2: theme.appColors.primaryVariant2 + case ThemeColor.sentMessage: theme.appColors.sentMessage + case ThemeColor.sentQuote: theme.appColors.sentQuote + case ThemeColor.receivedMessage: theme.appColors.receivedMessage + case ThemeColor.receivedQuote: theme.appColors.receivedQuote + } + }, set: onColorChange) +} + +struct WallpaperSetupView: View { + var wallpaperType: WallpaperType? + var base: DefaultTheme + var initialWallpaper: AppWallpaper? + var editColor: (ThemeColor) -> Binding + var onTypeChange: (WallpaperType?) -> Void + + var body: some View { + if let wallpaperType, case let WallpaperType.image(_, _, scaleType) = wallpaperType { + let wallpaperScaleType = if let scaleType { + scaleType + } else if let initialWallpaper, case let WallpaperType.image(_, _, scaleType) = initialWallpaper.type, let scaleType { + scaleType + } else { + WallpaperScaleType.fill + } + WallpaperScaleTypeChooser(wallpaperScaleType: Binding.constant(wallpaperScaleType), wallpaperType: wallpaperType, onTypeChange: onTypeChange) + } + + + if let wallpaperType, wallpaperType.isPreset { + WallpaperScaleChooser(wallpaperScale: Binding.constant(initialWallpaper?.type.scale ?? 1), wallpaperType: wallpaperType, onTypeChange: onTypeChange) + } else if let wallpaperType, case let WallpaperType.image(_, _, scaleType) = wallpaperType, scaleType == WallpaperScaleType.repeat { + WallpaperScaleChooser(wallpaperScale: Binding.constant(initialWallpaper?.type.scale ?? 1), wallpaperType: wallpaperType, onTypeChange: onTypeChange) + } + + if wallpaperType?.isPreset == true || wallpaperType?.isImage == true { + picker(.wallpaperBackground, editColor) + picker(.wallpaperTint, editColor) + } + + picker(.sentMessage, editColor) + picker(.sentQuote, editColor) + picker(.receivedMessage, editColor) + picker(.receivedQuote, editColor) + + } + + private struct WallpaperScaleChooser: View { + @Binding var wallpaperScale: Float + var wallpaperType: WallpaperType? + var onTypeChange: (WallpaperType?) -> Void + + var body: some View { + HStack { + Text("\(wallpaperScale)".prefix(4)) + .frame(width: 40, height: 36, alignment: .leading) + Slider( + value: Binding(get: { wallpaperScale }, set: { scale in + if let wallpaperType, case let WallpaperType.preset(filename, _) = wallpaperType { + onTypeChange(WallpaperType.preset(filename, Float("\(scale)".prefix(9)))) + } else if let wallpaperType, case let WallpaperType.image(filename, _, scaleType) = wallpaperType { + onTypeChange(WallpaperType.image(filename, Float("\(scale)".prefix(9)), scaleType)) + } + }), + in: 0.5...2, + step: 0.0000001 + ) + .frame(height: 36) + } + } + } + + private struct WallpaperScaleTypeChooser: View { + @Binding var wallpaperScaleType: WallpaperScaleType + var wallpaperType: WallpaperType? + var onTypeChange: (WallpaperType?) -> Void + + var body: some View { + Picker("Scale", selection: Binding(get: { wallpaperScaleType }, set: { scaleType in + if let wallpaperType, case let WallpaperType.image(filename, scale, _) = wallpaperType { + onTypeChange(WallpaperType.image(filename, scale, scaleType)) + } + })) { + ForEach(Array(WallpaperScaleType.allCases), id: \.self) { type in + Text(type.text) + } + } + .frame(height: 36) + } + } +} + +private struct picker: View { + var name: ThemeColor + @State var color: Color + var editColor: (ThemeColor) -> Binding + // Prevent a race between setting a color here and applying externally changed color to the binding + @State private var lastColorUpdate: Date = .now + + init(_ name: ThemeColor, _ editColor: @escaping (ThemeColor) -> Binding) { + self.name = name + self.color = editColor(name).wrappedValue + self.editColor = editColor + } + + var body: some View { + ColorPickerView(name: name, selection: $color) + .onChange(of: color) { newColor in + let editedColor = editColor(name) + if editedColor.wrappedValue != newColor { + editedColor.wrappedValue = newColor + lastColorUpdate = .now + } + } + .onChange(of: editColor(name).wrappedValue) { newValue in + // Allows to update underlying color in the picker when color changed externally, for example, by reseting colors of a theme or changing the theme + if lastColorUpdate < Date.now - 1 && newValue != color { + color = newValue + } + } + } +} + +struct ColorPickerView: View { + var name: ThemeColor + @State var selection: Binding + + var body: some View { + let supportsOpacity = switch name { + case .wallpaperTint: true + case .sentMessage: true + case .sentQuote: true + case .receivedMessage: true + case .receivedQuote: true + default: UIColor(selection.wrappedValue).cgColor.alpha < 1 + } + ColorPicker(name.text, selection: selection, supportsOpacity: supportsOpacity) + } +} + +struct WallpaperImporter: ViewModifier { + @Binding var showImageImporter: Bool + var onChooseImage: (UIImage) -> Void + + func body(content: Content) -> some View { + content.sheet(isPresented: $showImageImporter) { + // LALAL TODO: limit by 5 mb + LibraryMediaListPicker(addMedia: { onChooseImage($0.uiImage) }, selectionLimit: 1, filter: .images, finishedPreprocessing: { }) { itemsSelected in + await MainActor.run { + showImageImporter = false + } + } + } + // content.fileImporter( + // isPresented: $showImageImporter, + // allowedContentTypes: [.image], + // allowsMultipleSelection: false + // ) { result in + // if case let .success(files) = result, let fileURL = files.first { + // do { + // var fileSize: Int? = nil + // if fileURL.startAccessingSecurityScopedResource() { + // let resourceValues = try fileURL.resourceValues(forKeys: [.fileSizeKey]) + // fileSize = resourceValues.fileSize + // } + // fileURL.stopAccessingSecurityScopedResource() + // if let fileSize = fileSize, + // // Same as Android/desktop + // fileSize <= 5_000_000, + // let image = UIImage(contentsOfFile: fileURL.path){ + // onChooseImage(image) + // } else { + // let prettyMaxFileSize = ByteCountFormatter.string(fromByteCount: 5_500_000, countStyle: .binary) + // AlertManager.shared.showAlertMsg( + // title: "Large file!", + // message: "Currently maximum supported file size is \(prettyMaxFileSize)." + // ) + // } + // } catch { + // logger.error("Appearance fileImporter error \(error.localizedDescription)") + // } + // } + // } + } +} + + +/// deprecated. Remove in 2025 func getUIAccentColorDefault() -> CGColor { let defs = UserDefaults.standard return CGColor( @@ -127,15 +1028,78 @@ func getUIAccentColorDefault() -> CGColor { ) } -func setUIAccentColorDefault(_ color: CGColor) { - if let cs = color.components { - let defs = UserDefaults.standard - defs.set(cs[0], forKey: DEFAULT_ACCENT_COLOR_RED) - defs.set(cs[1], forKey: DEFAULT_ACCENT_COLOR_GREEN) - defs.set(cs[2], forKey: DEFAULT_ACCENT_COLOR_BLUE) +private var updateBackendTask: Task = Task {} + +private func saveThemeToDatabase(_ themeUserDestination: (Int64, ThemeModeOverrides?)?) { + let m = ChatModel.shared + let oldThemes = m.currentUser?.uiThemes + if let themeUserDestination { + DispatchQueue.main.async { + // Update before save to make it work seamless + m.updateCurrentUserUiThemes(uiThemes: themeUserDestination.1) + } + } + Task { + if themeUserDestination == nil { + do { + try apiSaveAppSettings(settings: AppSettings.current.prepareForExport()) + } catch { + logger.error("Error saving settings: \(error)") + } + } else if let themeUserDestination, await !apiSetUserUIThemes(userId: themeUserDestination.0, themes: themeUserDestination.1) { + // If failed to apply for some reason return the old themes + m.updateCurrentUserUiThemes(uiThemes: oldThemes) + } } } +private func removeUserThemeModeOverrides(_ themeUserDestination: Binding<(Int64, ThemeModeOverrides?)?>, _ perUserTheme: Binding) { + guard let dest = themeUserDestination.wrappedValue else { return } + perUserTheme.wrappedValue = ThemeModeOverride(mode: CurrentColors.base.mode) + themeUserDestination.wrappedValue = (dest.0, nil) + var wallpaperFilesToDelete: [String] = [] + if let type = ChatModel.shared.currentUser?.uiThemes?.light?.type, case let WallpaperType.image(filename, _, _) = type { + wallpaperFilesToDelete.append(filename) + } + if let type = ChatModel.shared.currentUser?.uiThemes?.dark?.type, case let WallpaperType.image(filename, _, _) = type { + wallpaperFilesToDelete.append(filename) + } + wallpaperFilesToDelete.forEach(removeWallpaperFile) +} + +private func decodeYAML(_ string: String) -> T? { + do { + return try YAMLDecoder().decode(T.self, from: string) + } catch { + logger.error("Error decoding YAML: \(error)") + return nil + } +} + +private func encodeThemeOverrides(_ value: ThemeOverrides) throws -> String { + let encoder = YAMLEncoder() + encoder.options = YAMLEncoder.Options(sequenceStyle: .block, mappingStyle: .block, newLineScalarStyle: .doubleQuoted) + + guard var node = try Yams.compose(yaml: try encoder.encode(value)) else { + throw RuntimeError("Error while composing a node from object") + } + node["base"]?.scalar?.style = .doubleQuoted + + ThemeColors.CodingKeys.allCases.forEach { key in + node["colors"]?[key.stringValue]?.scalar?.style = .doubleQuoted + } + + ThemeWallpaper.CodingKeys.allCases.forEach { key in + if case .scale = key { + // let number be without quotes + } else { + node["wallpaper"]?[key.stringValue]?.scalar?.style = .doubleQuoted + } + } + return try Yams.serialize(node: node) +} + +/// deprecated. Remove in 2025 func getUserInterfaceStyleDefault() -> UIUserInterfaceStyle { switch UserDefaults.standard.integer(forKey: DEFAULT_USER_INTERFACE_STYLE) { case 1: return .light @@ -144,17 +1108,6 @@ func getUserInterfaceStyleDefault() -> UIUserInterfaceStyle { } } -func setUserInterfaceStyleDefault(_ style: UIUserInterfaceStyle) { - var v: Int - switch style { - case .unspecified: v = 0 - case .light: v = 1 - case .dark: v = 2 - default: v = 0 - } - UserDefaults.standard.set(v, forKey: DEFAULT_USER_INTERFACE_STYLE) -} - struct AppearanceSettings_Previews: PreviewProvider { static var previews: some View { AppearanceSettings() diff --git a/apps/ios/Shared/Views/UserSettings/CallSettings.swift b/apps/ios/Shared/Views/UserSettings/CallSettings.swift index 3409e7ab0e..bae343ee88 100644 --- a/apps/ios/Shared/Views/UserSettings/CallSettings.swift +++ b/apps/ios/Shared/Views/UserSettings/CallSettings.swift @@ -10,6 +10,7 @@ import SwiftUI import SimpleXChat struct CallSettings: View { + @EnvironmentObject var theme: AppTheme @AppStorage(DEFAULT_WEBRTC_POLICY_RELAY) private var webrtcPolicyRelay = true @AppStorage(GROUP_DEFAULT_CALL_KIT_ENABLED, store: groupDefaults) private var callKitEnabled = true @AppStorage(DEFAULT_CALL_KIT_CALLS_IN_RECENTS) private var callKitCallsInRecents = false @@ -22,17 +23,21 @@ struct CallSettings: View { NavigationLink { RTCServers() .navigationTitle("Your ICE servers") + .modifier(ThemedBackground(grouped: true)) } label: { Text("WebRTC ICE servers") } Toggle("Always use relay", isOn: $webrtcPolicyRelay) } header: { Text("Settings") + .foregroundColor(theme.colors.secondary) } footer: { if webrtcPolicyRelay { Text("Relay server protects your IP address, but it can observe the duration of the call.") + .foregroundColor(theme.colors.secondary) } else { Text("Relay server is only used if necessary. Another party can observe your IP address.") + .foregroundColor(theme.colors.secondary) } } @@ -46,6 +51,7 @@ struct CallSettings: View { } } header: { Text("Interface") + .foregroundColor(theme.colors.secondary) } footer: { if callKitEnabled { Text("You can accept calls from lock screen, without device and app authentication.") @@ -55,7 +61,7 @@ struct CallSettings: View { } } - Section("Limitations") { + Section(header: Text("Limitations").foregroundColor(theme.colors.secondary)) { VStack(alignment: .leading, spacing: 8) { textListItem("1.", "Do NOT use SimpleX for emergency calls.") textListItem("2.", "Unless you use iOS call interface, enable Do Not Disturb mode to avoid interruptions.") diff --git a/apps/ios/Shared/Views/UserSettings/DeveloperView.swift b/apps/ios/Shared/Views/UserSettings/DeveloperView.swift index 3bbfbfe33e..e55ff5cfb6 100644 --- a/apps/ios/Shared/Views/UserSettings/DeveloperView.swift +++ b/apps/ios/Shared/Views/UserSettings/DeveloperView.swift @@ -10,6 +10,7 @@ import SwiftUI import SimpleXChat struct DeveloperView: View { + @EnvironmentObject var theme: AppTheme @AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false @AppStorage(GROUP_DEFAULT_CONFIRM_DB_UPGRADES, store: groupDefaults) private var confirmDatabaseUpgrades = false @Environment(\.colorScheme) var colorScheme @@ -23,24 +24,26 @@ struct DeveloperView: View { .resizable() .frame(width: 24, height: 24) .opacity(0.5) + .colorMultiply(theme.colors.secondary) Text("Install [SimpleX Chat for terminal](https://github.com/simplex-chat/simplex-chat)") .padding(.leading, 36) } NavigationLink { TerminalView() } label: { - settingsRow("terminal") { Text("Chat console") } + settingsRow("terminal", color: theme.colors.secondary) { Text("Chat console") } } - settingsRow("internaldrive") { + settingsRow("internaldrive", color: theme.colors.secondary) { Toggle("Confirm database upgrades", isOn: $confirmDatabaseUpgrades) } - settingsRow("chevron.left.forwardslash.chevron.right") { + settingsRow("chevron.left.forwardslash.chevron.right", color: theme.colors.secondary) { Toggle("Show developer options", isOn: $developerTools) } } header: { Text("") } footer: { - (developerTools ? Text("Show:") : Text("Hide:")) + Text(" ") + Text("Database IDs and Transport isolation option.") + ((developerTools ? Text("Show:") : Text("Hide:")) + Text(" ") + Text("Database IDs and Transport isolation option.")) + .foregroundColor(theme.colors.secondary) } } } diff --git a/apps/ios/Shared/Views/UserSettings/HiddenProfileView.swift b/apps/ios/Shared/Views/UserSettings/HiddenProfileView.swift index 509874619f..5f20055b2b 100644 --- a/apps/ios/Shared/Views/UserSettings/HiddenProfileView.swift +++ b/apps/ios/Shared/Views/UserSettings/HiddenProfileView.swift @@ -13,6 +13,7 @@ struct HiddenProfileView: View { @State var user: User @Binding var profileHidden: Bool @EnvironmentObject private var m: ChatModel + @EnvironmentObject var theme: AppTheme @Environment(\.dismiss) var dismiss: DismissAction @State private var hidePassword = "" @State private var confirmHidePassword = "" @@ -36,7 +37,7 @@ struct HiddenProfileView: View { PassphraseField(key: $hidePassword, placeholder: "Password to show", valid: passwordValid, showStrength: true) PassphraseField(key: $confirmHidePassword, placeholder: "Confirm password", valid: confirmValid) - settingsRow("lock") { + settingsRow("lock", color: theme.colors.secondary) { Button("Save profile password") { Task { do { @@ -58,8 +59,10 @@ struct HiddenProfileView: View { .disabled(saveDisabled) } header: { Text("Hidden profile password") + .foregroundColor(theme.colors.secondary) } footer: { Text("To reveal your hidden profile, enter a full password into a search field in **Your chat profiles** page.") + .foregroundColor(theme.colors.secondary) .font(.body) .padding(.top, 8) } @@ -70,6 +73,7 @@ struct HiddenProfileView: View { message: Text(savePasswordError ?? "") ) } + .modifier(ThemedBackground(grouped: true)) } var passwordValid: Bool { hidePassword == hidePassword.trimmingCharacters(in: .whitespaces) } diff --git a/apps/ios/Shared/Views/UserSettings/IncognitoHelp.swift b/apps/ios/Shared/Views/UserSettings/IncognitoHelp.swift index fc478596a9..a0250afddf 100644 --- a/apps/ios/Shared/Views/UserSettings/IncognitoHelp.swift +++ b/apps/ios/Shared/Views/UserSettings/IncognitoHelp.swift @@ -27,6 +27,7 @@ struct IncognitoHelp: View { } .listRowBackground(Color.clear) } + .modifier(ThemedBackground()) } } diff --git a/apps/ios/Shared/Views/UserSettings/MarkdownHelp.swift b/apps/ios/Shared/Views/UserSettings/MarkdownHelp.swift index afb0af66c1..cf9cada592 100644 --- a/apps/ios/Shared/Views/UserSettings/MarkdownHelp.swift +++ b/apps/ios/Shared/Views/UserSettings/MarkdownHelp.swift @@ -9,6 +9,8 @@ import SwiftUI struct MarkdownHelp: View { + @EnvironmentObject var theme: AppTheme + var body: some View { VStack(alignment: .leading, spacing: 8) { Text("You can use markdown to format messages:") @@ -21,7 +23,7 @@ struct MarkdownHelp: View { ( mdFormat("#secret#", Text("secret") .foregroundColor(.clear) - .underline(color: .primary) + Text(" (can be copied)")) + .underline(color: theme.colors.onBackground) + Text(" (can be copied)")) ) .textSelection(.enabled) } diff --git a/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift b/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift index 19ae3e61ab..b07f0f6a13 100644 --- a/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift +++ b/apps/ios/Shared/Views/UserSettings/NetworkAndServers.swift @@ -29,6 +29,7 @@ private enum NetworkAlert: Identifiable { struct NetworkAndServers: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false @AppStorage(DEFAULT_SHOW_SENT_VIA_RPOXY) private var showSentViaProxy = false @AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false @@ -48,6 +49,7 @@ struct NetworkAndServers: View { NavigationLink { ProtocolServersView(serverProtocol: .smp) .navigationTitle("Your SMP servers") + .modifier(ThemedBackground(grouped: true)) } label: { Text("SMP servers") } @@ -55,6 +57,7 @@ struct NetworkAndServers: View { NavigationLink { ProtocolServersView(serverProtocol: .xftp) .navigationTitle("Your XFTP servers") + .modifier(ThemedBackground(grouped: true)) } label: { Text("XFTP servers") } @@ -76,13 +79,16 @@ struct NetworkAndServers: View { NavigationLink { AdvancedNetworkSettings() .navigationTitle("Network settings") + .modifier(ThemedBackground(grouped: true)) } label: { Text("Advanced network settings") } } header: { Text("Messages & files") + .foregroundColor(theme.colors.secondary) } footer: { Text("Using .onion hosts requires compatible VPN provider.") + .foregroundColor(theme.colors.secondary) } Section { @@ -100,6 +106,7 @@ struct NetworkAndServers: View { Toggle("Show message status", isOn: $showSentViaProxy) } header: { Text("Private message routing") + .foregroundColor(theme.colors.secondary) } footer: { VStack(alignment: .leading) { Text("To protect your IP address, private routing uses your SMP servers to deliver messages.") @@ -107,18 +114,20 @@ struct NetworkAndServers: View { Text("Show → on messages sent via private routing.") } } + .foregroundColor(theme.colors.secondary) } - Section("Calls") { + Section(header: Text("Calls").foregroundColor(theme.colors.secondary)) { NavigationLink { RTCServers() .navigationTitle("Your ICE servers") + .modifier(ThemedBackground(grouped: true)) } label: { Text("WebRTC ICE servers") } } - Section("Network connection") { + Section(header: Text("Network connection").foregroundColor(theme.colors.secondary)) { HStack { Text(m.networkInfo.networkType.text) Spacer() diff --git a/apps/ios/Shared/Views/UserSettings/NotificationsView.swift b/apps/ios/Shared/Views/UserSettings/NotificationsView.swift index 1d924f4085..b9c92c9919 100644 --- a/apps/ios/Shared/Views/UserSettings/NotificationsView.swift +++ b/apps/ios/Shared/Views/UserSettings/NotificationsView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct NotificationsView: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @State private var notificationMode: NotificationsMode = ChatModel.shared.notificationMode @State private var showAlert: NotificationAlert? @State private var legacyDatabase = dbContainerGroupDefault.get() == .documents @@ -45,12 +46,14 @@ struct NotificationsView: View { } footer: { VStack(alignment: .leading) { Text(ntfModeDescription(notificationMode)) + .foregroundColor(theme.colors.secondary) } .font(.callout) .padding(.top, 1) } } .navigationTitle("Send notifications") + .modifier(ThemedBackground(grouped: true)) .navigationBarTitleDisplayMode(.inline) } label: { HStack { @@ -70,6 +73,7 @@ struct NotificationsView: View { } footer: { VStack(alignment: .leading, spacing: 1) { Text("You can set lock screen notification preview via settings.") + .foregroundColor(theme.colors.secondary) Button("Open Settings") { DispatchQueue.main.async { UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil) @@ -79,6 +83,7 @@ struct NotificationsView: View { } } .navigationTitle("Show preview") + .modifier(ThemedBackground(grouped: true)) .navigationBarTitleDisplayMode(.inline) } label: { HStack { @@ -89,14 +94,16 @@ struct NotificationsView: View { } if let server = m.notificationServer { - smpServers("Push server", [server]) + smpServers("Push server", [server], theme.colors.secondary) testServerButton(server) } } header: { Text("Push notifications") + .foregroundColor(theme.colors.secondary) } footer: { if legacyDatabase { Text("Please restart the app and migrate the database to enable push notifications.") + .foregroundColor(theme.colors.secondary) .font(.callout) .padding(.top, 1) } @@ -237,6 +244,7 @@ func ntfModeDescription(_ mode: NotificationsMode) -> LocalizedStringKey { } struct SelectionListView: View { + @EnvironmentObject var theme: AppTheme var list: [Item] @Binding var selection: Item var onSelection: ((Item) -> Void)? @@ -244,32 +252,24 @@ struct SelectionListView: View { var body: some View { ForEach(list) { item in - HStack { - Text(item.label) - Spacer() - if selection == item { - Image(systemName: "checkmark") - .resizable().scaledToFit().frame(width: 16) - .foregroundColor(.accentColor) - } - } - .contentShape(Rectangle()) - .listRowBackground(Color(uiColor: tapped == item ? .secondarySystemFill : .systemBackground)) - .onTapGesture { + Button { if selection == item { return } if let f = onSelection { f(item) } else { selection = item } - } - ._onButtonGesture { down in - if down { - tapped = item - } else { - tapped = nil + } label: { + HStack { + Text(item.label).foregroundColor(theme.colors.onBackground) + Spacer() + if selection == item { + Image(systemName: "checkmark") + .resizable().scaledToFit().frame(width: 16) + .foregroundColor(theme.colors.primary) + } } - } perform: {} + } } .environment(\.editMode, .constant(.active)) } diff --git a/apps/ios/Shared/Views/UserSettings/PreferencesView.swift b/apps/ios/Shared/Views/UserSettings/PreferencesView.swift index 2e560f8578..0c10da2103 100644 --- a/apps/ios/Shared/Views/UserSettings/PreferencesView.swift +++ b/apps/ios/Shared/Views/UserSettings/PreferencesView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct PreferencesView: View { @EnvironmentObject var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @State var profile: LocalProfile @State var preferences: FullPreferences @State var currentPreferences: FullPreferences @@ -35,7 +36,7 @@ struct PreferencesView: View { private func featureSection(_ feature: ChatFeature, _ allowFeature: Binding) -> some View { Section { - settingsRow(feature.icon) { + settingsRow(feature.icon, color: theme.colors.secondary) { Picker(feature.text, selection: allowFeature) { ForEach(FeatureAllowed.values) { allow in Text(allow.text) @@ -44,7 +45,7 @@ struct PreferencesView: View { .frame(height: 36) } } - footer: { featureFooter(feature, allowFeature) } + footer: { featureFooter(feature, allowFeature).foregroundColor(theme.colors.secondary) } } @@ -54,11 +55,11 @@ struct PreferencesView: View { get: { allowFeature.wrappedValue == .always || allowFeature.wrappedValue == .yes }, set: { yes, _ in allowFeature.wrappedValue = yes ? .yes : .no } ) - settingsRow(ChatFeature.timedMessages.icon) { + settingsRow(ChatFeature.timedMessages.icon, color: theme.colors.secondary) { Toggle(ChatFeature.timedMessages.text, isOn: allow) } } - footer: { featureFooter(.timedMessages, allowFeature) } + footer: { featureFooter(.timedMessages, allowFeature).foregroundColor(theme.colors.secondary) } } private func featureFooter(_ feature: ChatFeature, _ allowFeature: Binding) -> some View { diff --git a/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift b/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift index 01f31d66b4..879ee301f2 100644 --- a/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift +++ b/apps/ios/Shared/Views/UserSettings/PrivacySettings.swift @@ -11,6 +11,7 @@ import SimpleXChat struct PrivacySettings: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @AppStorage(DEFAULT_PRIVACY_ACCEPT_IMAGES) private var autoAcceptImages = true @AppStorage(DEFAULT_PRIVACY_LINK_PREVIEWS) private var useLinkPreviews = true @AppStorage(DEFAULT_PRIVACY_SHOW_CHAT_PREVIEWS) private var showChatPreviews = true @@ -44,34 +45,35 @@ struct PrivacySettings: View { var body: some View { VStack { List { - Section("Device") { + Section(header: Text("Device").foregroundColor(theme.colors.secondary)) { NavigationLink { SimplexLockView(prefPerformLA: $prefPerformLA, currentLAMode: $currentLAMode) .navigationTitle("SimpleX Lock") + .modifier(ThemedBackground(grouped: true)) } label: { if prefPerformLA { settingsRow("lock.fill", color: .green) { simplexLockRow(currentLAMode.text) } } else { - settingsRow("lock") { + settingsRow("lock", color: theme.colors.secondary) { simplexLockRow("Off") } } } - settingsRow("eye.slash") { + settingsRow("eye.slash", color: theme.colors.secondary) { Toggle("Protect app screen", isOn: $protectScreen) } } Section { - settingsRow("network") { + settingsRow("network", color: theme.colors.secondary) { Toggle("Send link previews", isOn: $useLinkPreviews) } - settingsRow("message") { + settingsRow("message", color: theme.colors.secondary) { Toggle("Show last messages", isOn: $showChatPreviews) } - settingsRow("rectangle.and.pencil.and.ellipsis") { + settingsRow("rectangle.and.pencil.and.ellipsis", color: theme.colors.secondary) { Toggle("Message draft", isOn: $saveLastDraft) } .onChange(of: saveLastDraft) { saveDraft in @@ -80,7 +82,7 @@ struct PrivacySettings: View { m.draftChatId = nil } } - settingsRow("link") { + settingsRow("link", color: theme.colors.secondary) { Picker("SimpleX links", selection: $simplexLinkMode) { ForEach( SimpleXLinkMode.values + (SimpleXLinkMode.values.contains(simplexLinkMode) ? [] : [simplexLinkMode]) @@ -95,48 +97,54 @@ struct PrivacySettings: View { } } header: { Text("Chats") + .foregroundColor(theme.colors.secondary) } Section { - settingsRow("lock.doc") { + settingsRow("lock.doc", color: theme.colors.secondary) { Toggle("Encrypt local files", isOn: $encryptLocalFiles) .onChange(of: encryptLocalFiles) { setEncryptLocalFiles($0) } } - settingsRow("photo") { + settingsRow("photo", color: theme.colors.secondary) { Toggle("Auto-accept images", isOn: $autoAcceptImages) .onChange(of: autoAcceptImages) { privacyAcceptImagesGroupDefault.set($0) } } - settingsRow("network.badge.shield.half.filled") { + settingsRow("network.badge.shield.half.filled", color: theme.colors.secondary) { Toggle("Protect IP address", isOn: $askToApproveRelays) } } header: { Text("Files") + .foregroundColor(theme.colors.secondary) } footer: { if askToApproveRelays { Text("The app will ask to confirm downloads from unknown file servers (except .onion).") + .foregroundColor(theme.colors.secondary) } else { Text("Without Tor or VPN, your IP address will be visible to file servers.") + .foregroundColor(theme.colors.secondary) } } Section { - settingsRow("person") { + settingsRow("person", color: theme.colors.secondary) { Toggle("Contacts", isOn: $contactReceipts) } - settingsRow("person.2") { + settingsRow("person.2", color: theme.colors.secondary) { Toggle("Small groups (max 20)", isOn: $groupReceipts) } } header: { Text("Send delivery receipts to") + .foregroundColor(theme.colors.secondary) } footer: { VStack(alignment: .leading) { Text("These settings are for your current profile **\(m.currentUser?.displayName ?? "")**.") Text("They can be overridden in contact and group settings.") } + .foregroundColor(theme.colors.secondary) .frame(maxWidth: .infinity, alignment: .leading) } .confirmationDialog(contactReceiptsDialogTitle, isPresented: $contactReceiptsDialogue, titleVisibility: .visible) { @@ -332,6 +340,7 @@ struct SimplexLockView: View { @Binding var prefPerformLA: Bool @Binding var currentLAMode: LAMode @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @AppStorage(DEFAULT_LA_NOTICE_SHOWN) private var prefLANoticeShown = false @State private var laMode: LAMode = privacyLocalAuthModeDefault.get() @AppStorage(DEFAULT_LA_LOCK_DELAY) private var laLockDelay = 30 @@ -411,12 +420,12 @@ struct SimplexLockView: View { } if performLA && laMode == .passcode { - Section("Self-destruct passcode") { + Section(header: Text("Self-destruct passcode").foregroundColor(theme.colors.secondary)) { Toggle(isOn: $selfDestruct) { HStack(spacing: 6) { Text("Enable self-destruct") Image(systemName: "info.circle") - .foregroundColor(.accentColor) + .foregroundColor(theme.colors.primary) .font(.system(size: 14)) } .onTapGesture { diff --git a/apps/ios/Shared/Views/UserSettings/ProtocolServerView.swift b/apps/ios/Shared/Views/UserSettings/ProtocolServerView.swift index 8926ee09fa..f4e5459613 100644 --- a/apps/ios/Shared/Views/UserSettings/ProtocolServerView.swift +++ b/apps/ios/Shared/Views/UserSettings/ProtocolServerView.swift @@ -11,6 +11,7 @@ import SimpleXChat struct ProtocolServerView: View { @Environment(\.dismiss) var dismiss: DismissAction + @EnvironmentObject var theme: AppTheme let serverProtocol: ServerProtocol @Binding var server: ServerCfg @State var serverToEdit: ServerCfg @@ -50,7 +51,7 @@ struct ProtocolServerView: View { private func presetServer() -> some View { return VStack { List { - Section("Preset server address") { + Section(header: Text("Preset server address").foregroundColor(theme.colors.secondary)) { Text(serverToEdit.server) .textSelection(.enabled) } @@ -76,6 +77,7 @@ struct ProtocolServerView: View { } header: { HStack { Text("Your server address") + .foregroundColor(theme.colors.secondary) if !valid { Spacer() Image(systemName: "exclamationmark.circle").foregroundColor(.red) @@ -84,7 +86,7 @@ struct ProtocolServerView: View { } useServerSection(valid) if valid { - Section("Add to another device") { + Section(header: Text("Add to another device").foregroundColor(theme.colors.secondary)) { MutableQRCode(uri: $serverToEdit.server) .listRowInsets(EdgeInsets(top: 12, leading: 12, bottom: 12, trailing: 12)) } @@ -94,7 +96,7 @@ struct ProtocolServerView: View { } private func useServerSection(_ valid: Bool) -> some View { - Section("Use server") { + Section(header: Text("Use server").foregroundColor(theme.colors.secondary)) { HStack { Button("Test server") { testing = true diff --git a/apps/ios/Shared/Views/UserSettings/ProtocolServersView.swift b/apps/ios/Shared/Views/UserSettings/ProtocolServersView.swift index db82008182..857bab69fb 100644 --- a/apps/ios/Shared/Views/UserSettings/ProtocolServersView.swift +++ b/apps/ios/Shared/Views/UserSettings/ProtocolServersView.swift @@ -14,6 +14,7 @@ private let howToUrl = URL(string: "https://simplex.chat/docs/server.html")! struct ProtocolServersView: View { @Environment(\.dismiss) var dismiss: DismissAction @EnvironmentObject private var m: ChatModel + @EnvironmentObject var theme: AppTheme @Environment(\.editMode) private var editMode let serverProtocol: ServerProtocol @State private var currServers: [ServerCfg] = [] @@ -67,8 +68,10 @@ struct ProtocolServersView: View { } } header: { Text("\(proto) servers") + .foregroundColor(theme.colors.secondary) } footer: { Text("The servers for new connections of your current chat profile **\(m.currentUser?.displayName ?? "")**.") + .foregroundColor(theme.colors.secondary) .lineLimit(10) } @@ -94,6 +97,7 @@ struct ProtocolServersView: View { } .sheet(isPresented: $showScanProtoServer) { ScanProtocolServer(servers: $servers) + .modifier(ThemedBackground(grouped: true)) } .modifier(BackButton(disabled: Binding.constant(false)) { if saveDisabled { @@ -172,6 +176,7 @@ struct ProtocolServersView: View { serverEnabled: srv.enabled == .enabled ) .navigationBarTitle(srv.preset ? "Preset server" : "Your server") + .modifier(ThemedBackground(grouped: true)) .navigationBarTitleDisplayMode(.large) } label: { let address = parseServerAddress(srv.server) @@ -183,7 +188,7 @@ struct ProtocolServersView: View { } else if !uniqueAddress(srv, address) { Image(systemName: "exclamationmark.circle").foregroundColor(.red) } else if srv.enabled != .enabled { - Image(systemName: "slash.circle").foregroundColor(.secondary) + Image(systemName: "slash.circle").foregroundColor(theme.colors.secondary) } else { showTestStatus(server: srv) } @@ -198,7 +203,7 @@ struct ProtocolServersView: View { if srv.enabled == .enabled { v } else { - v.foregroundColor(.secondary) + v.foregroundColor(theme.colors.secondary) } } } diff --git a/apps/ios/Shared/Views/UserSettings/RTCServers.swift b/apps/ios/Shared/Views/UserSettings/RTCServers.swift index 1b4c65dc2e..ef891738cc 100644 --- a/apps/ios/Shared/Views/UserSettings/RTCServers.swift +++ b/apps/ios/Shared/Views/UserSettings/RTCServers.swift @@ -13,6 +13,7 @@ private let howToUrl = URL(string: "https://simplex.chat/docs/webrtc.html#config let serversFont = Font.custom("Menlo", size: 14) struct RTCServers: View { + @EnvironmentObject var theme: AppTheme @State private var userRTCServers: [String] = [] @State private var isUserRTCServers = false @State private var isUserRTCServersToggle = false @@ -53,6 +54,7 @@ struct RTCServers: View { } footer: { if !isUserRTCServers { Text("Using SimpleX Chat servers.") + .foregroundColor(theme.colors.secondary) } } @@ -80,6 +82,7 @@ struct RTCServers: View { } } header: { Text("ICE servers (one per line)") + .foregroundColor(theme.colors.secondary) } footer: { HStack(spacing: 20) { if editRTCServers { diff --git a/apps/ios/Shared/Views/UserSettings/SetDeliveryReceiptsView.swift b/apps/ios/Shared/Views/UserSettings/SetDeliveryReceiptsView.swift index 4925b7af8d..e03dace43d 100644 --- a/apps/ios/Shared/Views/UserSettings/SetDeliveryReceiptsView.swift +++ b/apps/ios/Shared/Views/UserSettings/SetDeliveryReceiptsView.swift @@ -11,12 +11,13 @@ import SimpleXChat struct SetDeliveryReceiptsView: View { @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme var body: some View { VStack(spacing: 16) { Text("Delivery receipts!") .font(.title) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .padding(.vertical) .multilineTextAlignment(.center) @@ -89,7 +90,7 @@ struct SetDeliveryReceiptsView: View { .padding() .padding(.horizontal) .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(Color(uiColor: .systemBackground)) + .background(AppTheme.shared.colors.background) } } diff --git a/apps/ios/Shared/Views/UserSettings/SettingsView.swift b/apps/ios/Shared/Views/UserSettings/SettingsView.swift index a2df236738..b195efb985 100644 --- a/apps/ios/Shared/Views/UserSettings/SettingsView.swift +++ b/apps/ios/Shared/Views/UserSettings/SettingsView.swift @@ -41,10 +41,10 @@ let DEFAULT_CHAT_V3_DB_MIGRATION = "chatV3DBMigration" let DEFAULT_DEVELOPER_TOOLS = "developerTools" let DEFAULT_ENCRYPTION_STARTED = "encryptionStarted" let DEFAULT_ENCRYPTION_STARTED_AT = "encryptionStartedAt" -let DEFAULT_ACCENT_COLOR_RED = "accentColorRed" -let DEFAULT_ACCENT_COLOR_GREEN = "accentColorGreen" -let DEFAULT_ACCENT_COLOR_BLUE = "accentColorBlue" -let DEFAULT_USER_INTERFACE_STYLE = "userInterfaceStyle" +let DEFAULT_ACCENT_COLOR_RED = "accentColorRed" // deprecated, only used for migration +let DEFAULT_ACCENT_COLOR_GREEN = "accentColorGreen" // deprecated, only used for migration +let DEFAULT_ACCENT_COLOR_BLUE = "accentColorBlue" // deprecated, only used for migration +let DEFAULT_USER_INTERFACE_STYLE = "userInterfaceStyle" // deprecated, only used for migration let DEFAULT_PROFILE_IMAGE_CORNER_RADIUS = "profileImageCornerRadius" let DEFAULT_CONNECT_VIA_LINK_TAB = "connectViaLinkTab" let DEFAULT_LIVE_MESSAGE_ALERT_SHOWN = "liveMessageAlertShown" @@ -63,6 +63,11 @@ let DEFAULT_CONNECT_REMOTE_VIA_MULTICAST_AUTO = "connectRemoteViaMulticastAuto" let DEFAULT_SHOW_SENT_VIA_RPOXY = "showSentViaProxy" let DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE = "showSubscriptionPercentage" +let DEFAULT_CURRENT_THEME = "currentTheme" +let DEFAULT_SYSTEM_DARK_THEME = "systemDarkTheme" +let DEFAULT_CURRENT_THEME_IDS = "currentThemeIds" +let DEFAULT_THEME_OVERRIDES = "themeOverrides" + let ANDROID_DEFAULT_CALL_ON_LOCK_SCREEN = "androidCallOnLockScreen" let appDefaults: [String: Any] = [ @@ -86,10 +91,6 @@ let appDefaults: [String: Any] = [ DEFAULT_CHAT_V3_DB_MIGRATION: V3DBMigrationState.offer.rawValue, DEFAULT_DEVELOPER_TOOLS: false, DEFAULT_ENCRYPTION_STARTED: false, - DEFAULT_ACCENT_COLOR_RED: 0.000, - DEFAULT_ACCENT_COLOR_GREEN: 0.533, - DEFAULT_ACCENT_COLOR_BLUE: 1.000, - DEFAULT_USER_INTERFACE_STYLE: 0, DEFAULT_PROFILE_IMAGE_CORNER_RADIUS: defaultProfileImageCorner, DEFAULT_CONNECT_VIA_LINK_TAB: ConnectViaLinkTab.scan.rawValue, DEFAULT_LIVE_MESSAGE_ALERT_SHOWN: false, @@ -103,7 +104,12 @@ let appDefaults: [String: Any] = [ DEFAULT_CONNECT_REMOTE_VIA_MULTICAST_AUTO: true, DEFAULT_SHOW_SENT_VIA_RPOXY: false, DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE: false, - ANDROID_DEFAULT_CALL_ON_LOCK_SCREEN: AppSettingsLockScreenCalls.show.rawValue + ANDROID_DEFAULT_CALL_ON_LOCK_SCREEN: AppSettingsLockScreenCalls.show.rawValue, + + DEFAULT_THEME_OVERRIDES: "{}", + DEFAULT_CURRENT_THEME: DefaultTheme.SYSTEM_THEME_NAME, + DEFAULT_SYSTEM_DARK_THEME: DefaultTheme.DARK.themeName, + DEFAULT_CURRENT_THEME_IDS: "{}" ] // not used anymore @@ -150,14 +156,73 @@ let onboardingStageDefault = EnumDefault(defaults: UserDefaults let customDisappearingMessageTimeDefault = IntDefault(defaults: UserDefaults.standard, forKey: DEFAULT_CUSTOM_DISAPPEARING_MESSAGE_TIME) +let currentThemeDefault = StringDefault(defaults: UserDefaults.standard, forKey: DEFAULT_CURRENT_THEME, withDefault: DefaultTheme.SYSTEM_THEME_NAME) +let systemDarkThemeDefault = StringDefault(defaults: UserDefaults.standard, forKey: DEFAULT_SYSTEM_DARK_THEME, withDefault: DefaultTheme.DARK.themeName) +let currentThemeIdsDefault = CodableDefault<[String: String]>(defaults: UserDefaults.standard, forKey: DEFAULT_CURRENT_THEME_IDS, withDefault: [:] ) +let themeOverridesDefault: CodableDefault<[ThemeOverrides]> = CodableDefault(defaults: UserDefaults.standard, forKey: DEFAULT_THEME_OVERRIDES, withDefault: []) + func setGroupDefaults() { privacyAcceptImagesGroupDefault.set(UserDefaults.standard.bool(forKey: DEFAULT_PRIVACY_ACCEPT_IMAGES)) } +public class StringDefault { + var defaults: UserDefaults + var key: String + var defaultValue: String + + public init(defaults: UserDefaults = UserDefaults.standard, forKey: String, withDefault: String) { + self.defaults = defaults + self.key = forKey + self.defaultValue = withDefault + } + + public func get() -> String { + defaults.string(forKey: key) ?? defaultValue + } + + public func set(_ value: String) { + defaults.set(value, forKey: key) + defaults.synchronize() + } +} + +public class CodableDefault { + var defaults: UserDefaults + var key: String + var defaultValue: T + + public init(defaults: UserDefaults = UserDefaults.standard, forKey: String, withDefault: T) { + self.defaults = defaults + self.key = forKey + self.defaultValue = withDefault + } + + var cache: T? = nil + + public func get() -> T { + if let cache { + return cache + } else if let value = defaults.string(forKey: key) { + let res = decodeJSON(value) ?? defaultValue + cache = res + return res + } + return defaultValue + } + + public func set(_ value: T) { + defaults.set(encodeJSON(value), forKey: key) + cache = value + //defaults.synchronize() + } +} + + struct SettingsView: View { @Environment(\.colorScheme) var colorScheme @EnvironmentObject var chatModel: ChatModel @EnvironmentObject var sceneDelegate: SceneDelegate + @EnvironmentObject var theme: AppTheme @Binding var showSettings: Bool @State private var showProgress: Bool = false @@ -177,11 +242,12 @@ struct SettingsView: View { let user = chatModel.currentUser NavigationView { List { - Section("You") { + Section(header: Text("You").foregroundColor(theme.colors.secondary)) { if let user = user { NavigationLink { UserProfile() .navigationTitle("Your current profile") + .modifier(ThemedBackground()) } label: { ProfilePreview(profileOf: user) .padding(.leading, -8) @@ -191,7 +257,7 @@ struct SettingsView: View { NavigationLink { UserProfilesView(showSettings: $showSettings) } label: { - settingsRow("person.crop.rectangle.stack") { Text("Your chat profiles") } + settingsRow("person.crop.rectangle.stack", color: theme.colors.secondary) { Text("Your chat profiles") } } @@ -199,39 +265,43 @@ struct SettingsView: View { NavigationLink { UserAddressView(shareViaProfile: user.addressShared) .navigationTitle("SimpleX address") + .modifier(ThemedBackground(grouped: true)) .navigationBarTitleDisplayMode(.large) } label: { - settingsRow("qrcode") { Text("Your SimpleX address") } + settingsRow("qrcode", color: theme.colors.secondary) { Text("Your SimpleX address") } } NavigationLink { PreferencesView(profile: user.profile, preferences: user.fullPreferences, currentPreferences: user.fullPreferences) .navigationTitle("Your preferences") + .modifier(ThemedBackground(grouped: true)) } label: { - settingsRow("switch.2") { Text("Chat preferences") } + settingsRow("switch.2", color: theme.colors.secondary) { Text("Chat preferences") } } } NavigationLink { ConnectDesktopView(viaSettings: true) } label: { - settingsRow("desktopcomputer") { Text("Use from desktop") } + settingsRow("desktopcomputer", color: theme.colors.secondary) { Text("Use from desktop") } } NavigationLink { MigrateFromDevice(showSettings: $showSettings, showProgressOnSettings: $showProgress) .navigationTitle("Migrate device") + .modifier(ThemedBackground(grouped: true)) .navigationBarTitleDisplayMode(.large) } label: { - settingsRow("tray.and.arrow.up") { Text("Migrate to another device") } + settingsRow("tray.and.arrow.up", color: theme.colors.secondary) { Text("Migrate to another device") } } } .disabled(chatModel.chatRunning != true) - Section("Settings") { + Section(header: Text("Settings").foregroundColor(theme.colors.secondary)) { NavigationLink { NotificationsView() .navigationTitle("Notifications") + .modifier(ThemedBackground(grouped: true)) } label: { HStack { notificationsIcon() @@ -243,24 +313,27 @@ struct SettingsView: View { NavigationLink { NetworkAndServers() .navigationTitle("Network & servers") + .modifier(ThemedBackground(grouped: true)) } label: { - settingsRow("externaldrive.connected.to.line.below") { Text("Network & servers") } + settingsRow("externaldrive.connected.to.line.below", color: theme.colors.secondary) { Text("Network & servers") } } .disabled(chatModel.chatRunning != true) NavigationLink { CallSettings() .navigationTitle("Your calls") + .modifier(ThemedBackground(grouped: true)) } label: { - settingsRow("video") { Text("Audio & video calls") } + settingsRow("video", color: theme.colors.secondary) { Text("Audio & video calls") } } .disabled(chatModel.chatRunning != true) NavigationLink { PrivacySettings() .navigationTitle("Your privacy") + .modifier(ThemedBackground(grouped: true)) } label: { - settingsRow("lock") { Text("Privacy & security") } + settingsRow("lock", color: theme.colors.secondary) { Text("Privacy & security") } } .disabled(chatModel.chatRunning != true) @@ -268,8 +341,9 @@ struct SettingsView: View { NavigationLink { AppearanceSettings() .navigationTitle("Appearance") + .modifier(ThemedBackground(grouped: true)) } label: { - settingsRow("sun.max") { Text("Appearance") } + settingsRow("sun.max", color: theme.colors.secondary) { Text("Appearance") } } .disabled(chatModel.chatRunning != true) } @@ -277,30 +351,33 @@ struct SettingsView: View { chatDatabaseRow() } - Section("Help") { + Section(header: Text("Help").foregroundColor(theme.colors.secondary)) { if let user = user { NavigationLink { ChatHelp(showSettings: $showSettings) .navigationTitle("Welcome \(user.displayName)!") + .modifier(ThemedBackground()) .frame(maxHeight: .infinity, alignment: .top) } label: { - settingsRow("questionmark") { Text("How to use it") } + settingsRow("questionmark", color: theme.colors.secondary) { Text("How to use it") } } } NavigationLink { WhatsNewView(viaSettings: true) + .modifier(ThemedBackground()) .navigationBarTitleDisplayMode(.inline) } label: { - settingsRow("plus") { Text("What's new") } + settingsRow("plus", color: theme.colors.secondary) { Text("What's new") } } NavigationLink { SimpleXInfo(onboarding: false) .navigationBarTitle("", displayMode: .inline) + .modifier(ThemedBackground()) .frame(maxHeight: .infinity, alignment: .top) } label: { - settingsRow("info") { Text("About SimpleX Chat") } + settingsRow("info", color: theme.colors.secondary) { Text("About SimpleX Chat") } } - settingsRow("number") { + settingsRow("number", color: theme.colors.secondary) { Button("Send questions and ideas") { showSettings = false DispatchQueue.main.async { @@ -309,12 +386,12 @@ struct SettingsView: View { } } .disabled(chatModel.chatRunning != true) - settingsRow("envelope") { Text("[Send us email](mailto:chat@simplex.chat)") } + settingsRow("envelope", color: theme.colors.secondary) { Text("[Send us email](mailto:chat@simplex.chat)") } } - Section("Support SimpleX Chat") { - settingsRow("keyboard") { Text("[Contribute](https://github.com/simplex-chat/simplex-chat#contribute)") } - settingsRow("star") { + Section(header: Text("Support SimpleX Chat").foregroundColor(theme.colors.secondary)) { + settingsRow("keyboard", color: theme.colors.secondary) { Text("[Contribute](https://github.com/simplex-chat/simplex-chat#contribute)") } + settingsRow("star", color: theme.colors.secondary) { Button("Rate the app") { if let scene = sceneDelegate.windowScene { SKStoreReviewController.requestReview(in: scene) @@ -326,27 +403,31 @@ struct SettingsView: View { .resizable() .frame(width: 24, height: 24) .opacity(0.5) + .colorMultiply(theme.colors.secondary) Text("[Star on GitHub](https://github.com/simplex-chat/simplex-chat)") .padding(.leading, indent) } } - Section("Develop") { + Section(header: Text("Develop").foregroundColor(theme.colors.secondary)) { NavigationLink { DeveloperView() .navigationTitle("Developer tools") + .modifier(ThemedBackground(grouped: true)) } label: { - settingsRow("chevron.left.forwardslash.chevron.right") { Text("Developer tools") } + settingsRow("chevron.left.forwardslash.chevron.right", color: theme.colors.secondary) { Text("Developer tools") } } NavigationLink { VersionView() .navigationBarTitle("App version") + .modifier(ThemedBackground()) } label: { Text("v\(appVersion ?? "?") (\(appBuild ?? "?"))") } } } .navigationTitle("Your settings") + .modifier(ThemedBackground(grouped: true)) } .onDisappear { chatModel.showingTerminal = false @@ -358,8 +439,9 @@ struct SettingsView: View { NavigationLink { DatabaseView(showSettings: $showSettings, chatItemTTL: chatModel.chatItemTTL) .navigationTitle("Your chat database") + .modifier(ThemedBackground(grouped: true)) } label: { - let color: Color = chatModel.chatDbEncrypted == false ? .orange : .secondary + let color: Color = chatModel.chatDbEncrypted == false ? .orange : theme.colors.secondary settingsRow("internaldrive", color: color) { HStack { Text("Database passphrase & export") @@ -390,13 +472,13 @@ struct SettingsView: View { switch (chatModel.tokenStatus) { case .new: icon = "bolt" - color = .secondary + color = theme.colors.secondary case .registered: icon = "bolt.fill" - color = .secondary + color = theme.colors.secondary case .invalid: icon = "bolt.slash" - color = .secondary + color = theme.colors.secondary case .confirmed: icon = "bolt.fill" color = .yellow @@ -405,10 +487,10 @@ struct SettingsView: View { color = .green case .expired: icon = "bolt.slash.fill" - color = .secondary + color = theme.colors.secondary case .none: icon = "bolt" - color = .secondary + color = theme.colors.secondary } return Image(systemName: icon) .padding(.trailing, 9) @@ -416,7 +498,7 @@ struct SettingsView: View { } } -func settingsRow(_ icon: String, color: Color = .secondary, content: @escaping () -> Content) -> some View { +func settingsRow(_ icon: String, color: Color/* = .secondary*/, content: @escaping () -> Content) -> some View { ZStack(alignment: .leading) { Image(systemName: icon).frame(maxWidth: 24, maxHeight: 24, alignment: .center) .symbolRenderingMode(.monochrome) @@ -427,7 +509,7 @@ func settingsRow(_ icon: String, color: Color = .secondary, cont struct ProfilePreview: View { var profileOf: NamedChat - var color = Color(uiColor: .tertiarySystemFill) + var color = Color(uiColor: .tertiarySystemGroupedBackground) var body: some View { HStack { diff --git a/apps/ios/Shared/Views/UserSettings/UserAddressView.swift b/apps/ios/Shared/Views/UserSettings/UserAddressView.swift index 96eeffd16d..a22a10cd9c 100644 --- a/apps/ios/Shared/Views/UserSettings/UserAddressView.swift +++ b/apps/ios/Shared/Views/UserSettings/UserAddressView.swift @@ -13,6 +13,7 @@ import SimpleXChat struct UserAddressView: View { @Environment(\.dismiss) var dismiss: DismissAction @EnvironmentObject private var chatModel: ChatModel + @EnvironmentObject var theme: AppTheme @State var viaCreateLinkView = false @State var shareViaProfile = false @State private var aas = AutoAcceptState() @@ -110,6 +111,7 @@ struct UserAddressView: View { createAddressButton() } footer: { Text("Create an address to let people connect with you.") + .foregroundColor(theme.colors.secondary) } Section { @@ -201,6 +203,7 @@ struct UserAddressView: View { learnMoreButton() } header: { Text("Address") + .foregroundColor(theme.colors.secondary) } if aas.enable { @@ -211,6 +214,7 @@ struct UserAddressView: View { deleteAddressButton() } footer: { Text("Your contacts will remain connected.") + .foregroundColor(theme.colors.secondary) } .id(bottomID) } @@ -251,7 +255,7 @@ struct UserAddressView: View { Button { showShareSheet(items: [simplexChatLink(userAddress.connReqContact)]) } label: { - settingsRow("square.and.arrow.up") { + settingsRow("square.and.arrow.up", color: theme.colors.secondary) { Text("Share address") } } @@ -261,7 +265,7 @@ struct UserAddressView: View { Button { showMailView = true } label: { - settingsRow("envelope") { + settingsRow("envelope", color: theme.colors.secondary) { Text("Invite friends") } } @@ -288,7 +292,7 @@ struct UserAddressView: View { } private func autoAcceptToggle() -> some View { - settingsRow("checkmark") { + settingsRow("checkmark", color: theme.colors.secondary) { Toggle("Auto-accept", isOn: $aas.enable) .onChange(of: aas.enable) { _ in saveAAS() @@ -300,16 +304,17 @@ struct UserAddressView: View { NavigationLink { UserAddressLearnMore() .navigationTitle("SimpleX address") + .modifier(ThemedBackground(grouped: true)) .navigationBarTitleDisplayMode(.large) } label: { - settingsRow("info.circle") { + settingsRow("info.circle", color: theme.colors.secondary) { Text("About SimpleX address") } } } private func shareWithContactsButton() -> some View { - settingsRow("person") { + settingsRow("person", color: theme.colors.secondary) { Toggle("Share with contacts", isOn: $shareViaProfile) .onChange(of: shareViaProfile) { on in if ignoreShareViaProfileChange { @@ -384,13 +389,14 @@ struct UserAddressView: View { .disabled(aas == savedAAS) } header: { Text("Auto-accept") + .foregroundColor(theme.colors.secondary) } } private func acceptIncognitoToggle() -> some View { settingsRow( aas.incognito ? "theatermasks.fill" : "theatermasks", - color: aas.incognito ? .indigo : .secondary + color: aas.incognito ? .indigo : theme.colors.secondary ) { Toggle("Accept incognito", isOn: $aas.incognito) } @@ -401,7 +407,7 @@ struct UserAddressView: View { Group { if aas.welcomeText.isEmpty { TextEditor(text: Binding.constant(NSLocalizedString("Enter welcome message… (optional)", comment: "placeholder"))) - .foregroundColor(.secondary) + .foregroundColor(theme.colors.secondary) .disabled(true) } TextEditor(text: $aas.welcomeText) diff --git a/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift b/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift index 5da7c8e877..13b9b2b097 100644 --- a/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift +++ b/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift @@ -8,6 +8,7 @@ import SimpleXChat struct UserProfilesView: View { @EnvironmentObject private var m: ChatModel + @EnvironmentObject private var theme: AppTheme @Binding var showSettings: Bool @Environment(\.editMode) private var editMode @AppStorage(DEFAULT_SHOW_HIDDEN_PROFILES_NOTICE) private var showHiddenProfilesNotice = true @@ -100,6 +101,7 @@ struct UserProfilesView: View { } } footer: { Text("Tap to activate profile.") + .foregroundColor(theme.colors.secondary) .font(.body) .padding(.top, 8) @@ -111,6 +113,7 @@ struct UserProfilesView: View { } } .navigationTitle("Your chat profiles") + .modifier(ThemedBackground(grouped: true)) .searchable(text: $searchTextOrPassword, placement: .navigationBarDrawer(displayMode: .always)) .autocorrectionDisabled(true) .textInputAutocapitalization(.never) @@ -210,7 +213,7 @@ struct UserProfilesView: View { actionHeader("Delete profile", user) Section { passwordField - settingsRow("trash") { + settingsRow("trash", color: theme.colors.secondary) { Button("Delete chat profile", role: .destructive) { profileAction = nil Task { await removeUser(user, delSMPQueues, viewPwd: actionPassword) } @@ -220,6 +223,7 @@ struct UserProfilesView: View { } footer: { if actionEnabled(user) { Text("All chats and messages will be deleted - this cannot be undone!") + .foregroundColor(theme.colors.secondary) .font(.callout) } } @@ -227,7 +231,7 @@ struct UserProfilesView: View { actionHeader("Unhide profile", user) Section { passwordField - settingsRow("lock.open") { + settingsRow("lock.open", color: theme.colors.secondary) { Button("Unhide chat profile") { profileAction = nil setUserPrivacy(user) { try await apiUnhideUser(user.userId, viewPwd: actionPassword) } @@ -237,6 +241,7 @@ struct UserProfilesView: View { } } } + .modifier(ThemedBackground()) } @ViewBuilder func actionHeader(_ title: LocalizedStringKey, _ user: User) -> some View { @@ -309,23 +314,23 @@ struct UserProfilesView: View { } } label: { HStack { - ProfileImage(imageStr: user.image, size: 44, color: Color(uiColor: .tertiarySystemFill)) + ProfileImage(imageStr: user.image, size: 44) .padding(.vertical, 4) .padding(.trailing, 12) Text(user.chatViewName) Spacer() if user.activeUser { - Image(systemName: "checkmark").foregroundColor(.primary) + Image(systemName: "checkmark").foregroundColor(theme.colors.onBackground) } else if user.hidden { - Image(systemName: "lock").foregroundColor(.secondary) + Image(systemName: "lock").foregroundColor(theme.colors.secondary) } else if !user.showNtfs { - Image(systemName: "speaker.slash").foregroundColor(.secondary) + Image(systemName: "speaker.slash").foregroundColor(theme.colors.secondary) } else { Image(systemName: "checkmark").foregroundColor(.clear) } } } - .foregroundColor(.primary) + .foregroundColor(theme.colors.onBackground) .swipeActions(edge: .leading, allowsFullSwipe: true) { if user.hidden { Button("Unhide") { @@ -356,7 +361,7 @@ struct UserProfilesView: View { } } } - .tint(.accentColor) + .tint(theme.colors.primary) } } if #available(iOS 16, *) { diff --git a/apps/ios/SimpleX NSE/NotificationService.swift b/apps/ios/SimpleX NSE/NotificationService.swift index 12094c7053..764415b1aa 100644 --- a/apps/ios/SimpleX NSE/NotificationService.swift +++ b/apps/ios/SimpleX NSE/NotificationService.swift @@ -439,8 +439,7 @@ func doStartChat() -> DBMigrationResult? { logger.debug("NotificationService active user \(String(describing: user))") do { try setNetworkConfig(networkConfig) - try apiSetTempFolder(tempFolder: getTempFilesDirectory().path) - try apiSetFilesFolder(filesFolder: getAppFilesDirectory().path) + try apiSetAppFilePaths(filesFolder: getAppFilesDirectory().path, tempFolder: getTempFilesDirectory().path, assetsFolder: getWallpaperDirectory().deletingLastPathComponent().path) try apiSetEncryptLocalFiles(privacyEncryptLocalFilesGroupDefault.get()) // prevent suspension while starting chat suspendLock.wait() @@ -660,14 +659,8 @@ func apiSuspendChat(timeoutMicroseconds: Int) -> Bool { return false } -func apiSetTempFolder(tempFolder: String) throws { - let r = sendSimpleXCmd(.setTempFolder(tempFolder: tempFolder)) - if case .cmdOk = r { return } - throw r -} - -func apiSetFilesFolder(filesFolder: String) throws { - let r = sendSimpleXCmd(.setFilesFolder(filesFolder: filesFolder)) +func apiSetAppFilePaths(filesFolder: String, tempFolder: String, assetsFolder: String) throws { + let r = sendSimpleXCmd(.apiSetAppFilePaths(filesFolder: filesFolder, tempFolder: tempFolder, assetsFolder: assetsFolder)) if case .cmdOk = r { return } throw r } diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 4a0dc23bff..f7ff222d28 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -181,9 +181,18 @@ 64F1CC3B28B39D8600CD1FB1 /* IncognitoHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F1CC3A28B39D8600CD1FB1 /* IncognitoHelp.swift */; }; 8C05382E2B39887E006436DC /* VideoUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C05382D2B39887E006436DC /* VideoUtils.swift */; }; 8C69FE7D2B8C7D2700267E38 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C69FE7C2B8C7D2700267E38 /* AppSettings.swift */; }; + 8C74C3E52C1B900600039E77 /* ThemeTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C7E3CE32C0DEAC400BFF63A /* ThemeTypes.swift */; }; + 8C74C3E72C1B901900039E77 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C852B072C1086D100BA61E8 /* Color.swift */; }; + 8C74C3E82C1B905B00039E77 /* ChatWallpaperTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C804B1D2C11F966007A63C8 /* ChatWallpaperTypes.swift */; }; + 8C74C3EA2C1B90AF00039E77 /* ThemeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C86EBE42C0DAE4F00E12243 /* ThemeManager.swift */; }; + 8C74C3EC2C1B92A900039E77 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C74C3EB2C1B92A900039E77 /* Theme.swift */; }; + 8C74C3EE2C1B942300039E77 /* ChatWallpaper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C74C3ED2C1B942300039E77 /* ChatWallpaper.swift */; }; 8C7D949A2B88952700B7B9E1 /* MigrateToDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C7D94992B88952700B7B9E1 /* MigrateToDevice.swift */; }; 8C7DF3202B7CDB0A00C886D0 /* MigrateFromDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C7DF31F2B7CDB0A00C886D0 /* MigrateFromDevice.swift */; }; + 8C7F8F0E2C19C0C100D16888 /* ViewModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C7F8F0D2C19C0C100D16888 /* ViewModifiers.swift */; }; + 8C8118722C220B5B00E6FC94 /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = 8C8118712C220B5B00E6FC94 /* Yams */; }; 8C81482C2BD91CD4002CBEC3 /* AudioDevicePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C81482B2BD91CD4002CBEC3 /* AudioDevicePicker.swift */; }; + 8C9BC2652C240D5200875A27 /* ThemeModeEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */; }; 8CC4ED902BD7B8530078AEE8 /* CallAudioDeviceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC4ED8F2BD7B8530078AEE8 /* CallAudioDeviceManager.swift */; }; 8CC956EE2BC0041000412A11 /* NetworkObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC956ED2BC0041000412A11 /* NetworkObserver.swift */; }; CEEA861D2C2ABCB50084E1EA /* ReverseList.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEEA861C2C2ABCB50084E1EA /* ReverseList.swift */; }; @@ -479,9 +488,17 @@ 64F1CC3A28B39D8600CD1FB1 /* IncognitoHelp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IncognitoHelp.swift; sourceTree = ""; }; 8C05382D2B39887E006436DC /* VideoUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoUtils.swift; sourceTree = ""; }; 8C69FE7C2B8C7D2700267E38 /* AppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettings.swift; sourceTree = ""; }; + 8C74C3EB2C1B92A900039E77 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; + 8C74C3ED2C1B942300039E77 /* ChatWallpaper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatWallpaper.swift; sourceTree = ""; }; 8C7D94992B88952700B7B9E1 /* MigrateToDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrateToDevice.swift; sourceTree = ""; }; 8C7DF31F2B7CDB0A00C886D0 /* MigrateFromDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrateFromDevice.swift; sourceTree = ""; }; + 8C7E3CE32C0DEAC400BFF63A /* ThemeTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeTypes.swift; sourceTree = ""; }; + 8C7F8F0D2C19C0C100D16888 /* ViewModifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModifiers.swift; sourceTree = ""; }; + 8C804B1D2C11F966007A63C8 /* ChatWallpaperTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatWallpaperTypes.swift; sourceTree = ""; }; 8C81482B2BD91CD4002CBEC3 /* AudioDevicePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioDevicePicker.swift; sourceTree = ""; }; + 8C852B072C1086D100BA61E8 /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = ""; }; + 8C86EBE42C0DAE4F00E12243 /* ThemeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManager.swift; sourceTree = ""; }; + 8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeModeEditor.swift; sourceTree = ""; }; 8CC4ED8F2BD7B8530078AEE8 /* CallAudioDeviceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallAudioDeviceManager.swift; sourceTree = ""; }; 8CC956ED2BC0041000412A11 /* NetworkObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkObserver.swift; sourceTree = ""; }; CEEA861C2C2ABCB50084E1EA /* ReverseList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReverseList.swift; sourceTree = ""; }; @@ -502,6 +519,7 @@ buildActionMask = 2147483647; files = ( 5CE2BA702845308900EC33A6 /* SimpleXChat.framework in Frameworks */, + 8C8118722C220B5B00E6FC94 /* Yams in Frameworks */, D741547829AF89AF0022400A /* StoreKit.framework in Frameworks */, D7197A1829AE89660055C05A /* WebRTC in Frameworks */, D77B92DC2952372200A5A1CC /* SwiftyGif in Frameworks */, @@ -662,6 +680,9 @@ 64C3B0202A0D359700E19930 /* CustomTimePicker.swift */, 5CEBD7452A5C0A8F00665FE2 /* KeyboardPadding.swift */, 8C05382D2B39887E006436DC /* VideoUtils.swift */, + 8C7F8F0D2C19C0C100D16888 /* ViewModifiers.swift */, + 8C74C3ED2C1B942300039E77 /* ChatWallpaper.swift */, + 8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */, ); path = Helpers; sourceTree = ""; @@ -686,6 +707,7 @@ 5CA059C2279559F40002BEB4 /* Shared */ = { isa = PBXGroup; children = ( + 8C74C3E92C1B909200039E77 /* Theme */, 5CA059C3279559F40002BEB4 /* SimpleXApp.swift */, 5C36027227F47AD5009F19D9 /* AppDelegate.swift */, 5CA059C4279559F40002BEB4 /* ContentView.swift */, @@ -823,6 +845,7 @@ 5CE2BA692845308900EC33A6 /* SimpleXChat */ = { isa = PBXGroup; children = ( + 8C86EBE32C0DAE3700E12243 /* Theme */, 5CDCAD5228186F9500503DA2 /* AppGroup.swift */, 5CDCAD7228188CFF00503DA2 /* ChatTypes.swift */, 5CDCAD7428188D2900503DA2 /* APITypes.swift */, @@ -916,6 +939,15 @@ path = Group; sourceTree = ""; }; + 8C74C3E92C1B909200039E77 /* Theme */ = { + isa = PBXGroup; + children = ( + 8C86EBE42C0DAE4F00E12243 /* ThemeManager.swift */, + 8C74C3EB2C1B92A900039E77 /* Theme.swift */, + ); + path = Theme; + sourceTree = ""; + }; 8C7D94982B8894D300B7B9E1 /* Migration */ = { isa = PBXGroup; children = ( @@ -925,6 +957,16 @@ path = Migration; sourceTree = ""; }; + 8C86EBE32C0DAE3700E12243 /* Theme */ = { + isa = PBXGroup; + children = ( + 8C7E3CE32C0DEAC400BFF63A /* ThemeTypes.swift */, + 8C852B072C1086D100BA61E8 /* Color.swift */, + 8C804B1D2C11F966007A63C8 /* ChatWallpaperTypes.swift */, + ); + path = Theme; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -963,6 +1005,7 @@ D77B92DB2952372200A5A1CC /* SwiftyGif */, D7F0E33829964E7E0068AF69 /* LZString */, D7197A1729AE89660055C05A /* WebRTC */, + 8C8118712C220B5B00E6FC94 /* Yams */, ); productName = "SimpleX (iOS)"; productReference = 5CA059CA279559F40002BEB4 /* SimpleX.app */; @@ -1083,6 +1126,7 @@ D77B92DA2952372200A5A1CC /* XCRemoteSwiftPackageReference "SwiftyGif" */, D7F0E33729964E7D0068AF69 /* XCRemoteSwiftPackageReference "lzstring-swift" */, D7197A1629AE89660055C05A /* XCRemoteSwiftPackageReference "WebRTC" */, + 8C73C1162C21E17B00892670 /* XCRemoteSwiftPackageReference "Yams" */, ); productRefGroup = 5CA059CB279559F40002BEB4 /* Products */; projectDirPath = ""; @@ -1156,6 +1200,7 @@ 5C93293129239BED0090FFF9 /* ProtocolServerView.swift in Sources */, 5C9CC7AD28C55D7800BEF955 /* DatabaseEncryptionView.swift in Sources */, 5CBD285A295711D700EC2CF4 /* ImageUtils.swift in Sources */, + 8C74C3EC2C1B92A900039E77 /* Theme.swift in Sources */, 6419EC562AB8BC8B004A607A /* ContextInvitingContactMemberView.swift in Sources */, 5CE4407927ADB701007B033A /* EmojiItemView.swift in Sources */, 8C7D949A2B88952700B7B9E1 /* MigrateToDevice.swift in Sources */, @@ -1187,6 +1232,7 @@ 5CB0BA90282713D900B3292C /* SimpleXInfo.swift in Sources */, 5C063D2727A4564100AEC577 /* ChatPreviewView.swift in Sources */, 5CC868F329EB540C0017BBFD /* CIRcvDecryptionError.swift in Sources */, + 8C7F8F0E2C19C0C100D16888 /* ViewModifiers.swift in Sources */, 5C35CFCB27B2E91D00FB6C6D /* NtfManager.swift in Sources */, 5C9D13A3282187BB00AB8B43 /* WebRTC.swift in Sources */, 5C9A5BDB2871E05400A5B906 /* SetNotificationsMode.swift in Sources */, @@ -1211,6 +1257,7 @@ 5CB346E72868D76D001FD2EF /* NotificationsView.swift in Sources */, 647F090E288EA27B00644C40 /* GroupMemberInfoView.swift in Sources */, 646BB38E283FDB6D001CE359 /* LocalAuthenticationUtils.swift in Sources */, + 8C74C3EA2C1B90AF00039E77 /* ThemeManager.swift in Sources */, 5C7505A227B65FDB00BE3227 /* CIMetaView.swift in Sources */, 5CEBD7462A5C0A8F00665FE2 /* KeyboardPadding.swift in Sources */, 5C35CFC827B2782E00FB6C6D /* BGManager.swift in Sources */, @@ -1228,6 +1275,7 @@ 6454036F2822A9750090DDFF /* ComposeFileView.swift in Sources */, 5C5DB70E289ABDD200730FFF /* AppearanceSettings.swift in Sources */, 5C5F2B6D27EBC3FE006A9D5F /* ImagePicker.swift in Sources */, + 8C74C3EE2C1B942300039E77 /* ChatWallpaper.swift in Sources */, 5C3CCFCC2AE6BD3100C3F0C3 /* ConnectDesktopView.swift in Sources */, 5C9C2DA92899DA6F00CC63B1 /* NetworkAndServers.swift in Sources */, 5C6BA667289BD954009B8ECC /* DismissSheets.swift in Sources */, @@ -1237,6 +1285,7 @@ 5CA059EB279559F40002BEB4 /* SimpleXApp.swift in Sources */, 64D0C2C029F9688300B38D5F /* UserAddressView.swift in Sources */, 6448BBB628FA9D56000D2AB9 /* GroupLinkView.swift in Sources */, + 8C9BC2652C240D5200875A27 /* ThemeModeEditor.swift in Sources */, 5CB346E92869E8BA001FD2EF /* PushEnvironment.swift in Sources */, 5C55A91F283AD0E400C4E99E /* CallManager.swift in Sources */, 5CFA59D12864782E00863A68 /* ChatArchiveView.swift in Sources */, @@ -1313,6 +1362,7 @@ 5C00168128C4FE760094D739 /* KeyChain.swift in Sources */, 5CE2BA97284537A800EC33A6 /* dummy.m in Sources */, 5CE2BA922845340900EC33A6 /* FileUtils.swift in Sources */, + 8C74C3E72C1B901900039E77 /* Color.swift in Sources */, 5CD67B902B0E858A00C510B1 /* hs_init.c in Sources */, 5CE2BA91284533A300EC33A6 /* Notifications.swift in Sources */, 5CE2BA79284530CC00EC33A6 /* SimpleXChat.docc in Sources */, @@ -1321,7 +1371,9 @@ 5CE2BA8F284533A300EC33A6 /* APITypes.swift in Sources */, 5C9D811A2AA8727A001D49FD /* CryptoFile.swift in Sources */, 5CE2BA8C284533A300EC33A6 /* AppGroup.swift in Sources */, + 8C74C3E52C1B900600039E77 /* ThemeTypes.swift in Sources */, 5CE2BA8D284533A300EC33A6 /* CallTypes.swift in Sources */, + 8C74C3E82C1B905B00039E77 /* ChatWallpaperTypes.swift in Sources */, 5CE2BA8E284533A300EC33A6 /* API.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1919,6 +1971,14 @@ minimumVersion = 2.0.0; }; }; + 8C73C1162C21E17B00892670 /* XCRemoteSwiftPackageReference "Yams" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/jpsim/Yams"; + requirement = { + kind = exactVersion; + version = 5.1.2; + }; + }; D7197A1629AE89660055C05A /* XCRemoteSwiftPackageReference "WebRTC" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/simplex-chat/WebRTC.git"; @@ -1951,6 +2011,11 @@ package = 5C8F01CB27A6F0D8007D2C8D /* XCRemoteSwiftPackageReference "CodeScanner" */; productName = CodeScanner; }; + 8C8118712C220B5B00E6FC94 /* Yams */ = { + isa = XCSwiftPackageProductDependency; + package = 8C73C1162C21E17B00892670 /* XCRemoteSwiftPackageReference "Yams" */; + productName = Yams; + }; D7197A1729AE89660055C05A /* WebRTC */ = { isa = XCSwiftPackageProductDependency; package = D7197A1629AE89660055C05A /* XCRemoteSwiftPackageReference "WebRTC" */; diff --git a/apps/ios/SimpleX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/apps/ios/SimpleX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index cfacb2381a..d3e61c88f9 100644 --- a/apps/ios/SimpleX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/apps/ios/SimpleX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,4 +1,5 @@ { + "originHash" : "e2611d1e91fd8071abc106776ba14ee2e395d2ad08a78e073381294abc10f115", "pins" : [ { "identity" : "codescanner", @@ -33,7 +34,16 @@ "state" : { "revision" : "34bedc50f9c58dccf4967ea59c7e6a47d620803b" } + }, + { + "identity" : "yams", + "kind" : "remoteSourceControl", + "location" : "https://github.com/jpsim/Yams", + "state" : { + "revision" : "9234124cff5e22e178988c18d8b95a8ae8007f76", + "version" : "5.1.2" + } } ], - "version" : 2 + "version" : 3 } diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index c5c35c1d1c..2d3663b9f8 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -8,6 +8,7 @@ import Foundation import SwiftUI +import Yams public let jsonDecoder = getJSONDecoder() public let jsonEncoder = getJSONEncoder() @@ -29,8 +30,7 @@ public enum ChatCommand { case apiStopChat case apiActivateChat(restoreChat: Bool) case apiSuspendChat(timeoutMicroseconds: Int) - case setTempFolder(tempFolder: String) - case setFilesFolder(filesFolder: String) + case apiSetAppFilePaths(filesFolder: String, tempFolder: String, assetsFolder: String) case apiSetEncryptLocalFiles(enable: Bool) case apiExportArchive(config: ArchiveConfig) case apiImportArchive(config: ArchiveConfig) @@ -107,6 +107,8 @@ public enum ChatCommand { case apiSetContactPrefs(contactId: Int64, preferences: Preferences) case apiSetContactAlias(contactId: Int64, localAlias: String) case apiSetConnectionAlias(connId: Int64, localAlias: String) + case apiSetUserUIThemes(userId: Int64, themes: ThemeModeOverrides?) + case apiSetChatUIThemes(chatId: String, themes: ThemeModeOverrides?) case apiCreateMyAddress(userId: Int64) case apiDeleteMyAddress(userId: Int64) case apiShowMyAddress(userId: Int64) @@ -173,8 +175,7 @@ public enum ChatCommand { case .apiStopChat: return "/_stop" case let .apiActivateChat(restore): return "/_app activate restore=\(onOff(restore))" case let .apiSuspendChat(timeoutMicroseconds): return "/_app suspend \(timeoutMicroseconds)" - case let .setTempFolder(tempFolder): return "/_temp_folder \(tempFolder)" - case let .setFilesFolder(filesFolder): return "/_files_folder \(filesFolder)" + case let .apiSetAppFilePaths(filesFolder, tempFolder, assetsFolder): return "/set file paths \(encodeJSON(AppFilePaths(appFilesFolder: filesFolder, appTempFolder: tempFolder, appAssetsFolder: assetsFolder)))" case let .apiSetEncryptLocalFiles(enable): return "/_files_encrypt \(onOff(enable))" case let .apiExportArchive(cfg): return "/_db export \(encodeJSON(cfg))" case let .apiImportArchive(cfg): return "/_db import \(encodeJSON(cfg))" @@ -273,6 +274,8 @@ public enum ChatCommand { case let .apiSetContactPrefs(contactId, preferences): return "/_set prefs @\(contactId) \(encodeJSON(preferences))" case let .apiSetContactAlias(contactId, localAlias): return "/_set alias @\(contactId) \(localAlias.trimmingCharacters(in: .whitespaces))" case let .apiSetConnectionAlias(connId, localAlias): return "/_set alias :\(connId) \(localAlias.trimmingCharacters(in: .whitespaces))" + case let .apiSetUserUIThemes(userId, themes): return "/_set theme user \(userId) \(themes != nil ? encodeJSON(themes) : "")" + case let .apiSetChatUIThemes(chatId, themes): return "/_set theme \(chatId) \(themes != nil ? encodeJSON(themes) : "")" case let .apiCreateMyAddress(userId): return "/_address \(userId)" case let .apiDeleteMyAddress(userId): return "/_delete_address \(userId)" case let .apiShowMyAddress(userId): return "/_show_address \(userId)" @@ -332,8 +335,7 @@ public enum ChatCommand { case .apiStopChat: return "apiStopChat" case .apiActivateChat: return "apiActivateChat" case .apiSuspendChat: return "apiSuspendChat" - case .setTempFolder: return "setTempFolder" - case .setFilesFolder: return "setFilesFolder" + case .apiSetAppFilePaths: return "apiSetAppFilePaths" case .apiSetEncryptLocalFiles: return "apiSetEncryptLocalFiles" case .apiExportArchive: return "apiExportArchive" case .apiImportArchive: return "apiImportArchive" @@ -410,6 +412,8 @@ public enum ChatCommand { case .apiSetContactPrefs: return "apiSetContactPrefs" case .apiSetContactAlias: return "apiSetContactAlias" case .apiSetConnectionAlias: return "apiSetConnectionAlias" + case .apiSetUserUIThemes: return "apiSetUserUIThemes" + case .apiSetChatUIThemes: return "apiSetChatUIThemes" case .apiCreateMyAddress: return "apiCreateMyAddress" case .apiDeleteMyAddress: return "apiDeleteMyAddress" case .apiShowMyAddress: return "apiShowMyAddress" @@ -863,7 +867,7 @@ public enum ChatResponse: Decodable, Error { case let .contactInfo(u, contact, connectionStats_, customUserProfile): return withUser(u, "contact: \(String(describing: contact))\nconnectionStats_: \(String(describing: connectionStats_))\ncustomUserProfile: \(String(describing: customUserProfile))") case let .groupMemberInfo(u, groupInfo, member, connectionStats_): return withUser(u, "groupInfo: \(String(describing: groupInfo))\nmember: \(String(describing: member))\nconnectionStats_: \(String(describing: connectionStats_))") case let .queueInfo(u, rcvMsgInfo, queueInfo): - let msgInfo = if let info = rcvMsgInfo { encodeJSON(rcvMsgInfo) } else { "none" } + let msgInfo = if let info = rcvMsgInfo { encodeJSON(info) } else { "none" } return withUser(u, "rcvMsgInfo: \(msgInfo)\nqueueInfo: \(encodeJSON(queueInfo))") case let .contactSwitchStarted(u, contact, connectionStats): return withUser(u, "contact: \(String(describing: contact))\nconnectionStats: \(String(describing: connectionStats))") case let .groupMemberSwitchStarted(u, groupInfo, member, connectionStats): return withUser(u, "groupInfo: \(String(describing: groupInfo))\nmember: \(String(describing: member))\nconnectionStats: \(String(describing: connectionStats))") @@ -2093,6 +2097,11 @@ public struct AppSettings: Codable, Equatable, Hashable { public var androidCallOnLockScreen: AppSettingsLockScreenCalls? = nil public var iosCallKitEnabled: Bool? = nil public var iosCallKitCallsInRecents: Bool? = nil + public var uiProfileImageCornerRadius: Float? = nil + public var uiColorScheme: String? = nil + public var uiDarkColorScheme: String? = nil + public var uiCurrentThemeIds: [String: String]? = nil + public var uiThemes: [ThemeOverrides]? = nil public func prepareForExport() -> AppSettings { var empty = AppSettings() @@ -2117,6 +2126,11 @@ public struct AppSettings: Codable, Equatable, Hashable { if androidCallOnLockScreen != def.androidCallOnLockScreen { empty.androidCallOnLockScreen = androidCallOnLockScreen } if iosCallKitEnabled != def.iosCallKitEnabled { empty.iosCallKitEnabled = iosCallKitEnabled } if iosCallKitCallsInRecents != def.iosCallKitCallsInRecents { empty.iosCallKitCallsInRecents = iosCallKitCallsInRecents } + if uiProfileImageCornerRadius != def.uiProfileImageCornerRadius { empty.uiProfileImageCornerRadius = uiProfileImageCornerRadius } + if uiColorScheme != def.uiColorScheme { empty.uiColorScheme = uiColorScheme } + if uiDarkColorScheme != def.uiDarkColorScheme { empty.uiDarkColorScheme = uiDarkColorScheme } + if uiCurrentThemeIds != def.uiCurrentThemeIds { empty.uiCurrentThemeIds = uiCurrentThemeIds } + if uiThemes != def.uiThemes { empty.uiThemes = uiThemes } return empty } @@ -2141,7 +2155,12 @@ public struct AppSettings: Codable, Equatable, Hashable { confirmDBUpgrades: false, androidCallOnLockScreen: AppSettingsLockScreenCalls.show, iosCallKitEnabled: true, - iosCallKitCallsInRecents: false + iosCallKitCallsInRecents: false, + uiProfileImageCornerRadius: 22.5, + uiColorScheme: DefaultTheme.SYSTEM_THEME_NAME, + uiDarkColorScheme: DefaultTheme.SIMPLEX.themeName, + uiCurrentThemeIds: nil as [String: String]?, + uiThemes: nil as [ThemeOverrides]? ) } } @@ -2247,6 +2266,12 @@ public enum MsgType: String, Codable, Hashable { case quota } +public struct AppFilePaths: Encodable { + public let appFilesFolder: String + public let appTempFolder: String + public let appAssetsFolder: String +} + public struct PresentedServersSummary: Codable { public var statsStartedAt: Date public var allUsersSMP: SMPServersSummary diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index 46cb384a58..eb92deb4e9 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -27,6 +27,7 @@ public struct User: Identifiable, Decodable, UserLike, NamedChat, Hashable { public var sendRcptsContacts: Bool public var sendRcptsSmallGroups: Bool public var viewPwdHash: UserPwdHash? + public var uiThemes: ThemeModeOverrides? public var id: Int64 { userId } @@ -523,8 +524,8 @@ public struct FeatureEnabled: Decodable, Hashable { : NSLocalizedString("off", comment: "enabled status") } - public var iconColor: Color { - forUser ? .green : forContact ? .yellow : .secondary + public func iconColor(_ secondaryColor: Color) -> Color { + forUser ? .green : forContact ? .yellow : secondaryColor } } @@ -1152,10 +1153,10 @@ public enum GroupFeatureEnabled: String, Codable, Identifiable, Hashable { } } - public var iconColor: Color { + public func iconColor(_ secondaryColor: Color) -> Color { switch self { case .on: return .green - case .off: return .secondary + case .off: return secondaryColor } } } @@ -1506,6 +1507,7 @@ public struct Contact: Identifiable, Decodable, NamedChat, Hashable { var chatTs: Date? var contactGroupMemberId: Int64? var contactGrpInvSent: Bool + public var uiThemes: ThemeModeOverrides? public var id: ChatId { get { "@\(contactId)" } } public var apiId: Int64 { get { contactId } } @@ -1845,6 +1847,7 @@ public struct GroupInfo: Identifiable, Decodable, NamedChat, Hashable { var createdAt: Date var updatedAt: Date var chatTs: Date? + public var uiThemes: ThemeModeOverrides? public var id: ChatId { get { "#\(groupId)" } } public var apiId: Int64 { get { groupId } } @@ -2655,8 +2658,8 @@ public struct CIMeta: Decodable, Hashable { return false } - public func statusIcon(_ metaColor: Color = .secondary) -> (String, Color)? { - itemStatus.statusIcon(metaColor) + public func statusIcon(_ metaColor: Color/* = .secondary*/, _ primaryColor: Color = .accentColor) -> (String, Color)? { + itemStatus.statusIcon(metaColor, primaryColor) } public static func getSample(_ id: Int64, _ ts: Date, _ text: String, _ status: CIStatus = .sndNew, itemDeleted: CIDeleted? = nil, itemEdited: Bool = false, itemLive: Bool = false, deletable: Bool = true, editable: Bool = true) -> CIMeta { @@ -2744,7 +2747,7 @@ public enum CIStatus: Decodable, Hashable { } } - public func statusIcon(_ metaColor: Color = .secondary) -> (String, Color)? { + public func statusIcon(_ metaColor: Color/* = .secondary*/, _ primaryColor: Color = .accentColor) -> (String, Color)? { switch self { case .sndNew: return nil case .sndSent: return ("checkmark", metaColor) @@ -2756,7 +2759,7 @@ public enum CIStatus: Decodable, Hashable { case .sndErrorAuth: return ("multiply", .red) case .sndError: return ("multiply", .red) case .sndWarning: return ("exclamationmark.triangle.fill", .orange) - case .rcvNew: return ("circlebadge.fill", Color.accentColor) + case .rcvNew: return ("circlebadge.fill", primaryColor) case .rcvRead: return nil case .invalid: return ("questionmark", metaColor) } diff --git a/apps/ios/SimpleXChat/FileUtils.swift b/apps/ios/SimpleXChat/FileUtils.swift index 125600f3f3..8b0d082aed 100644 --- a/apps/ios/SimpleXChat/FileUtils.swift +++ b/apps/ios/SimpleXChat/FileUtils.swift @@ -8,6 +8,7 @@ import Foundation import OSLog +import UIKit let logger = Logger() @@ -85,6 +86,8 @@ public func deleteAppDatabaseAndFiles() { try? fm.removeItem(at: getTempFilesDirectory()) try? fm.removeItem(at: getMigrationTempFilesDirectory()) try? fm.createDirectory(at: getTempFilesDirectory(), withIntermediateDirectories: true) + try? fm.removeItem(at: getWallpaperDirectory()) + try? fm.createDirectory(at: getWallpaperDirectory(), withIntermediateDirectories: true) deleteAppFiles() _ = kcDatabasePassword.remove() storeDBPassphraseGroupDefault.set(true) @@ -196,6 +199,14 @@ public func getAppFilePath(_ fileName: String) -> URL { getAppFilesDirectory().appendingPathComponent(fileName) } +public func getWallpaperDirectory() -> URL { + getAppDirectory().appendingPathComponent("assets", isDirectory: true).appendingPathComponent("wallpapers", isDirectory: true) +} + +public func getWallpaperFilePath(_ filename: String) -> URL { + getWallpaperDirectory().appendingPathComponent(filename) +} + public func saveFile(_ data: Data, _ fileName: String, encrypted: Bool) -> CryptoFile? { let filePath = getAppFilePath(fileName) do { diff --git a/apps/ios/SimpleXChat/Theme/ChatWallpaperTypes.swift b/apps/ios/SimpleXChat/Theme/ChatWallpaperTypes.swift new file mode 100644 index 0000000000..662f8b43d1 --- /dev/null +++ b/apps/ios/SimpleXChat/Theme/ChatWallpaperTypes.swift @@ -0,0 +1,402 @@ +// +// ChatWallpaper.swift +// SimpleX (iOS) +// +// Created by Avently on 06.06.2024. +// Copyright © 2024 SimpleX Chat. All rights reserved. +// + +import Foundation +import SwiftUI + +public enum PresetWallpaper: CaseIterable { + case cats + case flowers + case hearts + case kids + case school + case travel + + var res: UIImage { + UIImage(named: "wallpaper_\(filename)")! + } + + public var filename: String { + switch self { + case .cats: "cats" + case .flowers: "flowers" + case .hearts: "hearts" + case .kids: "kids" + case .school: "school" + case .travel: "travel" + } + } + + public var scale: Float { + switch self { + case .cats: 0.63 + case .flowers: 0.53 + case .hearts: 0.59 + case .kids: 0.53 + case .school: 0.53 + case .travel: 0.68 + } + } + + public var background: [DefaultTheme: Color] { + switch self { + case .cats: wallpaperBackgrounds(light: "#ffF8F6EA") + case .flowers: wallpaperBackgrounds(light: "#ffE2FFE4") + case .hearts: wallpaperBackgrounds(light: "#ffFDECEC") + case .kids: wallpaperBackgrounds(light: "#ffdbfdfb") + case .school: wallpaperBackgrounds(light: "#ffE7F5FF") + case .travel: wallpaperBackgrounds(light: "#fff9eeff") + } + } + + public var tint: [DefaultTheme: Color] { + switch self { + case .cats: [ + DefaultTheme.LIGHT: "#ffefdca6".colorFromReadableHex(), + DefaultTheme.DARK: "#ff4b3b0e".colorFromReadableHex(), + DefaultTheme.SIMPLEX: "#ff51400f".colorFromReadableHex(), + DefaultTheme.BLACK: "#ff4b3b0e".colorFromReadableHex() + ] + case .flowers: [ + DefaultTheme.LIGHT: "#ff9CEA59".colorFromReadableHex(), + DefaultTheme.DARK: "#ff31560D".colorFromReadableHex(), + DefaultTheme.SIMPLEX: "#ff36600f".colorFromReadableHex(), + DefaultTheme.BLACK: "#ff31560D".colorFromReadableHex() + ] + case .hearts: [ + DefaultTheme.LIGHT: "#fffde0e0".colorFromReadableHex(), + DefaultTheme.DARK: "#ff3c0f0f".colorFromReadableHex(), + DefaultTheme.SIMPLEX: "#ff411010".colorFromReadableHex(), + DefaultTheme.BLACK: "#ff3C0F0F".colorFromReadableHex() + ] + case .kids: [ + DefaultTheme.LIGHT: "#ffadeffc".colorFromReadableHex(), + DefaultTheme.DARK: "#ff16404B".colorFromReadableHex(), + DefaultTheme.SIMPLEX: "#ff184753".colorFromReadableHex(), + DefaultTheme.BLACK: "#ff16404B".colorFromReadableHex() + ] + case .school: [ + DefaultTheme.LIGHT: "#ffCEEBFF".colorFromReadableHex(), + DefaultTheme.DARK: "#ff0F293B".colorFromReadableHex(), + DefaultTheme.SIMPLEX: "#ff112f43".colorFromReadableHex(), + DefaultTheme.BLACK: "#ff0F293B".colorFromReadableHex() + ] + case .travel: [ + DefaultTheme.LIGHT: "#ffeedbfe".colorFromReadableHex(), + DefaultTheme.DARK: "#ff311E48".colorFromReadableHex(), + DefaultTheme.SIMPLEX: "#ff35204e".colorFromReadableHex(), + DefaultTheme.BLACK: "#ff311E48".colorFromReadableHex() + ] + } + } + + public var colors: [DefaultTheme: ThemeColors] { + switch self { + case .cats: [ + DefaultTheme.LIGHT: ThemeColors.from( + sentMessage: "#fffffaed", + sentQuote: "#fffaf0d6", + receivedMessage: "#ffF8F7F4", + receivedQuote: "#ffefede9" + ), + DefaultTheme.DARK: ThemeColors.from( + sentMessage: "#ff2f2919", + sentQuote: "#ff473a1d", + receivedMessage: "#ff272624", + receivedQuote: "#ff373633" + ), + DefaultTheme.SIMPLEX: ThemeColors.from( + sentMessage: "#ff41371b", + sentQuote: "#ff654f1c", + receivedMessage: "#ff272624", + receivedQuote: "#ff373633" + ), + DefaultTheme.BLACK: ThemeColors.from( + sentMessage: "#ff41371b", + sentQuote: "#ff654f1c", + receivedMessage: "#ff1f1e1b", + receivedQuote: "#ff2f2d27" + ) + ] + case .flowers: [ + DefaultTheme.LIGHT: ThemeColors.from( + sentMessage: "#fff1ffe5", + sentQuote: "#ffdcf9c4", + receivedMessage: "#ffF4F8F2", + receivedQuote: "#ffe7ece7" + ), + DefaultTheme.DARK: ThemeColors.from( + sentMessage: "#ff163521", + sentQuote: "#ff1B5330", + receivedMessage: "#ff242523", + receivedQuote: "#ff353733" + ), + DefaultTheme.SIMPLEX: ThemeColors.from( + sentMessage: "#ff184739", + sentQuote: "#ff1F6F4B", + receivedMessage: "#ff242523", + receivedQuote: "#ff353733" + ), + DefaultTheme.BLACK: ThemeColors.from( + sentMessage: "#ff184739", + sentQuote: "#ff1F6F4B", + receivedMessage: "#ff1c1f1a", + receivedQuote: "#ff282b25" + ) + ] + case .hearts: [ + DefaultTheme.LIGHT: ThemeColors.from( + sentMessage: "#fffff4f4", + sentQuote: "#ffffdfdf", + receivedMessage: "#fff8f6f6", + receivedQuote: "#ffefebeb" + ), + DefaultTheme.DARK: ThemeColors.from( + sentMessage: "#ff301515", + sentQuote: "#ff4C1818", + receivedMessage: "#ff242121", + receivedQuote: "#ff3b3535" + ), + DefaultTheme.SIMPLEX: ThemeColors.from( + sentMessage: "#ff491A28", + sentQuote: "#ff761F29", + receivedMessage: "#ff242121", + receivedQuote: "#ff3b3535" + ), + DefaultTheme.BLACK: ThemeColors.from( + sentMessage: "#ff491A28", + sentQuote: "#ff761F29", + receivedMessage: "#ff1f1b1b", + receivedQuote: "#ff2e2626" + ) + ] + case .kids: [ + DefaultTheme.LIGHT: ThemeColors.from( + sentMessage: "#ffeafeff", + sentQuote: "#ffcbf4f7", + receivedMessage: "#fff3fafa", + receivedQuote: "#ffe4efef" + ), + DefaultTheme.DARK: ThemeColors.from( + sentMessage: "#ff16302F", + sentQuote: "#ff1a4a49", + receivedMessage: "#ff252626", + receivedQuote: "#ff373A39" + ), + DefaultTheme.SIMPLEX: ThemeColors.from( + sentMessage: "#ff1a4745", + sentQuote: "#ff1d6b69", + receivedMessage: "#ff252626", + receivedQuote: "#ff373a39" + ), + DefaultTheme.BLACK: ThemeColors.from( + sentMessage: "#ff1a4745", + sentQuote: "#ff1d6b69", + receivedMessage: "#ff1e1f1f", + receivedQuote: "#ff262b29" + ) + ] + case .school: [ + DefaultTheme.LIGHT: ThemeColors.from( + sentMessage: "#ffeef9ff", + sentQuote: "#ffD6EDFA", + receivedMessage: "#ffF3F5F9", + receivedQuote: "#ffe4e8ee" + ), + DefaultTheme.DARK: ThemeColors.from( + sentMessage: "#ff172833", + sentQuote: "#ff1C3E4F", + receivedMessage: "#ff26282c", + receivedQuote: "#ff393c40" + ), + DefaultTheme.SIMPLEX: ThemeColors.from( + sentMessage: "#ff1A3C5D", + sentQuote: "#ff235b80", + receivedMessage: "#ff26282c", + receivedQuote: "#ff393c40" + ), + DefaultTheme.BLACK: ThemeColors.from( + sentMessage: "#ff1A3C5D", + sentQuote: "#ff235b80", + receivedMessage: "#ff1d1e22", + receivedQuote: "#ff292b2f" + ) + ] + case .travel: [ + DefaultTheme.LIGHT: ThemeColors.from( + sentMessage: "#fffcf6ff", + sentQuote: "#fff2e0fc", + receivedMessage: "#ffF6F4F7", + receivedQuote: "#ffede9ee" + ), + DefaultTheme.DARK: ThemeColors.from( + sentMessage: "#ff33263B", + sentQuote: "#ff53385E", + receivedMessage: "#ff272528", + receivedQuote: "#ff3B373E" + ), + DefaultTheme.SIMPLEX: ThemeColors.from( + sentMessage: "#ff3C255D", + sentQuote: "#ff623485", + receivedMessage: "#ff26273B", + receivedQuote: "#ff3A394F" + ), + DefaultTheme.BLACK: ThemeColors.from( + sentMessage: "#ff3C255D", + sentQuote: "#ff623485", + receivedMessage: "#ff231f23", + receivedQuote: "#ff2c2931" + ) + ] + } + } + + public static func from(_ filename: String) -> PresetWallpaper? { + switch filename { + case PresetWallpaper.cats.filename: PresetWallpaper.cats + case PresetWallpaper.flowers.filename: PresetWallpaper.flowers + case PresetWallpaper.hearts.filename: PresetWallpaper.hearts + case PresetWallpaper.kids.filename: PresetWallpaper.kids + case PresetWallpaper.school.filename: PresetWallpaper.school + case PresetWallpaper.travel.filename: PresetWallpaper.travel + default: nil + } + } +} + +func wallpaperBackgrounds(light: String) -> [DefaultTheme : Color] { + [ + DefaultTheme.LIGHT: light.colorFromReadableHex(), + DefaultTheme.DARK: "#ff121212".colorFromReadableHex(), + DefaultTheme.SIMPLEX: "#ff111528".colorFromReadableHex(), + DefaultTheme.BLACK: "#ff070707".colorFromReadableHex() + ] +} + +public enum WallpaperScaleType: String, Codable, CaseIterable { + case fill + case fit + case `repeat` + + public var text: String { + switch self { + case .fill: "Fill" + case .fit: "Fit" + case .repeat: "Repeat" + } + } + + public func computeScaleFactor(_ srcSize: CGSize, _ dstSize: CGSize) -> (CGFloat, CGFloat) { + switch self { + case .fill: + let widthScale = dstSize.width / srcSize.width + let heightScale = dstSize.height / srcSize.height + return (max(widthScale, heightScale), max(widthScale, heightScale)) + case .fit: fallthrough + case .repeat: + let widthScale = dstSize.width / srcSize.width + let heightScale = dstSize.height / srcSize.height + return (min(widthScale, heightScale), min(widthScale, heightScale)) + } + } +} + +public enum WallpaperType: Equatable { + public var image: SwiftUI.Image? { + if let uiImage { + return SwiftUI.Image(uiImage: uiImage) + } + return nil + } + + public var uiImage: UIImage? { + let filename: String + switch self { + case let .preset(f, _): filename = f + case let .image(f, _, _): filename = f + default: return nil + } + if filename == "" { return nil } + if let image = WallpaperType.cachedImages[filename] { + return image + } else { + let res: UIImage? + if case let .preset(filename, _) = self { + res = (PresetWallpaper.from(filename) ?? PresetWallpaper.cats).res + } else { + // In case of unintentional image deletion don't crash the app + res = UIImage(contentsOfFile: getWallpaperFilePath(filename).path) + } + if let res { + WallpaperType.cachedImages[filename] = res + } + return res + } + } + + public func sameType(_ other: WallpaperType?) -> Bool { + if case let .preset(filename, _) = self, case let .preset(otherFilename, _) = other { filename == otherFilename } + else if case .image = self, case .image = other { true } + else if case .empty = self, case .empty = other { true } + else { false } + } + + public var isPreset: Bool { switch self { case .preset: true; default: false } } + + public var isImage: Bool { switch self { case .image: true; default: false } } + + public var isEmpty: Bool { switch self { case .empty: true; default: false } } + + public var scale: Float { + switch self { + case let .preset(_, scale): scale ?? 1 + case let .image(_, scale, _): scale ?? 1 + case .empty: 1 + } + } + + public func samePreset(other: PresetWallpaper?) -> Bool { if case let .preset(filename, _) = self, filename == other?.filename { true } else { false } } + + case preset(_ filename: String, _ scale: Float?) + + case image(_ filename: String, _ scale: Float?, _ scaleType: WallpaperScaleType?) + + case empty + + public func defaultBackgroundColor(_ theme: DefaultTheme, _ themeBackground: Color) -> Color { + if case let .preset(filename, _) = self { + (PresetWallpaper.from(filename) ?? PresetWallpaper.cats).background[theme]! + } else { + themeBackground + } + } + + public func defaultTintColor(_ theme: DefaultTheme) -> Color { + if case let .preset(filename, _) = self { + (PresetWallpaper.from(filename) ?? PresetWallpaper.cats).tint[theme]! + } else if case let .image(_, _, scaleType) = self, scaleType == WallpaperScaleType.repeat { + Color.clear + } else { + Color.clear + } + } + + public static var cachedImages: [String: UIImage] = [:] + + public static func from(_ wallpaper: ThemeWallpaper?) -> WallpaperType? { + if wallpaper == nil { + return nil + } else if let preset = wallpaper?.preset { + return WallpaperType.preset(preset, wallpaper?.scale) + } else if let imageFile = wallpaper?.imageFile { + return WallpaperType.image(imageFile, wallpaper?.scale, wallpaper?.scaleType) + } else { + return WallpaperType.empty + } + } +} diff --git a/apps/ios/SimpleXChat/Theme/Color.swift b/apps/ios/SimpleXChat/Theme/Color.swift new file mode 100644 index 0000000000..3e8fe1b6e7 --- /dev/null +++ b/apps/ios/SimpleXChat/Theme/Color.swift @@ -0,0 +1,114 @@ +// +// Color.swift +// SimpleX (iOS) +// +// Created by Avently on 05.06.2024. +// Copyright © 2024 SimpleX Chat. All rights reserved. +// + +import Foundation +import SwiftUI + +//let Purple200 = Color(0xFFBB86FC) +//let Purple500 = Color(0xFF6200EE) +//let Purple700 = Color(0xFF3700B3) +//let Teal200 = Color(0xFF03DAC5) +//let Gray = Color(0x22222222) +//let Indigo = Color(0xFF9966FF) +let SimplexBlue = Color(0, 136, 255, a: 255) +//let SimplexGreen = Color(77, 218, 103, a: 255) +//let SecretColor = Color(0x40808080) +let LightGray = Color(241, 242, 246, a: 255) +let DarkGray = Color(43, 44, 46, a: 255) +let HighOrLowlight = Color(139, 135, 134, a: 255) +//let MessagePreviewDark = Color(179, 175, 174, a: 255) +//let MessagePreviewLight = Color(49, 45, 44, a: 255) +//let ToolbarLight = Color(220, 220, 220, a: 12) +//let ToolbarDark = Color(80, 80, 80, a: 12) +//let SettingsSecondaryLight = Color(200, 196, 195, a: 90) +//let GroupDark = Color(80, 80, 80, a: 60) +//let IncomingCallLight = Color(239, 237, 236, a: 255) +//let WarningOrange = Color(255, 127, 0, a: 255) +//let WarningYellow = Color(255, 192, 0, a: 255) +//let FileLight = Color(183, 190, 199, a: 255) +//let FileDark = Color(101, 101, 106, a: 255) + +extension Color { + public init(_ argb: Int64) { + let a = Double((argb & 0xFF000000) >> 24) / 255.0 + let r = Double((argb & 0xFF0000) >> 16) / 255.0 + let g = Double((argb & 0xFF00) >> 8) / 255.0 + let b = Double((argb & 0xFF)) / 255.0 + self.init(.sRGB, red: r, green: g, blue: b, opacity: a) + } + + public init(_ r: Int, _ g: Int, _ b: Int, a: Int) { + self.init(.sRGB, red: Double(r) / 255.0, green: Double(g) / 255.0, blue: Double(b) / 255.0, opacity: Double(a) / 255.0) + } + + public func toReadableHex() -> String { + let uiColor: UIColor = .init(self) + var (r, g, b, a): (CGFloat, CGFloat, CGFloat, CGFloat) = (0, 0, 0, 0) + uiColor.getRed(&r, green: &g, blue: &b, alpha: &a) + // Can be negative values and more than 1. Extended color range, making it normal + r = min(1, max(0, r)) + g = min(1, max(0, g)) + b = min(1, max(0, b)) + a = min(1, max(0, a)) + return String(format: "#%02x%02x%02x%02x", + Int((a * 255).rounded()), + Int((r * 255).rounded()), + Int((g * 255).rounded()), + Int((b * 255).rounded()) + ) + } + + public func darker(_ factor: CGFloat = 0.1) -> Color { + var (r, g, b, a): (CGFloat, CGFloat, CGFloat, CGFloat) = (0, 0, 0, 0) + UIColor(self).getRed(&r, green: &g, blue: &b, alpha: &a) + return Color(.sRGB, red: max(r * (1 - factor), 0), green: max(g * (1 - factor), 0), blue: max(b * (1 - factor), 0), opacity: a) + } + + public func lighter(_ factor: CGFloat = 0.1) -> Color { + var (r, g, b, a): (CGFloat, CGFloat, CGFloat, CGFloat) = (0, 0, 0, 0) + UIColor(self).getRed(&r, green: &g, blue: &b, alpha: &a) + return Color(.sRGB, red: min(r * (1 + factor), 1), green: min(g * (1 + factor), 1), blue: min(b * (1 + factor), 1), opacity: a) + } + + public func asGroupedBackground(_ mode: DefaultThemeMode) -> Color { + let uiColor: UIColor = .init(self) + var (r, g, b, a): (CGFloat, CGFloat, CGFloat, CGFloat) = (0, 0, 0, 0) + uiColor.getRed(&r, green: &g, blue: &b, alpha: &a) + return mode == DefaultThemeMode.light + ? Color(.sRGB, red: max(0, r - 0.052), green: max(0, g - 0.051), blue: max(0, b - 0.032), opacity: a) + : Color(.sRGB, red: min(1, r + 0.11), green: min(1, g + 0.11), blue: min(1, b + 0.115), opacity: a) + } +} + +extension String { + func colorFromReadableHex() -> Color { + // https://stackoverflow.com/a/56874327 + let hex = self.trimmingCharacters(in: ["#", " "]) + var int: UInt64 = 0 + Scanner(string: hex).scanHexInt64(&int) + let a, r, g, b: UInt64 + switch hex.count { + case 3: // RGB (12-bit) + (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) + case 6: // RGB (24-bit) + (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) + case 8: // ARGB (32-bit) + (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) + default: + (a, r, g, b) = (1, 1, 1, 0) + } + + return Color( + .sRGB, + red: Double(r) / 255, + green: Double(g) / 255, + blue: Double(b) / 255, + opacity: Double(a) / 255 + ) + } +} diff --git a/apps/ios/SimpleXChat/Theme/ThemeTypes.swift b/apps/ios/SimpleXChat/Theme/ThemeTypes.swift new file mode 100644 index 0000000000..4074382543 --- /dev/null +++ b/apps/ios/SimpleXChat/Theme/ThemeTypes.swift @@ -0,0 +1,736 @@ +// +// Theme.swift +// SimpleX (iOS) +// +// Created by Avently on 03.06.2024. +// Copyright © 2024 SimpleX Chat. All rights reserved. +// + +import Foundation +import SwiftUI + +public enum DefaultTheme: String, Codable, Equatable { + case LIGHT + case DARK + case SIMPLEX + case BLACK + + public static let SYSTEM_THEME_NAME: String = "SYSTEM" + + public var themeName: String { self.rawValue } + + public var mode: DefaultThemeMode { + self == .LIGHT + ? DefaultThemeMode.light + : DefaultThemeMode.dark + } + + public func hasChangedAnyColor(_ overrides: ThemeOverrides?) -> Bool { + if let overrides { + overrides.colors != ThemeColors() || (overrides.wallpaper != nil && (overrides.wallpaper?.background != nil || overrides.wallpaper?.tint != nil)) + } else { + false + } + } +} + +public enum DefaultThemeMode: String, Codable { + case light + case dark +} + +public class Colors: ObservableObject, NSCopying, Equatable { + @Published public var primary: Color + @Published public var primaryVariant: Color + @Published public var secondary: Color + @Published public var secondaryVariant: Color + @Published public var background: Color + @Published public var surface: Color + @Published public var error: Color + @Published public var onBackground: Color + @Published public var onSurface: Color + @Published public var isLight: Bool + + public init(primary: Color, primaryVariant: Color, secondary: Color, secondaryVariant: Color, background: Color, surface: Color, error: Color, onBackground: Color, onSurface: Color, isLight: Bool) { + self.primary = primary + self.primaryVariant = primaryVariant + self.secondary = secondary + self.secondaryVariant = secondaryVariant + self.background = background + self.surface = surface + self.error = error + self.onBackground = onBackground + self.onSurface = onSurface + self.isLight = isLight + } + + public static func == (lhs: Colors, rhs: Colors) -> Bool { + lhs.primary == rhs.primary && + lhs.primaryVariant == rhs.primaryVariant && + lhs.secondary == rhs.secondary && + lhs.secondaryVariant == rhs.secondaryVariant && + lhs.background == rhs.background && + lhs.surface == rhs.surface && + lhs.error == rhs.error && + lhs.onBackground == rhs.onBackground && + lhs.onSurface == rhs.onSurface && + lhs.isLight == rhs.isLight + } + + public func copy(with zone: NSZone? = nil) -> Any { + Colors(primary: self.primary, primaryVariant: self.primaryVariant, secondary: self.secondary, secondaryVariant: self.secondaryVariant, background: self.background, surface: self.surface, error: self.error, onBackground: self.onBackground, onSurface: self.onSurface, isLight: self.isLight) + } + + public func clone() -> Colors { copy() as! Colors } +} + +public class AppColors: ObservableObject, NSCopying, Equatable { + @Published public var title: Color + @Published public var primaryVariant2: Color + @Published public var sentMessage: Color + @Published public var sentQuote: Color + @Published public var receivedMessage: Color + @Published public var receivedQuote: Color + + public init(title: Color, primaryVariant2: Color, sentMessage: Color, sentQuote: Color, receivedMessage: Color, receivedQuote: Color) { + self.title = title + self.primaryVariant2 = primaryVariant2 + self.sentMessage = sentMessage + self.sentQuote = sentQuote + self.receivedMessage = receivedMessage + self.receivedQuote = receivedQuote + } + + public static func == (lhs: AppColors, rhs: AppColors) -> Bool { + lhs.title == rhs.title && + lhs.primaryVariant2 == rhs.primaryVariant2 && + lhs.sentMessage == rhs.sentMessage && + lhs.sentQuote == rhs.sentQuote && + lhs.receivedQuote == rhs.receivedMessage && + lhs.receivedQuote == rhs.receivedQuote + } + + public func copy(with zone: NSZone? = nil) -> Any { + AppColors(title: self.title, primaryVariant2: self.primaryVariant2, sentMessage: self.sentMessage, sentQuote: self.sentQuote, receivedMessage: self.receivedMessage, receivedQuote: self.receivedQuote) + } + + public func clone() -> AppColors { copy() as! AppColors } + + public func copy( + title: Color?, + primaryVariant2: Color?, + sentMessage: Color?, + sentQuote: Color?, + receivedMessage: Color?, + receivedQuote: Color? + ) -> AppColors { + AppColors( + title: title ?? self.title, + primaryVariant2: primaryVariant2 ?? self.primaryVariant2, + sentMessage: sentMessage ?? self.sentMessage, + sentQuote: sentQuote ?? self.sentQuote, + receivedMessage: receivedMessage ?? self.receivedMessage, + receivedQuote: receivedQuote ?? self.receivedQuote + ) + } +} + +public class AppWallpaper: ObservableObject, NSCopying, Equatable { + public static func == (lhs: AppWallpaper, rhs: AppWallpaper) -> Bool { + lhs.background == rhs.background && + lhs.tint == rhs.tint && + lhs.type == rhs.type + } + + @Published public var background: Color? = nil + @Published public var tint: Color? = nil + @Published public var type: WallpaperType = WallpaperType.empty + + public init(background: Color?, tint: Color?, type: WallpaperType) { + self.background = background + self.tint = tint + self.type = type + } + + public func copy(with zone: NSZone? = nil) -> Any { + AppWallpaper(background: self.background, tint: self.tint, type: self.type) + } + + public func clone() -> AppWallpaper { copy() as! AppWallpaper } + + public func copyWithoutDefault(_ background: Color?, _ tint: Color?, _ type: WallpaperType) -> AppWallpaper { + AppWallpaper( + background: background, + tint: tint, + type: type + ) + } +} + +public enum ThemeColor { + case primary + case primaryVariant + case secondary + case secondaryVariant + case background + case surface + case title + case sentMessage + case sentQuote + case receivedMessage + case receivedQuote + case primaryVariant2 + case wallpaperBackground + case wallpaperTint + + public func fromColors(_ colors: Colors, _ appColors: AppColors, _ appWallpaper: AppWallpaper) -> Color? { + switch (self) { + case .primary: colors.primary + case .primaryVariant: colors.primaryVariant + case .secondary: colors.secondary + case .secondaryVariant: colors.secondaryVariant + case .background: colors.background + case .surface: colors.surface + case .title: appColors.title + case .primaryVariant2: appColors.primaryVariant2 + case .sentMessage: appColors.sentMessage + case .sentQuote: appColors.sentQuote + case .receivedMessage: appColors.receivedMessage + case .receivedQuote: appColors.receivedQuote + case .wallpaperBackground: appWallpaper.background + case .wallpaperTint: appWallpaper.tint + } + } + + public var text: LocalizedStringKey { + switch (self) { + case .primary: "Accent" + case .primaryVariant: "Additional accent" + case .secondary: "Secondary" + case .secondaryVariant: "Additional secondary" + case .background: "Background" + case .surface: "Menus" + case .title: "Title" + case .primaryVariant2: "Additional accent 2" + case .sentMessage: "Sent message" + case .sentQuote: "Sent reply" + case .receivedMessage: "Received message" + case .receivedQuote: "Received reply" + case .wallpaperBackground: "Wallpaper background" + case .wallpaperTint: "Wallpaper accent" + } + } +} + +public struct ThemeColors: Codable, Equatable, Hashable { + public var primary: String? = nil + public var primaryVariant: String? = nil + public var secondary: String? = nil + public var secondaryVariant: String? = nil + public var background: String? = nil + public var surface: String? = nil + public var title: String? = nil + public var primaryVariant2: String? = nil + public var sentMessage: String? = nil + public var sentQuote: String? = nil + public var receivedMessage: String? = nil + public var receivedQuote: String? = nil + + public init(primary: String? = nil, primaryVariant: String? = nil, secondary: String? = nil, secondaryVariant: String? = nil, background: String? = nil, surface: String? = nil, title: String? = nil, primaryVariant2: String? = nil, sentMessage: String? = nil, sentQuote: String? = nil, receivedMessage: String? = nil, receivedQuote: String? = nil) { + self.primary = primary + self.primaryVariant = primaryVariant + self.secondary = secondary + self.secondaryVariant = secondaryVariant + self.background = background + self.surface = surface + self.title = title + self.primaryVariant2 = primaryVariant2 + self.sentMessage = sentMessage + self.sentQuote = sentQuote + self.receivedMessage = receivedMessage + self.receivedQuote = receivedQuote + } + + public enum CodingKeys: String, CodingKey, CaseIterable { + case primary = "accent" + case primaryVariant = "accentVariant" + case secondary + case secondaryVariant + case background + case surface = "menus" + case title + case primaryVariant2 = "accentVariant2" + case sentMessage + case sentQuote = "sentReply" + case receivedMessage + case receivedQuote = "receivedReply" + } + + public static func from(sentMessage: String, sentQuote: String, receivedMessage: String, receivedQuote: String) -> ThemeColors { + var c = ThemeColors() + c.sentMessage = sentMessage + c.sentQuote = sentQuote + c.receivedMessage = receivedMessage + c.receivedQuote = receivedQuote + return c + } + + public static func from(_ colors: Colors, _ appColors: AppColors) -> ThemeColors { + ThemeColors( + primary: colors.primary.toReadableHex(), + primaryVariant: colors.primaryVariant.toReadableHex(), + secondary: colors.secondary.toReadableHex(), + secondaryVariant: colors.secondaryVariant.toReadableHex(), + background: colors.background.toReadableHex(), + surface: colors.surface.toReadableHex(), + title: appColors.title.toReadableHex(), + primaryVariant2: appColors.primaryVariant2.toReadableHex(), + sentMessage: appColors.sentMessage.toReadableHex(), + sentQuote: appColors.sentQuote.toReadableHex(), + receivedMessage: appColors.receivedMessage.toReadableHex(), + receivedQuote: appColors.receivedQuote.toReadableHex() + ) + } +} + +public struct ThemeWallpaper: Codable, Equatable, Hashable { + public var preset: String? + public var scale: Float? + public var scaleType: WallpaperScaleType? + public var background: String? + public var tint: String? + public var image: String? + public var imageFile: String? + + public init(preset: String? = nil, scale: Float? = nil, scaleType: WallpaperScaleType? = nil, background: String? = nil, tint: String? = nil, image: String? = nil, imageFile: String? = nil) { + self.preset = preset + self.scale = scale + self.scaleType = scaleType + self.background = background + self.tint = tint + self.image = image + self.imageFile = imageFile + } + + public enum CodingKeys: String, CodingKey, CaseIterable { + case preset + case scale + case scaleType + case background + case tint + case image + case imageFile + } + + public func toAppWallpaper() -> AppWallpaper { + AppWallpaper ( + background: background?.colorFromReadableHex(), + tint: tint?.colorFromReadableHex(), + type: WallpaperType.from(self) ?? WallpaperType.empty + ) + } + + public func withFilledWallpaperPath() -> ThemeWallpaper { + let aw = toAppWallpaper() + let type = aw.type + let preset: String? = if case let WallpaperType.preset(filename, _) = type { filename } else { nil } + let scale: Float? = if scale == nil { nil } else { + if case let WallpaperType.preset(_, scale) = type { + scale + } else if case let WallpaperType.image(_, scale, _) = type { + scale + } else { + nil + } + } + let scaleType: WallpaperScaleType? = if scaleType == nil { nil } else if case let WallpaperType.image(_, _, scaleType) = type { scaleType } else { nil } + let imageFile: String? = if case let WallpaperType.image(filename, _, _) = type { filename } else { nil } + return ThemeWallpaper ( + preset: preset, + scale: scale, + scaleType: scaleType, + background: aw.background?.toReadableHex(), + tint: aw.tint?.toReadableHex(), + image: nil, + imageFile: imageFile + ) + } + + public static func from(_ type: WallpaperType, _ background: String?, _ tint: String?) -> ThemeWallpaper { + let preset: String? = if case let WallpaperType.preset(filename, _) = type { filename } else { nil } + let scale: Float? = if case let WallpaperType.preset(_, scale) = type { scale } else if case let WallpaperType.image(_, scale, _) = type { scale } else { nil } + let scaleType: WallpaperScaleType? = if case let WallpaperType.image(_, _, scaleType) = type { scaleType } else { nil } + let imageFile: String? = if case let WallpaperType.image(filename, _, _) = type { filename } else { nil } + return ThemeWallpaper( + preset: preset, + scale: scale, + scaleType: scaleType, + background: background, + tint: tint, + image: nil, + imageFile: imageFile + ) + } +} + +/// If you add new properties, make sure they serialized to YAML correctly, see: +/// encodeThemeOverrides() +public struct ThemeOverrides: Codable, Equatable, Hashable { + public var themeId: String = UUID().uuidString + public var base: DefaultTheme + public var colors: ThemeColors = ThemeColors() + public var wallpaper: ThemeWallpaper? = nil + + public init(themeId: String = UUID().uuidString, base: DefaultTheme, colors: ThemeColors = ThemeColors(), wallpaper: ThemeWallpaper? = nil) { + self.themeId = themeId + self.base = base + self.colors = colors + self.wallpaper = wallpaper + } + + public func isSame(_ type: WallpaperType?, _ themeName: String) -> Bool { + if base.themeName != themeName { + return false + } + return if let preset = wallpaper?.preset, let type, case let WallpaperType.preset(filename, _) = type, preset == filename { + true + } else if wallpaper?.imageFile != nil, let type, case WallpaperType.image = type { + true + } else if wallpaper?.preset == nil && wallpaper?.imageFile == nil && type == nil { + true + } else if wallpaper?.preset == nil && wallpaper?.imageFile == nil, let type, case WallpaperType.empty = type { + true + } else { + false + } + } + + public func withUpdatedColor(_ name: ThemeColor, _ color: String?) -> ThemeOverrides { + var c = colors + var w = wallpaper + switch name { + case ThemeColor.primary: c.primary = color + case ThemeColor.primaryVariant: c.primaryVariant = color + case ThemeColor.secondary: c.secondary = color + case ThemeColor.secondaryVariant: c.secondaryVariant = color + case ThemeColor.background: c.background = color + case ThemeColor.surface: c.surface = color + case ThemeColor.title: c.title = color + case ThemeColor.primaryVariant2: c.primaryVariant2 = color + case ThemeColor.sentMessage: c.sentMessage = color + case ThemeColor.sentQuote: c.sentQuote = color + case ThemeColor.receivedMessage: c.receivedMessage = color + case ThemeColor.receivedQuote: c.receivedQuote = color + case ThemeColor.wallpaperBackground: w?.background = color + case ThemeColor.wallpaperTint: w?.tint = color + } + return ThemeOverrides(themeId: themeId, base: base, colors: c, wallpaper: w) + } + + public func toColors(_ base: DefaultTheme, _ perChatTheme: ThemeColors?, _ perUserTheme: ThemeColors?, _ presetWallpaperTheme: ThemeColors?) -> Colors { + let baseColors = switch base { + case DefaultTheme.LIGHT: LightColorPalette + case DefaultTheme.DARK: DarkColorPalette + case DefaultTheme.SIMPLEX: SimplexColorPalette + case DefaultTheme.BLACK: BlackColorPalette + } + let c = baseColors.clone() + c.primary = perChatTheme?.primary?.colorFromReadableHex() ?? perUserTheme?.primary?.colorFromReadableHex() ?? colors.primary?.colorFromReadableHex() ?? presetWallpaperTheme?.primary?.colorFromReadableHex() ?? baseColors.primary + c.primaryVariant = perChatTheme?.primaryVariant?.colorFromReadableHex() ?? perUserTheme?.primaryVariant?.colorFromReadableHex() ?? colors.primaryVariant?.colorFromReadableHex() ?? presetWallpaperTheme?.primaryVariant?.colorFromReadableHex() ?? baseColors.primaryVariant + c.secondary = perChatTheme?.secondary?.colorFromReadableHex() ?? perUserTheme?.secondary?.colorFromReadableHex() ?? colors.secondary?.colorFromReadableHex() ?? presetWallpaperTheme?.secondary?.colorFromReadableHex() ?? baseColors.secondary + c.secondaryVariant = perChatTheme?.secondaryVariant?.colorFromReadableHex() ?? perUserTheme?.secondaryVariant?.colorFromReadableHex() ?? colors.secondaryVariant?.colorFromReadableHex() ?? presetWallpaperTheme?.secondaryVariant?.colorFromReadableHex() ?? baseColors.secondaryVariant + c.background = perChatTheme?.background?.colorFromReadableHex() ?? perUserTheme?.background?.colorFromReadableHex() ?? colors.background?.colorFromReadableHex() ?? presetWallpaperTheme?.background?.colorFromReadableHex() ?? baseColors.background + c.surface = perChatTheme?.surface?.colorFromReadableHex() ?? perUserTheme?.surface?.colorFromReadableHex() ?? colors.surface?.colorFromReadableHex() ?? presetWallpaperTheme?.surface?.colorFromReadableHex() ?? baseColors.surface + return c + } + + public func toAppColors(_ base: DefaultTheme, _ perChatTheme: ThemeColors?, _ perChatWallpaperType: WallpaperType?, _ perUserTheme: ThemeColors?, _ perUserWallpaperType: WallpaperType?, _ presetWallpaperTheme: ThemeColors?) -> AppColors { + let baseColors = switch base { + case DefaultTheme.LIGHT: LightColorPaletteApp + case DefaultTheme.DARK: DarkColorPaletteApp + case DefaultTheme.SIMPLEX: SimplexColorPaletteApp + case DefaultTheme.BLACK: BlackColorPaletteApp + } + + let sentMessageFallback = colors.sentMessage?.colorFromReadableHex() ?? presetWallpaperTheme?.sentMessage?.colorFromReadableHex() ?? baseColors.sentMessage + let sentQuoteFallback = colors.sentQuote?.colorFromReadableHex() ?? presetWallpaperTheme?.sentQuote?.colorFromReadableHex() ?? baseColors.sentQuote + let receivedMessageFallback = colors.receivedMessage?.colorFromReadableHex() ?? presetWallpaperTheme?.receivedMessage?.colorFromReadableHex() ?? baseColors.receivedMessage + let receivedQuoteFallback = colors.receivedQuote?.colorFromReadableHex() ?? presetWallpaperTheme?.receivedQuote?.colorFromReadableHex() ?? baseColors.receivedQuote + + let c = baseColors.clone() + c.title = perChatTheme?.title?.colorFromReadableHex() ?? perUserTheme?.title?.colorFromReadableHex() ?? colors.title?.colorFromReadableHex() ?? presetWallpaperTheme?.title?.colorFromReadableHex() ?? baseColors.title + c.primaryVariant2 = perChatTheme?.primaryVariant2?.colorFromReadableHex() ?? perUserTheme?.primaryVariant2?.colorFromReadableHex() ?? colors.primaryVariant2?.colorFromReadableHex() ?? presetWallpaperTheme?.primaryVariant2?.colorFromReadableHex() ?? baseColors.primaryVariant2 + c.sentMessage = if let c = perChatTheme?.sentMessage { c.colorFromReadableHex() } else if let perUserTheme, (perChatWallpaperType == nil || perUserWallpaperType == nil || perChatWallpaperType!.sameType(perUserWallpaperType)) { perUserTheme.sentMessage?.colorFromReadableHex() ?? sentMessageFallback } else { sentMessageFallback } + c.sentQuote = if let c = perChatTheme?.sentQuote { c.colorFromReadableHex() } else if let perUserTheme, (perChatWallpaperType == nil || perUserWallpaperType == nil || perChatWallpaperType!.sameType(perUserWallpaperType)) { perUserTheme.sentQuote?.colorFromReadableHex() ?? sentQuoteFallback } else { sentQuoteFallback } + c.receivedMessage = if let c = perChatTheme?.receivedMessage { c.colorFromReadableHex() } else if let perUserTheme, (perChatWallpaperType == nil || perUserWallpaperType == nil || perChatWallpaperType!.sameType(perUserWallpaperType)) { perUserTheme.receivedMessage?.colorFromReadableHex() ?? receivedMessageFallback } + else { receivedMessageFallback } + c.receivedQuote = if let c = perChatTheme?.receivedQuote { c.colorFromReadableHex() } else if let perUserTheme, (perChatWallpaperType == nil || perUserWallpaperType == nil || perChatWallpaperType!.sameType(perUserWallpaperType)) { perUserTheme.receivedQuote?.colorFromReadableHex() ?? receivedQuoteFallback } else { receivedQuoteFallback } + return c + } + + public func toAppWallpaper(_ themeOverridesForType: WallpaperType?, _ perChatTheme: ThemeModeOverride?, _ perUserTheme: ThemeModeOverride?, _ themeBackgroundColor: Color) -> AppWallpaper { + let mainType: WallpaperType + if let t = themeOverridesForType { mainType = t } + // type can be nil if override is empty `"wallpaper": "{}"`, in this case no wallpaper is needed, empty. + // It's not nil to override upper level wallpaper + else if let w = perChatTheme?.wallpaper { mainType = w.toAppWallpaper().type } + else if let w = perUserTheme?.wallpaper { mainType = w.toAppWallpaper().type } + else if let w = wallpaper { mainType = w.toAppWallpaper().type } + else { return AppWallpaper(background: nil, tint: nil, type: WallpaperType.empty) } + + let first: ThemeWallpaper? = if mainType.sameType(perChatTheme?.wallpaper?.toAppWallpaper().type) { perChatTheme?.wallpaper } else { nil } + let second: ThemeWallpaper? = if mainType.sameType(perUserTheme?.wallpaper?.toAppWallpaper().type) { perUserTheme?.wallpaper } else { nil } + let third: ThemeWallpaper? = if mainType.sameType(self.wallpaper?.toAppWallpaper().type) { self.wallpaper } else { nil } + + let wallpaper: WallpaperType + switch mainType { + case let WallpaperType.preset(preset, scale): + let scale = if themeOverridesForType == nil { scale ?? first?.scale ?? second?.scale ?? third?.scale } else { second?.scale ?? third?.scale ?? scale } + wallpaper = WallpaperType.preset(preset, scale) + case let WallpaperType.image(filename, scale, scaleType): + let scale = if themeOverridesForType == nil { scale ?? first?.scale ?? second?.scale ?? third?.scale } else { second?.scale ?? third?.scale ?? scale } + let scaleType = if themeOverridesForType == nil { scaleType ?? first?.scaleType ?? second?.scaleType ?? third?.scaleType } else { second?.scaleType ?? third?.scaleType ?? scaleType } + let imageFile = if themeOverridesForType == nil { filename } else { first?.imageFile ?? second?.imageFile ?? third?.imageFile ?? filename } + wallpaper = WallpaperType.image(imageFile, scale, scaleType) + case WallpaperType.empty: + wallpaper = WallpaperType.empty + } + let background = (first?.background ?? second?.background ?? third?.background)?.colorFromReadableHex() ?? mainType.defaultBackgroundColor(base, themeBackgroundColor) + let tint = (first?.tint ?? second?.tint ?? third?.tint)?.colorFromReadableHex() ?? mainType.defaultTintColor(base) + + return AppWallpaper(background: background, tint: tint, type: wallpaper) + } + + public func withFilledColors(_ base: DefaultTheme, _ perChatTheme: ThemeColors?, _ perChatWallpaperType: WallpaperType?, _ perUserTheme: ThemeColors?, _ perUserWallpaperType: WallpaperType?, _ presetWallpaperTheme: ThemeColors?) -> ThemeColors { + let c = toColors(base, perChatTheme, perUserTheme, presetWallpaperTheme) + let ac = toAppColors(base, perChatTheme, perChatWallpaperType, perUserTheme, perUserWallpaperType, presetWallpaperTheme) + return ThemeColors( + primary: c.primary.toReadableHex(), + primaryVariant: c.primaryVariant.toReadableHex(), + secondary: c.secondary.toReadableHex(), + secondaryVariant: c.secondaryVariant.toReadableHex(), + background: c.background.toReadableHex(), + surface: c.surface.toReadableHex(), + title: ac.title.toReadableHex(), + primaryVariant2: ac.primaryVariant2.toReadableHex(), + sentMessage: ac.sentMessage.toReadableHex(), + sentQuote: ac.sentQuote.toReadableHex(), + receivedMessage: ac.receivedMessage.toReadableHex(), + receivedQuote: ac.receivedQuote.toReadableHex() + ) + } +} + +extension [ThemeOverrides] { + public func getTheme(_ themeId: String?) -> ThemeOverrides? { + self.first { $0.themeId == themeId } + } + + public func getTheme(_ themeId: String?, _ type: WallpaperType?, _ base: DefaultTheme) -> ThemeOverrides? { + self.first { $0.themeId == themeId || $0.isSame(type, base.themeName) } + } + + public func replace(_ theme: ThemeOverrides) -> [ThemeOverrides] { + let index = self.firstIndex { $0.themeId == theme.themeId || + // prevent situation when two themes has the same type but different theme id (maybe something was changed in prefs by hand) + $0.isSame(WallpaperType.from(theme.wallpaper), theme.base.themeName) + } + var a = self.map { $0 } + if let index { + a[index] = theme + } else { + a.append(theme) + } + return a + } + + public func sameTheme(_ type: WallpaperType?, _ themeName: String) -> ThemeOverrides? { first { $0.isSame(type, themeName) } } + + public func skipDuplicates() -> [ThemeOverrides] { + var res: [ThemeOverrides] = [] + self.forEach { theme in + let themeType = WallpaperType.from(theme.wallpaper) + if !res.contains(where: { $0.themeId == theme.themeId || $0.isSame(themeType, theme.base.themeName) }) { + res.append(theme) + } + } + return res + } + +} + +public struct ThemeModeOverrides: Codable, Hashable { + public var light: ThemeModeOverride? = nil + public var dark: ThemeModeOverride? = nil + + public init(light: ThemeModeOverride? = nil, dark: ThemeModeOverride? = nil) { + self.light = light + self.dark = dark + } + + public func preferredMode(_ darkTheme: Bool) -> ThemeModeOverride? { + darkTheme ? dark : light + } +} + +public struct ThemeModeOverride: Codable, Equatable, Hashable { + public var mode: DefaultThemeMode// = CurrentColors.base.mode + public var colors: ThemeColors = ThemeColors() + public var wallpaper: ThemeWallpaper? = nil + + public init(mode: DefaultThemeMode, colors: ThemeColors = ThemeColors(), wallpaper: ThemeWallpaper? = nil) { + self.mode = mode + self.colors = colors + self.wallpaper = wallpaper + } + + public var type: WallpaperType? { WallpaperType.from(wallpaper) } + + public func withUpdatedColor(_ name: ThemeColor, _ color: String?) -> ThemeModeOverride { + var c = colors + var w = wallpaper + switch (name) { + case ThemeColor.primary: c.primary = color + case ThemeColor.primaryVariant: c.primaryVariant = color + case ThemeColor.secondary: c.secondary = color + case ThemeColor.secondaryVariant: c.secondaryVariant = color + case ThemeColor.background: c.background = color + case ThemeColor.surface: c.surface = color + case ThemeColor.title: c.title = color + case ThemeColor.primaryVariant2: c.primaryVariant2 = color + case ThemeColor.sentMessage: c.sentMessage = color + case ThemeColor.sentQuote: c.sentQuote = color + case ThemeColor.receivedMessage: c.receivedMessage = color + case ThemeColor.receivedQuote: c.receivedQuote = color + case ThemeColor.wallpaperBackground: w?.background = color + case ThemeColor.wallpaperTint: w?.tint = color + } + return ThemeModeOverride(mode: mode, colors: c, wallpaper: w) + } + + public static func withFilledAppDefaults(_ mode: DefaultThemeMode, _ base: DefaultTheme) -> ThemeModeOverride { + ThemeModeOverride( + mode: mode, + colors: ThemeOverrides(base: base).withFilledColors(base, nil, nil, nil, nil, nil), + wallpaper: ThemeWallpaper(preset: PresetWallpaper.school.filename) + ) + } +} + +public let DarkColorPalette = Colors( + primary: SimplexBlue, + primaryVariant: SimplexBlue, + secondary: HighOrLowlight, + secondaryVariant: DarkGray, + background: Color.black, + surface: Color(0xFF222222), + error: Color.red, + onBackground: Color.white, + onSurface: Color.white, + isLight: false +) +public let DarkColorPaletteApp = AppColors( + title: .white, + primaryVariant2: Color(0xFF18262E), + sentMessage: Color(0xFF18262E), + sentQuote: Color(0xFF1D3847), + receivedMessage: Color(0xff262627), + receivedQuote: Color(0xff373739) +) + +public let LightColorPalette = Colors ( + primary: SimplexBlue, + primaryVariant: SimplexBlue, + secondary: HighOrLowlight, + secondaryVariant: LightGray, + background: Color.white, + surface: Color.white, + error: Color.red, + onBackground: Color.black, + onSurface: Color.black, + isLight: true +) +public let LightColorPaletteApp = AppColors( + title: .black, + primaryVariant2: Color(0xFFE9F7FF), + sentMessage: Color(0xFFE9F7FF), + sentQuote: Color(0xFFD6F0FF), + receivedMessage: Color(0xfff5f5f6), + receivedQuote: Color(0xffececee) +) + +public let SimplexColorPalette = Colors( + primary: Color(0xFF70F0F9), + primaryVariant: Color(0xFF1298A5), + secondary: HighOrLowlight, + secondaryVariant: Color(0xFF2C464D), + background: Color(0xFF111528), + surface: Color(0xFF121C37), + error: Color.red, + onBackground: Color.white, + onSurface: Color.white, + isLight: false +) +public let SimplexColorPaletteApp = AppColors( + title: .white, + primaryVariant2: Color(0xFF172941), + sentMessage: Color(0xFF172941), + sentQuote: Color(0xFF1C3A57), + receivedMessage: Color(0xff25283a), + receivedQuote: Color(0xff36394a) +) + +public let BlackColorPalette = Colors( + primary: Color(0xff0077e0), + primaryVariant: Color(0xff0077e0), + secondary: HighOrLowlight, + secondaryVariant: DarkGray, + background: Color(0xff070707), + surface: Color(0xff161617), + error: Color.red, + onBackground: Color.white, + onSurface: Color.white, + isLight: false +) +public let BlackColorPaletteApp = AppColors( + title: .white, + primaryVariant2: Color(0xff243747), + sentMessage: Color(0xFF18262E), + sentQuote: Color(0xFF1D3847), + receivedMessage: Color(0xff1b1b1b), + receivedQuote: Color(0xff29292b) +) + +extension Colors { + public func updateColorsFrom(_ other: Colors) { + primary = other.primary + primaryVariant = other.primaryVariant + secondary = other.secondary + secondaryVariant = other.secondaryVariant + background = other.background + surface = other.surface + error = other.error + onBackground = other.onBackground + onSurface = other.onSurface + isLight = other.isLight + } +} + +extension AppColors { + public func updateColorsFrom(_ other: AppColors) { + title = other.title + primaryVariant2 = other.primaryVariant2 + sentMessage = other.sentMessage + sentQuote = other.sentQuote + receivedMessage = other.receivedMessage + receivedQuote = other.receivedQuote + } +} + +extension AppWallpaper { + public func updateWallpaperFrom(_ other: AppWallpaper) { + background = other.background + tint = other.tint + type = other.type + } +} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt index 45f656a011..f6e113ea13 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt @@ -32,7 +32,6 @@ enum class DefaultTheme { val mode: DefaultThemeMode get() = if (this == LIGHT) DefaultThemeMode.LIGHT else DefaultThemeMode.DARK - // Call it only with base theme, not SYSTEM fun hasChangedAnyColor(overrides: ThemeOverrides?): Boolean { if (overrides == null) return false return overrides.colors != ThemeColors() || From 6a273677f114098f38f89e8a86370020998ce45b Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Wed, 3 Jul 2024 22:51:21 +0100 Subject: [PATCH 25/43] docs: contributing (#4392) * docs: contributing * corrections --- docs/CONTRIBUTING.md | 45 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index bc013cd7eb..493496fd3d 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -34,48 +34,49 @@ You will have to add `/opt/homebrew/opt/openssl@1.1/bin` to your PATH in order t - `stable-android` - used to build stable Android core library with Nix (GHC 8.10.7) - only for Android armv7a. -- `stable-ios` - used to build stable iOS core library with Nix (GHC 8.10.7) – this branch should be the same as `stable-android` except Nix configuration files. Deprecated. - -- `master` - branch for beta version releases (GHC 9.6.3). - -- `master-ghc8107` - branch for beta version releases (GHC 8.10.7). Deprecated. +- `master` - branch for beta version releases (compatible with both GHC 9.6.3 and 8.10.7). - `master-android` - used to build beta Android core library with Nix (GHC 8.10.7) - only for Android armv7a. -- `master-ios` - used to build beta iOS core library with Nix (GHC 8.10.7). Deprecated. - -- `windows-ghc8107` - branch for windows core library build (GHC 8.10.7). Deprecated? - -`master-ios` and `windows-ghc8107` branches should be the same as `master-ghc8107` except Nix configuration files. - **In simplexmq repo** -- `master` - uses GHC 9.6.3 its commit should be used in `master` branch of simplex-chat repo. - -- `master-ghc8107` - its commit should be used in `master-android` (and `master-ios`) branch of simplex-chat repo. Deprecated. +- `master` - compatible with both GHC 9.6.3 and 8.10.7. ## Development & release process 1. Make PRs to `master` branch _only_ for both simplex-chat and simplexmq repos. -2. If simplexmq repo was changed, to build mobile core libraries you need to merge its `master` branch into `master-ghc8107` branch. - -3. To build core libraries for Android, iOS and windows: +2. To build core libraries for Android, iOS and windows: - merge `master` branch to `master-android` branch. -- update code to be compatible with GHC 8.10.7 (see below). - push to GitHub. -4. All libraries should be built from `master` branch, Android armv7a - from `master-android` branch. +3. All libraries should be built from `master` branch, Android armv7a - from `master-android` branch. -5. To build Desktop and CLI apps, make tag in `master` branch, APK files should be attached to the release. +4. To build Desktop and CLI apps, make tag in `master` branch, APK files should be attached to the release. -6. After the public release to App Store and Play Store, merge: +5. After the public release to App Store and Play Store, merge: - `master` to `stable` - `master` to `master-android` (and compile/update code) - `master-android` to `stable-android` -7. Independently, `master` branch of simplexmq repo should be merged to `stable` branch on stable releases. +6. Independently, `master` branch of simplexmq repo should be merged to `stable` branch on stable releases. +## Branches and PRs + +Use change scope (or comma separated scopes) as the first word in the PR names, followed by the colon. Commit name itself should be lowercase, in present tense. + +The PR names in simplex-chat repo are used in release notes, they should describe the solved problem and not the change. Possible PR scopes: +- ios +- android +- desktop +- core +- docs +- website +- ci + +We squash PRs, do not rewrite branch history after the review. + +For some complex features we create feature branches that will be merged once ready - do not make commits directly to them, make PRs to feature branches. ## Differences between GHC 8.10.7 and GHC 9.6.3 From f12e5048281c808926e05f8a18bacbeb07842352 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Thu, 4 Jul 2024 07:58:13 +0100 Subject: [PATCH 26/43] core: update simplexmq (fast connection handshake) (#4369) * core: update simplexmq (fast connection handshake) * core: update simplexmq (fast connection handshake) * fix encoding tests * fix tests --- tests/ChatClient.hs | 22 ++++- tests/ChatTests/Direct.hs | 184 ++++++++---------------------------- tests/ChatTests/Groups.hs | 53 ++++++++++- tests/ChatTests/Profiles.hs | 68 ++++++++++++- 4 files changed, 175 insertions(+), 152 deletions(-) diff --git a/tests/ChatClient.hs b/tests/ChatClient.hs index efca493002..ca5b92e04e 100644 --- a/tests/ChatClient.hs +++ b/tests/ChatClient.hs @@ -36,7 +36,7 @@ import Simplex.Chat.Terminal.Output (newChatTerminal) import Simplex.Chat.Types import Simplex.FileTransfer.Description (kb, mb) import Simplex.FileTransfer.Server (runXFTPServerBlocking) -import Simplex.FileTransfer.Server.Env (XFTPServerConfig (..), defaultFileExpiration) +import Simplex.FileTransfer.Server.Env (XFTPServerConfig (..), defaultFileExpiration, supportedXFTPhandshakes) import Simplex.FileTransfer.Transport (supportedFileServerVRange) import Simplex.Messaging.Agent (disposeAgentClient) import Simplex.Messaging.Agent.Env.SQLite @@ -48,10 +48,11 @@ import Simplex.Messaging.Client (ProtocolClientConfig (..)) import Simplex.Messaging.Client.Agent (defaultSMPClientAgentConfig) import Simplex.Messaging.Crypto.Ratchet (supportedE2EEncryptVRange) import qualified Simplex.Messaging.Crypto.Ratchet as CR +import Simplex.Messaging.Protocol (srvHostnamesSMPClientVersion) import Simplex.Messaging.Server (runSMPServerBlocking) import Simplex.Messaging.Server.Env.STM import Simplex.Messaging.Transport -import Simplex.Messaging.Transport.Server (defaultTransportServerConfig) +import Simplex.Messaging.Transport.Server (TransportServerConfig (..), defaultTransportServerConfig) import Simplex.Messaging.Version import Simplex.Messaging.Version.Internal import System.Directory (createDirectoryIfMissing, removeDirectoryRecursive) @@ -135,6 +136,14 @@ testAgentCfg = { reconnectInterval = (reconnectInterval aCfg) {initialInterval = 50000} } +testAgentCfgSlow :: AgentConfig +testAgentCfgSlow = + testAgentCfg + { smpClientVRange = mkVersionRange (Version 1) srvHostnamesSMPClientVersion, -- v2 + smpAgentVRange = mkVersionRange duplexHandshakeSMPAgentVersion pqdrSMPAgentVersion, -- v5 + smpCfg = (smpCfg testAgentCfg) {serverVRange = mkVersionRange batchCmdsSMPVersion sendingProxySMPVersion} -- v8 + } + testCfg :: ChatConfig testCfg = defaultChatConfig @@ -144,6 +153,9 @@ testCfg = tbqSize = 16 } +testCfgSlow :: ChatConfig +testCfgSlow = testCfg {agentConfig = testAgentCfgSlow} + testAgentCfgVPrev :: AgentConfig testAgentCfgVPrev = testAgentCfg @@ -427,11 +439,11 @@ smpServerCfg = serverStatsLogFile = "tests/smp-server-stats.daily.log", serverStatsBackupFile = Nothing, smpServerVRange = supportedServerSMPRelayVRange, - transportConfig = defaultTransportServerConfig, + transportConfig = defaultTransportServerConfig {alpn = Just supportedSMPHandshakes}, smpHandshakeTimeout = 1000000, controlPort = Nothing, smpAgentCfg = defaultSMPClientAgentConfig, - allowSMPProxy = False, + allowSMPProxy = True, serverClientConcurrency = 16, information = Nothing } @@ -473,7 +485,7 @@ xftpServerConfig = serverStatsLogFile = "tests/tmp/xftp-server-stats.daily.log", serverStatsBackupFile = Nothing, controlPort = Nothing, - transportConfig = defaultTransportServerConfig, + transportConfig = defaultTransportServerConfig {alpn = Just supportedXFTPhandshakes}, responseDelay = 0 } diff --git a/tests/ChatTests/Direct.hs b/tests/ChatTests/Direct.hs index 8345a90b0c..aaf91af910 100644 --- a/tests/ChatTests/Direct.hs +++ b/tests/ChatTests/Direct.hs @@ -63,11 +63,22 @@ chatDirectTests = do it "get and set XFTP servers" testGetSetXFTPServers it "test XFTP server connection" testTestXFTPServer describe "async connection handshake" $ do - it "connect when initiating client goes offline" testAsyncInitiatingOffline - it "connect when accepting client goes offline" testAsyncAcceptingOffline + describe "connect when initiating client goes offline" $ do + it "curr" $ testAsyncInitiatingOffline testCfg testCfg + it "v5" $ testAsyncInitiatingOffline testCfgSlow testCfgSlow + it "v5/curr" $ testAsyncInitiatingOffline testCfgSlow testCfg + it "curr/v5" $ testAsyncInitiatingOffline testCfg testCfgSlow + describe "connect when accepting client goes offline" $ do + it "curr" $ testAsyncAcceptingOffline testCfg testCfg + it "v5" $ testAsyncAcceptingOffline testCfgSlow testCfgSlow + it "v5/curr" $ testAsyncAcceptingOffline testCfgSlow testCfg + it "curr/v5" $ testAsyncAcceptingOffline testCfg testCfgSlow describe "connect, fully asynchronous (when clients are never simultaneously online)" $ do + it "curr" testFullAsyncFast -- fails in CI - xit'' "v2" testFullAsync + xit'' "v5" $ testFullAsyncSlow testCfgSlow testCfgSlow + xit'' "v5/curr" $ testFullAsyncSlow testCfgSlow testCfg + xit'' "curr/v5" $ testFullAsyncSlow testCfg testCfgSlow describe "webrtc calls api" $ do it "negotiate call" testNegotiateCall describe "maintenance mode" $ do @@ -842,41 +853,38 @@ testTestXFTPServer = alice <## "XFTP server test failed at Connect, error: BROKER {brokerAddress = \"xftp://LcJU@localhost:7002\", brokerErr = NETWORK}" alice <## "Possibly, certificate fingerprint in XFTP server address is incorrect" -testAsyncInitiatingOffline :: HasCallStack => FilePath -> IO () -testAsyncInitiatingOffline tmp = do - putStrLn "testAsyncInitiatingOffline" - inv <- withNewTestChat tmp "alice" aliceProfile $ \alice -> do +testAsyncInitiatingOffline :: HasCallStack => ChatConfig -> ChatConfig -> FilePath -> IO () +testAsyncInitiatingOffline aliceCfg bobCfg tmp = do + inv <- withNewTestChatCfg tmp aliceCfg "alice" aliceProfile $ \alice -> do threadDelay 250000 alice ##> "/c" getInvitation alice - withNewTestChat tmp "bob" bobProfile $ \bob -> do + withNewTestChatCfg tmp bobCfg "bob" bobProfile $ \bob -> do threadDelay 250000 bob ##> ("/c " <> inv) bob <## "confirmation sent!" - withTestChat tmp "alice" $ \alice -> do + withTestChatCfg tmp aliceCfg "alice" $ \alice -> do concurrently_ (bob <## "alice (Alice): contact is connected") (alice <## "bob (Bob): contact is connected") -testAsyncAcceptingOffline :: HasCallStack => FilePath -> IO () -testAsyncAcceptingOffline tmp = do - putStrLn "testAsyncAcceptingOffline" - inv <- withNewTestChat tmp "alice" aliceProfile $ \alice -> do +testAsyncAcceptingOffline :: HasCallStack => ChatConfig -> ChatConfig -> FilePath -> IO () +testAsyncAcceptingOffline aliceCfg bobCfg tmp = do + inv <- withNewTestChatCfg tmp aliceCfg "alice" aliceProfile $ \alice -> do alice ##> "/c" getInvitation alice - withNewTestChat tmp "bob" bobProfile $ \bob -> do + withNewTestChatCfg tmp bobCfg "bob" bobProfile $ \bob -> do threadDelay 250000 bob ##> ("/c " <> inv) bob <## "confirmation sent!" - withTestChat tmp "alice" $ \alice -> do - withTestChat tmp "bob" $ \bob -> do + withTestChatCfg tmp aliceCfg "alice" $ \alice -> do + withTestChatCfg tmp bobCfg "bob" $ \bob -> do concurrently_ (bob <## "alice (Alice): contact is connected") (alice <## "bob (Bob): contact is connected") -testFullAsync :: HasCallStack => FilePath -> IO () -testFullAsync tmp = do - putStrLn "testFullAsync" +testFullAsyncFast :: HasCallStack => FilePath -> IO () +testFullAsyncFast tmp = do inv <- withNewTestChat tmp "alice" aliceProfile $ \alice -> do threadDelay 250000 alice ##> "/c" @@ -885,143 +893,33 @@ testFullAsync tmp = do threadDelay 250000 bob ##> ("/c " <> inv) bob <## "confirmation sent!" - withTestChat tmp "alice" $ \_ -> pure () -- connecting... notification in UI - withTestChat tmp "bob" $ \_ -> pure () -- connecting... notification in UI - withTestChat tmp "alice" $ \alice -> do - alice <## "1 contacts connected (use /cs for the list)" + threadDelay 250000 + withTestChat tmp "alice" $ \alice -> alice <## "bob (Bob): contact is connected" - withTestChat tmp "bob" $ \bob -> do - bob <## "1 contacts connected (use /cs for the list)" + withTestChat tmp "bob" $ \bob -> bob <## "alice (Alice): contact is connected" -testFullAsyncV1 :: HasCallStack => FilePath -> IO () -testFullAsyncV1 tmp = do - putStrLn "testFullAsyncV1" - inv <- withNewAlice $ \alice -> do - putStrLn "1" +testFullAsyncSlow :: HasCallStack => ChatConfig -> ChatConfig -> FilePath -> IO () +testFullAsyncSlow aliceCfg bobCfg tmp = do + inv <- withNewTestChatCfg tmp aliceCfg "alice" aliceProfile $ \alice -> do + threadDelay 250000 alice ##> "/c" - putStrLn "2" getInvitation alice - putStrLn "3" - withNewBob $ \bob -> do - putStrLn "4" + withNewTestChatCfg tmp bobCfg "bob" bobProfile $ \bob -> do + threadDelay 250000 bob ##> ("/c " <> inv) - putStrLn "5" bob <## "confirmation sent!" - putStrLn "6" - withAlice $ \_ -> pure () - putStrLn "7" - withBob $ \_ -> pure () - putStrLn "8" + withAlice $ \_ -> pure () -- connecting... notification in UI + withBob $ \_ -> pure () -- connecting... notification in UI withAlice $ \alice -> do - putStrLn "9" alice <## "1 contacts connected (use /cs for the list)" - putStrLn "10" - withBob $ \_ -> pure () - putStrLn "11" - withAlice $ \alice -> do - putStrLn "12" - alice <## "1 contacts connected (use /cs for the list)" - putStrLn "13" alice <## "bob (Bob): contact is connected" - putStrLn "14" withBob $ \bob -> do - putStrLn "15" bob <## "1 contacts connected (use /cs for the list)" - putStrLn "16" bob <## "alice (Alice): contact is connected" where - withNewAlice = withNewTestChatV1 tmp "alice" aliceProfile - withAlice = withTestChatV1 tmp "alice" - withNewBob = withNewTestChatV1 tmp "bob" bobProfile - withBob = withTestChatV1 tmp "bob" - -testFullAsyncV1toV2 :: HasCallStack => FilePath -> IO () -testFullAsyncV1toV2 tmp = do - putStrLn "testFullAsyncV1toV2" - inv <- withNewAlice $ \alice -> do - putStrLn "1" - alice ##> "/c" - putStrLn "2" - getInvitation alice - putStrLn "3" - withNewBob $ \bob -> do - putStrLn "4" - bob ##> ("/c " <> inv) - putStrLn "5" - bob <## "confirmation sent!" - withAlice $ \_ -> pure () - putStrLn "6" - withBob $ \_ -> pure () - putStrLn "7" - withAlice $ \alice -> do - putStrLn "8" - alice <## "1 contacts connected (use /cs for the list)" - putStrLn "9" - withBob $ \_ -> pure () - putStrLn "10" - withAlice $ \alice -> do - putStrLn "11" - alice <## "1 contacts connected (use /cs for the list)" - putStrLn "12" - alice <## "bob (Bob): contact is connected" - putStrLn "13" - withBob $ \bob -> do - putStrLn "14" - bob <## "1 contacts connected (use /cs for the list)" - putStrLn "15" - bob <## "alice (Alice): contact is connected" - where - withNewAlice = withNewTestChat tmp "alice" aliceProfile - withAlice = withTestChat tmp "alice" - withNewBob = withNewTestChatV1 tmp "bob" bobProfile - withBob = withTestChatV1 tmp "bob" - -testFullAsyncV2toV1 :: HasCallStack => FilePath -> IO () -testFullAsyncV2toV1 tmp = do - putStrLn "testFullAsyncV2toV1" - inv <- withNewAlice $ \alice -> do - putStrLn "1" - alice ##> "/c" - putStrLn "2" - getInvitation alice - putStrLn "3" - withNewBob $ \bob -> do - putStrLn "4" - bob ##> ("/c " <> inv) - putStrLn "5" - bob <## "confirmation sent!" - putStrLn "6" - withAlice $ \_ -> pure () - putStrLn "7" - withBob $ \_ -> pure () - putStrLn "8" - withAlice $ \alice -> do - putStrLn "9" - alice <## "1 contacts connected (use /cs for the list)" - putStrLn "10" - withBob $ \_ -> pure () - putStrLn "11" - withAlice $ \alice -> do - putStrLn "12" - alice <## "1 contacts connected (use /cs for the list)" - putStrLn "13" - alice <## "bob (Bob): contact is connected" - putStrLn "14" - withBob $ \bob -> do - putStrLn "15" - bob <## "1 contacts connected (use /cs for the list)" - putStrLn "16" - bob <## "alice (Alice): contact is connected" - where - withNewAlice = withNewTestChatV1 tmp "alice" aliceProfile - {-# INLINE withNewAlice #-} - withAlice = withTestChatV1 tmp "alice" - {-# INLINE withAlice #-} - withNewBob = withNewTestChat tmp "bob" bobProfile - {-# INLINE withNewBob #-} - withBob = withTestChat tmp "bob" - {-# INLINE withBob #-} + withAlice = withTestChatCfg tmp aliceCfg "alice" + withBob = withTestChatCfg tmp aliceCfg "bob" testCallType :: CallType testCallType = CallType {media = CMVideo, capabilities = CallCapabilities {encryption = True}} @@ -2463,7 +2361,7 @@ testMsgDecryptError tmp = withTestChat tmp "bob" $ \bob -> do bob <## "1 contacts connected (use /cs for the list)" alice #> "@bob hello again" - bob <# "alice> skipped message ID 10..12" + bob <# "alice> skipped message ID 9..11" bob <# "alice> hello again" bob #> "@alice received!" alice <# "bob> received!" diff --git a/tests/ChatTests/Groups.hs b/tests/ChatTests/Groups.hs index 009a26cf0b..6f1ba20246 100644 --- a/tests/ChatTests/Groups.hs +++ b/tests/ChatTests/Groups.hs @@ -90,6 +90,7 @@ chatGroupTests = do describe "group links without contact connection plan" $ do it "group link without contact - known group" testPlanGroupLinkNoContactKnown it "group link without contact - connecting" testPlanGroupLinkNoContactConnecting + it "group link without contact - connecting (slow handshake)" testPlanGroupLinkNoContactConnectingSlow describe "group message errors" $ do it "show message decryption error" testGroupMsgDecryptError it "should report ratchet de-synchronization, synchronize ratchets" testGroupSyncRatchet @@ -2527,7 +2528,7 @@ testPlanHostContactDeletedGroupLinkKnown = testPlanGroupLinkOwn :: HasCallStack => FilePath -> IO () testPlanGroupLinkOwn tmp = - withNewTestChatCfg tmp testCfgGroupLinkViaContact "alice" aliceProfile $ \alice -> do + withNewTestChatCfg tmp (mkCfgGroupLinkViaContact testCfgSlow) "alice" aliceProfile $ \alice -> do threadDelay 100000 alice ##> "/g team" alice <## "group #team is created" @@ -2630,7 +2631,7 @@ testPlanGroupLinkConnecting tmp = do bob ##> ("/c " <> gLink) bob <## "group link: connecting" where - cfg = testCfgGroupLinkViaContact + cfg = mkCfgGroupLinkViaContact testCfgSlow testPlanGroupLinkLeaveRejoin :: HasCallStack => FilePath -> IO () testPlanGroupLinkLeaveRejoin = @@ -3228,6 +3229,52 @@ testPlanGroupLinkNoContactConnecting tmp = do withTestChat tmp "bob" $ \bob -> do threadDelay 500000 bob <## "#team: joining the group..." + bob <## "#team: you joined the group" + + bob ##> ("/_connect plan 1 " <> gLink) + bob <## "group link: known group #team" + bob <## "use #team to send messages" + + let gLinkSchema2 = linkAnotherSchema gLink + bob ##> ("/_connect plan 1 " <> gLinkSchema2) + bob <## "group link: known group #team" + bob <## "use #team to send messages" + + bob ##> ("/c " <> gLink) + bob <## "group link: known group #team" + bob <## "use #team to send messages" + +testPlanGroupLinkNoContactConnectingSlow :: HasCallStack => FilePath -> IO () +testPlanGroupLinkNoContactConnectingSlow tmp = do + gLink <- withNewTestChatCfg tmp testCfgSlow "alice" aliceProfile $ \alice -> do + alice ##> "/g team" + alice <## "group #team is created" + alice <## "to add members use /a team or /create link #team" + alice ##> "/create link #team" + getGroupLink alice "team" GRMember True + withNewTestChatCfg tmp testCfgSlow "bob" bobProfile $ \bob -> do + threadDelay 100000 + + bob ##> ("/c " <> gLink) + bob <## "connection request sent!" + + bob ##> ("/_connect plan 1 " <> gLink) + bob <## "group link: connecting, allowed to reconnect" + + let gLinkSchema2 = linkAnotherSchema gLink + bob ##> ("/_connect plan 1 " <> gLinkSchema2) + bob <## "group link: connecting, allowed to reconnect" + + threadDelay 100000 + withTestChatCfg tmp testCfgSlow "alice" $ \alice -> do + alice + <### [ "1 group links active", + "#team: group is empty", + "bob (Bob): accepting request to join group #team..." + ] + withTestChatCfg tmp testCfgSlow "bob" $ \bob -> do + threadDelay 500000 + bob <## "#team: joining the group..." bob ##> ("/_connect plan 1 " <> gLink) bob <## "group link: connecting to group #team" @@ -3253,7 +3300,7 @@ testGroupMsgDecryptError tmp = bob <## "1 contacts connected (use /cs for the list)" bob <## "#team: connected to server(s)" alice #> "#team hello again" - bob <# "#team alice> skipped message ID 10..12" + bob <# "#team alice> skipped message ID 9..11" bob <# "#team alice> hello again" bob #> "#team received!" alice <# "#team bob> received!" diff --git a/tests/ChatTests/Profiles.hs b/tests/ChatTests/Profiles.hs index f29d6d848a..a3352c7f4f 100644 --- a/tests/ChatTests/Profiles.hs +++ b/tests/ChatTests/Profiles.hs @@ -17,8 +17,8 @@ import Simplex.Chat.Store.Shared (createContact) import Simplex.Chat.Types (ConnStatus (..), Profile (..)) import Simplex.Chat.Types.Shared (GroupMemberRole (..)) import Simplex.Chat.Types.UITheme -import Simplex.Messaging.Util (encodeJSON) import Simplex.Messaging.Encoding.String (StrEncoding (..)) +import Simplex.Messaging.Util (encodeJSON) import System.Directory (copyFile, createDirectoryIfMissing) import Test.Hspec hiding (it) @@ -42,6 +42,7 @@ chatProfileTests = do it "contact address ok to connect; known contact" testPlanAddressOkKnown it "own contact address" testPlanAddressOwn it "connecting via contact address" testPlanAddressConnecting + it "connecting via contact address (slow handshake)" testPlanAddressConnectingSlow it "re-connect with deleted contact" testPlanAddressContactDeletedReconnected it "contact via address" testPlanAddressContactViaAddress describe "incognito" $ do @@ -51,6 +52,7 @@ chatProfileTests = do it "set connection incognito" testSetConnectionIncognito it "reset connection incognito" testResetConnectionIncognito it "set connection incognito prohibited during negotiation" testSetConnectionIncognitoProhibitedDuringNegotiation + it "set connection incognito prohibited during negotiation (slow handshake)" testSetConnectionIncognitoProhibitedDuringNegotiationSlow it "connection incognito unchanged errors" testConnectionIncognitoUnchangedErrors it "set, reset, set connection incognito" testSetResetSetConnectionIncognito it "join group incognito" testJoinGroupIncognito @@ -705,6 +707,49 @@ testPlanAddressConnecting tmp = do alice ##> "/ac bob" alice <## "bob (Bob): accepting contact request..." withTestChat tmp "bob" $ \bob -> do + threadDelay 500000 + bob <## "alice (Alice): contact is connected" + bob @@@ [("@alice", "Audio/video calls: enabled")] + bob ##> ("/_connect plan 1 " <> cLink) + bob <## "contact address: known contact alice" + bob <## "use @alice to send messages" + + let cLinkSchema2 = linkAnotherSchema cLink + bob ##> ("/_connect plan 1 " <> cLinkSchema2) + bob <## "contact address: known contact alice" + bob <## "use @alice to send messages" + + bob ##> ("/c " <> cLink) + bob <## "contact address: known contact alice" + bob <## "use @alice to send messages" + +testPlanAddressConnectingSlow :: HasCallStack => FilePath -> IO () +testPlanAddressConnectingSlow tmp = do + cLink <- withNewTestChatCfg tmp testCfgSlow "alice" aliceProfile $ \alice -> do + alice ##> "/ad" + getContactLink alice True + withNewTestChatCfg tmp testCfgSlow "bob" bobProfile $ \bob -> do + threadDelay 100000 + + bob ##> ("/c " <> cLink) + bob <## "connection request sent!" + + bob ##> ("/_connect plan 1 " <> cLink) + bob <## "contact address: connecting, allowed to reconnect" + + let cLinkSchema2 = linkAnotherSchema cLink + bob ##> ("/_connect plan 1 " <> cLinkSchema2) + bob <## "contact address: connecting, allowed to reconnect" + + threadDelay 100000 + withTestChatCfg tmp testCfgSlow "alice" $ \alice -> do + alice <## "Your address is active! To show: /sa" + alice <## "bob (Bob) wants to connect to you!" + alice <## "to accept: /ac bob" + alice <## "to reject: /rc bob (the sender will NOT be notified)" + alice ##> "/ac bob" + alice <## "bob (Bob): accepting contact request..." + withTestChatCfg tmp testCfgSlow "bob" $ \bob -> do threadDelay 500000 bob @@@ [("@alice", "")] bob ##> ("/_connect plan 1 " <> cLink) @@ -1050,9 +1095,30 @@ testSetConnectionIncognitoProhibitedDuringNegotiation tmp = do bob <## "confirmation sent!" withTestChat tmp "alice" $ \alice -> do threadDelay 250000 + alice <## "bob (Bob): contact is connected" alice ##> "/_set incognito :1 on" alice <## "chat db error: SEPendingConnectionNotFound {connId = 1}" withTestChat tmp "bob" $ \bob -> do + bob <## "alice (Alice): contact is connected" + alice <##> bob + alice `hasContactProfiles` ["alice", "bob"] + bob `hasContactProfiles` ["alice", "bob"] + +testSetConnectionIncognitoProhibitedDuringNegotiationSlow :: HasCallStack => FilePath -> IO () +testSetConnectionIncognitoProhibitedDuringNegotiationSlow tmp = do + inv <- withNewTestChatCfg tmp testCfgSlow "alice" aliceProfile $ \alice -> do + threadDelay 250000 + alice ##> "/connect" + getInvitation alice + withNewTestChatCfg tmp testCfgSlow "bob" bobProfile $ \bob -> do + threadDelay 250000 + bob ##> ("/c " <> inv) + bob <## "confirmation sent!" + withTestChatCfg tmp testCfgSlow "alice" $ \alice -> do + threadDelay 250000 + alice ##> "/_set incognito :1 on" + alice <## "chat db error: SEPendingConnectionNotFound {connId = 1}" + withTestChatCfg tmp testCfgSlow "bob" $ \bob -> do concurrently_ (bob <## "alice (Alice): contact is connected") (alice <## "bob (Bob): contact is connected") From 0509ff9a1b6183a05d94177c090a609527463441 Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Thu, 4 Jul 2024 07:00:12 +0000 Subject: [PATCH 27/43] docs: Flatpak download (#4393) * docs: Flathub * correction --------- Co-authored-by: Evgeny Poberezkin --- docs/DOWNLOADS.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/DOWNLOADS.md b/docs/DOWNLOADS.md index fcbe5d0446..06850e76d2 100644 --- a/docs/DOWNLOADS.md +++ b/docs/DOWNLOADS.md @@ -1,10 +1,10 @@ --- title: Download SimpleX apps permalink: /downloads/index.html -revision: 11.02.2024 +revision: 03.07.2024 --- -| Updated 23.03.2024 | Languages: EN | +| Updated 03.07.2024 | Languages: EN | # Download SimpleX apps The latest stable version is v5.8. @@ -21,7 +21,7 @@ You can get the latest beta releases from [GitHub](https://github.com/simplex-ch You can link your mobile device with desktop to use the same profile remotely, but this is only possible when both devices are connected to the same local network. -**Linux**: [AppImage](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-x86_64.AppImage) (most Linux distros), [Ubuntu 20.04](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-ubuntu-20_04-x86_64.deb) (and Debian-based distros), [Ubuntu 22.04](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-ubuntu-22_04-x86_64.deb). +**Linux**: [AppImage](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-x86_64.AppImage) or [Flatpak](https://flathub.org/apps/chat.simplex.simplex) (most Linux distros), [Ubuntu 20.04](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-ubuntu-20_04-x86_64.deb) (and Debian-based distros), [Ubuntu 22.04](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-ubuntu-22_04-x86_64.deb). **Mac**: [aarch64](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-macos-aarch64.dmg) (Apple Silicon), [x86_64](https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-desktop-macos-x86_64.dmg) (Intel). From 1e6dc8002c0ebc5fe329066efc19248726fa055d Mon Sep 17 00:00:00 2001 From: sh <37271604+shumvgolove@users.noreply.github.com> Date: Thu, 4 Jul 2024 13:39:16 +0000 Subject: [PATCH 28/43] flatpak: update metainfo (#4400) --- scripts/flatpak/chat.simplex.simplex.metainfo.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/scripts/flatpak/chat.simplex.simplex.metainfo.xml b/scripts/flatpak/chat.simplex.simplex.metainfo.xml index dd3f1143b5..15c6f22d28 100644 --- a/scripts/flatpak/chat.simplex.simplex.metainfo.xml +++ b/scripts/flatpak/chat.simplex.simplex.metainfo.xml @@ -38,6 +38,18 @@ + + https://github.com/simplex-chat/simplex-chat/releases/tag/v5.8.2 + +

    General:

    +
      +
    1. missed call notification.
    2. +
    3. remove notifications of hidden/removed user profiles.
    4. +
    5. support for faster connection with the new contacts (disabled in this version).
    6. +
    7. general fixes.
    8. +
    + +

    General:

    From 44c0861fe48f03d7593912d8fb5dd3667575669f Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Thu, 4 Jul 2024 21:11:20 +0400 Subject: [PATCH 29/43] ios: apply theming to servers summary view (#4404) --- apps/ios/Shared/Views/ChatList/ServersSummaryView.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift b/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift index ca55d9493b..00cbe9a236 100644 --- a/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift +++ b/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift @@ -36,6 +36,7 @@ struct ServersSummaryView: View { viewBody() .navigationTitle("Servers info") .navigationBarTitleDisplayMode(.large) + .modifier(ThemedBackground(grouped: true)) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { shareButton() @@ -264,6 +265,7 @@ struct ServersSummaryView: View { ) .navigationBarTitle("SMP server") .navigationBarTitleDisplayMode(.large) + .modifier(ThemedBackground(grouped: true)) } label: { HStack { Text(serverAddress(srvSumm.smpServer)) @@ -332,6 +334,7 @@ struct ServersSummaryView: View { ) .navigationBarTitle("XFTP server") .navigationBarTitleDisplayMode(.large) + .modifier(ThemedBackground(grouped: true)) } label: { HStack { Text(serverAddress(srvSumm.xftpServer)) @@ -470,6 +473,7 @@ struct SMPServerSummaryView: View { NavigationLink { ProtocolServersView(serverProtocol: .smp) .navigationTitle("Your SMP servers") + .modifier(ThemedBackground(grouped: true)) } label: { Text("Open server settings") } @@ -563,6 +567,7 @@ struct SMPStatsView: View { DetailedSMPStatsView(stats: stats, statsStartedAt: statsStartedAt) .navigationTitle("Detailed statistics") .navigationBarTitleDisplayMode(.large) + .modifier(ThemedBackground(grouped: true)) } label: { Text("Details") } @@ -662,6 +667,7 @@ struct XFTPServerSummaryView: View { NavigationLink { ProtocolServersView(serverProtocol: .xftp) .navigationTitle("Your XFTP servers") + .modifier(ThemedBackground(grouped: true)) } label: { Text("Open server settings") } @@ -692,6 +698,7 @@ struct XFTPStatsView: View { DetailedXFTPStatsView(stats: stats, statsStartedAt: statsStartedAt) .navigationTitle("Detailed statistics") .navigationBarTitleDisplayMode(.large) + .modifier(ThemedBackground(grouped: true)) } label: { Text("Details") } From 5d7abf31cebfff9363f1f085015e2eea840a3a3a Mon Sep 17 00:00:00 2001 From: Arturs Krumins Date: Thu, 4 Jul 2024 19:37:03 +0200 Subject: [PATCH 30/43] ios: make message corners rounded when selecting context menus (#4401) Co-authored-by: Evgeny Poberezkin --- .../Chat/ChatItem/CIGroupInvitationView.swift | 1 - .../Chat/ChatItem/CIInvalidJSONView.swift | 1 - .../Chat/ChatItem/CIRcvDecryptionError.swift | 2 - .../Views/Chat/ChatItem/DeletedItemView.swift | 1 - .../Views/Chat/ChatItem/FramedItemView.swift | 1 - .../ChatItem/IntegrityErrorItemView.swift | 1 - .../Chat/ChatItem/MarkedDeletedItemView.swift | 1 - .../Shared/Views/Chat/ChatItemInfoView.swift | 4 +- apps/ios/Shared/Views/Chat/ChatView.swift | 1 + apps/ios/Shared/Views/Chat/ReverseList.swift | 1 + .../Views/Helpers/ChatItemClipShape.swift | 63 +++++++++++++++++++ apps/ios/SimpleX.xcodeproj/project.pbxproj | 4 ++ 12 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 apps/ios/Shared/Views/Helpers/ChatItemClipShape.swift diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIGroupInvitationView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIGroupInvitationView.swift index 62e9852853..ef0fec5dfe 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIGroupInvitationView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIGroupInvitationView.swift @@ -70,7 +70,6 @@ struct CIGroupInvitationView: View { .padding(.horizontal, 12) .padding(.vertical, 6) .background(chatItemFrameColor(chatItem, theme)) - .cornerRadius(18) .textSelection(.disabled) .onPreferenceChange(DetermineWidth.Key.self) { frameWidth = $0 } .onChange(of: inProgress) { inProgress in diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIInvalidJSONView.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIInvalidJSONView.swift index f9802089df..18fd682646 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIInvalidJSONView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIInvalidJSONView.swift @@ -22,7 +22,6 @@ struct CIInvalidJSONView: View { .padding(.horizontal, 12) .padding(.vertical, 6) .background(Color(uiColor: .tertiarySystemGroupedBackground)) - .cornerRadius(18) .textSelection(.disabled) .onTapGesture { showJSON = true } .appSheet(isPresented: $showJSON) { diff --git a/apps/ios/Shared/Views/Chat/ChatItem/CIRcvDecryptionError.swift b/apps/ios/Shared/Views/Chat/ChatItem/CIRcvDecryptionError.swift index e127ca86cf..7023449e9f 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/CIRcvDecryptionError.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/CIRcvDecryptionError.swift @@ -132,7 +132,6 @@ struct CIRcvDecryptionError: View { .onTapGesture(perform: { onClick() }) .padding(.vertical, 6) .background(Color(uiColor: .tertiarySystemGroupedBackground)) - .cornerRadius(18) .textSelection(.disabled) } @@ -152,7 +151,6 @@ struct CIRcvDecryptionError: View { .onTapGesture(perform: { onClick() }) .padding(.vertical, 6) .background(Color(uiColor: .tertiarySystemGroupedBackground)) - .cornerRadius(18) .textSelection(.disabled) } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/DeletedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/DeletedItemView.swift index 54356c5a6e..ed2340b6c4 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/DeletedItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/DeletedItemView.swift @@ -25,7 +25,6 @@ struct DeletedItemView: View { .padding(.leading, 12) .padding(.vertical, 6) .background(chatItemFrameColor(chatItem, theme)) - .cornerRadius(18) .textSelection(.disabled) } } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift index db1a74e213..5d6327139a 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/FramedItemView.swift @@ -76,7 +76,6 @@ struct FramedItemView: View { } } .background(chatItemFrameColorMaybeImageOrVideo(chatItem, theme)) - .cornerRadius(18) .onPreferenceChange(DetermineWidth.Key.self) { msgWidth = $0 } if let (title, text) = chatItem.meta.itemStatus.statusInfo { diff --git a/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift index de71b1fa08..822dda4d06 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/IntegrityErrorItemView.swift @@ -70,7 +70,6 @@ struct CIMsgError: View { .padding(.leading, 12) .padding(.vertical, 6) .background(Color(uiColor: .tertiarySystemGroupedBackground)) - .cornerRadius(18) .textSelection(.disabled) .onTapGesture(perform: onTap) } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/MarkedDeletedItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/MarkedDeletedItemView.swift index b81f113d22..f8bd9156da 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/MarkedDeletedItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/MarkedDeletedItemView.swift @@ -23,7 +23,6 @@ struct MarkedDeletedItemView: View { .padding(.horizontal, 12) .padding(.vertical, 6) .background(chatItemFrameColor(chatItem, theme)) - .cornerRadius(18) .textSelection(.disabled) } diff --git a/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift b/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift index a55b07495a..3312833ccc 100644 --- a/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift @@ -232,7 +232,7 @@ struct ChatItemInfoView: View { .padding(.horizontal, 12) .padding(.vertical, 6) .background(chatItemFrameColor(ci, theme)) - .cornerRadius(18) + .modifier(ChatItemClipped()) .contextMenu { if itemVersion.msgContent.text != "" { Button { @@ -302,7 +302,7 @@ struct ChatItemInfoView: View { .padding(.horizontal, 12) .padding(.vertical, 6) .background(quotedMsgFrameColor(qi, theme)) - .cornerRadius(18) + .modifier(ChatItemClipped()) .contextMenu { if qi.text != "" { Button { diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index 34ad68f031..40c97202b4 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -754,6 +754,7 @@ struct ChatView: View { playbackState: $playbackState, playbackTime: $playbackTime ) + .modifier(ChatItemClipped(ci)) .contextMenu { menu(ci, range, live: composeState.liveMessage != nil) } .accessibilityLabel("") if ci.content.msgContent != nil && (ci.meta.itemDeleted == nil || revealed) && ci.reactions.count > 0 { diff --git a/apps/ios/Shared/Views/Chat/ReverseList.swift b/apps/ios/Shared/Views/Chat/ReverseList.swift index 512aa9196a..d8a362e847 100644 --- a/apps/ios/Shared/Views/Chat/ReverseList.swift +++ b/apps/ios/Shared/Views/Chat/ReverseList.swift @@ -55,6 +55,7 @@ struct ReverseList: UIV // 1. Style tableView.separatorStyle = .none tableView.transform = .verticalFlip + tableView.backgroundColor = .clear // 2. Register cells if #available(iOS 16.0, *) { diff --git a/apps/ios/Shared/Views/Helpers/ChatItemClipShape.swift b/apps/ios/Shared/Views/Helpers/ChatItemClipShape.swift new file mode 100644 index 0000000000..3e5200f281 --- /dev/null +++ b/apps/ios/Shared/Views/Helpers/ChatItemClipShape.swift @@ -0,0 +1,63 @@ +// +// ChatItemClipShape.swift +// SimpleX (iOS) +// +// Created by Levitating Pineapple on 04/07/2024. +// Copyright © 2024 SimpleX Chat. All rights reserved. +// + +import SwiftUI +import SimpleXChat + +/// Modifier, which provides clipping mask for ``ChatItemWithMenu`` view +/// and it's previews: (drag interaction, context menu, etc.) +/// Supports [Dynamic Type](https://developer.apple.com/documentation/uikit/uifont/scaling_fonts_automatically) +/// by retaining pill shape, even when ``ChatItem``'s height is less that twice its corner radius +struct ChatItemClipped: ViewModifier { + struct ClipShape: Shape { + let maxCornerRadius: Double + + func path(in rect: CGRect) -> Path { + Path( + roundedRect: rect, + cornerRadius: min((rect.height / 2), maxCornerRadius), + style: .circular + ) + } + } + + init() { + clipShape = ClipShape( + maxCornerRadius: 18 + ) + } + + init(_ chatItem: ChatItem) { + clipShape = ClipShape( + maxCornerRadius: { + switch chatItem.content { + case + .sndMsgContent, + .rcvMsgContent, + .sndDeleted, + .rcvDeleted, + .sndModerated, + .rcvModerated, + .rcvBlocked: 18 + default: 8 + } + }() + ) + } + + private let clipShape: ClipShape + + func body(content: Content) -> some View { + content + .contentShape(.dragPreview, clipShape) + .contentShape(.contextMenuPreview, clipShape) + .clipShape(clipShape) + } +} + + diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index f7ff222d28..1c5c032e11 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -195,6 +195,7 @@ 8C9BC2652C240D5200875A27 /* ThemeModeEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */; }; 8CC4ED902BD7B8530078AEE8 /* CallAudioDeviceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC4ED8F2BD7B8530078AEE8 /* CallAudioDeviceManager.swift */; }; 8CC956EE2BC0041000412A11 /* NetworkObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC956ED2BC0041000412A11 /* NetworkObserver.swift */; }; + CE984D4B2C36C5D500E3AEFF /* ChatItemClipShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */; }; CEEA861D2C2ABCB50084E1EA /* ReverseList.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEEA861C2C2ABCB50084E1EA /* ReverseList.swift */; }; D7197A1829AE89660055C05A /* WebRTC in Frameworks */ = {isa = PBXBuildFile; productRef = D7197A1729AE89660055C05A /* WebRTC */; }; D72A9088294BD7A70047C86D /* NativeTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72A9087294BD7A70047C86D /* NativeTextEditor.swift */; }; @@ -501,6 +502,7 @@ 8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeModeEditor.swift; sourceTree = ""; }; 8CC4ED8F2BD7B8530078AEE8 /* CallAudioDeviceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallAudioDeviceManager.swift; sourceTree = ""; }; 8CC956ED2BC0041000412A11 /* NetworkObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkObserver.swift; sourceTree = ""; }; + CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemClipShape.swift; sourceTree = ""; }; CEEA861C2C2ABCB50084E1EA /* ReverseList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReverseList.swift; sourceTree = ""; }; D72A9087294BD7A70047C86D /* NativeTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeTextEditor.swift; sourceTree = ""; }; D741547729AF89AF0022400A /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/StoreKit.framework; sourceTree = DEVELOPER_DIR; }; @@ -683,6 +685,7 @@ 8C7F8F0D2C19C0C100D16888 /* ViewModifiers.swift */, 8C74C3ED2C1B942300039E77 /* ChatWallpaper.swift */, 8C9BC2642C240D5100875A27 /* ThemeModeEditor.swift */, + CE984D4A2C36C5D500E3AEFF /* ChatItemClipShape.swift */, ); path = Helpers; sourceTree = ""; @@ -1225,6 +1228,7 @@ 5C7505A827B6D34800BE3227 /* ChatInfoToolbar.swift in Sources */, 5C10D88A28F187F300E58BF0 /* FullScreenMediaView.swift in Sources */, D72A9088294BD7A70047C86D /* NativeTextEditor.swift in Sources */, + CE984D4B2C36C5D500E3AEFF /* ChatItemClipShape.swift in Sources */, 64D0C2C629FAC1EC00B38D5F /* AddContactLearnMore.swift in Sources */, 5C3A88D127DF57800060F1C2 /* FramedItemView.swift in Sources */, 5C65F343297D45E100B67AF3 /* VersionView.swift in Sources */, From 1c10209a31c0b2ee2399e63f24290a6855408785 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Thu, 4 Jul 2024 20:29:44 +0100 Subject: [PATCH 31/43] blog: future of privacy (#4396) * blog: future of privacy * update --- ...-of-privacy-enforcing-privacy-standards.md | 51 ++++++++++++++++++ blog/images/20240704-privacy.jpg | Bin 0 -> 200908 bytes .../src/_includes/blog_previews/20240704.html | 3 ++ 3 files changed, 54 insertions(+) create mode 100644 blog/20240704-future-of-privacy-enforcing-privacy-standards.md create mode 100644 blog/images/20240704-privacy.jpg create mode 100644 website/src/_includes/blog_previews/20240704.html diff --git a/blog/20240704-future-of-privacy-enforcing-privacy-standards.md b/blog/20240704-future-of-privacy-enforcing-privacy-standards.md new file mode 100644 index 0000000000..681242e044 --- /dev/null +++ b/blog/20240704-future-of-privacy-enforcing-privacy-standards.md @@ -0,0 +1,51 @@ +--- +layout: layouts/article.html +title: "The Future of Privacy: Enforcing Privacy Standards" +date: 2024-07-04 +previewBody: blog_previews/20240704.html +image: images/20240704-privacy.jpg +imageWide: true +permalink: "/blog/20240704-future-of-privacy-enforcing-privacy-standards.html" +--- + +# The Future of Privacy: Enforcing Privacy Standards + +**Published:** Jul 4, 2024 + +Recent anti-privacy legislations and proposals in [Europe](https://www.theverge.com/2024/6/19/24181214/eu-chat-control-law-propose-scanning-encrypted-messages-csam), [the US](https://theconversation.com/section-702-foreign-surveillance-law-lives-on-but-privacy-fight-continues-229253) and [Australia](https://www.theguardian.com/technology/article/2024/jun/20/meredith-walker-signal-boss-government-encryption-laws) threaten to infringe our fundamental right to privacy and to create grave risks to the [safety](https://simplex.chat/blog/20240601-protecting-children-safety-requires-e2e-encryption.html) of children and vulnerable people. It's time we shift the focus: privacy should be a non-negotiable duty of technology providers, not just a right users must constantly fight to protect, and not something that users can be asked to consent away as a condition of access to a service. + +Tech giants are trying to normalize surveillance capitalism, often with little to no consequences globally. These companies are contributing to a growing ecosystem where opting out of invasive data hoarding practices is becoming increasingly challenging, if not outright impossible. We are being gaslit by the technology executives who try to justify profiteering from AI theft, from [Microsoft](https://www.computing.co.uk/news/4330395/microsoft-ai-chief-makes-questionable-claims-about-copyright-online-content) claiming all our content is fair game for their exploitation to unethical startups like [Perplexity](https://www.theverge.com/2024/6/27/24187405/perplexity-ai-twitter-lie-plagiarism) turning the word “[privacy](https://x.com/perplexity_ai/status/1789007907092066559)” into a marketable farce. + +## The AI Hype’s Impact on Privacy + +The exaggeration of AI’s actual capabilities and the continuous promotion of its “intelligence” is creating a rat race where tech companies and well-funded startups are evading accountability, as they eagerly collect and exploit more data than ever.  + +They're prioritizing AI development over user privacy and rights, setting a dangerous precedent for current and future online engagements. They've already normalized the use of AI to scan and analyze supposedly private communications - from emails to instant messages - repackaging this intrusion as "productivity tools”. Meanwhile, most consumers actually want [more data privacy](https://iapp.org/news/a/most-consumers-want-data-privacy-and-will-act-to-defend-it), not less, and are increasingly concerned by the lack of it. + +The legal push towards “client-side scanning”, attacks on end-to-end encryption and the support for pro-surveillance legislation gives credibility to these highly intrusive practices that literally endanger lives. And we know that moral obligations mean nothing to corporations benefiting from these exploitative models, so we have to ensure that our demands for privacy are legally enforceable and non-negotiable.  + +## Legal Action + +We are encouraged to see more legal pressure on companies that exploit user data on a daily basis. For example, the European Center for Digital Rights’ (Noyb) [complaints](https://noyb.eu/en/noyb-urges-11-dpas-immediately-stop-metas-abuse-personal-data-ai) against Meta’s abuse of personal data to train their AI and, and the demands from the Norwegian Consumer Council to data protection authority to ensure that applicable laws are enforced against Meta considering there is “[no way to remove personal data from AI models once Meta has begun the training](https://www.forbrukerradet.no/side/legal-complaint-against-metas-use-of-personal-content-for-ai-training/)”. + +Noyb is taking a strong stance against [other companies](https://noyb.eu/en/project/cases) with similar exploitative models, including facial recognition surveillance tools often misused by law enforcement agencies. Consider [supporting](https://noyb.eu/en/support) their ongoing efforts — we strongly believe legal action is one of the most effective means to hold these companies accountable for their persistent abuses, which are otherwise shielded by heavily funded self-serving lobby groups. + +## Privacy as a Legal Obligation + +We must shift from a defensive stance to a proactive one by proposing privacy legislation that puts users in direct control of their private data. + +This legislation should: +1. Establish non-negotiable provider duties for protecting user privacy, with hefty fines and consequences for service operators who do not comply. +2. Prevent providers from circumventing these duties through user consent clauses — it should be legally prohibited to ask for a consent to share user data or to use it for anything other than providing a service. +3. Prevent providers from asking for any more personal information from the users than technically necessary and legally required. For example, asking for a phone number as a condition of access to a service should be made illegal in most cases — it does not provide a sufficient security, exposes users' private information and allows simple aggregation of users' data across multiple services. +4. Create a strong legal framework that cannot be resisted or modified + +By codifying these principles into law, we can establish a strong technological framework that is built to create more value for end users, while protecting their privacy against data exploitation, criminal use and identity theft. We will continue the fight against illogical legislative proposals designed to normalize mass surveillance, but our efforts should equally gear towards creating and supporting new models and technological foundations that bring us far closer to the reality we urgently need. + +## Collective Action + +There is great work being done by advocacy organizations, and service providers need to contribute to this fight as well by shifting the narrative and reclaiming the term “privacy” from the tech giants who co-opted and corrupted it. We must play a bigger role in supporting users in setting stronger boundaries, making demands, and refusing anything less than genuine privacy and data ownership, while getting comfortable with holding providers accountable for any violations. + +Privacy should be seen as a fundamental obligation of technology providers, and legislators must actively enforce this expectation. The more consumers make this demand, the more pressure we put on anti-privacy lobbyists with rogue motives, the easier it will be to hold abusers accountable, and the more likely we can collectively ensure that a privacy-first web becomes a reality. + +You can support privacy today by signing [the petition](https://www.globalencryption.org/2024/05/joint-statement-on-the-dangers-of-the-may-2024-council-of-the-eu-compromise-proposal-on-eu-csam/) prepared by Global Encryption Coalition in support of communication privacy. You can also write to your elected representatives, explaining them how data privacy and encrypted communications protect children safety and reduce crime. diff --git a/blog/images/20240704-privacy.jpg b/blog/images/20240704-privacy.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bfcbf11d3f5f216fc52b38faa3a99fcd34800d12 GIT binary patch literal 200908 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ℜ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
    HI7g8uv7?x~~+_2>9EcS;^_2YV)eX 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's time we shift the focus: privacy should be a non-negotiable duty of technology providers, not just a + right users must fight to protect, and not something that users can be asked to consent away as a + condition of access to a service.

    \ No newline at end of file From f90de83215bfbb9fd0168f07d3c9f80feefe264c Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Fri, 5 Jul 2024 08:23:29 +0100 Subject: [PATCH 32/43] ios: corrections, localizations (#4406) --- .../Views/ChatList/ServersSummaryView.swift | 44 +- .../UserSettings/AppearanceSettings.swift | 2 +- .../bg.xcloc/Localized Contents/bg.xliff | 525 +++++++++++++- .../bg.xcloc/contents.json | 4 +- .../cs.xcloc/Localized Contents/cs.xliff | 525 +++++++++++++- .../cs.xcloc/contents.json | 4 +- .../de.xcloc/Localized Contents/de.xliff | 525 +++++++++++++- .../de.xcloc/contents.json | 4 +- .../en.xcloc/Localized Contents/en.xliff | 653 +++++++++++++++++- .../en.xcloc/contents.json | 4 +- .../es.xcloc/Localized Contents/es.xliff | 525 +++++++++++++- .../es.xcloc/contents.json | 4 +- .../fi.xcloc/Localized Contents/fi.xliff | 525 +++++++++++++- .../fi.xcloc/contents.json | 4 +- .../fr.xcloc/Localized Contents/fr.xliff | 525 +++++++++++++- .../fr.xcloc/contents.json | 4 +- .../hu.xcloc/Localized Contents/hu.xliff | 525 +++++++++++++- .../hu.xcloc/contents.json | 4 +- .../it.xcloc/Localized Contents/it.xliff | 525 +++++++++++++- .../it.xcloc/contents.json | 4 +- .../ja.xcloc/Localized Contents/ja.xliff | 525 +++++++++++++- .../ja.xcloc/contents.json | 4 +- .../nl.xcloc/Localized Contents/nl.xliff | 525 +++++++++++++- .../nl.xcloc/contents.json | 4 +- .../pl.xcloc/Localized Contents/pl.xliff | 525 +++++++++++++- .../pl.xcloc/contents.json | 4 +- .../ru.xcloc/Localized Contents/ru.xliff | 525 +++++++++++++- .../ru.xcloc/contents.json | 4 +- .../th.xcloc/Localized Contents/th.xliff | 525 +++++++++++++- .../th.xcloc/contents.json | 4 +- .../tr.xcloc/Localized Contents/tr.xliff | 525 +++++++++++++- .../tr.xcloc/contents.json | 4 +- .../uk.xcloc/Localized Contents/uk.xliff | 525 +++++++++++++- .../uk.xcloc/contents.json | 4 +- .../Localized Contents/zh-Hans.xliff | 525 +++++++++++++- .../zh-Hans.xcloc/contents.json | 4 +- 36 files changed, 8850 insertions(+), 317 deletions(-) diff --git a/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift b/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift index 00cbe9a236..1fb889f863 100644 --- a/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift +++ b/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift @@ -363,7 +363,7 @@ struct ServersSummaryView: View { Button { alert = SomeAlert( alert: Alert( - title: Text("Reset all servers statistics?"), + title: Text("Reset all statistics?"), message: Text("Servers statistics will be reset - this cannot be undone!"), primaryButton: .destructive(Text("Reset")) { Task { @@ -425,7 +425,7 @@ struct SubscriptionStatusPercentageView: View { var body: some View { let onionHosts = networkUseOnionHostsGroupDefault.get() let (_, _, _, statusPercent) = subscriptionStatusColorAndPercentage(m.networkInfo.online, onionHosts, subs, sess) - Text("\(Int(floor(statusPercent * 100)))%") + Text(verbatim: "\(Int(floor(statusPercent * 100)))%") .foregroundColor(.secondary) .font(.caption) } @@ -595,21 +595,21 @@ struct DetailedSMPStatsView: View { infoRowTwoValues("Sent via proxy", "attempts", stats._sentViaProxy, stats._sentViaProxyAttempts) infoRowTwoValues("Proxied", "attempts", stats._sentProxied, stats._sentProxiedAttempts) Text("Send errors") - indentedInfoRow("AUTH", numOrDash(stats._sentAuthErrs)) - indentedInfoRow("QUOTA", numOrDash(stats._sentQuotaErrs)) - indentedInfoRow("expired", numOrDash(stats._sentExpiredErrs)) - indentedInfoRow("other", numOrDash(stats._sentOtherErrs)) + infoRow(Text(verbatim: "AUTH"), numOrDash(stats._sentAuthErrs)).padding(.leading, 24) + infoRow(Text(verbatim: "QUOTA"), numOrDash(stats._sentQuotaErrs)).padding(.leading, 24) + infoRow("expired", numOrDash(stats._sentExpiredErrs)).padding(.leading, 24) + infoRow("other", numOrDash(stats._sentOtherErrs)).padding(.leading, 24) } Section("Received messages") { infoRow("Received total", numOrDash(stats._recvMsgs)) Text("Receive errors") - indentedInfoRow("duplicates", numOrDash(stats._recvDuplicates)) - indentedInfoRow("decryption errors", numOrDash(stats._recvCryptoErrs)) - indentedInfoRow("other errors", numOrDash(stats._recvErrs)) + infoRow("duplicates", numOrDash(stats._recvDuplicates)).padding(.leading, 24) + infoRow("decryption errors", numOrDash(stats._recvCryptoErrs)).padding(.leading, 24) + infoRow("other errors", numOrDash(stats._recvErrs)).padding(.leading, 24) infoRowTwoValues("Acknowledged", "attempts", stats._ackMsgs, stats._ackAttempts) Text("Acknowledgement errors") - indentedInfoRow("NO_MSG errors", numOrDash(stats._ackNoMsgErrs)) - indentedInfoRow("other errors", numOrDash(stats._ackOtherErrs)) + infoRow(Text(verbatim: "NO_MSG errors"), numOrDash(stats._ackNoMsgErrs)).padding(.leading, 24) + infoRow("other errors", numOrDash(stats._ackOtherErrs)).padding(.leading, 24) } Section { infoRow("Created", numOrDash(stats._connCreated)) @@ -618,7 +618,7 @@ struct DetailedSMPStatsView: View { infoRowTwoValues("Deleted", "attempts", stats._connDeleted, stats._connDelAttempts) infoRow("Deletion errors", numOrDash(stats._connDelErrs)) infoRowTwoValues("Subscribed", "attempts", stats._connSubscribed, stats._connSubAttempts) - infoRow("Subscription results ignored", numOrDash(stats._connSubIgnored)) + infoRow("Subscriptions ignored", numOrDash(stats._connSubIgnored)) infoRow("Subscription errors", numOrDash(stats._connSubErrs)) } header: { Text("Connections") @@ -631,29 +631,19 @@ struct DetailedSMPStatsView: View { private func infoRowTwoValues(_ title: LocalizedStringKey, _ title2: LocalizedStringKey, _ value: Int, _ value2: Int) -> some View { HStack { - Text(title) + Text(" / ").font(.caption2) + Text(title2).font(.caption2) + Text(title) + Text(verbatim: " / ").font(.caption2) + Text(title2).font(.caption2) Spacer() Group { if value == 0 && value2 == 0 { - Text("-") + Text(verbatim: "-") } else { - Text(numOrDash(value)) + Text(" / ").font(.caption2) + Text(numOrDash(value2)).font(.caption2) + Text(numOrDash(value)) + Text(verbatim: " / ").font(.caption2) + Text(numOrDash(value2)).font(.caption2) } } .foregroundStyle(.secondary) } } -private func indentedInfoRow(_ title: LocalizedStringKey, _ value: String) -> some View { - HStack { - Text(title) - .padding(.leading, 24) - Spacer() - Text(value) - .foregroundStyle(.secondary) - } -} - struct XFTPServerSummaryView: View { var summary: XFTPServerSummary var statsStartedAt: Date @@ -732,8 +722,8 @@ struct DetailedXFTPStatsView: View { infoRow("Size", prettySize(stats._downloadsSize)) infoRowTwoValues("Chunks downloaded", "attempts", stats._downloads, stats._downloadAttempts) Text("Download errors") - indentedInfoRow("AUTH", numOrDash(stats._downloadAuthErrs)) - indentedInfoRow("other", numOrDash(stats._downloadErrs)) + infoRow(Text(verbatim: "AUTH"), numOrDash(stats._downloadAuthErrs)).padding(.leading, 24) + infoRow("other", numOrDash(stats._downloadErrs)).padding(.leading, 24) } header: { Text("Downloaded files") } footer: { diff --git a/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift b/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift index 209f25496d..89f8c12423 100644 --- a/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift +++ b/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift @@ -747,7 +747,7 @@ struct ThemeDestinationPicker: View { let values = [(nil, "All profiles")] + m.users.filter { $0.user.activeUser }.map { ($0.user.userId, $0.user.chatViewName)} if values.contains(where: { (userId, text) in userId == themeUserDestination?.0 }) { - Picker("Apply to mode", selection: $themeUserDest) { + Picker("Apply to", selection: $themeUserDest) { ForEach(values, id: \.0) { (_, text) in Text(text) } diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff index 673d6668f9..3d2a5ffb59 100644 --- a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff +++ b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff @@ -2,7 +2,7 @@
    - +
    @@ -557,9 +557,8 @@ Повече за SimpleX адреса No comment provided by engineer. - - Accent color - Основен цвят + + Accent No comment provided by engineer. @@ -583,6 +582,14 @@ Приеми инкогнито accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Добавете адрес към вашия профил, така че вашите контакти да могат да го споделят с други хора. Актуализацията на профила ще бъде изпратена до вашите контакти. @@ -623,6 +630,18 @@ Добави съобщение при посрещане No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address Адрес @@ -648,6 +667,10 @@ Разширени мрежови настройки No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. Всички данни от приложението бяха изтрити. @@ -663,6 +686,10 @@ Всички данни се изтриват при въвеждане. No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. Всички членове на групата ще останат свързани. @@ -683,6 +710,10 @@ Всички нови съобщения от %@ ще бъдат скрити! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. Всички ваши контакти ще останат свързани. @@ -881,6 +912,10 @@ Приложи No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload Архивиране и качване @@ -956,6 +991,10 @@ Назад No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address Грешен адрес на настолното устройство @@ -981,6 +1020,10 @@ По-добри съобщения No comment provided by engineer. + + Black + No comment provided by engineer. + Block Блокирай @@ -1091,6 +1134,10 @@ Няма достъп до Keychain за запазване на паролата за базата данни No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file Файлът не може да бъде получен @@ -1161,6 +1208,10 @@ Архив на чата No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console Конзола @@ -1206,6 +1257,10 @@ Чат настройки No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats Чатове @@ -1236,6 +1291,18 @@ Избери от библиотеката No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear Изчисти @@ -1261,9 +1328,8 @@ Изчисти проверката No comment provided by engineer. - - Colors - Цветове + + Color mode No comment provided by engineer. @@ -1276,6 +1342,10 @@ Сравнете кодовете за сигурност с вашите контакти. No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers Конфигурирай ICE сървъри @@ -1384,16 +1454,28 @@ This is your own one-time link! Свързване с %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop Свързано настолно устройство No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop Свързан с настолно устройство No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… Свързване със сървъра… @@ -1439,6 +1521,18 @@ This is your own one-time link! Времето на изчакване за установяване на връзката изтече No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows Контактът позволява @@ -1492,7 +1586,11 @@ This is your own one-time link! Copy Копирай - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1569,6 +1667,10 @@ This is your own one-time link! Създай своя профил No comment provided by engineer. + + Created + No comment provided by engineer. + Created at Създаден на @@ -1604,6 +1706,10 @@ This is your own one-time link! Текуща парола… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. В момента максималният поддържан размер на файла е %@. @@ -1614,11 +1720,19 @@ This is your own one-time link! Персонализирано време No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark Тъмна No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID ID в базата данни @@ -1923,6 +2037,10 @@ This cannot be undone! Изтрий потребителския профил? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at Изтрито на @@ -1933,6 +2051,10 @@ This cannot be undone! Изтрито на: %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery Доставка @@ -1972,6 +2094,14 @@ This cannot be undone! Destination server error: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop Разработване @@ -2125,6 +2255,10 @@ This cannot be undone! Изтегли chat item action + + Download errors + No comment provided by engineer. + Download failed Неуспешно изтегляне @@ -2135,6 +2269,14 @@ This cannot be undone! Свали файл server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive Архива се изтегля @@ -2505,6 +2647,10 @@ This cannot be undone! Грешка при експортиране на чат базата данни No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Грешка при импортиране на чат базата данни @@ -2530,11 +2676,23 @@ This cannot be undone! Грешка при получаване на файл No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member Грешка при отстраняване на член No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers Грешка при запазване на %@ сървъра @@ -2653,7 +2811,8 @@ This cannot be undone! Error: %@ Грешка: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2665,6 +2824,10 @@ This cannot be undone! Грешка: няма файл с база данни No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. Дори когато е деактивиран в разговора. @@ -2690,6 +2853,10 @@ This cannot be undone! Грешка при експортиране: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. Експортиран архив на базата данни. @@ -2725,6 +2892,26 @@ This cannot be undone! Любим No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. Файлът ще бъде изтрит от сървърите. @@ -2909,6 +3096,14 @@ Error: %2$@ GIF файлове и стикери No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group Група @@ -3189,6 +3384,10 @@ Error: %2$@ Неуспешно импортиране No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive Импортиране на архив @@ -3311,6 +3510,10 @@ Error: %2$@ Интерфейс No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code Невалиден QR код @@ -3669,6 +3872,10 @@ This is your link for group %@! Членът ще бъде премахнат от групата - това не може да бъде отменено! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error Грешка при доставката на съобщението @@ -3720,6 +3927,18 @@ This is your link for group %@! Източникът на съобщението остава скрит. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text Текст на съобщението @@ -3745,6 +3964,14 @@ This is your link for group %@! Съобщенията от %@ ще бъдат показани! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. Съобщенията, файловете и разговорите са защитени чрез **криптиране от край до край** с перфектна секретност при препращане, правдоподобно опровержение и възстановяване при взлом. @@ -3994,6 +4221,10 @@ This is your link for group %@! Няма история No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection Няма мрежова връзка @@ -4178,6 +4409,10 @@ This is your link for group %@! Отвори миграцията към друго устройство authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles Отвори потребителските профили @@ -4283,6 +4518,10 @@ This is your link for group %@! Постави получения линк No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. Хората могат да се свържат с вас само чрез ликовете, които споделяте. @@ -4308,6 +4547,11 @@ This is your link for group %@! Моля, попитайте вашия контакт, за да активирате изпращане на гласови съобщения. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Моля, проверете дали сте използвали правилния линк или поискайте вашия контакт, за да ви изпрати друг. @@ -4405,6 +4649,10 @@ Error: %@ Визуализация No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security Поверителност и сигурност @@ -4467,6 +4715,10 @@ Error: %@ Профилна парола No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. Актуализацията на профила ще бъде изпратена до вашите контакти. @@ -4546,6 +4798,14 @@ Enable in *Network & servers* settings. Време за изчакване на протокола за KB No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications Push известия @@ -4611,6 +4871,10 @@ Enable in *Network & servers* settings. Потвърждениeто за доставка е деактивирано No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at Получено в @@ -4631,6 +4895,18 @@ Enable in *Network & servers* settings. Получено съобщение message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. Получаващият адрес ще бъде променен към друг сървър. Промяната на адреса ще завърши, след като подателят е онлайн. @@ -4661,11 +4937,31 @@ Enable in *Network & servers* settings. Получателите виждат актуализации, докато ги въвеждате. No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Повторно се свържете с всички свързани сървъри, за да принудите доставката на съобщенията. Използва се допълнителен трафик. No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? Повторно свърване със сървърите? @@ -4716,6 +5012,10 @@ Enable in *Network & servers* settings. Премахване No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member Острани член @@ -4786,16 +5086,32 @@ Enable in *Network & servers* settings. Нулиране No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors Нулирай цветовете No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults Възстановяване на настройките по подразбиране No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Рестартирайте приложението, за да създадете нов чат профил @@ -4866,6 +5182,10 @@ Enable in *Network & servers* settings. Стартиране на чат No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers SMP сървъри @@ -4980,6 +5300,14 @@ Enable in *Network & servers* settings. Запазено съобщение message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code Сканирай QR код @@ -5020,11 +5348,19 @@ Enable in *Network & servers* settings. Търсене или поставяне на SimpleX линк No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue Сигурна опашка server test step + + Secured + No comment provided by engineer. + Security assessment Оценка на сигурността @@ -5040,6 +5376,10 @@ Enable in *Network & servers* settings. Избери No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Самоунищожение @@ -5090,6 +5430,10 @@ Enable in *Network & servers* settings. Изпрати изчезващо съобщение No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews Изпрати визуализация на линковете @@ -5198,6 +5542,10 @@ Enable in *Network & servers* settings. Изпратено на: %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event Събитие за изпратен файл @@ -5208,11 +5556,31 @@ Enable in *Network & servers* settings. Изпратено съобщение message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. Изпратените съобщения ще бъдат изтрити след зададеното време. No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. srv error text. @@ -5232,6 +5600,10 @@ Enable in *Network & servers* settings. Тестът на сървъра е неуспешен! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. srv error text @@ -5241,6 +5613,14 @@ Enable in *Network & servers* settings. Сървъри No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code Код на сесията @@ -5256,6 +5636,10 @@ Enable in *Network & servers* settings. Задай име на контакт… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences Задай групови настройки @@ -5374,6 +5758,10 @@ Enable in *Network & servers* settings. Покажи: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address SimpleX Адрес @@ -5449,6 +5837,10 @@ Enable in *Network & servers* settings. Опростен режим инкогнито No comment provided by engineer. + + Size + No comment provided by engineer. + Skip Пропускане @@ -5494,6 +5886,14 @@ Enable in *Network & servers* settings. Започни миграция No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop Спри @@ -5559,6 +5959,22 @@ Enable in *Network & servers* settings. Изпрати No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat Подкрепете SimpleX Chat @@ -5639,6 +6055,10 @@ Enable in *Network & servers* settings. Докосни за започване на нов чат No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. Тестът е неуспешен на стъпка %@. @@ -5775,9 +6195,8 @@ It can happen because of some bug or when the connection is compromised.Текстът, който поставихте, не е SimpleX линк за връзка. No comment provided by engineer. - - Theme - Тема + + Themes No comment provided by engineer. @@ -5845,11 +6264,19 @@ It can happen because of some bug or when the connection is compromised.Това е вашят еднократен линк за връзка! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. Тази настройка се прилага за съобщения в текущия ви профил **%@**. No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: За да задавате въпроси и да получавате актуализации: @@ -5916,11 +6343,19 @@ You will be prompted to complete authentication before this feature is enabled.< Избор на инкогнито при свързване. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation Транспортна изолация No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Опит за свързване със сървъра, използван за получаване на съобщения от този контакт (грешка: %@). @@ -6112,6 +6547,10 @@ To connect, please ask your contact to create another connection link and check Актуализирай и отвори чата No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed Неуспешно качване @@ -6122,6 +6561,14 @@ To connect, please ask your contact to create another connection link and check Качи файл server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive Архивът се качва @@ -6195,6 +6642,10 @@ To connect, please ask your contact to create another connection link and check Потребителски профил No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. Използването на .onion хостове изисква съвместим VPN доставчик. @@ -6330,6 +6781,14 @@ To connect, please ask your contact to create another connection link and check Изчаква се получаването на видеото No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures Внимание: стартирането на чата на множество устройства не се поддържа и ще доведе до неуспешно изпращане на съобщения @@ -6432,11 +6891,19 @@ To connect, please ask your contact to create another connection link and check Wrong key or unknown connection - most likely this connection is deleted. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! Грешна парола! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers XFTP сървъри @@ -6519,6 +6986,10 @@ Repeat join request? Поканени сте в групата No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. Можете да приемате обаждания от заключен екран, без идентификация на устройство и приложението. @@ -6925,6 +7396,10 @@ SimpleX сървърите не могат да видят вашия профи и %lld други събития No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) аудио разговор (не е e2e криптиран) @@ -6958,7 +7433,7 @@ SimpleX сървърите не могат да видят вашия профи blocked by admin блокиран от админ - marked deleted chat item preview text + blocked chat item bold @@ -7115,6 +7590,10 @@ SimpleX сървърите не могат да видят вашия профи дни time unit + + decryption errors + No comment provided by engineer. + default (%@) по подразбиране (%@) @@ -7165,6 +7644,10 @@ SimpleX сървърите не могат да видят вашия профи дублирано съобщение integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted e2e криптиран @@ -7245,6 +7728,10 @@ SimpleX сървърите не могат да видят вашия профи събитие се случи No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded препратено @@ -7452,6 +7939,14 @@ SimpleX сървърите не могат да видят вашия профи включено group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner собственик @@ -7759,7 +8254,7 @@ last received msg: %2$@
    - +
    @@ -7796,7 +8291,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/contents.json b/apps/ios/SimpleX Localizations/bg.xcloc/contents.json index 23e8239ce8..5356e25a2e 100644 --- a/apps/ios/SimpleX Localizations/bg.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/bg.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "bg", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff b/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff index 24c71a3487..7feb1a7b27 100644 --- a/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff +++ b/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff @@ -2,7 +2,7 @@
    - +
    @@ -539,9 +539,8 @@ O SimpleX adrese No comment provided by engineer. - - Accent color - Zbarvení + + Accent No comment provided by engineer. @@ -565,6 +564,14 @@ Přijmout inkognito accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Přidejte adresu do svého profilu, aby ji vaše kontakty mohly sdílet s dalšími lidmi. Aktualizace profilu bude zaslána vašim kontaktům. @@ -604,6 +611,18 @@ Přidat uvítací zprávu No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address Adresa @@ -628,6 +647,10 @@ Pokročilá nastavení sítě No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. Všechna data aplikace jsou smazána. @@ -643,6 +666,10 @@ Všechna data se při zadání vymažou. No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. Všichni členové skupiny zůstanou připojeni. @@ -661,6 +688,10 @@ All new messages from %@ will be hidden! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. Všechny vaše kontakty zůstanou připojeny. @@ -853,6 +884,10 @@ Apply No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload No comment provided by engineer. @@ -926,6 +961,10 @@ Zpět No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address No comment provided by engineer. @@ -949,6 +988,10 @@ Lepší zprávy No comment provided by engineer. + + Black + No comment provided by engineer. + Block No comment provided by engineer. @@ -1050,6 +1093,10 @@ Nelze získat přístup ke klíčence pro uložení hesla databáze No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file Nelze přijmout soubor @@ -1119,6 +1166,10 @@ Chat se archivuje No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console Konzola pro chat @@ -1162,6 +1213,10 @@ Předvolby chatu No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats Chaty @@ -1191,6 +1246,18 @@ Vybrat z knihovny No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear Vyčistit @@ -1215,9 +1282,8 @@ Zrušte ověření No comment provided by engineer. - - Colors - Barvy + + Color mode No comment provided by engineer. @@ -1230,6 +1296,10 @@ Porovnejte bezpečnostní kódy se svými kontakty. No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers Konfigurace serverů ICE @@ -1326,14 +1396,26 @@ This is your own one-time link! Connect with %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… Připojování k serveru… @@ -1377,6 +1459,18 @@ This is your own one-time link! Časový limit připojení No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows Kontakt povolil @@ -1430,7 +1524,11 @@ This is your own one-time link! Copy Kopírovat - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1503,6 +1601,10 @@ This is your own one-time link! Vytvořte si profil No comment provided by engineer. + + Created + No comment provided by engineer. + Created at No comment provided by engineer. @@ -1534,6 +1636,10 @@ This is your own one-time link! Aktuální přístupová fráze… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. Aktuálně maximální podporovaná velikost souboru je %@. @@ -1544,11 +1650,19 @@ This is your own one-time link! Vlastní čas No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark Tmavý No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID ID databáze @@ -1848,6 +1962,10 @@ This cannot be undone! Smazat uživatelský profil? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at Smazáno v @@ -1858,6 +1976,10 @@ This cannot be undone! Smazáno v: %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery Doručenka @@ -1894,6 +2016,14 @@ This cannot be undone! Destination server error: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop Vyvinout @@ -2043,6 +2173,10 @@ This cannot be undone! Download chat item action + + Download errors + No comment provided by engineer. + Download failed No comment provided by engineer. @@ -2052,6 +2186,14 @@ This cannot be undone! Stáhnout soubor server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive No comment provided by engineer. @@ -2408,6 +2550,10 @@ This cannot be undone! Chyba při exportu databáze chatu No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Chyba při importu databáze chatu @@ -2432,11 +2578,23 @@ This cannot be undone! Chyba při příjmu souboru No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member Chyba při odebrání člena No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers Chyba při ukládání serverů %@ @@ -2551,7 +2709,8 @@ This cannot be undone! Error: %@ Chyba: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2563,6 +2722,10 @@ This cannot be undone! Chyba: žádný soubor databáze No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. I při vypnutí v konverzaci. @@ -2587,6 +2750,10 @@ This cannot be undone! Chyba exportu: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. Exportovaný archiv databáze. @@ -2620,6 +2787,26 @@ This cannot be undone! Oblíbené No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. Soubor bude smazán ze serverů. @@ -2795,6 +2982,14 @@ Error: %2$@ GIFy a nálepky No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group Skupina @@ -3069,6 +3264,10 @@ Error: %2$@ Import failed No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive No comment provided by engineer. @@ -3185,6 +3384,10 @@ Error: %2$@ Rozhranní No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code No comment provided by engineer. @@ -3526,6 +3729,10 @@ This is your link for group %@! Člen bude odstraněn ze skupiny - toto nelze vzít zpět! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error Chyba doručení zprávy @@ -3576,6 +3783,18 @@ This is your link for group %@! Message source remains private. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text Text zprávy @@ -3599,6 +3818,14 @@ This is your link for group %@! Messages from %@ will be shown! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. No comment provided by engineer. @@ -3835,6 +4062,10 @@ This is your link for group %@! Žádná historie No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection No comment provided by engineer. @@ -4014,6 +4245,10 @@ This is your link for group %@! Open migration to another device authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles Otevřít uživatelské profily @@ -4109,6 +4344,10 @@ This is your link for group %@! Paste the link you received No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. Lidé se s vámi mohou spojit pouze prostřednictvím odkazů, které sdílíte. @@ -4133,6 +4372,11 @@ This is your link for group %@! Prosím, požádejte kontaktní osobu, aby umožnila odesílání hlasových zpráv. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Zkontrolujte, zda jste použili správný odkaz, nebo požádejte kontakt, aby vám poslal jiný. @@ -4227,6 +4471,10 @@ Error: %@ Náhled No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security Ochrana osobních údajů a zabezpečení @@ -4285,6 +4533,10 @@ Error: %@ Heslo profilu No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. Aktualizace profilu bude zaslána vašim kontaktům. @@ -4363,6 +4615,14 @@ Enable in *Network & servers* settings. Časový limit protokolu na KB No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications Nabízená oznámení @@ -4425,6 +4685,10 @@ Enable in *Network & servers* settings. Informace o dodání jsou zakázány No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at Přijato v @@ -4445,6 +4709,18 @@ Enable in *Network & servers* settings. Přijatá zpráva message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. Přijímací adresa bude změněna na jiný server. Změna adresy bude dokončena po připojení odesílatele. @@ -4473,11 +4749,31 @@ Enable in *Network & servers* settings. Příjemci uvidí aktualizace během jejich psaní. No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Znovu připojte všechny připojené servery a vynuťte doručení zprávy. Využívá další provoz. No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? Znovu připojit servery? @@ -4528,6 +4824,10 @@ Enable in *Network & servers* settings. Odstranit No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member Odstranit člena @@ -4593,16 +4893,32 @@ Enable in *Network & servers* settings. Obnovit No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors Obnovení barev No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults Obnovení výchozího nastavení No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Restartujte aplikaci pro vytvoření nového chat profilu @@ -4672,6 +4988,10 @@ Enable in *Network & servers* settings. Spustit chat No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers SMP servery @@ -4782,6 +5102,14 @@ Enable in *Network & servers* settings. Saved message message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code Skenovat QR kód @@ -4819,11 +5147,19 @@ Enable in *Network & servers* settings. Search or paste SimpleX link No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue Zabezpečit frontu server test step + + Secured + No comment provided by engineer. + Security assessment Posouzení bezpečnosti @@ -4839,6 +5175,10 @@ Enable in *Network & servers* settings. Vybrat No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Sebedestrukce @@ -4889,6 +5229,10 @@ Enable in *Network & servers* settings. Poslat mizící zprávu No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews Odesílání náhledů odkazů @@ -4996,6 +5340,10 @@ Enable in *Network & servers* settings. Posláno v: % @ copied message info + + Sent directly + No comment provided by engineer. + Sent file event Odeslaná událost souboru @@ -5006,11 +5354,31 @@ Enable in *Network & servers* settings. Poslaná zpráva message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. Odeslané zprávy se po uplynutí nastavené doby odstraní. No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. srv error text. @@ -5030,6 +5398,10 @@ Enable in *Network & servers* settings. Test serveru se nezdařil! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. srv error text @@ -5039,6 +5411,14 @@ Enable in *Network & servers* settings. Servery No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code No comment provided by engineer. @@ -5053,6 +5433,10 @@ Enable in *Network & servers* settings. Nastavení jména kontaktu… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences Nastavení skupinových předvoleb @@ -5167,6 +5551,10 @@ Enable in *Network & servers* settings. Zobrazit: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address SimpleX Adresa @@ -5240,6 +5628,10 @@ Enable in *Network & servers* settings. Zjednodušený inkognito režim No comment provided by engineer. + + Size + No comment provided by engineer. + Skip Přeskočit @@ -5283,6 +5675,14 @@ Enable in *Network & servers* settings. Zahájit přenesení No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop Zastavit @@ -5346,6 +5746,22 @@ Enable in *Network & servers* settings. Odeslat No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat Podpořte SimpleX Chat @@ -5423,6 +5839,10 @@ Enable in *Network & servers* settings. Klepnutím na zahájíte nový chat No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. Test selhal v kroku %@. @@ -5557,9 +5977,8 @@ Může se to stát kvůli nějaké chybě, nebo pokud je spojení kompromitován The text you pasted is not a SimpleX link. No comment provided by engineer. - - Theme - Téma + + Themes No comment provided by engineer. @@ -5621,11 +6040,19 @@ Může se to stát kvůli nějaké chybě, nebo pokud je spojení kompromitován This is your own one-time link! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. Toto nastavení platí pro zprávy ve vašem aktuálním chat profilu **%@**. No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: Chcete-li položit jakékoli dotazy a dostávat aktuality: @@ -5691,11 +6118,19 @@ Před zapnutím této funkce budete vyzváni k dokončení ověření. Změnit inkognito režim při připojení. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation Izolace transportu No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Pokus o připojení k serveru používanému k přijímání zpráv od tohoto kontaktu (chyba: %@). @@ -5878,6 +6313,10 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu Zvýšit a otevřít chat No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed No comment provided by engineer. @@ -5887,6 +6326,14 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu Nahrát soubor server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive No comment provided by engineer. @@ -5956,6 +6403,10 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu Profil uživatele No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. Použití hostitelů .onion vyžaduje kompatibilního poskytovatele VPN. @@ -6082,6 +6533,14 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu Čekám na video No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures No comment provided by engineer. @@ -6176,11 +6635,19 @@ Chcete-li se připojit, požádejte svůj kontakt o vytvoření dalšího odkazu Wrong key or unknown connection - most likely this connection is deleted. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! Špatná přístupová fráze! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers XFTP servery @@ -6254,6 +6721,10 @@ Repeat join request? Jste pozváni do skupiny No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. Můžete přijímat hovory z obrazovky zámku, bez ověření zařízení a aplikace. @@ -6648,6 +7119,10 @@ Servery SimpleX nevidí váš profil. and %lld other events No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) zvukový hovor (nešifrovaný e2e) @@ -6677,7 +7152,7 @@ Servery SimpleX nevidí váš profil. blocked by admin - marked deleted chat item preview text + blocked chat item bold @@ -6833,6 +7308,10 @@ Servery SimpleX nevidí váš profil. dní time unit + + decryption errors + No comment provided by engineer. + default (%@) výchozí (%@) @@ -6882,6 +7361,10 @@ Servery SimpleX nevidí váš profil. duplicitní zpráva integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted e2e šifrované @@ -6961,6 +7444,10 @@ Servery SimpleX nevidí váš profil. event happened No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded No comment provided by engineer. @@ -7166,6 +7653,14 @@ Servery SimpleX nevidí váš profil. zapnuto group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner vlastník @@ -7457,7 +7952,7 @@ last received msg: %2$@
    - +
    @@ -7493,7 +7988,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/cs.xcloc/contents.json b/apps/ios/SimpleX Localizations/cs.xcloc/contents.json index 5c7c929ee3..aaa2ed1ee0 100644 --- a/apps/ios/SimpleX Localizations/cs.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/cs.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "cs", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff index 4889950d33..a33fb400c7 100644 --- a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff +++ b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff @@ -2,7 +2,7 @@
    - +
    @@ -557,9 +557,8 @@ Über die SimpleX-Adresse No comment provided by engineer. - - Accent color - Akzentfarbe + + Accent No comment provided by engineer. @@ -583,6 +582,14 @@ Inkognito akzeptieren accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Fügen Sie die Adresse Ihrem Profil hinzu, damit Ihre Kontakte sie mit anderen Personen teilen können. Es wird eine Profilaktualisierung an Ihre Kontakte gesendet. @@ -623,6 +630,18 @@ Begrüßungsmeldung hinzufügen No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address Adresse @@ -648,6 +667,10 @@ Erweiterte Netzwerkeinstellungen No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. Werden die App-Daten komplett gelöscht. @@ -663,6 +686,10 @@ Alle Daten werden gelöscht, sobald dieser eingegeben wird. No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. Alle Gruppenmitglieder bleiben verbunden. @@ -683,6 +710,10 @@ Von %@ werden alle neuen Nachrichten ausgeblendet! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. Alle Ihre Kontakte bleiben verbunden. @@ -883,6 +914,10 @@ Anwenden No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload Archivieren und Hochladen @@ -958,6 +993,10 @@ Zurück No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address Falsche Desktop-Adresse @@ -983,6 +1022,10 @@ Verbesserungen bei Nachrichten No comment provided by engineer. + + Black + No comment provided by engineer. + Block Blockieren @@ -1093,6 +1136,10 @@ Die App kann nicht auf den Schlüsselbund zugreifen, um das Datenbank-Passwort zu speichern No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file Datei kann nicht empfangen werden @@ -1164,6 +1211,10 @@ Datenbank Archiv No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console Chat-Konsole @@ -1209,6 +1260,10 @@ Chat-Präferenzen No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats Chats @@ -1239,6 +1294,18 @@ Aus dem Fotoalbum auswählen No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear Löschen @@ -1264,9 +1331,8 @@ Überprüfung zurücknehmen No comment provided by engineer. - - Colors - Farben + + Color mode No comment provided by engineer. @@ -1279,6 +1345,10 @@ Vergleichen Sie die Sicherheitscodes mit Ihren Kontakten. No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers ICE-Server konfigurieren @@ -1388,16 +1458,28 @@ Das ist Ihr eigener Einmal-Link! Mit %@ verbinden No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop Verbundener Desktop No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop Mit dem Desktop verbunden No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… Mit dem Server verbinden… @@ -1443,6 +1525,18 @@ Das ist Ihr eigener Einmal-Link! Verbindungszeitüberschreitung No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows Der Kontakt erlaubt @@ -1496,7 +1590,11 @@ Das ist Ihr eigener Einmal-Link! Copy Kopieren - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1573,6 +1671,10 @@ Das ist Ihr eigener Einmal-Link! Erstellen Sie Ihr Profil No comment provided by engineer. + + Created + No comment provided by engineer. + Created at Erstellt um @@ -1608,6 +1710,10 @@ Das ist Ihr eigener Einmal-Link! Aktuelles Passwort… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. Die derzeit maximal unterstützte Dateigröße beträgt %@. @@ -1618,11 +1724,19 @@ Das ist Ihr eigener Einmal-Link! Zeit anpassen No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark Dunkel No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID Datenbank-ID @@ -1927,6 +2041,10 @@ Das kann nicht rückgängig gemacht werden! Benutzerprofil löschen? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at Gelöscht um @@ -1937,6 +2055,10 @@ Das kann nicht rückgängig gemacht werden! Gelöscht um: %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery Zustellung @@ -1977,6 +2099,14 @@ Das kann nicht rückgängig gemacht werden! Zielserver-Fehler: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop Entwicklung @@ -2132,6 +2262,10 @@ Das kann nicht rückgängig gemacht werden! Herunterladen chat item action + + Download errors + No comment provided by engineer. + Download failed Herunterladen fehlgeschlagen @@ -2142,6 +2276,14 @@ Das kann nicht rückgängig gemacht werden! Datei herunterladen server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive Archiv wird heruntergeladen @@ -2512,6 +2654,10 @@ Das kann nicht rückgängig gemacht werden! Fehler beim Exportieren der Chat-Datenbank No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Fehler beim Importieren der Chat-Datenbank @@ -2537,11 +2683,23 @@ Das kann nicht rückgängig gemacht werden! Fehler beim Empfangen der Datei No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member Fehler beim Entfernen des Mitglieds No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers Fehler beim Speichern der %@-Server @@ -2660,7 +2818,8 @@ Das kann nicht rückgängig gemacht werden! Error: %@ Fehler: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2672,6 +2831,10 @@ Das kann nicht rückgängig gemacht werden! Fehler: Keine Datenbankdatei No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. Auch wenn sie im Chat deaktiviert sind. @@ -2697,6 +2860,10 @@ Das kann nicht rückgängig gemacht werden! Fehler beim Export: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. Exportiertes Datenbankarchiv. @@ -2732,6 +2899,26 @@ Das kann nicht rückgängig gemacht werden! Favorit No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. Die Datei wird von den Servern gelöscht. @@ -2921,6 +3108,14 @@ Fehler: %2$@ GIFs und Sticker No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group Gruppe @@ -3201,6 +3396,10 @@ Fehler: %2$@ Import ist fehlgeschlagen No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive Archiv wird importiert @@ -3323,6 +3522,10 @@ Fehler: %2$@ Schnittstelle No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code Ungültiger QR-Code @@ -3681,6 +3884,10 @@ Das ist Ihr Link für die Gruppe %@! Das Mitglied wird aus der Gruppe entfernt - dies kann nicht rückgängig gemacht werden! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error Fehler bei der Nachrichtenzustellung @@ -3735,6 +3942,18 @@ Das ist Ihr Link für die Gruppe %@! Die Nachrichtenquelle bleibt privat. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text Nachrichtentext @@ -3760,6 +3979,14 @@ Das ist Ihr Link für die Gruppe %@! Die Nachrichten von %@ werden angezeigt! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. Nachrichten, Dateien und Anrufe sind durch **Ende-zu-Ende-Verschlüsselung** mit Perfect Forward Secrecy, Ablehnung und Einbruchs-Wiederherstellung geschützt. @@ -4010,6 +4237,10 @@ Das ist Ihr Link für die Gruppe %@! Kein Nachrichtenverlauf No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection Keine Netzwerkverbindung @@ -4194,6 +4425,10 @@ Das ist Ihr Link für die Gruppe %@! Migration auf ein anderes Gerät öffnen authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles Benutzerprofile öffnen @@ -4299,6 +4534,10 @@ Das ist Ihr Link für die Gruppe %@! Fügen Sie den erhaltenen Link ein No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. Verbindungen mit Kontakten sind nur über Links möglich, die Sie oder Ihre Kontakte untereinander teilen. @@ -4324,6 +4563,11 @@ Das ist Ihr Link für die Gruppe %@! Bitten Sie Ihren Kontakt darum, das Senden von Sprachnachrichten zu aktivieren. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Überprüfen Sie bitte, ob Sie den richtigen Link genutzt haben oder bitten Sie Ihren Kontakt nochmal darum, Ihnen einen Link zuzusenden. @@ -4421,6 +4665,10 @@ Fehler: %@ Vorschau No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security Datenschutz & Sicherheit @@ -4486,6 +4734,10 @@ Fehler: %@ Passwort für Profil No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. Profil-Aktualisierung wird an Ihre Kontakte gesendet. @@ -4568,6 +4820,14 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Protokollzeitüberschreitung pro kB No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications Push-Benachrichtigungen @@ -4633,6 +4893,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Bestätigungen sind deaktiviert No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at Empfangen um @@ -4653,6 +4917,18 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Empfangene Nachricht message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. Die Empfängeradresse wird auf einen anderen Server geändert. Der Adresswechsel wird abgeschlossen, wenn der Absender wieder online ist. @@ -4683,11 +4959,31 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Die Empfänger sehen Nachrichtenaktualisierungen, während Sie sie eingeben. No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Alle verbundenen Server werden neu verbunden, um die Zustellung der Nachricht zu erzwingen. Dies verursacht zusätzlichen Datenverkehr. No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? Die Server neu verbinden? @@ -4738,6 +5034,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Entfernen No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member Mitglied entfernen @@ -4808,16 +5108,32 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Zurücksetzen No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors Farben zurücksetzen No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults Auf Voreinstellungen zurücksetzen No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Um ein neues Chat-Profil zu erstellen, starten Sie die App neu @@ -4888,6 +5204,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Chat starten No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers SMP-Server @@ -5003,6 +5323,14 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Gespeicherte Nachricht message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code QR-Code scannen @@ -5043,11 +5371,19 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Suchen oder fügen Sie den SimpleX-Link ein No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue Sichere Warteschlange server test step + + Secured + No comment provided by engineer. + Security assessment Sicherheits-Gutachten @@ -5063,6 +5399,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Auswählen No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Selbstzerstörung @@ -5113,6 +5453,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Verschwindende Nachricht senden No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews Link-Vorschau senden @@ -5223,6 +5567,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Gesendet um: %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event Datei-Ereignis wurde gesendet @@ -5233,11 +5581,31 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Gesendete Nachricht message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. Gesendete Nachrichten werden nach der eingestellten Zeit gelöscht. No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. Die Server-Adresse ist nicht mit den Netzwerk-Einstellungen kompatibel. @@ -5258,6 +5626,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Server Test ist fehlgeschlagen! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. Die Server-Version ist nicht mit den Netzwerk-Einstellungen kompatibel. @@ -5268,6 +5640,14 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Server No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code Sitzungscode @@ -5283,6 +5663,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Kontaktname festlegen… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences Gruppen-Präferenzen einstellen @@ -5403,6 +5787,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Anzeigen: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address SimpleX-Adresse @@ -5478,6 +5866,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Vereinfachter Inkognito-Modus No comment provided by engineer. + + Size + No comment provided by engineer. + Skip Überspringen @@ -5523,6 +5915,14 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Starten Sie die Migration No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop Beenden @@ -5588,6 +5988,22 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Bestätigen No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat Unterstützung von SimpleX Chat @@ -5668,6 +6084,10 @@ Aktivieren Sie es in den *Netzwerk & Server* Einstellungen. Zum Starten eines neuen Chats tippen No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. Der Test ist beim Schritt %@ fehlgeschlagen. @@ -5805,9 +6225,8 @@ Dies kann passieren, wenn es einen Fehler gegeben hat oder die Verbindung kompro Der von Ihnen eingefügte Text ist kein SimpleX-Link. No comment provided by engineer. - - Theme - Design + + Themes No comment provided by engineer. @@ -5875,11 +6294,19 @@ Dies kann passieren, wenn es einen Fehler gegeben hat oder die Verbindung kompro Das ist Ihr eigener Einmal-Link! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. Diese Einstellung gilt für Nachrichten in Ihrem aktuellen Chat-Profil **%@**. No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: Um Fragen zu stellen und aktuelle Informationen zu erhalten: @@ -5947,11 +6374,19 @@ Sie werden aufgefordert, die Authentifizierung abzuschließen, bevor diese Funkt Inkognito beim Verbinden einschalten. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation Transport-Isolation No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Beim Versuch die Verbindung mit dem Server aufzunehmen, der für den Empfang von Nachrichten mit diesem Kontakt genutzt wird, ist ein Fehler aufgetreten (Fehler: %@). @@ -6144,6 +6579,10 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s Aktualisieren und den Chat öffnen No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed Hochladen fehlgeschlagen @@ -6154,6 +6593,14 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s Datei hochladen server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive Archiv wird hochgeladen @@ -6229,6 +6676,10 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s Benutzerprofil No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. Für die Nutzung von .onion-Hosts sind kompatible VPN-Anbieter erforderlich. @@ -6364,6 +6815,14 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s Auf das Video warten No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures Warnung: Das Starten des Chats auf mehreren Geräten wird nicht unterstützt und wird zu Fehlern bei der Nachrichtenübermittlung führen @@ -6469,11 +6928,19 @@ Bitten Sie Ihren Kontakt darum einen weiteren Verbindungs-Link zu erzeugen, um s Falscher Schlüssel oder unbekannte Verbindung - höchstwahrscheinlich ist diese Verbindung gelöscht worden. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! Falsches Passwort! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers XFTP-Server @@ -6556,6 +7023,10 @@ Verbindungsanfrage wiederholen? Sie sind zu der Gruppe eingeladen No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. Sie können Anrufe ohne Geräte- und App-Authentifizierung vom Sperrbildschirm aus annehmen. @@ -6962,6 +7433,10 @@ SimpleX-Server können Ihr Profil nicht einsehen. und %lld weitere Ereignisse No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) Audioanruf (nicht E2E verschlüsselt) @@ -6995,7 +7470,7 @@ SimpleX-Server können Ihr Profil nicht einsehen. blocked by admin wurde vom Administrator blockiert - marked deleted chat item preview text + blocked chat item bold @@ -7152,6 +7627,10 @@ SimpleX-Server können Ihr Profil nicht einsehen. Tage time unit + + decryption errors + No comment provided by engineer. + default (%@) Voreinstellung (%@) @@ -7202,6 +7681,10 @@ SimpleX-Server können Ihr Profil nicht einsehen. Doppelte Nachricht integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted E2E-verschlüsselt @@ -7282,6 +7765,10 @@ SimpleX-Server können Ihr Profil nicht einsehen. event happened No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded weitergeleitet @@ -7489,6 +7976,14 @@ SimpleX-Server können Ihr Profil nicht einsehen. Ein group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner Eigentümer @@ -7799,7 +8294,7 @@ last received msg: %2$@
    - +
    @@ -7836,7 +8331,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/de.xcloc/contents.json b/apps/ios/SimpleX Localizations/de.xcloc/contents.json index 11924b71f5..18b517d802 100644 --- a/apps/ios/SimpleX Localizations/de.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/de.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "de", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff index aca1aefb11..30ee4a179a 100644 --- a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff +++ b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff @@ -2,7 +2,7 @@
    - +
    @@ -557,9 +557,9 @@ About SimpleX address No comment provided by engineer. - - Accent color - Accent color + + Accent + Accent No comment provided by engineer. @@ -583,6 +583,16 @@ Accept incognito accept contact request via notification + + Acknowledged + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. @@ -623,6 +633,21 @@ Add welcome message No comment provided by engineer. + + Additional accent + Additional accent + No comment provided by engineer. + + + Additional accent 2 + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + Additional secondary + No comment provided by engineer. + Address Address @@ -648,6 +673,11 @@ Advanced network settings No comment provided by engineer. + + Advanced settings + Advanced settings + No comment provided by engineer. + All app data is deleted. All app data is deleted. @@ -663,6 +693,11 @@ All data is erased when it is entered. No comment provided by engineer. + + All data is private to your device. + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. All group members will remain connected. @@ -683,6 +718,11 @@ All new messages from %@ will be hidden! No comment provided by engineer. + + All users + All users + No comment provided by engineer. + All your contacts will remain connected. All your contacts will remain connected. @@ -883,6 +923,11 @@ Apply No comment provided by engineer. + + Apply to + Apply to + No comment provided by engineer. + Archive and upload Archive and upload @@ -958,6 +1003,11 @@ Back No comment provided by engineer. + + Background + Background + No comment provided by engineer. + Bad desktop address Bad desktop address @@ -983,6 +1033,11 @@ Better messages No comment provided by engineer. + + Black + Black + No comment provided by engineer. + Block Block @@ -1093,6 +1148,11 @@ Cannot access keychain to save database password No comment provided by engineer. + + Cannot forward message + Cannot forward message + No comment provided by engineer. + Cannot receive file Cannot receive file @@ -1164,6 +1224,11 @@ Chat archive No comment provided by engineer. + + Chat colors + Chat colors + No comment provided by engineer. + Chat console Chat console @@ -1209,6 +1274,11 @@ Chat preferences No comment provided by engineer. + + Chat theme + Chat theme + No comment provided by engineer. + Chats Chats @@ -1239,6 +1309,21 @@ Choose from library No comment provided by engineer. + + Chunks deleted + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + Chunks uploaded + No comment provided by engineer. + Clear Clear @@ -1264,9 +1349,9 @@ Clear verification No comment provided by engineer. - - Colors - Colors + + Color mode + Color mode No comment provided by engineer. @@ -1279,6 +1364,11 @@ Compare security codes with your contacts. No comment provided by engineer. + + Completed + Completed + No comment provided by engineer. + Configure ICE servers Configure ICE servers @@ -1388,16 +1478,31 @@ This is your own one-time link! Connect with %@ No comment provided by engineer. + + Connected + Connected + No comment provided by engineer. + Connected desktop Connected desktop No comment provided by engineer. + + Connected servers + Connected servers + No comment provided by engineer. + Connected to desktop Connected to desktop No comment provided by engineer. + + Connecting + Connecting + No comment provided by engineer. + Connecting to server… Connecting to server… @@ -1443,6 +1548,21 @@ This is your own one-time link! Connection timeout No comment provided by engineer. + + Connection with desktop stopped + Connection with desktop stopped + No comment provided by engineer. + + + Connections + Connections + No comment provided by engineer. + + + Connections subscribed + Connections subscribed + No comment provided by engineer. + Contact allows Contact allows @@ -1496,7 +1616,12 @@ This is your own one-time link! Copy Copy - chat item action + No comment provided by engineer. + + + Copy error + Copy error + No comment provided by engineer. Core version: v%@ @@ -1573,6 +1698,11 @@ This is your own one-time link! Create your profile No comment provided by engineer. + + Created + Created + No comment provided by engineer. + Created at Created at @@ -1608,6 +1738,11 @@ This is your own one-time link! Current passphrase… No comment provided by engineer. + + Current user + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. Currently maximum supported file size is %@. @@ -1618,11 +1753,21 @@ This is your own one-time link! Custom time No comment provided by engineer. + + Customize theme + Customize theme + No comment provided by engineer. + Dark Dark No comment provided by engineer. + + Dark mode colors + Dark mode colors + No comment provided by engineer. + Database ID Database ID @@ -1928,6 +2073,11 @@ This cannot be undone! Delete user profile? No comment provided by engineer. + + Deleted + Deleted + No comment provided by engineer. + Deleted at Deleted at @@ -1938,6 +2088,11 @@ This cannot be undone! Deleted at: %@ copied message info + + Deletion errors + Deletion errors + No comment provided by engineer. + Delivery Delivery @@ -1978,6 +2133,16 @@ This cannot be undone! Destination server error: %@ snd error text + + Detailed statistics + Detailed statistics + No comment provided by engineer. + + + Details + Details + No comment provided by engineer. + Develop Develop @@ -2133,6 +2298,11 @@ This cannot be undone! Download chat item action + + Download errors + Download errors + No comment provided by engineer. + Download failed Download failed @@ -2143,6 +2313,16 @@ This cannot be undone! Download file server test step + + Downloaded + Downloaded + No comment provided by engineer. + + + Downloaded files + Downloaded files + No comment provided by engineer. + Downloading archive Downloading archive @@ -2513,6 +2693,11 @@ This cannot be undone! Error exporting chat database No comment provided by engineer. + + Error exporting theme: %@ + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Error importing chat database @@ -2538,11 +2723,26 @@ This cannot be undone! Error receiving file No comment provided by engineer. + + Error reconnecting server + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + Error reconnecting servers + No comment provided by engineer. + Error removing member Error removing member No comment provided by engineer. + + Error resetting statistics + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers Error saving %@ servers @@ -2661,7 +2861,8 @@ This cannot be undone! Error: %@ Error: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2673,6 +2874,11 @@ This cannot be undone! Error: no database file No comment provided by engineer. + + Errors + Errors + No comment provided by engineer. + Even when disabled in the conversation. Even when disabled in the conversation. @@ -2698,6 +2904,11 @@ This cannot be undone! Export error: No comment provided by engineer. + + Export theme + Export theme + No comment provided by engineer. + Exported database archive. Exported database archive. @@ -2733,6 +2944,31 @@ This cannot be undone! Favorite No comment provided by engineer. + + File error + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + File server error: %@ + file error text + + + File status + File status + No comment provided by engineer. + + + File status: %@ + File status: %@ + copied message info + File will be deleted from servers. File will be deleted from servers. @@ -2922,6 +3158,16 @@ Error: %2$@ GIFs and stickers No comment provided by engineer. + + Good afternoon! + Good afternoon! + message preview + + + Good morning! + Good morning! + message preview + Group Group @@ -3202,6 +3448,11 @@ Error: %2$@ Import failed No comment provided by engineer. + + Import theme + Import theme + No comment provided by engineer. + Importing archive Importing archive @@ -3324,6 +3575,11 @@ Error: %2$@ Interface No comment provided by engineer. + + Interface colors + Interface colors + No comment provided by engineer. + Invalid QR code Invalid QR code @@ -3682,6 +3938,11 @@ This is your link for group %@! Member will be removed from group - this cannot be undone! No comment provided by engineer. + + Menus + Menus + No comment provided by engineer. + Message delivery error Message delivery error @@ -3737,6 +3998,21 @@ This is your link for group %@! Message source remains private. No comment provided by engineer. + + Message status + Message status + No comment provided by engineer. + + + Message status: %@ + Message status: %@ + copied message info + + + Message subscriptions + Message subscriptions + No comment provided by engineer. + Message text Message text @@ -3762,6 +4038,16 @@ This is your link for group %@! Messages from %@ will be shown! No comment provided by engineer. + + Messages received + Messages received + No comment provided by engineer. + + + Messages sent + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. @@ -4012,6 +4298,11 @@ This is your link for group %@! No history No comment provided by engineer. + + No info, try to reload + No info, try to reload + No comment provided by engineer. + No network connection No network connection @@ -4196,6 +4487,11 @@ This is your link for group %@! Open migration to another device authentication reason + + Open server settings + Open server settings + No comment provided by engineer. + Open user profiles Open user profiles @@ -4301,6 +4597,11 @@ This is your link for group %@! Paste the link you received No comment provided by engineer. + + Pending + Pending + No comment provided by engineer. + People can connect to you only via the links you share. People can connect to you only via the links you share. @@ -4326,6 +4627,13 @@ This is your link for group %@! Please ask your contact to enable sending voice messages. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Please check that you used the correct link or ask your contact to send you another one. @@ -4423,6 +4731,11 @@ Error: %@ Preview No comment provided by engineer. + + Previously connected servers + Previously connected servers + No comment provided by engineer. + Privacy & security Privacy & security @@ -4488,6 +4801,11 @@ Error: %@ Profile password No comment provided by engineer. + + Profile theme + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. Profile update will be sent to your contacts. @@ -4570,6 +4888,16 @@ Enable in *Network & servers* settings. Protocol timeout per KB No comment provided by engineer. + + Proxied + Proxied + No comment provided by engineer. + + + Proxied servers + Proxied servers + No comment provided by engineer. + Push notifications Push notifications @@ -4635,6 +4963,11 @@ Enable in *Network & servers* settings. Receipts are disabled No comment provided by engineer. + + Receive errors + Receive errors + No comment provided by engineer. + Received at Received at @@ -4655,6 +4988,21 @@ Enable in *Network & servers* settings. Received message message info title + + Received messages + Received messages + No comment provided by engineer. + + + Received reply + Received reply + No comment provided by engineer. + + + Received total + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. Receiving address will be changed to a different server. Address change will complete after sender comes online. @@ -4685,11 +5033,36 @@ Enable in *Network & servers* settings. Recipients see updates as you type them. No comment provided by engineer. + + Reconnect + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Reconnect all connected servers to force message delivery. It uses additional traffic. No comment provided by engineer. + + Reconnect all servers + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + Reconnect server? + No comment provided by engineer. + Reconnect servers? Reconnect servers? @@ -4740,6 +5113,11 @@ Enable in *Network & servers* settings. Remove No comment provided by engineer. + + Remove image + Remove image + No comment provided by engineer. + Remove member Remove member @@ -4810,16 +5188,36 @@ Enable in *Network & servers* settings. Reset No comment provided by engineer. + + Reset all statistics + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + Reset all statistics? + No comment provided by engineer. + Reset colors Reset colors No comment provided by engineer. + + Reset to app theme + Reset to app theme + No comment provided by engineer. + Reset to defaults Reset to defaults No comment provided by engineer. + + Reset to user theme + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Restart the app to create a new chat profile @@ -4890,6 +5288,11 @@ Enable in *Network & servers* settings. Run chat No comment provided by engineer. + + SMP server + SMP server + No comment provided by engineer. + SMP servers SMP servers @@ -5005,6 +5408,16 @@ Enable in *Network & servers* settings. Saved message message info title + + Scale + Scale + No comment provided by engineer. + + + Scan / Paste link + Scan / Paste link + No comment provided by engineer. + Scan QR code Scan QR code @@ -5045,11 +5458,21 @@ Enable in *Network & servers* settings. Search or paste SimpleX link No comment provided by engineer. + + Secondary + Secondary + No comment provided by engineer. + Secure queue Secure queue server test step + + Secured + Secured + No comment provided by engineer. + Security assessment Security assessment @@ -5065,6 +5488,11 @@ Enable in *Network & servers* settings. Select No comment provided by engineer. + + Selected chat preferences prohibit this message. + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Self-destruct @@ -5115,6 +5543,11 @@ Enable in *Network & servers* settings. Send disappearing message No comment provided by engineer. + + Send errors + Send errors + No comment provided by engineer. + Send link previews Send link previews @@ -5225,6 +5658,11 @@ Enable in *Network & servers* settings. Sent at: %@ copied message info + + Sent directly + Sent directly + No comment provided by engineer. + Sent file event Sent file event @@ -5235,11 +5673,36 @@ Enable in *Network & servers* settings. Sent message message info title + + Sent messages + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. Sent messages will be deleted after set time. No comment provided by engineer. + + Sent reply + Sent reply + No comment provided by engineer. + + + Sent total + Sent total + No comment provided by engineer. + + + Sent via proxy + Sent via proxy + No comment provided by engineer. + + + Server address + Server address + No comment provided by engineer. + Server address is incompatible with network settings. Server address is incompatible with network settings. @@ -5260,6 +5723,11 @@ Enable in *Network & servers* settings. Server test failed! No comment provided by engineer. + + Server type + Server type + No comment provided by engineer. + Server version is incompatible with network settings. Server version is incompatible with network settings. @@ -5270,6 +5738,16 @@ Enable in *Network & servers* settings. Servers No comment provided by engineer. + + Servers info + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code Session code @@ -5285,6 +5763,11 @@ Enable in *Network & servers* settings. Set contact name… No comment provided by engineer. + + Set default theme + Set default theme + No comment provided by engineer. + Set group preferences Set group preferences @@ -5405,6 +5888,11 @@ Enable in *Network & servers* settings. Show: No comment provided by engineer. + + SimpleX + SimpleX + No comment provided by engineer. + SimpleX Address SimpleX Address @@ -5480,6 +5968,11 @@ Enable in *Network & servers* settings. Simplified incognito mode No comment provided by engineer. + + Size + Size + No comment provided by engineer. + Skip Skip @@ -5525,6 +6018,16 @@ Enable in *Network & servers* settings. Start migration No comment provided by engineer. + + Starting from %@. + Starting from %@. + No comment provided by engineer. + + + Statistics + Statistics + No comment provided by engineer. + Stop Stop @@ -5590,6 +6093,26 @@ Enable in *Network & servers* settings. Submit No comment provided by engineer. + + Subscribed + Subscribed + No comment provided by engineer. + + + Subscription errors + Subscription errors + No comment provided by engineer. + + + Subscription percentage + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat Support SimpleX Chat @@ -5670,6 +6193,11 @@ Enable in *Network & servers* settings. Tap to start a new chat No comment provided by engineer. + + Temporary file error + Temporary file error + No comment provided by engineer. + Test failed at step %@. Test failed at step %@. @@ -5807,9 +6335,9 @@ It can happen because of some bug or when the connection is compromised.The text you pasted is not a SimpleX link. No comment provided by engineer. - - Theme - Theme + + Themes + Themes No comment provided by engineer. @@ -5877,11 +6405,21 @@ It can happen because of some bug or when the connection is compromised.This is your own one-time link! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. This setting applies to messages in your current chat profile **%@**. No comment provided by engineer. + + Title + Title + No comment provided by engineer. + To ask any questions and to receive updates: To ask any questions and to receive updates: @@ -5949,11 +6487,21 @@ You will be prompted to complete authentication before this feature is enabled.< Toggle incognito when connecting. No comment provided by engineer. + + Total + Total + No comment provided by engineer. + Transport isolation Transport isolation No comment provided by engineer. + + Transport sessions + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Trying to connect to the server used to receive messages from this contact (error: %@). @@ -6146,6 +6694,11 @@ To connect, please ask your contact to create another connection link and check Upgrade and open chat No comment provided by engineer. + + Upload errors + Upload errors + No comment provided by engineer. + Upload failed Upload failed @@ -6156,6 +6709,16 @@ To connect, please ask your contact to create another connection link and check Upload file server test step + + Uploaded + Uploaded + No comment provided by engineer. + + + Uploaded files + Uploaded files + No comment provided by engineer. + Uploading archive Uploading archive @@ -6231,6 +6794,11 @@ To connect, please ask your contact to create another connection link and check User profile No comment provided by engineer. + + User selection + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. Using .onion hosts requires compatible VPN provider. @@ -6366,6 +6934,16 @@ To connect, please ask your contact to create another connection link and check Waiting for video No comment provided by engineer. + + Wallpaper accent + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures Warning: starting chat on multiple devices is not supported and will cause message delivery failures @@ -6471,11 +7049,21 @@ To connect, please ask your contact to create another connection link and check Wrong key or unknown connection - most likely this connection is deleted. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! Wrong passphrase! No comment provided by engineer. + + XFTP server + XFTP server + No comment provided by engineer. + XFTP servers XFTP servers @@ -6558,6 +7146,11 @@ Repeat join request? You are invited to group No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. You can accept calls from lock screen, without device and app authentication. @@ -6964,6 +7557,11 @@ SimpleX servers cannot see your profile. and %lld other events No comment provided by engineer. + + attempts + attempts + No comment provided by engineer. + audio call (not e2e encrypted) audio call (not e2e encrypted) @@ -6997,7 +7595,7 @@ SimpleX servers cannot see your profile. blocked by admin blocked by admin - marked deleted chat item preview text + blocked chat item bold @@ -7154,6 +7752,11 @@ SimpleX servers cannot see your profile. days time unit + + decryption errors + decryption errors + No comment provided by engineer. + default (%@) default (%@) @@ -7204,6 +7807,11 @@ SimpleX servers cannot see your profile. duplicate message integrity error chat item + + duplicates + duplicates + No comment provided by engineer. + e2e encrypted e2e encrypted @@ -7284,6 +7892,11 @@ SimpleX servers cannot see your profile. event happened No comment provided by engineer. + + expired + expired + No comment provided by engineer. + forwarded forwarded @@ -7491,6 +8104,16 @@ SimpleX servers cannot see your profile. on group pref value + + other + other + No comment provided by engineer. + + + other errors + other errors + No comment provided by engineer. + owner owner @@ -7804,7 +8427,7 @@ last received msg: %2$@
    - +
    @@ -7841,7 +8464,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/en.xcloc/contents.json b/apps/ios/SimpleX Localizations/en.xcloc/contents.json index 7d429820ee..2f39a1f1ee 100644 --- a/apps/ios/SimpleX Localizations/en.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/en.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "en", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff b/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff index d76630ab3f..7a2e73ae39 100644 --- a/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff +++ b/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff @@ -2,7 +2,7 @@
    - +
    @@ -557,9 +557,8 @@ Acerca de la dirección SimpleX No comment provided by engineer. - - Accent color - Color + + Accent No comment provided by engineer. @@ -583,6 +582,14 @@ Aceptar incógnito accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Añade la dirección a tu perfil para que tus contactos puedan compartirla con otros. La actualización del perfil se enviará a tus contactos. @@ -623,6 +630,18 @@ Añadir mensaje de bienvenida No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address Dirección @@ -648,6 +667,10 @@ Configuración avanzada de red No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. Todos los datos de la aplicación se eliminarán. @@ -663,6 +686,10 @@ Al introducirlo todos los datos son eliminados. No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. Todos los miembros del grupo permanecerán conectados. @@ -683,6 +710,10 @@ ¡Los mensajes nuevos de %@ estarán ocultos! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. Todos tus contactos permanecerán conectados. @@ -883,6 +914,10 @@ Aplicar No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload Archivar y subir @@ -958,6 +993,10 @@ Volver No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address Dirección ordenador incorrecta @@ -983,6 +1022,10 @@ Mensajes mejorados No comment provided by engineer. + + Black + No comment provided by engineer. + Block Bloquear @@ -1093,6 +1136,10 @@ Keychain inaccesible para guardar la contraseña de la base de datos No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file No se puede recibir el archivo @@ -1164,6 +1211,10 @@ Archivo del chat No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console Consola de Chat @@ -1209,6 +1260,10 @@ Preferencias de Chat No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats Chats @@ -1239,6 +1294,18 @@ Elige de la biblioteca No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear Vaciar @@ -1264,9 +1331,8 @@ Eliminar verificación No comment provided by engineer. - - Colors - Colores + + Color mode No comment provided by engineer. @@ -1279,6 +1345,10 @@ Compara los códigos de seguridad con tus contactos. No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers Configure servidores ICE @@ -1388,16 +1458,28 @@ This is your own one-time link! Conectar con %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop Ordenador conectado No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop Conectado con ordenador No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… Conectando con el servidor… @@ -1443,6 +1525,18 @@ This is your own one-time link! Tiempo de conexión expirado No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows El contacto permite @@ -1496,7 +1590,11 @@ This is your own one-time link! Copy Copiar - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1573,6 +1671,10 @@ This is your own one-time link! Crea tu perfil No comment provided by engineer. + + Created + No comment provided by engineer. + Created at Creado @@ -1608,6 +1710,10 @@ This is your own one-time link! Contraseña actual… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. El tamaño máximo de archivo admitido es %@. @@ -1618,11 +1724,19 @@ This is your own one-time link! Tiempo personalizado No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark Oscuro No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID ID base de datos @@ -1927,6 +2041,10 @@ This cannot be undone! ¿Eliminar perfil de usuario? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at Eliminado @@ -1937,6 +2055,10 @@ This cannot be undone! Eliminado: %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery Entrega @@ -1977,6 +2099,14 @@ This cannot be undone! Error del servidor de destino: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop Desarrollo @@ -2132,6 +2262,10 @@ This cannot be undone! Descargar chat item action + + Download errors + No comment provided by engineer. + Download failed Descarga fallida @@ -2142,6 +2276,14 @@ This cannot be undone! Descargar archivo server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive Descargando archivo @@ -2512,6 +2654,10 @@ This cannot be undone! Error al exportar base de datos No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Error al importar base de datos @@ -2537,11 +2683,23 @@ This cannot be undone! Error al recibir archivo No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member Error al eliminar miembro No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers Error al guardar servidores %@ @@ -2660,7 +2818,8 @@ This cannot be undone! Error: %@ Error: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2672,6 +2831,10 @@ This cannot be undone! Error: sin archivo de base de datos No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. Incluso si está desactivado para la conversación. @@ -2697,6 +2860,10 @@ This cannot be undone! Error al exportar: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. Archivo de base de datos exportado. @@ -2732,6 +2899,26 @@ This cannot be undone! Favoritos No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. El archivo será eliminado de los servidores. @@ -2921,6 +3108,14 @@ Error: %2$@ GIFs y stickers No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group Grupo @@ -3201,6 +3396,10 @@ Error: %2$@ Error de importación No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive Importando archivo @@ -3323,6 +3522,10 @@ Error: %2$@ Interfaz No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code Código QR no válido @@ -3681,6 +3884,10 @@ This is your link for group %@! El miembro será expulsado del grupo. ¡No podrá deshacerse! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error Error en la entrega del mensaje @@ -3735,6 +3942,18 @@ This is your link for group %@! El autor del mensaje se mantiene privado. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text Contacto y texto @@ -3760,6 +3979,14 @@ This is your link for group %@! ¡Los mensajes de %@ serán mostrados! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. Los mensajes, archivos y llamadas están protegidos mediante **cifrado de extremo a extremo** con secreto perfecto hacía adelante, repudio y recuperación tras ataque. @@ -4010,6 +4237,10 @@ This is your link for group %@! Sin historial No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection Sin conexión de red @@ -4194,6 +4425,10 @@ This is your link for group %@! Abrir menú migración a otro dispositivo authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles Abrir perfil de usuario @@ -4299,6 +4534,10 @@ This is your link for group %@! Pegar el enlace recibido No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. Las personas pueden conectarse contigo solo mediante los enlaces que compartes. @@ -4324,6 +4563,11 @@ This is your link for group %@! Solicita que tu contacto habilite el envío de mensajes de voz. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Comprueba que has usado el enlace correcto o pide a tu contacto que te envíe otro. @@ -4421,6 +4665,10 @@ Error: %@ Vista previa No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security Privacidad y Seguridad @@ -4486,6 +4734,10 @@ Error: %@ Contraseña del perfil No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. La actualización del perfil se enviará a tus contactos. @@ -4568,6 +4820,14 @@ Actívalo en ajustes de *Servidores y Redes*. Límite de espera del protocolo por KB No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications Notificaciones automáticas @@ -4633,6 +4893,10 @@ Actívalo en ajustes de *Servidores y Redes*. Las confirmaciones están desactivadas No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at Recibido a las @@ -4653,6 +4917,18 @@ Actívalo en ajustes de *Servidores y Redes*. Mensaje entrante message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. La dirección de recepción pasará a otro servidor. El cambio se completará cuando el remitente esté en línea. @@ -4683,11 +4959,31 @@ Actívalo en ajustes de *Servidores y Redes*. Los destinatarios ven actualizarse mientras escribes. No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Reconectar todos los servidores conectados para forzar la entrega del mensaje. Se usa tráfico adicional. No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? ¿Reconectar servidores? @@ -4738,6 +5034,10 @@ Actívalo en ajustes de *Servidores y Redes*. Eliminar No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member Expulsar miembro @@ -4808,16 +5108,32 @@ Actívalo en ajustes de *Servidores y Redes*. Restablecer No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors Restablecer colores No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults Restablecer valores predetarminados No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Reinicia la aplicación para crear un perfil nuevo @@ -4888,6 +5204,10 @@ Actívalo en ajustes de *Servidores y Redes*. Ejecutar chat No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers Servidores SMP @@ -5003,6 +5323,14 @@ Actívalo en ajustes de *Servidores y Redes*. Mensaje guardado message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code Escanear código QR @@ -5043,11 +5371,19 @@ Actívalo en ajustes de *Servidores y Redes*. Buscar o pegar enlace SimpleX No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue Cola segura server test step + + Secured + No comment provided by engineer. + Security assessment Evaluación de la seguridad @@ -5063,6 +5399,10 @@ Actívalo en ajustes de *Servidores y Redes*. Seleccionar No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Autodestrucción @@ -5113,6 +5453,10 @@ Actívalo en ajustes de *Servidores y Redes*. Enviar mensaje temporal No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews Enviar previsualizacion de enlaces @@ -5223,6 +5567,10 @@ Actívalo en ajustes de *Servidores y Redes*. Enviado: %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event Evento de archivo enviado @@ -5233,11 +5581,31 @@ Actívalo en ajustes de *Servidores y Redes*. Mensaje saliente message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. Los mensajes enviados se eliminarán una vez transcurrido el tiempo establecido. No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. La dirección del servidor es incompatible con la configuración de la red. @@ -5258,6 +5626,10 @@ Actívalo en ajustes de *Servidores y Redes*. ¡Error en prueba del servidor! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. La versión del servidor es incompatible con la configuración de red. @@ -5268,6 +5640,14 @@ Actívalo en ajustes de *Servidores y Redes*. Servidores No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code Código de sesión @@ -5283,6 +5663,10 @@ Actívalo en ajustes de *Servidores y Redes*. Escribe el nombre del contacto… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences Establecer preferencias de grupo @@ -5403,6 +5787,10 @@ Actívalo en ajustes de *Servidores y Redes*. Mostrar: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address Dirección SimpleX @@ -5478,6 +5866,10 @@ Actívalo en ajustes de *Servidores y Redes*. Modo incógnito simplificado No comment provided by engineer. + + Size + No comment provided by engineer. + Skip Omitir @@ -5523,6 +5915,14 @@ Actívalo en ajustes de *Servidores y Redes*. Iniciar migración No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop Parar @@ -5588,6 +5988,22 @@ Actívalo en ajustes de *Servidores y Redes*. Enviar No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat Soporte SimpleX Chat @@ -5668,6 +6084,10 @@ Actívalo en ajustes de *Servidores y Redes*. Pulsa para iniciar chat nuevo No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. La prueba ha fallado en el paso %@. @@ -5805,9 +6225,8 @@ Puede ocurrir por algún bug o cuando la conexión está comprometida. El texto pegado no es un enlace SimpleX. No comment provided by engineer. - - Theme - Tema + + Themes No comment provided by engineer. @@ -5875,11 +6294,19 @@ Puede ocurrir por algún bug o cuando la conexión está comprometida. ¡Este es tu propio enlace de un solo uso! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. Esta configuración se aplica a los mensajes del perfil actual **%@**. No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: Para consultar cualquier duda y recibir actualizaciones: @@ -5947,11 +6374,19 @@ Se te pedirá que completes la autenticación antes de activar esta función.Activa incógnito al conectar. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation Aislamiento de transporte No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Intentando conectar con el servidor usado para recibir mensajes de este contacto (error: %@). @@ -6145,6 +6580,10 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb Actualizar y abrir Chat No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed Error de subida @@ -6155,6 +6594,14 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb Subir archivo server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive Subiendo archivo @@ -6230,6 +6677,10 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb Perfil de usuario No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. Usar hosts .onion requiere un proveedor VPN compatible. @@ -6365,6 +6816,14 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb Esperando el vídeo No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures Atención: el inicio del chat en varios dispositivos es incompatible y provocará fallos en la entrega de mensajes @@ -6470,11 +6929,19 @@ Para conectarte, pide a tu contacto que cree otro enlace de conexión y comprueb Clave incorrecta o conexión desconocida - probablemente esta conexión fue eliminada. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! ¡Contraseña incorrecta! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers Servidores XFTP @@ -6557,6 +7024,10 @@ Repeat join request? Has sido invitado a un grupo No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. Puede aceptar llamadas desde la pantalla de bloqueo, sin autenticación de dispositivos y aplicaciones. @@ -6963,6 +7434,10 @@ Los servidores de SimpleX no pueden ver tu perfil. y %lld evento(s) más No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) llamada (sin cifrar) @@ -6996,7 +7471,7 @@ Los servidores de SimpleX no pueden ver tu perfil. blocked by admin bloqueado por administrador - marked deleted chat item preview text + blocked chat item bold @@ -7153,6 +7628,10 @@ Los servidores de SimpleX no pueden ver tu perfil. días time unit + + decryption errors + No comment provided by engineer. + default (%@) predeterminado (%@) @@ -7203,6 +7682,10 @@ Los servidores de SimpleX no pueden ver tu perfil. mensaje duplicado integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted cifrado de extremo a extremo @@ -7283,6 +7766,10 @@ Los servidores de SimpleX no pueden ver tu perfil. evento ocurrido No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded reenviado @@ -7490,6 +7977,14 @@ Los servidores de SimpleX no pueden ver tu perfil. Activado group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner propietario @@ -7800,7 +8295,7 @@ last received msg: %2$@
    - +
    @@ -7837,7 +8332,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/es.xcloc/contents.json b/apps/ios/SimpleX Localizations/es.xcloc/contents.json index c7d2c05ffa..340591e607 100644 --- a/apps/ios/SimpleX Localizations/es.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/es.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "es", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff b/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff index 77f9e29871..552af207a7 100644 --- a/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff +++ b/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff @@ -2,7 +2,7 @@
    - +
    @@ -534,9 +534,8 @@ Tietoja SimpleX osoitteesta No comment provided by engineer. - - Accent color - Korostusväri + + Accent No comment provided by engineer. @@ -560,6 +559,14 @@ Hyväksy tuntematon accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Lisää osoite profiiliisi, jotta kontaktisi voivat jakaa sen muiden kanssa. Profiilipäivitys lähetetään kontakteillesi. @@ -599,6 +606,18 @@ Lisää tervetuloviesti No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address Osoite @@ -623,6 +642,10 @@ Verkon lisäasetukset No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. Kaikki sovelluksen tiedot poistetaan. @@ -638,6 +661,10 @@ Kaikki tiedot poistetaan, kun se syötetään. No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. Kaikki ryhmän jäsenet pysyvät yhteydessä. @@ -656,6 +683,10 @@ All new messages from %@ will be hidden! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. Kaikki kontaktisi pysyvät yhteydessä. @@ -847,6 +878,10 @@ Apply No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload No comment provided by engineer. @@ -920,6 +955,10 @@ Takaisin No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address No comment provided by engineer. @@ -943,6 +982,10 @@ Parempia viestejä No comment provided by engineer. + + Black + No comment provided by engineer. + Block No comment provided by engineer. @@ -1043,6 +1086,10 @@ Ei pääsyä avainnippuun tietokannan salasanan tallentamiseksi No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file Tiedostoa ei voi vastaanottaa @@ -1112,6 +1159,10 @@ Chat-arkisto No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console Chat-konsoli @@ -1155,6 +1206,10 @@ Chat-asetukset No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats Keskustelut @@ -1184,6 +1239,18 @@ Valitse kirjastosta No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear Tyhjennä @@ -1208,9 +1275,8 @@ Tyhjennä vahvistus No comment provided by engineer. - - Colors - Värit + + Color mode No comment provided by engineer. @@ -1223,6 +1289,10 @@ Vertaa turvakoodeja kontaktiesi kanssa. No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers Määritä ICE-palvelimet @@ -1319,14 +1389,26 @@ This is your own one-time link! Connect with %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… Yhteyden muodostaminen palvelimeen… @@ -1370,6 +1452,18 @@ This is your own one-time link! Yhteyden aikakatkaisu No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows Kontakti sallii @@ -1423,7 +1517,11 @@ This is your own one-time link! Copy Kopioi - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1496,6 +1594,10 @@ This is your own one-time link! Luo profiilisi No comment provided by engineer. + + Created + No comment provided by engineer. + Created at No comment provided by engineer. @@ -1527,6 +1629,10 @@ This is your own one-time link! Nykyinen tunnuslause… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. Nykyinen tuettu enimmäistiedostokoko on %@. @@ -1537,11 +1643,19 @@ This is your own one-time link! Mukautettu aika No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark Tumma No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID Tietokannan tunnus @@ -1841,6 +1955,10 @@ This cannot be undone! Poista käyttäjäprofiili? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at Poistettu klo @@ -1851,6 +1969,10 @@ This cannot be undone! Poistettu klo: %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery Toimitus @@ -1887,6 +2009,14 @@ This cannot be undone! Destination server error: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop Kehitä @@ -2036,6 +2166,10 @@ This cannot be undone! Download chat item action + + Download errors + No comment provided by engineer. + Download failed No comment provided by engineer. @@ -2045,6 +2179,14 @@ This cannot be undone! Lataa tiedosto server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive No comment provided by engineer. @@ -2399,6 +2541,10 @@ This cannot be undone! Virhe vietäessä keskustelujen tietokantaa No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Virhe keskustelujen tietokannan tuonnissa @@ -2423,11 +2569,23 @@ This cannot be undone! Virhe tiedoston vastaanottamisessa No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member Virhe poistettaessa jäsentä No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers Virhe %@ palvelimien tallentamisessa @@ -2541,7 +2699,8 @@ This cannot be undone! Error: %@ Virhe: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2553,6 +2712,10 @@ This cannot be undone! Virhe: ei tietokantatiedostoa No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. Jopa kun ei käytössä keskustelussa. @@ -2577,6 +2740,10 @@ This cannot be undone! Vientivirhe: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. Viety tietokanta-arkisto. @@ -2610,6 +2777,26 @@ This cannot be undone! Suosikki No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. Tiedosto poistetaan palvelimilta. @@ -2785,6 +2972,14 @@ Error: %2$@ GIFit ja tarrat No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group Ryhmä @@ -3059,6 +3254,10 @@ Error: %2$@ Import failed No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive No comment provided by engineer. @@ -3175,6 +3374,10 @@ Error: %2$@ Käyttöliittymä No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code No comment provided by engineer. @@ -3516,6 +3719,10 @@ This is your link for group %@! Jäsen poistetaan ryhmästä - tätä ei voi perua! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error Viestin toimitusvirhe @@ -3566,6 +3773,18 @@ This is your link for group %@! Message source remains private. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text Viestin teksti @@ -3589,6 +3808,14 @@ This is your link for group %@! Messages from %@ will be shown! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. No comment provided by engineer. @@ -3824,6 +4051,10 @@ This is your link for group %@! Ei historiaa No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection No comment provided by engineer. @@ -4002,6 +4233,10 @@ This is your link for group %@! Open migration to another device authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles Avaa käyttäjäprofiilit @@ -4097,6 +4332,10 @@ This is your link for group %@! Paste the link you received No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. Ihmiset voivat ottaa sinuun yhteyttä vain jakamiesi linkkien kautta. @@ -4121,6 +4360,11 @@ This is your link for group %@! Pyydä kontaktiasi sallimaan ääniviestien lähettäminen. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Tarkista, että käytit oikeaa linkkiä tai pyydä kontaktiasi lähettämään sinulle uusi linkki. @@ -4215,6 +4459,10 @@ Error: %@ Esikatselu No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security Yksityisyys ja turvallisuus @@ -4273,6 +4521,10 @@ Error: %@ Profiilin salasana No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. Profiilipäivitys lähetetään kontakteillesi. @@ -4351,6 +4603,14 @@ Enable in *Network & servers* settings. Protokollan aikakatkaisu per KB No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications Push-ilmoitukset @@ -4413,6 +4673,10 @@ Enable in *Network & servers* settings. Kuittaukset pois käytöstä No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at Vastaanotettu klo @@ -4433,6 +4697,18 @@ Enable in *Network & servers* settings. Vastaanotettu viesti message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. Vastaanotto-osoite vaihdetaan toiseen palvelimeen. Osoitteenmuutos tehdään sen jälkeen, kun lähettäjä tulee verkkoon. @@ -4461,11 +4737,31 @@ Enable in *Network & servers* settings. Vastaanottajat näkevät päivitykset, kun kirjoitat niitä. No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Yhdistä kaikki yhdistetyt palvelimet uudelleen pakottaaksesi viestin toimituksen. Tämä käyttää ylimääräistä liikennettä. No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? Yhdistä palvelimet uudelleen? @@ -4516,6 +4812,10 @@ Enable in *Network & servers* settings. Poista No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member Poista jäsen @@ -4581,16 +4881,32 @@ Enable in *Network & servers* settings. Oletustilaan No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors Oletusvärit No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults Palauta oletusasetukset No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Käynnistä sovellus uudelleen uuden keskusteluprofiilin luomiseksi @@ -4660,6 +4976,10 @@ Enable in *Network & servers* settings. Käynnistä chat No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers SMP-palvelimet @@ -4770,6 +5090,14 @@ Enable in *Network & servers* settings. Saved message message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code Skannaa QR-koodi @@ -4807,11 +5135,19 @@ Enable in *Network & servers* settings. Search or paste SimpleX link No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue Turvallinen jono server test step + + Secured + No comment provided by engineer. + Security assessment Turvallisuusarviointi @@ -4827,6 +5163,10 @@ Enable in *Network & servers* settings. Valitse No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Itsetuho @@ -4876,6 +5216,10 @@ Enable in *Network & servers* settings. Lähetä katoava viesti No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews Lähetä linkkien esikatselu @@ -4983,6 +5327,10 @@ Enable in *Network & servers* settings. Lähetetty klo: %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event Lähetetty tiedosto tapahtuma @@ -4993,11 +5341,31 @@ Enable in *Network & servers* settings. Lähetetty viesti message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. Lähetetyt viestit poistetaan asetetun ajan kuluttua. No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. srv error text. @@ -5017,6 +5385,10 @@ Enable in *Network & servers* settings. Palvelintesti epäonnistui! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. srv error text @@ -5026,6 +5398,14 @@ Enable in *Network & servers* settings. Palvelimet No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code No comment provided by engineer. @@ -5040,6 +5420,10 @@ Enable in *Network & servers* settings. Aseta kontaktin nimi… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences Aseta ryhmän asetukset @@ -5154,6 +5538,10 @@ Enable in *Network & servers* settings. Näytä: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address SimpleX-osoite @@ -5226,6 +5614,10 @@ Enable in *Network & servers* settings. Simplified incognito mode No comment provided by engineer. + + Size + No comment provided by engineer. + Skip Ohita @@ -5269,6 +5661,14 @@ Enable in *Network & servers* settings. Aloita siirto No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop Lopeta @@ -5332,6 +5732,22 @@ Enable in *Network & servers* settings. Lähetä No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat SimpleX Chat tuki @@ -5409,6 +5825,10 @@ Enable in *Network & servers* settings. Aloita uusi keskustelu napauttamalla No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. Testi epäonnistui vaiheessa %@. @@ -5543,9 +5963,8 @@ Tämä voi johtua jostain virheestä tai siitä, että yhteys on vaarantunut.The text you pasted is not a SimpleX link. No comment provided by engineer. - - Theme - Teema + + Themes No comment provided by engineer. @@ -5607,11 +6026,19 @@ Tämä voi johtua jostain virheestä tai siitä, että yhteys on vaarantunut.This is your own one-time link! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. Tämä asetus koskee nykyisen keskusteluprofiilisi viestejä *%@**. No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: Voit esittää kysymyksiä ja saada päivityksiä: @@ -5676,11 +6103,19 @@ Sinua kehotetaan suorittamaan todennus loppuun, ennen kuin tämä ominaisuus ote Toggle incognito when connecting. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation Kuljetuksen eristäminen No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Yritetään muodostaa yhteyttä palvelimeen, jota käytetään tämän kontaktin viestien vastaanottamiseen (virhe: %@). @@ -5863,6 +6298,10 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja Päivitä ja avaa keskustelu No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed No comment provided by engineer. @@ -5872,6 +6311,14 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja Lataa tiedosto server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive No comment provided by engineer. @@ -5941,6 +6388,10 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja Käyttäjäprofiili No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. .onion-isäntien käyttäminen vaatii yhteensopivan VPN-palveluntarjoajan. @@ -6067,6 +6518,14 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja Odottaa videota No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures No comment provided by engineer. @@ -6161,11 +6620,19 @@ Jos haluat muodostaa yhteyden, pyydä kontaktiasi luomaan toinen yhteyslinkki ja Wrong key or unknown connection - most likely this connection is deleted. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! Väärä tunnuslause! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers XFTP-palvelimet @@ -6239,6 +6706,10 @@ Repeat join request? Sinut on kutsuttu ryhmään No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. Voit vastaanottaa puheluita lukitusnäytöltä ilman laitteen ja sovelluksen todennusta. @@ -6633,6 +7104,10 @@ SimpleX-palvelimet eivät näe profiiliasi. and %lld other events No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) äänipuhelu (ei e2e-salattu) @@ -6662,7 +7137,7 @@ SimpleX-palvelimet eivät näe profiiliasi. blocked by admin - marked deleted chat item preview text + blocked chat item bold @@ -6817,6 +7292,10 @@ SimpleX-palvelimet eivät näe profiiliasi. päivää time unit + + decryption errors + No comment provided by engineer. + default (%@) oletusarvo (%@) @@ -6866,6 +7345,10 @@ SimpleX-palvelimet eivät näe profiiliasi. päällekkäinen viesti integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted e2e-salattu @@ -6946,6 +7429,10 @@ SimpleX-palvelimet eivät näe profiiliasi. tapahtuma tapahtui No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded No comment provided by engineer. @@ -7151,6 +7638,14 @@ SimpleX-palvelimet eivät näe profiiliasi. päällä group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner omistaja @@ -7441,7 +7936,7 @@ last received msg: %2$@
    - +
    @@ -7477,7 +7972,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/fi.xcloc/contents.json b/apps/ios/SimpleX Localizations/fi.xcloc/contents.json index 0e3ae6dc56..78ce40cec5 100644 --- a/apps/ios/SimpleX Localizations/fi.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/fi.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "fi", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff b/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff index 7e6c0d113d..39bb04a814 100644 --- a/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff +++ b/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff @@ -2,7 +2,7 @@
    - +
    @@ -557,9 +557,8 @@ À propos de l'adresse SimpleX No comment provided by engineer. - - Accent color - Couleur principale + + Accent No comment provided by engineer. @@ -583,6 +582,14 @@ Accepter en incognito accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Ajoutez une adresse à votre profil, afin que vos contacts puissent la partager avec d'autres personnes. La mise à jour du profil sera envoyée à vos contacts. @@ -623,6 +630,18 @@ Ajouter un message d'accueil No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address Adresse @@ -648,6 +667,10 @@ Paramètres réseau avancés No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. Toutes les données de l'application sont supprimées. @@ -663,6 +686,10 @@ Toutes les données sont effacées lorsqu'il est saisi. No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. Tous les membres du groupe resteront connectés. @@ -683,6 +710,10 @@ Tous les nouveaux messages de %@ seront cachés ! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. Tous vos contacts resteront connectés. @@ -883,6 +914,10 @@ Appliquer No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload Archiver et transférer @@ -958,6 +993,10 @@ Retour No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address Mauvaise adresse de bureau @@ -983,6 +1022,10 @@ Meilleurs messages No comment provided by engineer. + + Black + No comment provided by engineer. + Block Bloquer @@ -1093,6 +1136,10 @@ Impossible d'accéder à la keychain pour enregistrer le mot de passe de la base de données No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file Impossible de recevoir le fichier @@ -1164,6 +1211,10 @@ Archives du chat No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console Console du chat @@ -1209,6 +1260,10 @@ Préférences de chat No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats Discussions @@ -1239,6 +1294,18 @@ Choisir dans la photothèque No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear Effacer @@ -1264,9 +1331,8 @@ Retirer la vérification No comment provided by engineer. - - Colors - Couleurs + + Color mode No comment provided by engineer. @@ -1279,6 +1345,10 @@ Comparez les codes de sécurité avec vos contacts. No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers Configurer les serveurs ICE @@ -1388,16 +1458,28 @@ Il s'agit de votre propre lien unique ! Se connecter avec %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop Bureau connecté No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop Connecté au bureau No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… Connexion au serveur… @@ -1443,6 +1525,18 @@ Il s'agit de votre propre lien unique ! Délai de connexion No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows Votre contact autorise @@ -1496,7 +1590,11 @@ Il s'agit de votre propre lien unique ! Copy Copier - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1573,6 +1671,10 @@ Il s'agit de votre propre lien unique ! Créez votre profil No comment provided by engineer. + + Created + No comment provided by engineer. + Created at Créé à @@ -1608,6 +1710,10 @@ Il s'agit de votre propre lien unique ! Phrase secrète actuelle… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. Actuellement, la taille maximale des fichiers supportés est de %@. @@ -1618,11 +1724,19 @@ Il s'agit de votre propre lien unique ! Délai personnalisé No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark Sombre No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID ID de base de données @@ -1927,6 +2041,10 @@ Cette opération ne peut être annulée ! Supprimer le profil utilisateur ? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at Supprimé à @@ -1937,6 +2055,10 @@ Cette opération ne peut être annulée ! Supprimé à : %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery Distribution @@ -1977,6 +2099,14 @@ Cette opération ne peut être annulée ! Erreur du serveur de destination : %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop Développer @@ -2132,6 +2262,10 @@ Cette opération ne peut être annulée ! Télécharger chat item action + + Download errors + No comment provided by engineer. + Download failed Échec du téléchargement @@ -2142,6 +2276,14 @@ Cette opération ne peut être annulée ! Télécharger le fichier server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive Téléchargement de l'archive @@ -2512,6 +2654,10 @@ Cette opération ne peut être annulée ! Erreur lors de l'exportation de la base de données du chat No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Erreur lors de l'importation de la base de données du chat @@ -2537,11 +2683,23 @@ Cette opération ne peut être annulée ! Erreur lors de la réception du fichier No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member Erreur lors de la suppression d'un membre No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers Erreur lors de la sauvegarde des serveurs %@ @@ -2660,7 +2818,8 @@ Cette opération ne peut être annulée ! Error: %@ Erreur : %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2672,6 +2831,10 @@ Cette opération ne peut être annulée ! Erreur : pas de fichier de base de données No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. Même s'il est désactivé dans la conversation. @@ -2697,6 +2860,10 @@ Cette opération ne peut être annulée ! Erreur lors de l'exportation : No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. Archive de la base de données exportée. @@ -2732,6 +2899,26 @@ Cette opération ne peut être annulée ! Favoris No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. Le fichier sera supprimé des serveurs. @@ -2921,6 +3108,14 @@ Erreur : %2$@ GIFs et stickers No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group Groupe @@ -3201,6 +3396,10 @@ Erreur : %2$@ Échec de l'importation No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive Importation de l'archive @@ -3323,6 +3522,10 @@ Erreur : %2$@ Interface No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code Code QR invalide @@ -3681,6 +3884,10 @@ Voici votre lien pour le groupe %@ ! Ce membre sera retiré du groupe - impossible de revenir en arrière ! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error Erreur de distribution du message @@ -3735,6 +3942,18 @@ Voici votre lien pour le groupe %@ ! La source du message reste privée. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text Texte du message @@ -3760,6 +3979,14 @@ Voici votre lien pour le groupe %@ ! Les messages de %@ seront affichés ! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. Les messages, fichiers et appels sont protégés par un chiffrement **de bout en bout** avec une confidentialité persistante, une répudiation et une récupération en cas d'effraction. @@ -4010,6 +4237,10 @@ Voici votre lien pour le groupe %@ ! Aucun historique No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection Pas de connexion au réseau @@ -4194,6 +4425,10 @@ Voici votre lien pour le groupe %@ ! Ouvrir le transfert vers un autre appareil authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles Ouvrir les profils d'utilisateurs @@ -4299,6 +4534,10 @@ Voici votre lien pour le groupe %@ ! Collez le lien que vous avez reçu No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. On ne peut se connecter à vous qu’avec les liens que vous partagez. @@ -4324,6 +4563,11 @@ Voici votre lien pour le groupe %@ ! Veuillez demander à votre contact de permettre l'envoi de messages vocaux. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Veuillez vérifier que vous avez utilisé le bon lien ou demandez à votre contact de vous en envoyer un autre. @@ -4421,6 +4665,10 @@ Erreur : %@ Aperçu No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security Vie privée et sécurité @@ -4486,6 +4734,10 @@ Erreur : %@ Mot de passe de profil No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. La mise à jour du profil sera envoyée à vos contacts. @@ -4568,6 +4820,14 @@ Activez-le dans les paramètres *Réseau et serveurs*. Délai d'attente du protocole par KB No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications Notifications push @@ -4633,6 +4893,10 @@ Activez-le dans les paramètres *Réseau et serveurs*. Les accusés de réception sont désactivés No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at Reçu à @@ -4653,6 +4917,18 @@ Activez-le dans les paramètres *Réseau et serveurs*. Message reçu message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. L'adresse de réception sera changée pour un autre serveur. Le changement d'adresse sera terminé lorsque l'expéditeur sera en ligne. @@ -4683,11 +4959,31 @@ Activez-le dans les paramètres *Réseau et serveurs*. Les destinataires voient les mises à jour au fur et à mesure que vous leur écrivez. No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Reconnecter tous les serveurs connectés pour forcer la livraison des messages. Cette méthode utilise du trafic supplémentaire. No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? Reconnecter les serveurs ? @@ -4738,6 +5034,10 @@ Activez-le dans les paramètres *Réseau et serveurs*. Supprimer No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member Retirer le membre @@ -4808,16 +5108,32 @@ Activez-le dans les paramètres *Réseau et serveurs*. Réinitialisation No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors Réinitialisation des couleurs No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults Réinitialisation des valeurs par défaut No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Redémarrez l'application pour créer un nouveau profil de chat @@ -4888,6 +5204,10 @@ Activez-le dans les paramètres *Réseau et serveurs*. Exécuter le chat No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers Serveurs SMP @@ -5003,6 +5323,14 @@ Activez-le dans les paramètres *Réseau et serveurs*. Message enregistré message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code Scanner un code QR @@ -5043,11 +5371,19 @@ Activez-le dans les paramètres *Réseau et serveurs*. Rechercher ou coller un lien SimpleX No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue File d'attente sécurisée server test step + + Secured + No comment provided by engineer. + Security assessment Évaluation de sécurité @@ -5063,6 +5399,10 @@ Activez-le dans les paramètres *Réseau et serveurs*. Choisir No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Autodestruction @@ -5113,6 +5453,10 @@ Activez-le dans les paramètres *Réseau et serveurs*. Envoyer un message éphémère No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews Envoi d'aperçus de liens @@ -5223,6 +5567,10 @@ Activez-le dans les paramètres *Réseau et serveurs*. Envoyé le : %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event Événement de fichier envoyé @@ -5233,11 +5581,31 @@ Activez-le dans les paramètres *Réseau et serveurs*. Message envoyé message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. Les messages envoyés seront supprimés après une durée déterminée. No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. L'adresse du serveur est incompatible avec les paramètres du réseau. @@ -5258,6 +5626,10 @@ Activez-le dans les paramètres *Réseau et serveurs*. Échec du test du serveur ! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. La version du serveur est incompatible avec les paramètres du réseau. @@ -5268,6 +5640,14 @@ Activez-le dans les paramètres *Réseau et serveurs*. Serveurs No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code Code de session @@ -5283,6 +5663,10 @@ Activez-le dans les paramètres *Réseau et serveurs*. Définir le nom du contact… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences Définir les préférences du groupe @@ -5403,6 +5787,10 @@ Activez-le dans les paramètres *Réseau et serveurs*. Afficher : No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address Adresse SimpleX @@ -5478,6 +5866,10 @@ Activez-le dans les paramètres *Réseau et serveurs*. Mode incognito simplifié No comment provided by engineer. + + Size + No comment provided by engineer. + Skip Passer @@ -5523,6 +5915,14 @@ Activez-le dans les paramètres *Réseau et serveurs*. Démarrer la migration No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop Arrêter @@ -5588,6 +5988,22 @@ Activez-le dans les paramètres *Réseau et serveurs*. Soumettre No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat Supporter SimpleX Chat @@ -5668,6 +6084,10 @@ Activez-le dans les paramètres *Réseau et serveurs*. Appuyez ici pour démarrer une nouvelle discussion No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. Échec du test à l'étape %@. @@ -5805,9 +6225,8 @@ Cela peut se produire en raison d'un bug ou lorsque la connexion est compromise. Le texte collé n'est pas un lien SimpleX. No comment provided by engineer. - - Theme - Thème + + Themes No comment provided by engineer. @@ -5875,11 +6294,19 @@ Cela peut se produire en raison d'un bug ou lorsque la connexion est compromise. Voici votre propre lien unique ! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. Ce paramètre s'applique aux messages de votre profil de chat actuel **%@**. No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: Si vous avez des questions et que vous souhaitez des réponses : @@ -5947,11 +6374,19 @@ Vous serez invité à confirmer l'authentification avant que cette fonction ne s Basculer en mode incognito lors de la connexion. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation Transport isolé No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Tentative de connexion au serveur utilisé pour recevoir les messages de ce contact (erreur : %@). @@ -6144,6 +6579,10 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien Mettre à niveau et ouvrir le chat No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed Échec de l'envoi @@ -6154,6 +6593,14 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien Transférer le fichier server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive Envoi de l'archive @@ -6229,6 +6676,10 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien Profil d'utilisateur No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. L'utilisation des hôtes .onion nécessite un fournisseur VPN compatible. @@ -6364,6 +6815,14 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien En attente de la vidéo No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures Attention : démarrer une session de chat sur plusieurs appareils n'est pas pris en charge et entraînera des dysfonctionnements au niveau de la transmission des messages @@ -6469,11 +6928,19 @@ Pour vous connecter, veuillez demander à votre contact de créer un autre lien Clé erronée ou connexion non identifiée - il est très probable que cette connexion soit supprimée. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! Mauvaise phrase secrète ! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers Serveurs XFTP @@ -6556,6 +7023,10 @@ Répéter la demande d'adhésion ? Vous êtes invité·e au groupe No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. Vous pouvez accepter des appels à partir de l'écran de verrouillage, sans authentification de l'appareil ou de l'application. @@ -6962,6 +7433,10 @@ Les serveurs SimpleX ne peuvent pas voir votre profil. et %lld autres événements No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) appel audio (sans chiffrement) @@ -6995,7 +7470,7 @@ Les serveurs SimpleX ne peuvent pas voir votre profil. blocked by admin bloqué par l'administrateur - marked deleted chat item preview text + blocked chat item bold @@ -7152,6 +7627,10 @@ Les serveurs SimpleX ne peuvent pas voir votre profil. jours time unit + + decryption errors + No comment provided by engineer. + default (%@) défaut (%@) @@ -7202,6 +7681,10 @@ Les serveurs SimpleX ne peuvent pas voir votre profil. message dupliqué integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted chiffré de bout en bout @@ -7282,6 +7765,10 @@ Les serveurs SimpleX ne peuvent pas voir votre profil. event happened No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded transféré @@ -7489,6 +7976,14 @@ Les serveurs SimpleX ne peuvent pas voir votre profil. on group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner propriétaire @@ -7799,7 +8294,7 @@ last received msg: %2$@
    - +
    @@ -7836,7 +8331,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/fr.xcloc/contents.json b/apps/ios/SimpleX Localizations/fr.xcloc/contents.json index 7df7c8ed26..22d271b92e 100644 --- a/apps/ios/SimpleX Localizations/fr.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/fr.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "fr", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff b/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff index 13594c8efa..f3374f2efb 100644 --- a/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff +++ b/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff @@ -2,7 +2,7 @@
    - +
    @@ -557,9 +557,8 @@ A SimpleX azonosítóról No comment provided by engineer. - - Accent color - Kiemelő szín + + Accent No comment provided by engineer. @@ -583,6 +582,14 @@ Fogadás inkognítóban accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Azonosító hozzáadása a profilhoz, hogy az ismerősei megoszthassák másokkal. A profilfrissítés elküldésre kerül az ismerősei számára. @@ -623,6 +630,18 @@ Üdvözlő üzenet hozzáadása No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address Cím @@ -648,6 +667,10 @@ Speciális hálózati beállítások No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. Minden alkalmazásadat törölve. @@ -663,6 +686,10 @@ A jelkód megadása után minden adat törlésre kerül. No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. Minden csoporttag kapcsolódva marad. @@ -683,6 +710,10 @@ Minden új üzenet elrejtésre kerül tőle: %@! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. Minden ismerős kapcsolódva marad. @@ -883,6 +914,10 @@ Alkalmaz No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload Archiválás és feltöltés @@ -958,6 +993,10 @@ Vissza No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address Hibás számítógép azonosító @@ -983,6 +1022,10 @@ Jobb üzenetek No comment provided by engineer. + + Black + No comment provided by engineer. + Block Blokkolás @@ -1093,6 +1136,10 @@ Nem lehet hozzáférni a kulcstartóhoz az adatbázis jelszavának mentéséhez No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file Nem lehet fogadni a fájlt @@ -1164,6 +1211,10 @@ Csevegési archívum No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console Csevegési konzol @@ -1209,6 +1260,10 @@ Csevegési beállítások No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats Csevegések @@ -1239,6 +1294,18 @@ Választás a könyvtárból No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear Kiürítés @@ -1264,9 +1331,8 @@ Hitelesítés törlése No comment provided by engineer. - - Colors - Színek + + Color mode No comment provided by engineer. @@ -1279,6 +1345,10 @@ Biztonsági kódok összehasonlítása az ismerősökkel. No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers ICE kiszolgálók beállítása @@ -1388,16 +1458,28 @@ Ez az egyszer használatos hivatkozása! Kapcsolódás ezzel: %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop Csatlakoztatott számítógép No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop Kapcsolódva a számítógéphez No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… Kapcsolódás a kiszolgálóhoz… @@ -1443,6 +1525,18 @@ Ez az egyszer használatos hivatkozása! Kapcsolat időtúllépés No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows Ismerős engedélyezi @@ -1496,7 +1590,11 @@ Ez az egyszer használatos hivatkozása! Copy Másolás - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1573,6 +1671,10 @@ Ez az egyszer használatos hivatkozása! Saját profil létrehozása No comment provided by engineer. + + Created + No comment provided by engineer. + Created at Létrehozva ekkor: @@ -1608,6 +1710,10 @@ Ez az egyszer használatos hivatkozása! Jelenlegi jelmondat… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. Jelenleg a maximális támogatott fájlméret %@. @@ -1618,11 +1724,19 @@ Ez az egyszer használatos hivatkozása! Személyreszabott idő No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark Sötét No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID Adatbázis ID @@ -1927,6 +2041,10 @@ Ez a művelet nem vonható vissza! Felhasználói profil törlése? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at Törölve ekkor: @@ -1937,6 +2055,10 @@ Ez a művelet nem vonható vissza! Törölve ekkor: %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery Kézbesítés @@ -1977,6 +2099,14 @@ Ez a művelet nem vonható vissza! Célkiszolgáló hiba: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop Fejlesztés @@ -2132,6 +2262,10 @@ Ez a művelet nem vonható vissza! Letöltés chat item action + + Download errors + No comment provided by engineer. + Download failed Sikertelen letöltés @@ -2142,6 +2276,14 @@ Ez a művelet nem vonható vissza! Fájl letöltése server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive Archívum letöltése @@ -2512,6 +2654,10 @@ Ez a művelet nem vonható vissza! Hiba a csevegési adatbázis exportálásakor No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Hiba a csevegési adatbázis importálásakor @@ -2537,11 +2683,23 @@ Ez a művelet nem vonható vissza! Hiba a fájl fogadásakor No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member Hiba a tag eltávolításakor No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers Hiba történt a %@ kiszolgálók mentése közben @@ -2660,7 +2818,8 @@ Ez a művelet nem vonható vissza! Error: %@ Hiba: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2672,6 +2831,10 @@ Ez a művelet nem vonható vissza! Hiba: nincs adatbázis fájl No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. Akkor is, ha le van tiltva a beszélgetésben. @@ -2697,6 +2860,10 @@ Ez a művelet nem vonható vissza! Exportálási hiba: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. Exportált adatbázis-archívum. @@ -2732,6 +2899,26 @@ Ez a művelet nem vonható vissza! Kedvenc No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. A fájl törölve lesz a kiszolgálóról. @@ -2921,6 +3108,14 @@ Hiba: %2$@ GIF-ek és matricák No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group Csoport @@ -3201,6 +3396,10 @@ Hiba: %2$@ Sikertelen importálás No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive Archívum importálása @@ -3323,6 +3522,10 @@ Hiba: %2$@ Felület No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code Érvénytelen QR-kód @@ -3681,6 +3884,10 @@ Ez az ön hivatkozása a(z) %@ csoporthoz! A tag eltávolítása a csoportból - ez a művelet nem vonható vissza! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error Üzenetkézbesítési hiba @@ -3735,6 +3942,18 @@ Ez az ön hivatkozása a(z) %@ csoporthoz! Az üzenet forrása titokban marad. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text Üzenet szövege @@ -3760,6 +3979,14 @@ Ez az ön hivatkozása a(z) %@ csoporthoz! A(z) %@ által írt üzenetek megjelennek! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. Az üzeneteket, fájlokat és hívásokat **végpontok közötti titkosítással**, sérülés utáni titkosság-védelemmel és -helyreállítással, továbbá visszautasítással védi. @@ -4010,6 +4237,10 @@ Ez az ön hivatkozása a(z) %@ csoporthoz! Nincsenek előzmények No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection Nincs hálózati kapcsolat @@ -4194,6 +4425,10 @@ Ez az ön hivatkozása a(z) %@ csoporthoz! Átköltöztetés megkezdése egy másik eszközre authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles Felhasználói profilok megnyitása @@ -4299,6 +4534,10 @@ Ez az ön hivatkozása a(z) %@ csoporthoz! Fogadott hivatkozás beillesztése No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. Az emberek csak az ön által megosztott hivatkozáson keresztül kapcsolódhatnak. @@ -4324,6 +4563,11 @@ Ez az ön hivatkozása a(z) %@ csoporthoz! Ismerős felkérése, hogy engedélyezze a hangüzenetek küldését. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Ellenőrizze, hogy a megfelelő hivatkozást használta-e, vagy kérje meg ismerősét, hogy küldjön egy másikat. @@ -4421,6 +4665,10 @@ Hiba: %@ Előnézet No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security Adatvédelem és biztonság @@ -4486,6 +4734,10 @@ Hiba: %@ Profiljelszó No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. A profilfrissítés elküldésre került az ismerősök számára. @@ -4568,6 +4820,14 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Protokoll időkorlát KB-onként No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications Push értesítések @@ -4633,6 +4893,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Üzenet kézbesítési jelentés letiltva No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at Fogadva ekkor: @@ -4653,6 +4917,18 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Fogadott üzenet message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. A fogadó cím egy másik kiszolgálóra változik. A címváltoztatás a feladó online állapotba kerülése után fejeződik be. @@ -4683,11 +4959,31 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< A címzettek a beírás közben látják a frissítéseket. No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Újrakapcsolódás az összes kiszolgálóhoz az üzenetek kézbesítésének kikényszerítéséhez. Ez további forgalmat használ. No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? Újrakapcsolódás a kiszolgálókhoz? @@ -4738,6 +5034,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Eltávolítás No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member Eltávolítás @@ -4808,16 +5108,32 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Alaphelyzetbe állítás No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors Színek alaphelyzetbe állítása No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults Alaphelyzetbe állítás No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Új csevegési profil létrehozásához indítsa újra az alkalmazást @@ -4888,6 +5204,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Csevegési szolgáltatás indítása No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers Üzenetküldő (SMP) kiszolgálók @@ -5003,6 +5323,14 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Mentett üzenet message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code QR-kód beolvasása @@ -5043,11 +5371,19 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Keresés, vagy SimpleX hivatkozás beillesztése No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue Biztonságos várólista server test step + + Secured + No comment provided by engineer. + Security assessment Biztonsági kiértékelés @@ -5063,6 +5399,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Választás No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Önmegsemmisítés @@ -5113,6 +5453,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Eltűnő üzenet küldése No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews Hivatkozás előnézetek küldése @@ -5223,6 +5567,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Elküldve ekkor: %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event Elküldött fájl esemény @@ -5233,11 +5581,31 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Elküldött üzenet message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. Az elküldött üzenetek törlésre kerülnek a beállított idő után. No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. A kiszolgáló címe nem kompatibilis a hálózati beállításokkal. @@ -5258,6 +5626,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Sikertelen kiszolgáló-teszt! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. A kiszolgáló verziója nem kompatibilis a hálózati beállításokkal. @@ -5268,6 +5640,14 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Kiszolgálók No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code Munkamenet kód @@ -5283,6 +5663,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Ismerős nevének beállítása… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences Csoportbeállítások megadása @@ -5403,6 +5787,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Megjelenítés: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address SimpleX azonosító @@ -5478,6 +5866,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Egyszerűsített inkognító mód No comment provided by engineer. + + Size + No comment provided by engineer. + Skip Kihagyás @@ -5523,6 +5915,14 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Átköltöztetés indítása No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop Megállítás @@ -5588,6 +5988,22 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Elküldés No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat Támogassa a SimpleX Chatet @@ -5668,6 +6084,10 @@ Engedélyezze a beállításokban a *Hálózat és kiszolgálók* menüpontban.< Koppintson az új csevegés indításához No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. A teszt sikertelen volt a(z) %@ lépésnél. @@ -5805,9 +6225,8 @@ Ez valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő. A beillesztett szöveg nem egy SimpleX hivatkozás. No comment provided by engineer. - - Theme - Téma + + Themes No comment provided by engineer. @@ -5875,11 +6294,19 @@ Ez valamilyen hiba, vagy sérült kapcsolat esetén fordulhat elő. Ez az egyszer használatos hivatkozása! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. Ez a beállítás a jelenlegi **%@** profiljában lévő üzenetekre érvényes. No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: Bármilyen kérdés feltevéséhez és a frissítésekért: @@ -5947,11 +6374,19 @@ A funkció engedélyezése előtt a rendszer felszólítja a hitelesítés befej Inkognitó mód kapcsolódáskor. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation Kapcsolat izolációs mód No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Kapcsolódási kísérlet ahhoz a kiszolgálóhoz, amely az adott ismerőstől érkező üzenetek fogadására szolgál (hiba: %@). @@ -6144,6 +6579,10 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol A csevegés frissítése és megnyitása No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed Sikertelen feltöltés @@ -6154,6 +6593,14 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol Fájl feltöltése server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive Archívum feltöltése @@ -6229,6 +6676,10 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol Felhasználói profil No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. A .onion kiszolgálók használatához kompatibilis VPN szolgáltatóra van szükség. @@ -6364,6 +6815,14 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol Videóra várakozás No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures Figyelmeztetés: a csevegés elindítása egyszerre több eszközön nem támogatott, továbbá üzenetkézbesítési hibákat okozhat @@ -6469,11 +6928,19 @@ A kapcsolódáshoz kérje meg ismerősét, hogy hozzon létre egy másik kapcsol Rossz kulcs vagy ismeretlen kapcsolat - valószínűleg ez a kapcsolat törlődött. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! Téves jelmondat! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers XFTP kiszolgálók @@ -6556,6 +7023,10 @@ Csatlakozási kérés megismétlése? Meghívást kapott a csoportba No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. Hívásokat fogadhat a lezárási képernyőről, eszköz- és alkalmazáshitelesítés nélkül. @@ -6962,6 +7433,10 @@ A SimpleX kiszolgálók nem látjhatják profilját. és %lld további esemény No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) hanghívás (nem e2e titkosított) @@ -6995,7 +7470,7 @@ A SimpleX kiszolgálók nem látjhatják profilját. blocked by admin letiltva az admin által - marked deleted chat item preview text + blocked chat item bold @@ -7152,6 +7627,10 @@ A SimpleX kiszolgálók nem látjhatják profilját. nap time unit + + decryption errors + No comment provided by engineer. + default (%@) alapértelmezett (%@) @@ -7202,6 +7681,10 @@ A SimpleX kiszolgálók nem látjhatják profilját. duplikálódott üzenet integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted e2e titkosított @@ -7282,6 +7765,10 @@ A SimpleX kiszolgálók nem látjhatják profilját. esemény történt No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded továbbított @@ -7489,6 +7976,14 @@ A SimpleX kiszolgálók nem látjhatják profilját. be group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner tulajdonos @@ -7799,7 +8294,7 @@ last received msg: %2$@
    - +
    @@ -7836,7 +8331,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/hu.xcloc/contents.json b/apps/ios/SimpleX Localizations/hu.xcloc/contents.json index bc788c3c10..0b16198498 100644 --- a/apps/ios/SimpleX Localizations/hu.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/hu.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "hu", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff b/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff index b6fd18f551..2929cc41dc 100644 --- a/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff +++ b/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff @@ -2,7 +2,7 @@
    - +
    @@ -557,9 +557,8 @@ Info sull'indirizzo SimpleX No comment provided by engineer. - - Accent color - Colore principale + + Accent No comment provided by engineer. @@ -583,6 +582,14 @@ Accetta in incognito accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Aggiungi l'indirizzo al tuo profilo, in modo che i tuoi contatti possano condividerlo con altre persone. L'aggiornamento del profilo verrà inviato ai tuoi contatti. @@ -623,6 +630,18 @@ Aggiungi messaggio di benvenuto No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address Indirizzo @@ -648,6 +667,10 @@ Impostazioni di rete avanzate No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. Tutti i dati dell'app vengono eliminati. @@ -663,6 +686,10 @@ Tutti i dati vengono cancellati quando inserito. No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. Tutti i membri del gruppo resteranno connessi. @@ -683,6 +710,10 @@ Tutti i nuovi messaggi da %@ verrranno nascosti! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. Tutti i tuoi contatti resteranno connessi. @@ -883,6 +914,10 @@ Applica No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload Archivia e carica @@ -958,6 +993,10 @@ Indietro No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address Indirizzo desktop errato @@ -983,6 +1022,10 @@ Messaggi migliorati No comment provided by engineer. + + Black + No comment provided by engineer. + Block Blocca @@ -1093,6 +1136,10 @@ Impossibile accedere al portachiavi per salvare la password del database No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file Impossibile ricevere il file @@ -1164,6 +1211,10 @@ Archivio chat No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console Console della chat @@ -1209,6 +1260,10 @@ Preferenze della chat No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats Chat @@ -1239,6 +1294,18 @@ Scegli dalla libreria No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear Svuota @@ -1264,9 +1331,8 @@ Annulla la verifica No comment provided by engineer. - - Colors - Colori + + Color mode No comment provided by engineer. @@ -1279,6 +1345,10 @@ Confronta i codici di sicurezza con i tuoi contatti. No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers Configura server ICE @@ -1388,16 +1458,28 @@ Questo è il tuo link una tantum! Connettersi con %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop Desktop connesso No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop Connesso al desktop No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… Connessione al server… @@ -1443,6 +1525,18 @@ Questo è il tuo link una tantum! Connessione scaduta No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows Il contatto lo consente @@ -1496,7 +1590,11 @@ Questo è il tuo link una tantum! Copy Copia - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1573,6 +1671,10 @@ Questo è il tuo link una tantum! Crea il tuo profilo No comment provided by engineer. + + Created + No comment provided by engineer. + Created at Creato il @@ -1608,6 +1710,10 @@ Questo è il tuo link una tantum! Password attuale… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. Attualmente la dimensione massima supportata è di %@. @@ -1618,11 +1724,19 @@ Questo è il tuo link una tantum! Tempo personalizzato No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark Scuro No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID ID database @@ -1927,6 +2041,10 @@ Non è reversibile! Eliminare il profilo utente? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at Eliminato il @@ -1937,6 +2055,10 @@ Non è reversibile! Eliminato il: %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery Consegna @@ -1977,6 +2099,14 @@ Non è reversibile! Errore del server di destinazione: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop Sviluppa @@ -2132,6 +2262,10 @@ Non è reversibile! Scarica chat item action + + Download errors + No comment provided by engineer. + Download failed Scaricamento fallito @@ -2142,6 +2276,14 @@ Non è reversibile! Scarica file server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive Scaricamento archivio @@ -2512,6 +2654,10 @@ Non è reversibile! Errore nell'esportazione del database della chat No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Errore nell'importazione del database della chat @@ -2537,11 +2683,23 @@ Non è reversibile! Errore nella ricezione del file No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member Errore nella rimozione del membro No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers Errore nel salvataggio dei server %@ @@ -2660,7 +2818,8 @@ Non è reversibile! Error: %@ Errore: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2672,6 +2831,10 @@ Non è reversibile! Errore: nessun file di database No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. Anche quando disattivato nella conversazione. @@ -2697,6 +2860,10 @@ Non è reversibile! Errore di esportazione: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. Archivio database esportato. @@ -2732,6 +2899,26 @@ Non è reversibile! Preferito No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. Il file verrà eliminato dai server. @@ -2921,6 +3108,14 @@ Errore: %2$@ GIF e adesivi No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group Gruppo @@ -3201,6 +3396,10 @@ Errore: %2$@ Importazione fallita No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive Importazione archivio @@ -3323,6 +3522,10 @@ Errore: %2$@ Interfaccia No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code Codice QR non valido @@ -3681,6 +3884,10 @@ Questo è il tuo link per il gruppo %@! Il membro verrà rimosso dal gruppo, non è reversibile! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error Errore di recapito del messaggio @@ -3735,6 +3942,18 @@ Questo è il tuo link per il gruppo %@! La fonte del messaggio resta privata. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text Testo del messaggio @@ -3760,6 +3979,14 @@ Questo è il tuo link per il gruppo %@! I messaggi da %@ verranno mostrati! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. I messaggi, i file e le chiamate sono protetti da **crittografia end-to-end** con perfect forward secrecy, ripudio e recupero da intrusione. @@ -4010,6 +4237,10 @@ Questo è il tuo link per il gruppo %@! Nessuna cronologia No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection Nessuna connessione di rete @@ -4194,6 +4425,10 @@ Questo è il tuo link per il gruppo %@! Apri migrazione ad un altro dispositivo authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles Apri i profili utente @@ -4299,6 +4534,10 @@ Questo è il tuo link per il gruppo %@! Incolla il link che hai ricevuto No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. Le persone possono connettersi a te solo tramite i link che condividi. @@ -4324,6 +4563,11 @@ Questo è il tuo link per il gruppo %@! Chiedi al tuo contatto di attivare l'invio dei messaggi vocali. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Controlla di aver usato il link giusto o chiedi al tuo contatto di inviartene un altro. @@ -4421,6 +4665,10 @@ Errore: %@ Anteprima No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security Privacy e sicurezza @@ -4486,6 +4734,10 @@ Errore: %@ Password del profilo No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. L'aggiornamento del profilo verrà inviato ai tuoi contatti. @@ -4568,6 +4820,14 @@ Attivalo nelle impostazioni *Rete e server*. Scadenza del protocollo per KB No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications Notifiche push @@ -4633,6 +4893,10 @@ Attivalo nelle impostazioni *Rete e server*. Le ricevute sono disattivate No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at Ricevuto il @@ -4653,6 +4917,18 @@ Attivalo nelle impostazioni *Rete e server*. Messaggio ricevuto message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. L'indirizzo di ricezione verrà cambiato in un server diverso. La modifica dell'indirizzo verrà completata dopo che il mittente sarà in linea. @@ -4683,11 +4959,31 @@ Attivalo nelle impostazioni *Rete e server*. I destinatari vedono gli aggiornamenti mentre li digiti. No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Riconnetti tutti i server connessi per imporre il recapito dei messaggi. Utilizza traffico aggiuntivo. No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? Riconnettere i server? @@ -4738,6 +5034,10 @@ Attivalo nelle impostazioni *Rete e server*. Rimuovi No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member Rimuovi membro @@ -4808,16 +5108,32 @@ Attivalo nelle impostazioni *Rete e server*. Ripristina No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors Ripristina i colori No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults Ripristina i predefiniti No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Riavvia l'app per creare un nuovo profilo di chat @@ -4888,6 +5204,10 @@ Attivalo nelle impostazioni *Rete e server*. Avvia chat No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers Server SMP @@ -5003,6 +5323,14 @@ Attivalo nelle impostazioni *Rete e server*. Messaggio salvato message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code Scansiona codice QR @@ -5043,11 +5371,19 @@ Attivalo nelle impostazioni *Rete e server*. Cerca o incolla un link SimpleX No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue Coda sicura server test step + + Secured + No comment provided by engineer. + Security assessment Valutazione della sicurezza @@ -5063,6 +5399,10 @@ Attivalo nelle impostazioni *Rete e server*. Seleziona No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Autodistruzione @@ -5113,6 +5453,10 @@ Attivalo nelle impostazioni *Rete e server*. Invia messaggio a tempo No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews Invia anteprime dei link @@ -5223,6 +5567,10 @@ Attivalo nelle impostazioni *Rete e server*. Inviato il: %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event Evento file inviato @@ -5233,11 +5581,31 @@ Attivalo nelle impostazioni *Rete e server*. Messaggio inviato message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. I messaggi inviati verranno eliminati dopo il tempo impostato. No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. L'indirizzo del server non è compatibile con le impostazioni di rete. @@ -5258,6 +5626,10 @@ Attivalo nelle impostazioni *Rete e server*. Test del server fallito! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. La versione del server non è compatibile con le impostazioni di rete. @@ -5268,6 +5640,14 @@ Attivalo nelle impostazioni *Rete e server*. Server No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code Codice di sessione @@ -5283,6 +5663,10 @@ Attivalo nelle impostazioni *Rete e server*. Imposta nome del contatto… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences Imposta le preferenze del gruppo @@ -5403,6 +5787,10 @@ Attivalo nelle impostazioni *Rete e server*. Mostra: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address Indirizzo SimpleX @@ -5478,6 +5866,10 @@ Attivalo nelle impostazioni *Rete e server*. Modalità incognito semplificata No comment provided by engineer. + + Size + No comment provided by engineer. + Skip Salta @@ -5523,6 +5915,14 @@ Attivalo nelle impostazioni *Rete e server*. Avvia la migrazione No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop Ferma @@ -5588,6 +5988,22 @@ Attivalo nelle impostazioni *Rete e server*. Invia No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat Supporta SimpleX Chat @@ -5668,6 +6084,10 @@ Attivalo nelle impostazioni *Rete e server*. Tocca per iniziare una chat No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. Test fallito al passo %@. @@ -5805,9 +6225,8 @@ Può accadere a causa di qualche bug o quando la connessione è compromessa.Il testo che hai incollato non è un link SimpleX. No comment provided by engineer. - - Theme - Tema + + Themes No comment provided by engineer. @@ -5875,11 +6294,19 @@ Può accadere a causa di qualche bug o quando la connessione è compromessa.Questo è il tuo link una tantum! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. Questa impostazione si applica ai messaggi del profilo di chat attuale **%@**. No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: Per porre domande e ricevere aggiornamenti: @@ -5947,11 +6374,19 @@ Ti verrà chiesto di completare l'autenticazione prima di attivare questa funzio Attiva/disattiva l'incognito quando ti colleghi. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation Isolamento del trasporto No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Tentativo di connessione al server usato per ricevere messaggi da questo contatto (errore: %@). @@ -6144,6 +6579,10 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e Aggiorna e apri chat No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed Invio fallito @@ -6154,6 +6593,14 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e Invia file server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive Invio dell'archivio @@ -6229,6 +6676,10 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e Profilo utente No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. L'uso di host .onion richiede un fornitore di VPN compatibile. @@ -6364,6 +6815,14 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e In attesa del video No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures Attenzione: avviare la chat su più dispositivi non è supportato e provocherà problemi di recapito dei messaggi @@ -6469,11 +6928,19 @@ Per connetterti, chiedi al tuo contatto di creare un altro link di connessione e Chiave sbagliata o connessione sconosciuta - molto probabilmente questa connessione è stata eliminata. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! Password sbagliata! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers Server XFTP @@ -6556,6 +7023,10 @@ Ripetere la richiesta di ingresso? Sei stato/a invitato/a al gruppo No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. Puoi accettare chiamate dalla schermata di blocco, senza l'autenticazione del dispositivo e dell'app. @@ -6962,6 +7433,10 @@ I server di SimpleX non possono vedere il tuo profilo. e altri %lld eventi No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) chiamata audio (non crittografata e2e) @@ -6995,7 +7470,7 @@ I server di SimpleX non possono vedere il tuo profilo. blocked by admin bloccato dall'amministratore - marked deleted chat item preview text + blocked chat item bold @@ -7152,6 +7627,10 @@ I server di SimpleX non possono vedere il tuo profilo. giorni time unit + + decryption errors + No comment provided by engineer. + default (%@) predefinito (%@) @@ -7202,6 +7681,10 @@ I server di SimpleX non possono vedere il tuo profilo. messaggio duplicato integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted crittografato e2e @@ -7282,6 +7765,10 @@ I server di SimpleX non possono vedere il tuo profilo. evento accaduto No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded inoltrato @@ -7489,6 +7976,14 @@ I server di SimpleX non possono vedere il tuo profilo. on group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner proprietario @@ -7799,7 +8294,7 @@ last received msg: %2$@
    - +
    @@ -7836,7 +8331,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/it.xcloc/contents.json b/apps/ios/SimpleX Localizations/it.xcloc/contents.json index 2ad653d36f..13870ab8dd 100644 --- a/apps/ios/SimpleX Localizations/it.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/it.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "it", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff b/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff index 395fcb9326..929a6692bc 100644 --- a/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff +++ b/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff @@ -2,7 +2,7 @@
    - +
    @@ -551,9 +551,8 @@ SimpleXアドレスについて No comment provided by engineer. - - Accent color - アクセントカラー + + Accent No comment provided by engineer. @@ -577,6 +576,14 @@ シークレットモードで承諾 accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. プロフィールにアドレスを追加し、連絡先があなたのアドレスを他の人と共有できるようにします。プロフィールの更新は連絡先に送信されます。 @@ -616,6 +623,18 @@ ウェルカムメッセージを追加 No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address アドレス @@ -640,6 +659,10 @@ ネットワーク詳細設定 No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. すべてのアプリデータが削除されます。 @@ -655,6 +678,10 @@ 入力するとすべてのデータが消去されます。 No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. グループ全員の接続が継続します。 @@ -673,6 +700,10 @@ All new messages from %@ will be hidden! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. あなたの連絡先が繋がったまま継続します。 @@ -870,6 +901,10 @@ Apply No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload No comment provided by engineer. @@ -943,6 +978,10 @@ 戻る No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address No comment provided by engineer. @@ -966,6 +1005,10 @@ より良いメッセージ No comment provided by engineer. + + Black + No comment provided by engineer. + Block No comment provided by engineer. @@ -1067,6 +1110,10 @@ データベースのパスワードを保存するためのキーチェーンにアクセスできません No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file ファイル受信ができません @@ -1136,6 +1183,10 @@ チャットのアーカイブ No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console チャットのコンソール @@ -1179,6 +1230,10 @@ チャット設定 No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats チャット @@ -1208,6 +1263,18 @@ ライブラリから選択 No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear 消す @@ -1232,9 +1299,8 @@ 検証を消す No comment provided by engineer. - - Colors - + + Color mode No comment provided by engineer. @@ -1247,6 +1313,10 @@ 連絡先とセキュリティコードを確認する。 No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers ICEサーバを設定 @@ -1343,14 +1413,26 @@ This is your own one-time link! Connect with %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… サーバーに接続中… @@ -1394,6 +1476,18 @@ This is your own one-time link! 接続タイムアウト No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows 連絡先の許可 @@ -1447,7 +1541,11 @@ This is your own one-time link! Copy コピー - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1520,6 +1618,10 @@ This is your own one-time link! プロフィールを作成する No comment provided by engineer. + + Created + No comment provided by engineer. + Created at No comment provided by engineer. @@ -1551,6 +1653,10 @@ This is your own one-time link! 現在の暗証フレーズ… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. 現在サポートされている最大ファイルサイズは %@. @@ -1561,11 +1667,19 @@ This is your own one-time link! カスタム時間 No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark ダークモード No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID データベースID @@ -1865,6 +1979,10 @@ This cannot be undone! ユーザープロフィールを削除しますか? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at 削除完了 @@ -1875,6 +1993,10 @@ This cannot be undone! 削除完了: %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery 配信 @@ -1911,6 +2033,14 @@ This cannot be undone! Destination server error: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop 開発 @@ -2060,6 +2190,10 @@ This cannot be undone! Download chat item action + + Download errors + No comment provided by engineer. + Download failed No comment provided by engineer. @@ -2069,6 +2203,14 @@ This cannot be undone! ファイルをダウンロード server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive No comment provided by engineer. @@ -2424,6 +2566,10 @@ This cannot be undone! チャットデータベースのエキスポートにエラー発生 No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database チャットデータベースのインポートにエラー発生 @@ -2448,11 +2594,23 @@ This cannot be undone! ファイル受信にエラー発生 No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member メンバー除名にエラー発生 No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers %@ サーバの保存エラー @@ -2566,7 +2724,8 @@ This cannot be undone! Error: %@ エラー : %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2578,6 +2737,10 @@ This cannot be undone! エラー: データベースが存在しません No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. 会話中に無効になっている場合でも。 @@ -2602,6 +2765,10 @@ This cannot be undone! エクスポートエラー: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. データベースのアーカイブをエクスポートします。 @@ -2635,6 +2802,26 @@ This cannot be undone! お気に入り No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. ファイルはサーバーから削除されます。 @@ -2810,6 +2997,14 @@ Error: %2$@ GIFとステッカー No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group グループ @@ -3084,6 +3279,10 @@ Error: %2$@ Import failed No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive No comment provided by engineer. @@ -3200,6 +3399,10 @@ Error: %2$@ インターフェース No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code No comment provided by engineer. @@ -3541,6 +3744,10 @@ This is your link for group %@! メンバーをグループから除名する (※元に戻せません※)! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error メッセージ送信エラー @@ -3590,6 +3797,18 @@ This is your link for group %@! Message source remains private. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text メッセージ内容 @@ -3613,6 +3832,14 @@ This is your link for group %@! Messages from %@ will be shown! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. No comment provided by engineer. @@ -3849,6 +4076,10 @@ This is your link for group %@! 履歴はありません No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection No comment provided by engineer. @@ -4028,6 +4259,10 @@ This is your link for group %@! Open migration to another device authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles ユーザープロフィールを開く @@ -4123,6 +4358,10 @@ This is your link for group %@! Paste the link you received No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. あなたと繋がることができるのは、あなたからリンクを頂いた方のみです。 @@ -4147,6 +4386,11 @@ This is your link for group %@! 音声メッセージを有効にするように連絡相手に要求してください。 No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. リンクが正しいかどうかご確認ください。または、連絡相手にもう一度リンクをお求めください。 @@ -4241,6 +4485,10 @@ Error: %@ プレビュー No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security プライバシーとセキュリティ @@ -4299,6 +4547,10 @@ Error: %@ プロフィールのパスワード No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. 連絡先にプロフィール更新のお知らせが届きます。 @@ -4377,6 +4629,14 @@ Enable in *Network & servers* settings. KB あたりのプロトコル タイムアウト No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications プッシュ通知 @@ -4438,6 +4698,10 @@ Enable in *Network & servers* settings. Receipts are disabled No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at 受信 @@ -4458,6 +4722,18 @@ Enable in *Network & servers* settings. 受信したメッセージ message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. 開発中の機能です!相手のクライアントが4.2でなければ機能しません。アドレス変更が完了すると、会話にメッセージが出ます。連絡相手 (またはグループのメンバー) からメッセージを受信できないかをご確認ください。 @@ -4486,11 +4762,31 @@ Enable in *Network & servers* settings. 受信者には、入力時に更新内容が表示されます。 No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. 接続されているすべてのサーバーを再接続して、メッセージを強制的に配信します。 追加のトラフィックを使用します。 No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? サーバーに再接続しますか? @@ -4541,6 +4837,10 @@ Enable in *Network & servers* settings. 削除 No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member メンバーを除名する @@ -4606,16 +4906,32 @@ Enable in *Network & servers* settings. 戻す No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors 既定の色に戻す No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults 既定に戻す No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile 新しいチャットプロファイルを作成するためにアプリを再起動する @@ -4685,6 +5001,10 @@ Enable in *Network & servers* settings. チャット起動 No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers SMPサーバ @@ -4795,6 +5115,14 @@ Enable in *Network & servers* settings. Saved message message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code QRコードを読み込む @@ -4832,11 +5160,19 @@ Enable in *Network & servers* settings. Search or paste SimpleX link No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue 待ち行列セキュリティ確認 server test step + + Secured + No comment provided by engineer. + Security assessment セキュリティ評価 @@ -4852,6 +5188,10 @@ Enable in *Network & servers* settings. 選択 No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct 自己破壊 @@ -4901,6 +5241,10 @@ Enable in *Network & servers* settings. 消えるメッセージを送信 No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews リンクのプレビューを送信 @@ -5001,6 +5345,10 @@ Enable in *Network & servers* settings. 送信日時: %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event 送信済みファイルイベント @@ -5011,11 +5359,31 @@ Enable in *Network & servers* settings. 送信 message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. 一定時間が経ったら送信されたメッセージが削除されます。 No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. srv error text. @@ -5035,6 +5403,10 @@ Enable in *Network & servers* settings. サーバテスト失敗! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. srv error text @@ -5044,6 +5416,14 @@ Enable in *Network & servers* settings. サーバ No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code No comment provided by engineer. @@ -5058,6 +5438,10 @@ Enable in *Network & servers* settings. 連絡先の名前を設定… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences グループの設定を行う @@ -5172,6 +5556,10 @@ Enable in *Network & servers* settings. 表示する: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address SimpleXアドレス @@ -5245,6 +5633,10 @@ Enable in *Network & servers* settings. シークレットモードの簡素化 No comment provided by engineer. + + Size + No comment provided by engineer. + Skip スキップ @@ -5288,6 +5680,14 @@ Enable in *Network & servers* settings. 移行の開始 No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop 停止 @@ -5351,6 +5751,22 @@ Enable in *Network & servers* settings. 送信 No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat Simplex Chatを支援 @@ -5428,6 +5844,10 @@ Enable in *Network & servers* settings. タップして新しいチャットを始める No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. テストはステップ %@ で失敗しました。 @@ -5562,9 +5982,8 @@ It can happen because of some bug or when the connection is compromised.The text you pasted is not a SimpleX link. No comment provided by engineer. - - Theme - テーマ + + Themes No comment provided by engineer. @@ -5625,11 +6044,19 @@ It can happen because of some bug or when the connection is compromised.This is your own one-time link! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. この設定は現在のチャットプロフィール **%@** のメッセージに適用されます。 No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: 質問や最新情報を受け取るには: @@ -5694,11 +6121,19 @@ You will be prompted to complete authentication before this feature is enabled.< Toggle incognito when connecting. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation トランスポート隔離 No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). この連絡先からのメッセージの受信に使用されるサーバーに接続しようとしています (エラー: %@)。 @@ -5881,6 +6316,10 @@ To connect, please ask your contact to create another connection link and check アップグレードしてチャットを開く No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed No comment provided by engineer. @@ -5890,6 +6329,14 @@ To connect, please ask your contact to create another connection link and check ファイルをアップロードする server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive No comment provided by engineer. @@ -5959,6 +6406,10 @@ To connect, please ask your contact to create another connection link and check ユーザープロフィール No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. .onionホストを使用するには、互換性のあるVPNプロバイダーが必要です。 @@ -6085,6 +6536,14 @@ To connect, please ask your contact to create another connection link and check ビデオ待機中 No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures No comment provided by engineer. @@ -6179,11 +6638,19 @@ To connect, please ask your contact to create another connection link and check Wrong key or unknown connection - most likely this connection is deleted. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! パスフレーズが違います! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers XFTPサーバ @@ -6257,6 +6724,10 @@ Repeat join request? グループ招待が届きました No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. デバイスやアプリの認証を行わずに、ロック画面から通話を受けることができます。 @@ -6651,6 +7122,10 @@ SimpleX サーバーはあなたのプロファイルを参照できません。 and %lld other events No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) 音声通話 (エンドツーエンド暗号化なし) @@ -6680,7 +7155,7 @@ SimpleX サーバーはあなたのプロファイルを参照できません。 blocked by admin - marked deleted chat item preview text + blocked chat item bold @@ -6835,6 +7310,10 @@ SimpleX サーバーはあなたのプロファイルを参照できません。 time unit + + decryption errors + No comment provided by engineer. + default (%@) デフォルト (%@) @@ -6884,6 +7363,10 @@ SimpleX サーバーはあなたのプロファイルを参照できません。 重複メッセージ integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted エンドツーエンド暗号化済み @@ -6964,6 +7447,10 @@ SimpleX サーバーはあなたのプロファイルを参照できません。 イベント発生 No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded No comment provided by engineer. @@ -7169,6 +7656,14 @@ SimpleX サーバーはあなたのプロファイルを参照できません。 オン group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner オーナー @@ -7459,7 +7954,7 @@ last received msg: %2$@
    - +
    @@ -7495,7 +7990,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/ja.xcloc/contents.json b/apps/ios/SimpleX Localizations/ja.xcloc/contents.json index 7d3c224e68..604a21be97 100644 --- a/apps/ios/SimpleX Localizations/ja.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/ja.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "ja", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff b/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff index e4ee887f4b..129dda6187 100644 --- a/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff +++ b/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff @@ -2,7 +2,7 @@
    - +
    @@ -557,9 +557,8 @@ Over SimpleX adres No comment provided by engineer. - - Accent color - Accent kleur + + Accent No comment provided by engineer. @@ -583,6 +582,14 @@ Accepteer incognito accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Voeg een adres toe aan uw profiel, zodat uw contacten het met andere mensen kunnen delen. Profiel update wordt naar uw contacten verzonden. @@ -623,6 +630,18 @@ Welkomst bericht toevoegen No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address Adres @@ -648,6 +667,10 @@ Geavanceerde netwerk instellingen No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. Alle app-gegevens worden verwijderd. @@ -663,6 +686,10 @@ Alle gegevens worden bij het invoeren gewist. No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. Alle groepsleden blijven verbonden. @@ -683,6 +710,10 @@ Alle nieuwe berichten van %@ worden verborgen! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. Al uw contacten blijven verbonden. @@ -883,6 +914,10 @@ Toepassen No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload Archiveren en uploaden @@ -958,6 +993,10 @@ Terug No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address Onjuist desktopadres @@ -983,6 +1022,10 @@ Betere berichten No comment provided by engineer. + + Black + No comment provided by engineer. + Block Blokkeren @@ -1093,6 +1136,10 @@ Geen toegang tot de keychain om database wachtwoord op te slaan No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file Kan bestand niet ontvangen @@ -1164,6 +1211,10 @@ Gesprek archief No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console Chat console @@ -1209,6 +1260,10 @@ Gesprek voorkeuren No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats Gesprekken @@ -1239,6 +1294,18 @@ Kies uit bibliotheek No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear Wissen @@ -1264,9 +1331,8 @@ Verwijderd verificatie No comment provided by engineer. - - Colors - Kleuren + + Color mode No comment provided by engineer. @@ -1279,6 +1345,10 @@ Vergelijk beveiligingscodes met je contacten. No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers ICE servers configureren @@ -1388,16 +1458,28 @@ Dit is uw eigen eenmalige link! Verbonden met %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop Verbonden desktop No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop Verbonden met desktop No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… Verbinden met de server… @@ -1443,6 +1525,18 @@ Dit is uw eigen eenmalige link! Timeout verbinding No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows Contact maakt het mogelijk @@ -1496,7 +1590,11 @@ Dit is uw eigen eenmalige link! Copy Kopiëren - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1573,6 +1671,10 @@ Dit is uw eigen eenmalige link! Maak je profiel aan No comment provided by engineer. + + Created + No comment provided by engineer. + Created at Gemaakt op @@ -1608,6 +1710,10 @@ Dit is uw eigen eenmalige link! Huidige wachtwoord… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. De momenteel maximaal ondersteunde bestandsgrootte is %@. @@ -1618,11 +1724,19 @@ Dit is uw eigen eenmalige link! Aangepaste tijd No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark Donker No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID Database-ID @@ -1927,6 +2041,10 @@ Dit kan niet ongedaan gemaakt worden! Gebruikers profiel verwijderen? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at Verwijderd om @@ -1937,6 +2055,10 @@ Dit kan niet ongedaan gemaakt worden! Verwijderd om: %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery Bezorging @@ -1977,6 +2099,14 @@ Dit kan niet ongedaan gemaakt worden! Bestemmingsserverfout: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop Ontwikkelen @@ -2132,6 +2262,10 @@ Dit kan niet ongedaan gemaakt worden! Downloaden chat item action + + Download errors + No comment provided by engineer. + Download failed Download mislukt @@ -2142,6 +2276,14 @@ Dit kan niet ongedaan gemaakt worden! Download bestand server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive Archief downloaden @@ -2512,6 +2654,10 @@ Dit kan niet ongedaan gemaakt worden! Fout bij het exporteren van de chat database No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Fout bij het importeren van de chat database @@ -2537,11 +2683,23 @@ Dit kan niet ongedaan gemaakt worden! Fout bij ontvangen van bestand No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member Fout bij verwijderen van lid No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers Fout bij opslaan van %@ servers @@ -2660,7 +2818,8 @@ Dit kan niet ongedaan gemaakt worden! Error: %@ Fout: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2672,6 +2831,10 @@ Dit kan niet ongedaan gemaakt worden! Fout: geen database bestand No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. Zelfs wanneer uitgeschakeld in het gesprek. @@ -2697,6 +2860,10 @@ Dit kan niet ongedaan gemaakt worden! Exportfout: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. Geëxporteerd database archief. @@ -2732,6 +2899,26 @@ Dit kan niet ongedaan gemaakt worden! Favoriet No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. Het bestand wordt van de servers verwijderd. @@ -2921,6 +3108,14 @@ Fout: %2$@ GIF's en stickers No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group Groep @@ -3201,6 +3396,10 @@ Fout: %2$@ Importeren is mislukt No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive Archief importeren @@ -3323,6 +3522,10 @@ Fout: %2$@ Interface No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code Ongeldige QR-code @@ -3681,6 +3884,10 @@ Dit is jouw link voor groep %@! Lid wordt uit de groep verwijderd, dit kan niet ongedaan worden gemaakt! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error Fout bij bezorging van bericht @@ -3735,6 +3942,18 @@ Dit is jouw link voor groep %@! Berichtbron blijft privé. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text Bericht tekst @@ -3760,6 +3979,14 @@ Dit is jouw link voor groep %@! Berichten van %@ worden getoond! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. Berichten, bestanden en oproepen worden beschermd door **end-to-end codering** met perfecte voorwaartse geheimhouding, afwijzing en inbraakherstel. @@ -4010,6 +4237,10 @@ Dit is jouw link voor groep %@! Geen geschiedenis No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection Geen netwerkverbinding @@ -4194,6 +4425,10 @@ Dit is jouw link voor groep %@! Open de migratie naar een ander apparaat authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles Gebruikers profielen openen @@ -4299,6 +4534,10 @@ Dit is jouw link voor groep %@! Plak de link die je hebt ontvangen No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. Mensen kunnen alleen verbinding met u maken via de links die u deelt. @@ -4324,6 +4563,11 @@ Dit is jouw link voor groep %@! Vraag uw contact om het verzenden van spraak berichten in te schakelen. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Controleer of u de juiste link heeft gebruikt of vraag uw contact om u een andere te sturen. @@ -4421,6 +4665,10 @@ Fout: %@ Voorbeeld No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security Privacy en beveiliging @@ -4486,6 +4734,10 @@ Fout: %@ Profiel wachtwoord No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. Profiel update wordt naar uw contacten verzonden. @@ -4568,6 +4820,14 @@ Schakel dit in in *Netwerk en servers*-instellingen. Protocol timeout per KB No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications Push meldingen @@ -4633,6 +4893,10 @@ Schakel dit in in *Netwerk en servers*-instellingen. Bevestigingen zijn uitgeschakeld No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at Ontvangen op @@ -4653,6 +4917,18 @@ Schakel dit in in *Netwerk en servers*-instellingen. Ontvangen bericht message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. Het ontvangstadres wordt gewijzigd naar een andere server. Adres wijziging wordt voltooid nadat de afzender online is. @@ -4683,11 +4959,31 @@ Schakel dit in in *Netwerk en servers*-instellingen. Ontvangers zien updates terwijl u ze typt. No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Verbind alle verbonden servers opnieuw om de bezorging van berichten af te dwingen. Het maakt gebruik van extra data. No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? Servers opnieuw verbinden? @@ -4738,6 +5034,10 @@ Schakel dit in in *Netwerk en servers*-instellingen. Verwijderen No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member Lid verwijderen @@ -4808,16 +5108,32 @@ Schakel dit in in *Netwerk en servers*-instellingen. Resetten No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors Kleuren resetten No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults Resetten naar standaardwaarden No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Start de app opnieuw om een nieuw chat profiel aan te maken @@ -4888,6 +5204,10 @@ Schakel dit in in *Netwerk en servers*-instellingen. Chat uitvoeren No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers SMP servers @@ -5003,6 +5323,14 @@ Schakel dit in in *Netwerk en servers*-instellingen. Opgeslagen bericht message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code Scan QR-code @@ -5043,11 +5371,19 @@ Schakel dit in in *Netwerk en servers*-instellingen. Zoeken of plak een SimpleX link No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue Veilige wachtrij server test step + + Secured + No comment provided by engineer. + Security assessment Beveiligingsbeoordeling @@ -5063,6 +5399,10 @@ Schakel dit in in *Netwerk en servers*-instellingen. Selecteer No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Zelfvernietiging @@ -5113,6 +5453,10 @@ Schakel dit in in *Netwerk en servers*-instellingen. Stuur een verdwijnend bericht No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews Link voorbeelden verzenden @@ -5223,6 +5567,10 @@ Schakel dit in in *Netwerk en servers*-instellingen. Verzonden op: %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event Verzonden bestandsgebeurtenis @@ -5233,11 +5581,31 @@ Schakel dit in in *Netwerk en servers*-instellingen. Verzonden bericht message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. Verzonden berichten worden na ingestelde tijd verwijderd. No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. Serveradres is niet compatibel met netwerkinstellingen. @@ -5258,6 +5626,10 @@ Schakel dit in in *Netwerk en servers*-instellingen. Servertest mislukt! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. Serverversie is incompatibel met netwerkinstellingen. @@ -5268,6 +5640,14 @@ Schakel dit in in *Netwerk en servers*-instellingen. Servers No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code Sessie code @@ -5283,6 +5663,10 @@ Schakel dit in in *Netwerk en servers*-instellingen. Contactnaam instellen… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences Groep voorkeuren instellen @@ -5403,6 +5787,10 @@ Schakel dit in in *Netwerk en servers*-instellingen. Toon: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address SimpleX adres @@ -5478,6 +5866,10 @@ Schakel dit in in *Netwerk en servers*-instellingen. Vereenvoudigde incognitomodus No comment provided by engineer. + + Size + No comment provided by engineer. + Skip Overslaan @@ -5523,6 +5915,14 @@ Schakel dit in in *Netwerk en servers*-instellingen. Start migratie No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop Stop @@ -5588,6 +5988,22 @@ Schakel dit in in *Netwerk en servers*-instellingen. Indienen No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat Ondersteuning van SimpleX Chat @@ -5668,6 +6084,10 @@ Schakel dit in in *Netwerk en servers*-instellingen. Tik om een nieuw gesprek te starten No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. Test mislukt bij stap %@. @@ -5805,9 +6225,8 @@ Het kan gebeuren vanwege een bug of wanneer de verbinding is aangetast. De tekst die u hebt geplakt is geen SimpleX link. No comment provided by engineer. - - Theme - Thema + + Themes No comment provided by engineer. @@ -5875,11 +6294,19 @@ Het kan gebeuren vanwege een bug of wanneer de verbinding is aangetast. Dit is uw eigen eenmalige link! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. Deze instelling is van toepassing op berichten in je huidige chat profiel **%@**. No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: Om vragen te stellen en updates te ontvangen: @@ -5947,11 +6374,19 @@ U wordt gevraagd de authenticatie te voltooien voordat deze functie wordt ingesc Schakel incognito in tijdens het verbinden. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation Transport isolation No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Proberen verbinding te maken met de server die wordt gebruikt om berichten van dit contact te ontvangen (fout: %@). @@ -6144,6 +6579,10 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak Upgrade en open chat No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed Upload mislukt @@ -6154,6 +6593,14 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak Upload bestand server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive Archief uploaden @@ -6229,6 +6676,10 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak Gebruikers profiel No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. Het gebruik van .onion-hosts vereist een compatibele VPN-provider. @@ -6364,6 +6815,14 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak Wachten op video No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures Waarschuwing: het starten van de chat op meerdere apparaten wordt niet ondersteund en zal leiden tot mislukte bezorging van berichten @@ -6469,11 +6928,19 @@ Om verbinding te maken, vraagt u uw contact om een andere verbinding link te mak Verkeerde sleutel of onbekende verbinding - hoogstwaarschijnlijk is deze verbinding verwijderd. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! Verkeerd wachtwoord! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers XFTP servers @@ -6556,6 +7023,10 @@ Deelnameverzoek herhalen? Je bent uitgenodigd voor de groep No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. U kunt oproepen van het vergrendelingsscherm accepteren, zonder apparaat- en app-verificatie. @@ -6962,6 +7433,10 @@ SimpleX servers kunnen uw profiel niet zien. en %lld andere gebeurtenissen No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) audio oproep (niet e2e versleuteld) @@ -6995,7 +7470,7 @@ SimpleX servers kunnen uw profiel niet zien. blocked by admin geblokkeerd door beheerder - marked deleted chat item preview text + blocked chat item bold @@ -7152,6 +7627,10 @@ SimpleX servers kunnen uw profiel niet zien. dagen time unit + + decryption errors + No comment provided by engineer. + default (%@) standaard (%@) @@ -7202,6 +7681,10 @@ SimpleX servers kunnen uw profiel niet zien. dubbel bericht integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted e2e versleuteld @@ -7282,6 +7765,10 @@ SimpleX servers kunnen uw profiel niet zien. gebeurtenis gebeurd No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded doorgestuurd @@ -7489,6 +7976,14 @@ SimpleX servers kunnen uw profiel niet zien. aan group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner Eigenaar @@ -7799,7 +8294,7 @@ last received msg: %2$@
    - +
    @@ -7836,7 +8331,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/nl.xcloc/contents.json b/apps/ios/SimpleX Localizations/nl.xcloc/contents.json index 20246f53d4..4c631c367e 100644 --- a/apps/ios/SimpleX Localizations/nl.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/nl.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "nl", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff b/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff index 3a165f8c43..31a6874e77 100644 --- a/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff +++ b/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff @@ -2,7 +2,7 @@
    - +
    @@ -557,9 +557,8 @@ O adresie SimpleX No comment provided by engineer. - - Accent color - Kolor akcentu + + Accent No comment provided by engineer. @@ -583,6 +582,14 @@ Akceptuj incognito accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Dodaj adres do swojego profilu, aby Twoje kontakty mogły go udostępnić innym osobom. Aktualizacja profilu zostanie wysłana do Twoich kontaktów. @@ -623,6 +630,18 @@ Dodaj wiadomość powitalną No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address Adres @@ -648,6 +667,10 @@ Zaawansowane ustawienia sieci No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. Wszystkie dane aplikacji są usunięte. @@ -663,6 +686,10 @@ Wszystkie dane są usuwane po jego wprowadzeniu. No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. Wszyscy członkowie grupy pozostaną połączeni. @@ -683,6 +710,10 @@ Wszystkie nowe wiadomości z %@ zostaną ukryte! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. Wszystkie Twoje kontakty pozostaną połączone. @@ -883,6 +914,10 @@ Zastosuj No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload Archiwizuj i prześlij @@ -958,6 +993,10 @@ Wstecz No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address Zły adres komputera @@ -983,6 +1022,10 @@ Lepsze wiadomości No comment provided by engineer. + + Black + No comment provided by engineer. + Block Zablokuj @@ -1093,6 +1136,10 @@ Nie można uzyskać dostępu do pęku kluczy, aby zapisać hasło do bazy danych No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file Nie można odebrać pliku @@ -1164,6 +1211,10 @@ Archiwum czatu No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console Konsola czatu @@ -1209,6 +1260,10 @@ Preferencje czatu No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats Czaty @@ -1239,6 +1294,18 @@ Wybierz z biblioteki No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear Wyczyść @@ -1264,9 +1331,8 @@ Wyczyść weryfikację No comment provided by engineer. - - Colors - Kolory + + Color mode No comment provided by engineer. @@ -1279,6 +1345,10 @@ Porównaj kody bezpieczeństwa ze swoimi kontaktami. No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers Skonfiguruj serwery ICE @@ -1388,16 +1458,28 @@ To jest twój jednorazowy link! Połącz z %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop Połączony komputer No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop Połączony do komputera No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… Łączenie z serwerem… @@ -1443,6 +1525,18 @@ To jest twój jednorazowy link! Czas połączenia minął No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows Kontakt pozwala @@ -1496,7 +1590,11 @@ To jest twój jednorazowy link! Copy Kopiuj - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1573,6 +1671,10 @@ To jest twój jednorazowy link! Utwórz swój profil No comment provided by engineer. + + Created + No comment provided by engineer. + Created at Utworzony o @@ -1608,6 +1710,10 @@ To jest twój jednorazowy link! Obecne hasło… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. Obecnie maksymalna obsługiwana wielkość pliku wynosi %@. @@ -1618,11 +1724,19 @@ To jest twój jednorazowy link! Niestandardowy czas No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark Ciemny No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID ID bazy danych @@ -1927,6 +2041,10 @@ To nie może być cofnięte! Usunąć profil użytkownika? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at Usunięto o @@ -1937,6 +2055,10 @@ To nie może być cofnięte! Usunięto o: %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery Dostarczenie @@ -1977,6 +2099,14 @@ To nie może być cofnięte! Błąd docelowego serwera: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop Deweloperskie @@ -2132,6 +2262,10 @@ To nie może być cofnięte! Pobierz chat item action + + Download errors + No comment provided by engineer. + Download failed Pobieranie nie udane @@ -2142,6 +2276,14 @@ To nie może być cofnięte! Pobierz plik server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive Pobieranie archiwum @@ -2512,6 +2654,10 @@ To nie może być cofnięte! Błąd eksportu bazy danych czatu No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Błąd importu bazy danych czatu @@ -2537,11 +2683,23 @@ To nie może być cofnięte! Błąd odbioru pliku No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member Błąd usuwania członka No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers Błąd zapisu %@ serwerów @@ -2660,7 +2818,8 @@ To nie może być cofnięte! Error: %@ Błąd: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2672,6 +2831,10 @@ To nie może być cofnięte! Błąd: brak pliku bazy danych No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. Nawet po wyłączeniu w rozmowie. @@ -2697,6 +2860,10 @@ To nie może być cofnięte! Błąd eksportu: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. Wyeksportowane archiwum bazy danych. @@ -2732,6 +2899,26 @@ To nie może być cofnięte! Ulubione No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. Plik zostanie usunięty z serwerów. @@ -2921,6 +3108,14 @@ Błąd: %2$@ GIF-y i naklejki No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group Grupa @@ -3201,6 +3396,10 @@ Błąd: %2$@ Import nie udał się No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive Importowanie archiwum @@ -3323,6 +3522,10 @@ Błąd: %2$@ Interfejs No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code Nieprawidłowy kod QR @@ -3681,6 +3884,10 @@ To jest twój link do grupy %@! Członek zostanie usunięty z grupy - nie można tego cofnąć! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error Błąd dostarczenia wiadomości @@ -3735,6 +3942,18 @@ To jest twój link do grupy %@! Źródło wiadomości pozostaje prywatne. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text Tekst wiadomości @@ -3760,6 +3979,14 @@ To jest twój link do grupy %@! Wiadomości od %@ zostaną pokazane! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. Wiadomości, pliki i połączenia są chronione przez **szyfrowanie end-to-end** z doskonałym utajnianiem z wyprzedzeniem i odzyskiem po złamaniu. @@ -4010,6 +4237,10 @@ To jest twój link do grupy %@! Brak historii No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection Brak połączenia z siecią @@ -4194,6 +4425,10 @@ To jest twój link do grupy %@! Otwórz migrację na innym urządzeniu authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles Otwórz profile użytkownika @@ -4299,6 +4534,10 @@ To jest twój link do grupy %@! Wklej link, który otrzymałeś No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. Ludzie mogą się z Tobą połączyć tylko poprzez linki, które udostępniasz. @@ -4324,6 +4563,11 @@ To jest twój link do grupy %@! Poproś Twój kontakt o włączenie wysyłania wiadomości głosowych. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Sprawdź, czy użyłeś prawidłowego linku lub poproś Twój kontakt o przesłanie innego. @@ -4421,6 +4665,10 @@ Błąd: %@ Podgląd No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security Prywatność i bezpieczeństwo @@ -4486,6 +4734,10 @@ Błąd: %@ Hasło profilu No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. Aktualizacja profilu zostanie wysłana do Twoich kontaktów. @@ -4568,6 +4820,14 @@ Włącz w ustawianiach *Sieć i serwery* . Limit czasu protokołu na KB No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications Powiadomienia push @@ -4633,6 +4893,10 @@ Włącz w ustawianiach *Sieć i serwery* . Potwierdzenia są wyłączone No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at Otrzymane o @@ -4653,6 +4917,18 @@ Włącz w ustawianiach *Sieć i serwery* . Otrzymano wiadomość message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. Adres odbiorczy zostanie zmieniony na inny serwer. Zmiana adresu zostanie zakończona gdy nadawca będzie online. @@ -4683,11 +4959,31 @@ Włącz w ustawianiach *Sieć i serwery* . Odbiorcy widzą aktualizacje podczas ich wpisywania. No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Połącz ponownie wszystkie połączone serwery, aby wymusić dostarczanie wiadomości. Wykorzystuje dodatkowy ruch. No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? Ponownie połączyć serwery? @@ -4738,6 +5034,10 @@ Włącz w ustawianiach *Sieć i serwery* . Usuń No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member Usuń członka @@ -4808,16 +5108,32 @@ Włącz w ustawianiach *Sieć i serwery* . Resetuj No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors Resetuj kolory No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults Przywróć wartości domyślne No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Uruchom ponownie aplikację, aby utworzyć nowy profil czatu @@ -4888,6 +5204,10 @@ Włącz w ustawianiach *Sieć i serwery* . Uruchom czat No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers Serwery SMP @@ -5003,6 +5323,14 @@ Włącz w ustawianiach *Sieć i serwery* . Zachowano wiadomość message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code Zeskanuj kod QR @@ -5043,11 +5371,19 @@ Włącz w ustawianiach *Sieć i serwery* . Wyszukaj lub wklej link SimpleX No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue Bezpieczna kolejka server test step + + Secured + No comment provided by engineer. + Security assessment Ocena bezpieczeństwa @@ -5063,6 +5399,10 @@ Włącz w ustawianiach *Sieć i serwery* . Wybierz No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Samozniszczenie @@ -5113,6 +5453,10 @@ Włącz w ustawianiach *Sieć i serwery* . Wyślij znikającą wiadomość No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews Wyślij podgląd linku @@ -5223,6 +5567,10 @@ Włącz w ustawianiach *Sieć i serwery* . Wysłano o: %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event Wyślij zdarzenie pliku @@ -5233,11 +5581,31 @@ Włącz w ustawianiach *Sieć i serwery* . Wyślij wiadomość message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. Wysłane wiadomości zostaną usunięte po ustawionym czasie. No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. Adres serwera jest niekompatybilny z ustawieniami sieciowymi. @@ -5258,6 +5626,10 @@ Włącz w ustawianiach *Sieć i serwery* . Test serwera nie powiódł się! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. Wersja serwera jest niekompatybilna z ustawieniami sieciowymi. @@ -5268,6 +5640,14 @@ Włącz w ustawianiach *Sieć i serwery* . Serwery No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code Kod sesji @@ -5283,6 +5663,10 @@ Włącz w ustawianiach *Sieć i serwery* . Ustaw nazwę kontaktu… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences Ustaw preferencje grupy @@ -5403,6 +5787,10 @@ Włącz w ustawianiach *Sieć i serwery* . Pokaż: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address Adres SimpleX @@ -5478,6 +5866,10 @@ Włącz w ustawianiach *Sieć i serwery* . Uproszczony tryb incognito No comment provided by engineer. + + Size + No comment provided by engineer. + Skip Pomiń @@ -5523,6 +5915,14 @@ Włącz w ustawianiach *Sieć i serwery* . Rozpocznij migrację No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop Zatrzymaj @@ -5588,6 +5988,22 @@ Włącz w ustawianiach *Sieć i serwery* . Zatwierdź No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat Wspieraj SimpleX Chat @@ -5668,6 +6084,10 @@ Włącz w ustawianiach *Sieć i serwery* . Dotknij, aby rozpocząć nowy czat No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. Test nie powiódł się na etapie %@. @@ -5805,9 +6225,8 @@ Może się to zdarzyć z powodu jakiegoś błędu lub gdy połączenie jest skom Tekst, który wkleiłeś nie jest linkiem SimpleX. No comment provided by engineer. - - Theme - Motyw + + Themes No comment provided by engineer. @@ -5875,11 +6294,19 @@ Może się to zdarzyć z powodu jakiegoś błędu lub gdy połączenie jest skom To jest twój jednorazowy link! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. To ustawienie dotyczy wiadomości Twojego bieżącego profilu czatu **%@**. No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: Aby zadać wszelkie pytania i otrzymywać aktualizacje: @@ -5947,11 +6374,19 @@ Przed włączeniem tej funkcji zostanie wyświetlony monit uwierzytelniania.Przełącz incognito przy połączeniu. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation Izolacja transportu No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Próbowanie połączenia z serwerem używanym do odbierania wiadomości od tego kontaktu (błąd: %@). @@ -6144,6 +6579,10 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc Zaktualizuj i otwórz czat No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed Wgrywanie nie udane @@ -6154,6 +6593,14 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc Prześlij plik server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive Wgrywanie archiwum @@ -6229,6 +6676,10 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc Profil użytkownika No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. Używanie hostów .onion wymaga kompatybilnego dostawcy VPN. @@ -6364,6 +6815,14 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc Oczekiwanie na film No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures Ostrzeżenie: rozpoczęcie czatu na wielu urządzeniach nie jest wspierane i spowoduje niepowodzenia dostarczania wiadomości @@ -6469,11 +6928,19 @@ Aby się połączyć, poproś Twój kontakt o utworzenie kolejnego linku połąc Zły klucz lub nieznane połączenie - najprawdopodobniej to połączenie jest usunięte. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! Nieprawidłowe hasło! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers Serwery XFTP @@ -6556,6 +7023,10 @@ Powtórzyć prośbę dołączenia? Jesteś zaproszony do grupy No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. Możesz przyjmować połączenia z ekranu blokady, bez uwierzytelniania urządzenia i aplikacji. @@ -6962,6 +7433,10 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu. i %lld innych wydarzeń No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) połączenie audio (nie szyfrowane e2e) @@ -6995,7 +7470,7 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu. blocked by admin zablokowany przez admina - marked deleted chat item preview text + blocked chat item bold @@ -7152,6 +7627,10 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu. dni time unit + + decryption errors + No comment provided by engineer. + default (%@) domyślne (%@) @@ -7202,6 +7681,10 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu. zduplikowana wiadomość integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted zaszyfrowany e2e @@ -7282,6 +7765,10 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu. nowe wydarzenie No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded przekazane dalej @@ -7489,6 +7976,14 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu. włączone group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner właściciel @@ -7799,7 +8294,7 @@ last received msg: %2$@
    - +
    @@ -7836,7 +8331,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/pl.xcloc/contents.json b/apps/ios/SimpleX Localizations/pl.xcloc/contents.json index 22043b831d..0074d85662 100644 --- a/apps/ios/SimpleX Localizations/pl.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/pl.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "pl", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff index 55c22354a9..0ae6e7ae24 100644 --- a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff +++ b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff @@ -2,7 +2,7 @@
    - +
    @@ -557,9 +557,8 @@ Об адресе SimpleX No comment provided by engineer. - - Accent color - Основной цвет + + Accent No comment provided by engineer. @@ -583,6 +582,14 @@ Принять инкогнито accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Добавьте адрес в свой профиль, чтобы Ваши контакты могли поделиться им. Профиль будет отправлен Вашим контактам. @@ -623,6 +630,18 @@ Добавить приветственное сообщение No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address Адрес @@ -648,6 +667,10 @@ Настройки сети No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. Все данные приложения будут удалены. @@ -663,6 +686,10 @@ Все данные удаляются при его вводе. No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. Все члены группы, которые соединились через эту ссылку, останутся в группе. @@ -683,6 +710,10 @@ Все новые сообщения от %@ будут скрыты! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. Все контакты, которые соединились через этот адрес, сохранятся. @@ -883,6 +914,10 @@ Применить No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload Архивировать и загрузить @@ -958,6 +993,10 @@ Назад No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address Неверный адрес компьютера @@ -983,6 +1022,10 @@ Улучшенные сообщения No comment provided by engineer. + + Black + No comment provided by engineer. + Block Заблокировать @@ -1093,6 +1136,10 @@ Ошибка доступа к Keychain при сохранении пароля No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file Невозможно получить файл @@ -1164,6 +1211,10 @@ Архив чата No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console Консоль @@ -1209,6 +1260,10 @@ Предпочтения No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats Чаты @@ -1239,6 +1294,18 @@ Выбрать из библиотеки No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear Очистить @@ -1264,9 +1331,8 @@ Сбросить подтверждение No comment provided by engineer. - - Colors - Цвета + + Color mode No comment provided by engineer. @@ -1279,6 +1345,10 @@ Сравните код безопасности с Вашими контактами. No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers Настройка ICE серверов @@ -1388,16 +1458,28 @@ This is your own one-time link! Соединиться с %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop Подключенный компьютер No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop Компьютер подключен No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… Устанавливается соединение с сервером… @@ -1443,6 +1525,18 @@ This is your own one-time link! Превышено время соединения No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows Контакт разрешает @@ -1496,7 +1590,11 @@ This is your own one-time link! Copy Скопировать - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1573,6 +1671,10 @@ This is your own one-time link! Создать профиль No comment provided by engineer. + + Created + No comment provided by engineer. + Created at Создано @@ -1608,6 +1710,10 @@ This is your own one-time link! Текущий пароль… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. Максимальный размер файла - %@. @@ -1618,11 +1724,19 @@ This is your own one-time link! Пользовательское время No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark Тёмная No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID ID базы данных @@ -1927,6 +2041,10 @@ This cannot be undone! Удалить профиль пользователя? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at Удалено @@ -1937,6 +2055,10 @@ This cannot be undone! Удалено: %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery Доставка @@ -1977,6 +2099,14 @@ This cannot be undone! Ошибка сервера получателя: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop Для разработчиков @@ -2132,6 +2262,10 @@ This cannot be undone! Загрузить chat item action + + Download errors + No comment provided by engineer. + Download failed Ошибка загрузки @@ -2142,6 +2276,14 @@ This cannot be undone! Загрузка файла server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive Загрузка архива @@ -2512,6 +2654,10 @@ This cannot be undone! Ошибка при экспорте архива чата No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Ошибка при импорте архива чата @@ -2537,11 +2683,23 @@ This cannot be undone! Ошибка при получении файла No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member Ошибка при удалении члена группы No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers Ошибка при сохранении %@ серверов @@ -2660,7 +2818,8 @@ This cannot be undone! Error: %@ Ошибка: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2672,6 +2831,10 @@ This cannot be undone! Ошибка: данные чата не найдены No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. Даже когда они выключены в разговоре. @@ -2697,6 +2860,10 @@ This cannot be undone! Ошибка при экспорте: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. Архив чата экспортирован. @@ -2732,6 +2899,26 @@ This cannot be undone! Избранный No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. Файл будет удалён с серверов. @@ -2921,6 +3108,14 @@ Error: %2$@ ГИФ файлы и стикеры No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group Группа @@ -3201,6 +3396,10 @@ Error: %2$@ Ошибка импорта No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive Импорт архива @@ -3323,6 +3522,10 @@ Error: %2$@ Интерфейс No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code Неверный QR код @@ -3681,6 +3884,10 @@ This is your link for group %@! Член группы будет удален - это действие нельзя отменить! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error Ошибка доставки сообщения @@ -3735,6 +3942,18 @@ This is your link for group %@! Источник сообщения остаётся конфиденциальным. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text Текст сообщения @@ -3760,6 +3979,14 @@ This is your link for group %@! Сообщения от %@ будут показаны! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. Сообщения, файлы и звонки защищены **end-to-end шифрованием** с прямой секретностью (PFS), правдоподобным отрицанием и восстановлением от взлома. @@ -4010,6 +4237,10 @@ This is your link for group %@! Нет истории No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection Нет интернет-соединения @@ -4194,6 +4425,10 @@ This is your link for group %@! Открытие миграции на другое устройство authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles Открыть профили пользователя @@ -4299,6 +4534,10 @@ This is your link for group %@! Вставьте полученную ссылку No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. С Вами можно соединиться только через созданные Вами ссылки. @@ -4324,6 +4563,11 @@ This is your link for group %@! Попросите у Вашего контакта разрешить отправку голосовых сообщений. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Пожалуйста, проверьте, что Вы использовали правильную ссылку или попросите, чтобы Ваш контакт отправил Вам другую ссылку. @@ -4421,6 +4665,10 @@ Error: %@ Просмотр No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security Конфиденциальность @@ -4486,6 +4734,10 @@ Error: %@ Пароль профиля No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. Обновлённый профиль будет отправлен Вашим контактам. @@ -4568,6 +4820,14 @@ Enable in *Network & servers* settings. Таймаут протокола на KB No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications Доставка уведомлений @@ -4633,6 +4893,10 @@ Enable in *Network & servers* settings. Отчёты о доставке выключены No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at Получено @@ -4653,6 +4917,18 @@ Enable in *Network & servers* settings. Полученное сообщение message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. Адрес получения сообщений будет перемещён на другой сервер. Изменение адреса завершится после того как отправитель будет онлайн. @@ -4683,11 +4959,31 @@ Enable in *Network & servers* settings. Получатели видят их в то время как Вы их набираете. No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Повторно подключите все серверы, чтобы принудительно доставить сообщения. Используется дополнительный трафик. No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? Переподключить серверы? @@ -4738,6 +5034,10 @@ Enable in *Network & servers* settings. Удалить No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member Удалить члена группы @@ -4808,16 +5108,32 @@ Enable in *Network & servers* settings. Сбросить No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors Сбросить цвета No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults Сбросить настройки No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Перезапустите приложение, чтобы создать новый профиль. @@ -4888,6 +5204,10 @@ Enable in *Network & servers* settings. Запустить chat No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers SMP серверы @@ -5003,6 +5323,14 @@ Enable in *Network & servers* settings. Сохраненное сообщение message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code Сканировать QR код @@ -5043,11 +5371,19 @@ Enable in *Network & servers* settings. Искать или вставьте ссылку SimpleX No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue Защита очереди server test step + + Secured + No comment provided by engineer. + Security assessment Аудит безопасности @@ -5063,6 +5399,10 @@ Enable in *Network & servers* settings. Выбрать No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Самоуничтожение @@ -5113,6 +5453,10 @@ Enable in *Network & servers* settings. Отправить исчезающее сообщение No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews Отправлять картинки ссылок @@ -5223,6 +5567,10 @@ Enable in *Network & servers* settings. Отправлено: %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event Отправка файла @@ -5233,11 +5581,31 @@ Enable in *Network & servers* settings. Отправленное сообщение message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. Отправленные сообщения будут удалены через заданное время. No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. Адрес сервера несовместим с настройками сети. @@ -5258,6 +5626,10 @@ Enable in *Network & servers* settings. Ошибка теста сервера! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. Версия сервера несовместима с настройками сети. @@ -5268,6 +5640,14 @@ Enable in *Network & servers* settings. Серверы No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code Код сессии @@ -5283,6 +5663,10 @@ Enable in *Network & servers* settings. Имя контакта… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences Предпочтения группы @@ -5403,6 +5787,10 @@ Enable in *Network & servers* settings. Показать: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address Адрес SimpleX @@ -5478,6 +5866,10 @@ Enable in *Network & servers* settings. Упрощенный режим Инкогнито No comment provided by engineer. + + Size + No comment provided by engineer. + Skip Пропустить @@ -5523,6 +5915,14 @@ Enable in *Network & servers* settings. Запустить перемещение данных No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop Остановить @@ -5588,6 +5988,22 @@ Enable in *Network & servers* settings. Продолжить No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat Поддержать SimpleX Chat @@ -5668,6 +6084,10 @@ Enable in *Network & servers* settings. Нажмите, чтобы начать чат No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. Ошибка теста на шаге %@. @@ -5805,9 +6225,8 @@ It can happen because of some bug or when the connection is compromised.Вставленный текст не является SimpleX-ссылкой. No comment provided by engineer. - - Theme - Тема + + Themes No comment provided by engineer. @@ -5875,11 +6294,19 @@ It can happen because of some bug or when the connection is compromised.Это ваша собственная одноразовая ссылка! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. Эта настройка применяется к сообщениям в Вашем текущем профиле чата **%@**. No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: Чтобы задать вопросы и получать уведомления о новых версиях, @@ -5947,11 +6374,19 @@ You will be prompted to complete authentication before this feature is enabled.< Установите режим Инкогнито при соединении. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation Отдельные сессии для No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Устанавливается соединение с сервером, через который Вы получаете сообщения от этого контакта (ошибка: %@). @@ -6144,6 +6579,10 @@ To connect, please ask your contact to create another connection link and check Обновить и открыть чат No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed Ошибка загрузки @@ -6154,6 +6593,14 @@ To connect, please ask your contact to create another connection link and check Загрузка файла server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive Загрузка архива @@ -6229,6 +6676,10 @@ To connect, please ask your contact to create another connection link and check Профиль чата No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. Для использования .onion хостов требуется совместимый VPN провайдер. @@ -6364,6 +6815,14 @@ To connect, please ask your contact to create another connection link and check Ожидание видео No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures Внимание: запуск чата на нескольких устройствах не поддерживается и приведет к сбоям доставки сообщений @@ -6469,11 +6928,19 @@ To connect, please ask your contact to create another connection link and check Неверный ключ или неизвестное соединение - скорее всего, это соединение удалено. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! Неправильный пароль! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers XFTP серверы @@ -6556,6 +7023,10 @@ Repeat join request? Вы приглашены в группу No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. Вы можете принимать звонки на экране блокировки, без аутентификации. @@ -6962,6 +7433,10 @@ SimpleX серверы не могут получить доступ к Ваше и %lld других событий No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) аудиозвонок (не e2e зашифрованный) @@ -6995,7 +7470,7 @@ SimpleX серверы не могут получить доступ к Ваше blocked by admin заблокировано администратором - marked deleted chat item preview text + blocked chat item bold @@ -7152,6 +7627,10 @@ SimpleX серверы не могут получить доступ к Ваше дней time unit + + decryption errors + No comment provided by engineer. + default (%@) по умолчанию (%@) @@ -7202,6 +7681,10 @@ SimpleX серверы не могут получить доступ к Ваше повторное сообщение integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted e2e зашифровано @@ -7282,6 +7765,10 @@ SimpleX серверы не могут получить доступ к Ваше событие произошло No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded переслано @@ -7489,6 +7976,14 @@ SimpleX серверы не могут получить доступ к Ваше да group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner владелец @@ -7799,7 +8294,7 @@ last received msg: %2$@
    - +
    @@ -7836,7 +8331,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/ru.xcloc/contents.json b/apps/ios/SimpleX Localizations/ru.xcloc/contents.json index 2d5d76dd8f..a28b0ed489 100644 --- a/apps/ios/SimpleX Localizations/ru.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/ru.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "ru", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff b/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff index 4f4f41aa38..bf2d6b8bed 100644 --- a/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff +++ b/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff @@ -2,7 +2,7 @@
    - +
    @@ -527,9 +527,8 @@ เกี่ยวกับที่อยู่ SimpleX No comment provided by engineer. - - Accent color - สีเน้น + + Accent No comment provided by engineer. @@ -552,6 +551,14 @@ ยอมรับโหมดไม่ระบุตัวตน accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. เพิ่มที่อยู่ลงในโปรไฟล์ของคุณ เพื่อให้ผู้ติดต่อของคุณสามารถแชร์กับผู้อื่นได้ การอัปเดตโปรไฟล์จะถูกส่งไปยังผู้ติดต่อของคุณ @@ -591,6 +598,18 @@ เพิ่มข้อความต้อนรับ No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address ที่อยู่ @@ -615,6 +634,10 @@ การตั้งค่าระบบเครือข่ายขั้นสูง No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. ข้อมูลแอปทั้งหมดถูกลบแล้ว. @@ -630,6 +653,10 @@ ข้อมูลทั้งหมดจะถูกลบเมื่อถูกป้อน No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. สมาชิกในกลุ่มทุกคนจะยังคงเชื่อมต่ออยู่. @@ -648,6 +675,10 @@ All new messages from %@ will be hidden! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. ผู้ติดต่อทั้งหมดของคุณจะยังคงเชื่อมต่ออยู่. @@ -839,6 +870,10 @@ Apply No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload No comment provided by engineer. @@ -912,6 +947,10 @@ กลับ No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address No comment provided by engineer. @@ -935,6 +974,10 @@ ข้อความที่ดีขึ้น No comment provided by engineer. + + Black + No comment provided by engineer. + Block No comment provided by engineer. @@ -1035,6 +1078,10 @@ ไม่สามารถเข้าถึง keychain เพื่อบันทึกรหัสผ่านฐานข้อมูล No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file ไม่สามารถรับไฟล์ได้ @@ -1104,6 +1151,10 @@ ที่เก็บแชทถาวร No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console คอนโซลแชท @@ -1147,6 +1198,10 @@ ค่ากําหนดในการแชท No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats แชท @@ -1176,6 +1231,18 @@ เลือกจากอัลบั้ม No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear ลบ @@ -1200,9 +1267,8 @@ ล้างการยืนยัน No comment provided by engineer. - - Colors - สี + + Color mode No comment provided by engineer. @@ -1215,6 +1281,10 @@ เปรียบเทียบรหัสความปลอดภัยกับผู้ติดต่อของคุณ No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers กำหนดค่าเซิร์ฟเวอร์ ICE @@ -1309,14 +1379,26 @@ This is your own one-time link! Connect with %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… กำลังเชื่อมต่อกับเซิร์ฟเวอร์… @@ -1360,6 +1442,18 @@ This is your own one-time link! หมดเวลาการเชื่อมต่อ No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows ผู้ติดต่ออนุญาต @@ -1413,7 +1507,11 @@ This is your own one-time link! Copy คัดลอก - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1485,6 +1583,10 @@ This is your own one-time link! สร้างโปรไฟล์ของคุณ No comment provided by engineer. + + Created + No comment provided by engineer. + Created at No comment provided by engineer. @@ -1516,6 +1618,10 @@ This is your own one-time link! รหัสผ่านปัจจุบัน… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. ขนาดไฟล์ที่รองรับสูงสุดในปัจจุบันคือ %@ @@ -1526,11 +1632,19 @@ This is your own one-time link! เวลาที่กําหนดเอง No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark มืด No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID ID ฐานข้อมูล @@ -1830,6 +1944,10 @@ This cannot be undone! ลบโปรไฟล์ผู้ใช้? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at ลบที่ @@ -1840,6 +1958,10 @@ This cannot be undone! ลบที่: %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery No comment provided by engineer. @@ -1875,6 +1997,14 @@ This cannot be undone! Destination server error: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop พัฒนา @@ -2023,6 +2153,10 @@ This cannot be undone! Download chat item action + + Download errors + No comment provided by engineer. + Download failed No comment provided by engineer. @@ -2032,6 +2166,14 @@ This cannot be undone! ดาวน์โหลดไฟล์ server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive No comment provided by engineer. @@ -2384,6 +2526,10 @@ This cannot be undone! เกิดข้อผิดพลาดในการส่งออกฐานข้อมูลแชท No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database เกิดข้อผิดพลาดในการนำเข้าฐานข้อมูลแชท @@ -2408,11 +2554,23 @@ This cannot be undone! เกิดข้อผิดพลาดในการรับไฟล์ No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member เกิดข้อผิดพลาดในการลบสมาชิก No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers เกิดข้อผิดพลาดในการบันทึกเซิร์ฟเวอร์ %@ @@ -2526,7 +2684,8 @@ This cannot be undone! Error: %@ ข้อผิดพลาด: % @ - snd error text + file error text + snd error text Error: URL is invalid @@ -2538,6 +2697,10 @@ This cannot be undone! เกิดข้อผิดพลาด: ไม่มีแฟ้มฐานข้อมูล No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. แม้ในขณะที่ปิดใช้งานในการสนทนา @@ -2562,6 +2725,10 @@ This cannot be undone! ข้อผิดพลาดในการส่งออก: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. ที่เก็บถาวรฐานข้อมูลที่ส่งออก @@ -2595,6 +2762,26 @@ This cannot be undone! ที่ชอบ No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. ไฟล์จะถูกลบออกจากเซิร์ฟเวอร์ @@ -2770,6 +2957,14 @@ Error: %2$@ GIFs และสติกเกอร์ No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group กลุ่ม @@ -3044,6 +3239,10 @@ Error: %2$@ Import failed No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive No comment provided by engineer. @@ -3159,6 +3358,10 @@ Error: %2$@ อินเตอร์เฟซ No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code No comment provided by engineer. @@ -3499,6 +3702,10 @@ This is your link for group %@! สมาชิกจะถูกลบออกจากกลุ่ม - ไม่สามารถยกเลิกได้! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error ข้อผิดพลาดในการส่งข้อความ @@ -3549,6 +3756,18 @@ This is your link for group %@! Message source remains private. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text ข้อความ @@ -3572,6 +3791,14 @@ This is your link for group %@! Messages from %@ will be shown! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. No comment provided by engineer. @@ -3805,6 +4032,10 @@ This is your link for group %@! ไม่มีประวัติ No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection No comment provided by engineer. @@ -3983,6 +4214,10 @@ This is your link for group %@! Open migration to another device authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles เปิดโปรไฟล์ผู้ใช้ @@ -4078,6 +4313,10 @@ This is your link for group %@! Paste the link you received No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. ผู้คนสามารถเชื่อมต่อกับคุณผ่านลิงก์ที่คุณแบ่งปันเท่านั้น @@ -4102,6 +4341,11 @@ This is your link for group %@! โปรดขอให้ผู้ติดต่อของคุณเปิดใช้งานการส่งข้อความเสียง No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. โปรดตรวจสอบว่าคุณใช้ลิงก์ที่ถูกต้องหรือขอให้ผู้ติดต่อของคุณส่งลิงก์ใหม่ให้คุณ @@ -4196,6 +4440,10 @@ Error: %@ ดูตัวอย่าง No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security ความเป็นส่วนตัวและความปลอดภัย @@ -4254,6 +4502,10 @@ Error: %@ รหัสผ่านโปรไฟล์ No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. การอัปเดตโปรไฟล์จะถูกส่งไปยังผู้ติดต่อของคุณ @@ -4332,6 +4584,14 @@ Enable in *Network & servers* settings. การหมดเวลาของโปรโตคอลต่อ KB No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications การแจ้งเตือนแบบทันที @@ -4393,6 +4653,10 @@ Enable in *Network & servers* settings. Receipts are disabled No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at ได้รับเมื่อ @@ -4413,6 +4677,18 @@ Enable in *Network & servers* settings. ได้รับข้อความ message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. ที่อยู่ผู้รับจะถูกเปลี่ยนเป็นเซิร์ฟเวอร์อื่น การเปลี่ยนแปลงที่อยู่จะเสร็จสมบูรณ์หลังจากที่ผู้ส่งออนไลน์ @@ -4441,11 +4717,31 @@ Enable in *Network & servers* settings. ผู้รับจะเห็นการอัปเดตเมื่อคุณพิมพ์ No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. เชื่อมต่อเซิร์ฟเวอร์ที่เชื่อมต่อทั้งหมดอีกครั้งเพื่อบังคับให้ส่งข้อความ มันใช้การจราจรเพิ่มเติม No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? เชื่อมต่อเซิร์ฟเวอร์อีกครั้งหรือไม่? @@ -4495,6 +4791,10 @@ Enable in *Network & servers* settings. ลบ No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member ลบสมาชิกออก @@ -4560,16 +4860,32 @@ Enable in *Network & servers* settings. รีเซ็ต No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors รีเซ็ตสี No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults รีเซ็ตเป็นค่าเริ่มต้น No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile รีสตาร์ทแอปเพื่อสร้างโปรไฟล์แชทใหม่ @@ -4639,6 +4955,10 @@ Enable in *Network & servers* settings. เรียกใช้แชท No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers เซิร์ฟเวอร์ SMP @@ -4749,6 +5069,14 @@ Enable in *Network & servers* settings. Saved message message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code สแกนคิวอาร์โค้ด @@ -4786,11 +5114,19 @@ Enable in *Network & servers* settings. Search or paste SimpleX link No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue คิวที่ปลอดภัย server test step + + Secured + No comment provided by engineer. + Security assessment การประเมินความปลอดภัย @@ -4806,6 +5142,10 @@ Enable in *Network & servers* settings. เลือก No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct ทําลายตัวเอง @@ -4855,6 +5195,10 @@ Enable in *Network & servers* settings. ส่งข้อความแบบที่หายไป No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews ส่งตัวอย่างลิงก์ @@ -4960,6 +5304,10 @@ Enable in *Network & servers* settings. ส่งเมื่อ: %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event เหตุการณ์ไฟล์ที่ส่ง @@ -4970,11 +5318,31 @@ Enable in *Network & servers* settings. ข้อความที่ส่งแล้ว message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. ข้อความที่ส่งจะถูกลบหลังเกินเวลาที่กําหนด No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. srv error text. @@ -4994,6 +5362,10 @@ Enable in *Network & servers* settings. การทดสอบเซิร์ฟเวอร์ล้มเหลว! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. srv error text @@ -5003,6 +5375,14 @@ Enable in *Network & servers* settings. เซิร์ฟเวอร์ No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code No comment provided by engineer. @@ -5017,6 +5397,10 @@ Enable in *Network & servers* settings. ตั้งชื่อผู้ติดต่อ… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences ตั้งค่าการกําหนดลักษณะกลุ่ม @@ -5130,6 +5514,10 @@ Enable in *Network & servers* settings. แสดง: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address ที่อยู่ SimpleX @@ -5202,6 +5590,10 @@ Enable in *Network & servers* settings. Simplified incognito mode No comment provided by engineer. + + Size + No comment provided by engineer. + Skip ข้าม @@ -5244,6 +5636,14 @@ Enable in *Network & servers* settings. เริ่มการย้ายข้อมูล No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop หยุด @@ -5307,6 +5707,22 @@ Enable in *Network & servers* settings. ส่ง No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat สนับสนุน SimpleX แชท @@ -5384,6 +5800,10 @@ Enable in *Network & servers* settings. แตะเพื่อเริ่มแชทใหม่ No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. การทดสอบล้มเหลวในขั้นตอน %@ @@ -5519,9 +5939,8 @@ It can happen because of some bug or when the connection is compromised.The text you pasted is not a SimpleX link. No comment provided by engineer. - - Theme - ธีม + + Themes No comment provided by engineer. @@ -5581,11 +6000,19 @@ It can happen because of some bug or when the connection is compromised.This is your own one-time link! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. การตั้งค่านี้ใช้กับข้อความในโปรไฟล์แชทปัจจุบันของคุณ **%@** No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: หากต้องการถามคำถามและรับการอัปเดต: @@ -5650,11 +6077,19 @@ You will be prompted to complete authentication before this feature is enabled.< Toggle incognito when connecting. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation การแยกการขนส่ง No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). กำลังพยายามเชื่อมต่อกับเซิร์ฟเวอร์ที่ใช้รับข้อความจากผู้ติดต่อนี้ (ข้อผิดพลาด: %@) @@ -5837,6 +6272,10 @@ To connect, please ask your contact to create another connection link and check อัปเกรดและเปิดการแชท No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed No comment provided by engineer. @@ -5846,6 +6285,14 @@ To connect, please ask your contact to create another connection link and check อัปโหลดไฟล์ server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive No comment provided by engineer. @@ -5913,6 +6360,10 @@ To connect, please ask your contact to create another connection link and check โปรไฟล์ผู้ใช้ No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. การใช้โฮสต์ .onion ต้องการผู้ให้บริการ VPN ที่เข้ากันได้ @@ -6039,6 +6490,14 @@ To connect, please ask your contact to create another connection link and check กําลังรอวิดีโอ No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures No comment provided by engineer. @@ -6133,11 +6592,19 @@ To connect, please ask your contact to create another connection link and check Wrong key or unknown connection - most likely this connection is deleted. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! รหัสผ่านผิด! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers เซิร์ฟเวอร์ XFTP @@ -6211,6 +6678,10 @@ Repeat join request? คุณได้รับเชิญให้เข้าร่วมกลุ่ม No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. คุณสามารถรับสายจากหน้าจอล็อกโดยไม่ต้องมีการตรวจสอบสิทธิ์อุปกรณ์และแอป @@ -6603,6 +7074,10 @@ SimpleX servers cannot see your profile. and %lld other events No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) การโทรด้วยเสียง (ไม่ได้ encrypt จากต้นจนจบ) @@ -6632,7 +7107,7 @@ SimpleX servers cannot see your profile. blocked by admin - marked deleted chat item preview text + blocked chat item bold @@ -6787,6 +7262,10 @@ SimpleX servers cannot see your profile. วัน time unit + + decryption errors + No comment provided by engineer. + default (%@) ค่าเริ่มต้น (%@) @@ -6835,6 +7314,10 @@ SimpleX servers cannot see your profile. ข้อความที่ซ้ำกัน integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted encrypted จากต้นจนจบ @@ -6914,6 +7397,10 @@ SimpleX servers cannot see your profile. event happened No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded No comment provided by engineer. @@ -7119,6 +7606,14 @@ SimpleX servers cannot see your profile. เปิด group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner เจ้าของ @@ -7409,7 +7904,7 @@ last received msg: %2$@
    - +
    @@ -7445,7 +7940,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/th.xcloc/contents.json b/apps/ios/SimpleX Localizations/th.xcloc/contents.json index b60f9edb3e..4562ab8385 100644 --- a/apps/ios/SimpleX Localizations/th.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/th.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "th", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff b/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff index 4a6418c596..482c3a038f 100644 --- a/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff +++ b/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff @@ -2,7 +2,7 @@
    - +
    @@ -557,9 +557,8 @@ SimpleX Chat adresi hakkında No comment provided by engineer. - - Accent color - Vurgu rengi + + Accent No comment provided by engineer. @@ -583,6 +582,14 @@ Takma adla kabul et accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Kişilerinizin başkalarıyla paylaşabilmesi için profilinize adres ekleyin. Profil güncellemesi kişilerinize gönderilecek. @@ -623,6 +630,18 @@ Karşılama mesajı ekleyin No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address Adres @@ -648,6 +667,10 @@ Gelişmiş ağ ayarları No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. Tüm uygulama verileri silinir. @@ -663,6 +686,10 @@ Kullanıldığında bütün veriler silinir. No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. Tüm grup üyeleri bağlı kalacaktır. @@ -683,6 +710,10 @@ %@ 'den gelen bütün yeni mesajlar saklı olacak! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. Konuştuğun kişilerin tümü bağlı kalacaktır. @@ -883,6 +914,10 @@ Uygula No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload Arşivle ve yükle @@ -958,6 +993,10 @@ Geri No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address Kötü bilgisayar adresi @@ -983,6 +1022,10 @@ Daha iyi mesajlar No comment provided by engineer. + + Black + No comment provided by engineer. + Block Engelle @@ -1093,6 +1136,10 @@ Veritabanı şifresini kaydetmek için Anahtar Zinciri'ne erişilemiyor No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file Dosya alınamıyor @@ -1164,6 +1211,10 @@ Sohbet arşivi No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console Sohbet konsolu @@ -1209,6 +1260,10 @@ Sohbet tercihleri No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats Sohbetler @@ -1239,6 +1294,18 @@ Kütüphaneden seç No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear Temizle @@ -1264,9 +1331,8 @@ Doğrulamayı temizle No comment provided by engineer. - - Colors - Renkler + + Color mode No comment provided by engineer. @@ -1279,6 +1345,10 @@ Güvenlik kodlarını kişilerinle karşılaştır. No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers ICE sunucularını ayarla @@ -1388,16 +1458,28 @@ Bu senin kendi tek kullanımlık bağlantın! %@ ile bağlan No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop Bilgisayara bağlandı No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop Bilgisayara bağlanıldı No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… Sunucuya bağlanıyor… @@ -1443,6 +1525,18 @@ Bu senin kendi tek kullanımlık bağlantın! Bağlantı süresi geçmiş No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows Kişi izin veriyor @@ -1496,7 +1590,11 @@ Bu senin kendi tek kullanımlık bağlantın! Copy Kopyala - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1573,6 +1671,10 @@ Bu senin kendi tek kullanımlık bağlantın! Profilini oluştur No comment provided by engineer. + + Created + No comment provided by engineer. + Created at Şurada oluşturuldu @@ -1608,6 +1710,10 @@ Bu senin kendi tek kullanımlık bağlantın! Şu anki parola… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. Şu anki maksimum desteklenen dosya boyutu %@ kadardır. @@ -1618,11 +1724,19 @@ Bu senin kendi tek kullanımlık bağlantın! Özel saat No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark Karanlık No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID Veritabanı kimliği @@ -1927,6 +2041,10 @@ Bu geri alınamaz! Kullanıcı profili silinsin mi? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at de silindi @@ -1937,6 +2055,10 @@ Bu geri alınamaz! %@ de silindi copied message info + + Deletion errors + No comment provided by engineer. + Delivery Teslimat @@ -1977,6 +2099,14 @@ Bu geri alınamaz! Hedef sunucu hatası: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop Geliştir @@ -2132,6 +2262,10 @@ Bu geri alınamaz! İndir chat item action + + Download errors + No comment provided by engineer. + Download failed Yükleme başarısız oldu @@ -2142,6 +2276,14 @@ Bu geri alınamaz! Dosya indir server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive Arşiv indiriliyor @@ -2512,6 +2654,10 @@ Bu geri alınamaz! Sohbet veritabanı dışa aktarılırken hata oluştu No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Sohbet veritabanı içe aktarılırken hata oluştu @@ -2537,11 +2683,23 @@ Bu geri alınamaz! Dosya alınırken sorun oluştu No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member Kişiyi silerken sorun oluştu No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers %@ sunucuları kaydedilirken sorun oluştu @@ -2660,7 +2818,8 @@ Bu geri alınamaz! Error: %@ Hata: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2672,6 +2831,10 @@ Bu geri alınamaz! Hata: veritabanı dosyası yok No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. Konuşma sırasında devre dışı bırakılsa bile. @@ -2697,6 +2860,10 @@ Bu geri alınamaz! Dışarı çıkarma hatası: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. Dışarı çıkarılmış veritabanı arşivi. @@ -2732,6 +2899,26 @@ Bu geri alınamaz! Favori No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. Dosya sunuculardan silinecek. @@ -2921,6 +3108,14 @@ Hata: %2$@ GİFler ve çıkartmalar No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group Grup @@ -3201,6 +3396,10 @@ Hata: %2$@ İçe aktarma başarısız oldu No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive Arşiv içe aktarılıyor @@ -3323,6 +3522,10 @@ Hata: %2$@ Arayüz No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code Geçersiz QR kodu @@ -3681,6 +3884,10 @@ Bu senin grup için bağlantın %@! Üye gruptan çıkarılacaktır - bu geri alınamaz! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error Mesaj gönderim hatası @@ -3735,6 +3942,18 @@ Bu senin grup için bağlantın %@! Mesaj kaynağı gizli kalır. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text Mesaj yazısı @@ -3760,6 +3979,14 @@ Bu senin grup için bağlantın %@! %@ den gelen mesajlar gösterilecektir! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. Mesajlar, dosyalar ve aramalar **uçtan uca şifreleme** ile mükemmel ileri gizlilik, inkar ve izinsiz giriş kurtarma ile korunur. @@ -4010,6 +4237,10 @@ Bu senin grup için bağlantın %@! Geçmiş yok No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection Ağ bağlantısı yok @@ -4194,6 +4425,10 @@ Bu senin grup için bağlantın %@! Başka bir cihaza açık geçiş authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles Kullanıcı profillerini aç @@ -4299,6 +4534,10 @@ Bu senin grup için bağlantın %@! Aldığın bağlantıyı yapıştır No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. İnsanlar size yalnızca paylaştığınız bağlantılar üzerinden ulaşabilir. @@ -4324,6 +4563,11 @@ Bu senin grup için bağlantın %@! Lütfen konuştuğunuz kişiden sesli mesaj göndermeyi etkinleştirmesini isteyin. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Lütfen doğru bağlantıyı kullandığınızı kontrol edin veya kişiden size başka bir bağlantı göndermesini isteyin. @@ -4421,6 +4665,10 @@ Hata: %@ Ön izleme No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security Gizlilik & güvenlik @@ -4486,6 +4734,10 @@ Hata: %@ Profil parolası No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. Profil güncellemesi kişilerinize gönderilecektir. @@ -4568,6 +4820,14 @@ Enable in *Network & servers* settings. KB başına protokol zaman aşımı No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications Anında bildirimler @@ -4633,6 +4893,10 @@ Enable in *Network & servers* settings. Gönderildi bilgisi devre dışı bırakıldı No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at Şuradan alındı @@ -4653,6 +4917,18 @@ Enable in *Network & servers* settings. Mesaj alındı message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. Alıcı adresi farklı bir sunucuya değiştirilecektir. Gönderici çevrimiçi olduktan sonra adres değişikliği tamamlanacaktır. @@ -4683,11 +4959,31 @@ Enable in *Network & servers* settings. Alıcılar yazdığına göre güncellemeleri görecektir. No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Mesaj teslimini zorlamak için bağlı tüm sunucuları yeniden bağlayın. Ek trafik kullanır. No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? Sunuculara yeniden bağlanılsın mı? @@ -4738,6 +5034,10 @@ Enable in *Network & servers* settings. Sil No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member Kişiyi sil @@ -4808,16 +5108,32 @@ Enable in *Network & servers* settings. Sıfırla No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors Renkleri sıfırla No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults Varsayılanlara sıfırla No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Yeni bir sohbet profili oluşturmak için uygulamayı yeniden başlatın @@ -4888,6 +5204,10 @@ Enable in *Network & servers* settings. Sohbeti çalıştır No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers SMP sunucuları @@ -5003,6 +5323,14 @@ Enable in *Network & servers* settings. Kaydedilmiş mesaj message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code QR kodu okut @@ -5043,11 +5371,19 @@ Enable in *Network & servers* settings. Ara veya SimpleX bağlantısını yapıştır No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue Sırayı koru server test step + + Secured + No comment provided by engineer. + Security assessment Güvenlik değerlendirmesi @@ -5063,6 +5399,10 @@ Enable in *Network & servers* settings. Seç No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Kendi kendini imha @@ -5113,6 +5453,10 @@ Enable in *Network & servers* settings. Kaybolan bir mesaj gönder No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews Bağlantı ön gösterimleri gönder @@ -5223,6 +5567,10 @@ Enable in *Network & servers* settings. Şuradan gönderildi: %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event Dosya etkinliği gönderildi @@ -5233,11 +5581,31 @@ Enable in *Network & servers* settings. Mesaj gönderildi message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. Gönderilen mesajlar ayarlanan süreden sonra silinecektir. No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. Sunucu adresi ağ ayarlarıyla uyumlu değil. @@ -5258,6 +5626,10 @@ Enable in *Network & servers* settings. Sunucu testinde hata oluştu! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. Sunucu sürümü ağ ayarlarıyla uyumlu değil. @@ -5268,6 +5640,14 @@ Enable in *Network & servers* settings. Sunucular No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code Oturum kodu @@ -5283,6 +5663,10 @@ Enable in *Network & servers* settings. Kişi adı gir… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences Grup tercihlerini ayarla @@ -5403,6 +5787,10 @@ Enable in *Network & servers* settings. Göster: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address SimpleX Adresi @@ -5478,6 +5866,10 @@ Enable in *Network & servers* settings. Basitleştirilmiş gizli mod No comment provided by engineer. + + Size + No comment provided by engineer. + Skip Atla @@ -5523,6 +5915,14 @@ Enable in *Network & servers* settings. Geçişi başlat No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop Dur @@ -5588,6 +5988,22 @@ Enable in *Network & servers* settings. Gönder No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat SimpleX Chat'e destek ol @@ -5668,6 +6084,10 @@ Enable in *Network & servers* settings. Yeni bir sohbet başlatmak için tıkla No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. Test %@ adımında başarısız oldu. @@ -5805,9 +6225,8 @@ Bazı hatalar nedeniyle veya bağlantı tehlikeye girdiğinde meydana gelebilir. Yapıştırdığın metin bir SimpleX bağlantısı değildir. No comment provided by engineer. - - Theme - Tema + + Themes No comment provided by engineer. @@ -5875,11 +6294,19 @@ Bazı hatalar nedeniyle veya bağlantı tehlikeye girdiğinde meydana gelebilir. Bu senin kendi tek kullanımlık bağlantın! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. Bu ayar, geçerli sohbet profiliniz **%@** deki mesajlara uygulanır. No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: Soru sormak ve güncellemeleri almak için: @@ -5947,11 +6374,19 @@ Bu özellik etkinleştirilmeden önce kimlik doğrulamayı tamamlamanız istenec Bağlanırken gizli moda geçiş yap. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation Taşıma izolasyonu No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Bu kişiden mesaj almak için kullanılan sunucuya bağlanılmaya çalışılıyor (hata: %@). @@ -6144,6 +6579,10 @@ Bağlanmak için lütfen kişinizden başka bir bağlantı oluşturmasını iste Yükselt ve sohbeti aç No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed Yükleme başarısız @@ -6154,6 +6593,14 @@ Bağlanmak için lütfen kişinizden başka bir bağlantı oluşturmasını iste Dosya yükle server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive Arşiv yükleme @@ -6229,6 +6676,10 @@ Bağlanmak için lütfen kişinizden başka bir bağlantı oluşturmasını iste Kullanıcı profili No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. .onion ana bilgisayarlarını kullanmak için uyumlu VPN sağlayıcısı gerekir. @@ -6364,6 +6815,14 @@ Bağlanmak için lütfen kişinizden başka bir bağlantı oluşturmasını iste Video bekleniyor No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures Uyarı: birden fazla cihazda sohbet başlatmak desteklenmez ve mesaj teslim hatalarına neden olur @@ -6469,11 +6928,19 @@ Bağlanmak için lütfen kişinizden başka bir bağlantı oluşturmasını iste Yanlış anahtar veya bilinmeyen bağlantı - büyük olasılıkla bu bağlantı silinmiştir. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! Yanlış parola! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers XFTP sunucuları @@ -6556,6 +7023,10 @@ Katılma isteği tekrarlansın mı? Gruba davet edildiniz No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. Cihaz ve uygulama kimlik doğrulaması olmadan kilit ekranından çağrı kabul edebilirsiniz. @@ -6962,6 +7433,10 @@ SimpleX sunucuları profilinizi göremez. ve %lld diğer etkinlikler No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) sesli arama (uçtan uca şifreli değil) @@ -6995,7 +7470,7 @@ SimpleX sunucuları profilinizi göremez. blocked by admin yönetici tarafından engellendi - marked deleted chat item preview text + blocked chat item bold @@ -7152,6 +7627,10 @@ SimpleX sunucuları profilinizi göremez. gün time unit + + decryption errors + No comment provided by engineer. + default (%@) varsayılan (%@) @@ -7202,6 +7681,10 @@ SimpleX sunucuları profilinizi göremez. yinelenen mesaj integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted uçtan uca şifrelenmiş @@ -7282,6 +7765,10 @@ SimpleX sunucuları profilinizi göremez. etkinlik yaşandı No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded iletildi @@ -7489,6 +7976,14 @@ SimpleX sunucuları profilinizi göremez. açık group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner sahip @@ -7799,7 +8294,7 @@ last received msg: %2$@
    - +
    @@ -7836,7 +8331,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/tr.xcloc/contents.json b/apps/ios/SimpleX Localizations/tr.xcloc/contents.json index 0aee97a599..6f74640a6b 100644 --- a/apps/ios/SimpleX Localizations/tr.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/tr.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "tr", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff b/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff index 258c42007a..7e19da7cbd 100644 --- a/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff +++ b/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff @@ -2,7 +2,7 @@
    - +
    @@ -557,9 +557,8 @@ Про адресу SimpleX No comment provided by engineer. - - Accent color - Акцентний колір + + Accent No comment provided by engineer. @@ -583,6 +582,14 @@ Прийняти інкогніто accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. Додайте адресу до свого профілю, щоб ваші контакти могли поділитися нею з іншими людьми. Повідомлення про оновлення профілю буде надіслано вашим контактам. @@ -623,6 +630,18 @@ Додати вітальне повідомлення No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address Адреса @@ -648,6 +667,10 @@ Розширені налаштування мережі No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. Всі дані програми видаляються. @@ -663,6 +686,10 @@ Всі дані стираються при введенні. No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. Всі учасники групи залишаться на зв'язку. @@ -683,6 +710,10 @@ Всі нові повідомлення від %@ будуть приховані! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. Всі ваші контакти залишаться на зв'язку. @@ -883,6 +914,10 @@ Подати заявку No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload Архівування та завантаження @@ -958,6 +993,10 @@ Назад No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address Неправильна адреса робочого столу @@ -983,6 +1022,10 @@ Кращі повідомлення No comment provided by engineer. + + Black + No comment provided by engineer. + Block Блокувати @@ -1093,6 +1136,10 @@ Не вдається отримати доступ до зв'язки ключів для збереження пароля до бази даних No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file Не вдається отримати файл @@ -1164,6 +1211,10 @@ Архів чату No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console Консоль чату @@ -1209,6 +1260,10 @@ Налаштування чату No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats Чати @@ -1239,6 +1294,18 @@ Виберіть з бібліотеки No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear Чисто @@ -1264,9 +1331,8 @@ Очистити перевірку No comment provided by engineer. - - Colors - Кольори + + Color mode No comment provided by engineer. @@ -1279,6 +1345,10 @@ Порівняйте коди безпеки зі своїми контактами. No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers Налаштування серверів ICE @@ -1388,16 +1458,28 @@ This is your own one-time link! Підключитися до %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop Підключений робочий стіл No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop Підключено до настільного комп'ютера No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… Підключення до сервера… @@ -1443,6 +1525,18 @@ This is your own one-time link! Тайм-аут з'єднання No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows Контакт дозволяє @@ -1496,7 +1590,11 @@ This is your own one-time link! Copy Копіювати - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1573,6 +1671,10 @@ This is your own one-time link! Створіть свій профіль No comment provided by engineer. + + Created + No comment provided by engineer. + Created at Створено за адресою @@ -1608,6 +1710,10 @@ This is your own one-time link! Поточна парольна фраза… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. Наразі максимальний підтримуваний розмір файлу - %@. @@ -1618,11 +1724,19 @@ This is your own one-time link! Індивідуальний час No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark Темний No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID Ідентифікатор бази даних @@ -1927,6 +2041,10 @@ This cannot be undone! Видалити профіль користувача? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at Видалено за @@ -1937,6 +2055,10 @@ This cannot be undone! Видалено за: %@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery Доставка @@ -1977,6 +2099,14 @@ This cannot be undone! Помилка сервера призначення: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop Розробник @@ -2132,6 +2262,10 @@ This cannot be undone! Завантажити chat item action + + Download errors + No comment provided by engineer. + Download failed Не вдалося завантажити @@ -2142,6 +2276,14 @@ This cannot be undone! Завантажити файл server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive Завантажити архів @@ -2512,6 +2654,10 @@ This cannot be undone! Помилка експорту бази даних чату No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database Помилка імпорту бази даних чату @@ -2537,11 +2683,23 @@ This cannot be undone! Помилка отримання файлу No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member Помилка видалення учасника No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers Помилка збереження %@ серверів @@ -2660,7 +2818,8 @@ This cannot be undone! Error: %@ Помилка: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2672,6 +2831,10 @@ This cannot be undone! Помилка: немає файлу бази даних No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. Навіть коли вимкнений у розмові. @@ -2697,6 +2860,10 @@ This cannot be undone! Помилка експорту: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. Експортований архів бази даних. @@ -2732,6 +2899,26 @@ This cannot be undone! Улюблений No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. Файл буде видалено з серверів. @@ -2921,6 +3108,14 @@ Error: %2$@ GIF-файли та наклейки No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group Група @@ -3201,6 +3396,10 @@ Error: %2$@ Не вдалося імпортувати No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive Імпорт архіву @@ -3323,6 +3522,10 @@ Error: %2$@ Інтерфейс No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code Неправильний QR-код @@ -3681,6 +3884,10 @@ This is your link for group %@! Учасник буде видалений з групи - це неможливо скасувати! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error Помилка доставки повідомлення @@ -3735,6 +3942,18 @@ This is your link for group %@! Джерело повідомлення залишається приватним. No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text Текст повідомлення @@ -3760,6 +3979,14 @@ This is your link for group %@! Повідомлення від %@ будуть показані! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. Повідомлення, файли та дзвінки захищені **наскрізним шифруванням** з ідеальною секретністю переадресації, відмовою та відновленням після злому. @@ -4010,6 +4237,10 @@ This is your link for group %@! Немає історії No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection Немає підключення до мережі @@ -4194,6 +4425,10 @@ This is your link for group %@! Відкрита міграція на інший пристрій authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles Відкрити профілі користувачів @@ -4299,6 +4534,10 @@ This is your link for group %@! Вставте отримане посилання No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. Люди можуть зв'язатися з вами лише за посиланнями, якими ви ділитеся. @@ -4324,6 +4563,11 @@ This is your link for group %@! Будь ласка, попросіть вашого контакту увімкнути відправку голосових повідомлень. No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. Будь ласка, перевірте, чи ви скористалися правильним посиланням, або попросіть контактну особу надіслати вам інше. @@ -4421,6 +4665,10 @@ Error: %@ Попередній перегляд No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security Конфіденційність і безпека @@ -4486,6 +4734,10 @@ Error: %@ Пароль до профілю No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. Оновлення профілю буде надіслано вашим контактам. @@ -4568,6 +4820,14 @@ Enable in *Network & servers* settings. Тайм-аут протоколу на КБ No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications Push-повідомлення @@ -4633,6 +4893,10 @@ Enable in *Network & servers* settings. Підтвердження виключені No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at Отримано за @@ -4653,6 +4917,18 @@ Enable in *Network & servers* settings. Отримано повідомлення message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. Адреса отримувача буде змінена на інший сервер. Зміна адреси завершиться після того, як відправник з'явиться в мережі. @@ -4683,11 +4959,31 @@ Enable in *Network & servers* settings. Одержувачі бачать оновлення, коли ви їх вводите. No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. Перепідключіть всі підключені сервери, щоб примусово доставити повідомлення. Це використовує додатковий трафік. No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? Перепідключити сервери? @@ -4738,6 +5034,10 @@ Enable in *Network & servers* settings. Видалити No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member Видалити учасника @@ -4808,16 +5108,32 @@ Enable in *Network & servers* settings. Перезавантаження No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors Скинути кольори No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults Відновити налаштування за замовчуванням No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile Перезапустіть програму, щоб створити новий профіль чату @@ -4888,6 +5204,10 @@ Enable in *Network & servers* settings. Запустити чат No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers Сервери SMP @@ -5003,6 +5323,14 @@ Enable in *Network & servers* settings. Збережене повідомлення message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code Відскануйте QR-код @@ -5043,11 +5371,19 @@ Enable in *Network & servers* settings. Знайдіть або вставте посилання SimpleX No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue Безпечна черга server test step + + Secured + No comment provided by engineer. + Security assessment Оцінка безпеки @@ -5063,6 +5399,10 @@ Enable in *Network & servers* settings. Виберіть No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct Самознищення @@ -5113,6 +5453,10 @@ Enable in *Network & servers* settings. Надіслати зникаюче повідомлення No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews Надіслати попередній перегляд за посиланням @@ -5223,6 +5567,10 @@ Enable in *Network & servers* settings. Надіслано за: %@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event Подія надісланого файлу @@ -5233,11 +5581,31 @@ Enable in *Network & servers* settings. Надіслано повідомлення message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. Надіслані повідомлення будуть видалені через встановлений час. No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. Адреса сервера несумісна з налаштуваннями мережі. @@ -5258,6 +5626,10 @@ Enable in *Network & servers* settings. Тест сервера завершився невдало! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. Серверна версія несумісна з мережевими налаштуваннями. @@ -5268,6 +5640,14 @@ Enable in *Network & servers* settings. Сервери No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code Код сесії @@ -5283,6 +5663,10 @@ Enable in *Network & servers* settings. Встановити ім'я контакту… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences Встановіть налаштування групи @@ -5403,6 +5787,10 @@ Enable in *Network & servers* settings. Показати: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address Адреса SimpleX @@ -5478,6 +5866,10 @@ Enable in *Network & servers* settings. Спрощений режим інкогніто No comment provided by engineer. + + Size + No comment provided by engineer. + Skip Пропустити @@ -5523,6 +5915,14 @@ Enable in *Network & servers* settings. Почати міграцію No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop Зупинити @@ -5588,6 +5988,22 @@ Enable in *Network & servers* settings. Надіслати No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat Підтримка чату SimpleX @@ -5668,6 +6084,10 @@ Enable in *Network & servers* settings. Натисніть, щоб почати новий чат No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. Тест завершився невдало на кроці %@. @@ -5805,9 +6225,8 @@ It can happen because of some bug or when the connection is compromised.Текст, який ви вставили, не є посиланням SimpleX. No comment provided by engineer. - - Theme - Тема + + Themes No comment provided by engineer. @@ -5875,11 +6294,19 @@ It can happen because of some bug or when the connection is compromised.Це ваше власне одноразове посилання! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. Це налаштування застосовується до повідомлень у вашому поточному профілі чату **%@**. No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: Задати будь-які питання та отримувати новини: @@ -5947,11 +6374,19 @@ You will be prompted to complete authentication before this feature is enabled.< Увімкніть інкогніто при підключенні. No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation Транспортна ізоляція No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). Спроба з'єднатися з сервером, який використовується для отримання повідомлень від цього контакту (помилка: %@). @@ -6144,6 +6579,10 @@ To connect, please ask your contact to create another connection link and check Оновлення та відкритий чат No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed Не вдалося завантфжити @@ -6154,6 +6593,14 @@ To connect, please ask your contact to create another connection link and check Завантажити файл server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive Завантаження архіву @@ -6229,6 +6676,10 @@ To connect, please ask your contact to create another connection link and check Профіль користувача No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. Для використання хостів .onion потрібен сумісний VPN-провайдер. @@ -6364,6 +6815,14 @@ To connect, please ask your contact to create another connection link and check Чекаємо на відео No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures Попередження: запуск чату на декількох пристроях не підтримується і може призвести до збоїв у доставці повідомлень @@ -6469,11 +6928,19 @@ To connect, please ask your contact to create another connection link and check Неправильний ключ або невідоме з'єднання - швидше за все, це з'єднання видалено. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! Неправильний пароль! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers Сервери XFTP @@ -6556,6 +7023,10 @@ Repeat join request? Запрошуємо вас до групи No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. Ви можете приймати дзвінки з екрана блокування без автентифікації пристрою та програми. @@ -6962,6 +7433,10 @@ SimpleX servers cannot see your profile. та %lld інших подій No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) аудіовиклик (без шифрування e2e) @@ -6995,7 +7470,7 @@ SimpleX servers cannot see your profile. blocked by admin заблоковано адміністратором - marked deleted chat item preview text + blocked chat item bold @@ -7152,6 +7627,10 @@ SimpleX servers cannot see your profile. днів time unit + + decryption errors + No comment provided by engineer. + default (%@) за замовчуванням (%@) @@ -7202,6 +7681,10 @@ SimpleX servers cannot see your profile. дублююче повідомлення integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted e2e зашифрований @@ -7282,6 +7765,10 @@ SimpleX servers cannot see your profile. відбулася подія No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded переслано @@ -7489,6 +7976,14 @@ SimpleX servers cannot see your profile. увімкненo group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner власник @@ -7799,7 +8294,7 @@ last received msg: %2$@
    - +
    @@ -7836,7 +8331,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/uk.xcloc/contents.json b/apps/ios/SimpleX Localizations/uk.xcloc/contents.json index 6c122f11ab..38238e7802 100644 --- a/apps/ios/SimpleX Localizations/uk.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/uk.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "uk", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file diff --git a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff index 9808c6fbcd..2ba735b08d 100644 --- a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff +++ b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff @@ -2,7 +2,7 @@
    - +
    @@ -545,9 +545,8 @@ 关于 SimpleX 地址 No comment provided by engineer. - - Accent color - 色调 + + Accent No comment provided by engineer. @@ -571,6 +570,14 @@ 接受隐身聊天 accept contact request via notification + + Acknowledged + No comment provided by engineer. + + + Acknowledgement errors + No comment provided by engineer. + Add address to your profile, so that your contacts can share it with other people. Profile update will be sent to your contacts. 将地址添加到您的个人资料,以便您的联系人可以与其他人共享。个人资料更新将发送给您的联系人。 @@ -611,6 +618,18 @@ 添加欢迎信息 No comment provided by engineer. + + Additional accent + No comment provided by engineer. + + + Additional accent 2 + No comment provided by engineer. + + + Additional secondary + No comment provided by engineer. + Address 地址 @@ -636,6 +655,10 @@ 高级网络设置 No comment provided by engineer. + + Advanced settings + No comment provided by engineer. + All app data is deleted. 已删除所有应用程序数据。 @@ -651,6 +674,10 @@ 所有数据在输入后将被删除。 No comment provided by engineer. + + All data is private to your device. + No comment provided by engineer. + All group members will remain connected. 所有群组成员将保持连接。 @@ -670,6 +697,10 @@ All new messages from %@ will be hidden! No comment provided by engineer. + + All users + No comment provided by engineer. + All your contacts will remain connected. 所有联系人会保持连接。 @@ -868,6 +899,10 @@ 应用 No comment provided by engineer. + + Apply to + No comment provided by engineer. + Archive and upload 存档和上传 @@ -943,6 +978,10 @@ 返回 No comment provided by engineer. + + Background + No comment provided by engineer. + Bad desktop address 糟糕的桌面地址 @@ -968,6 +1007,10 @@ 更好的消息 No comment provided by engineer. + + Black + No comment provided by engineer. + Block 封禁 @@ -1078,6 +1121,10 @@ 无法访问钥匙串以保存数据库密码 No comment provided by engineer. + + Cannot forward message + No comment provided by engineer. + Cannot receive file 无法接收文件 @@ -1148,6 +1195,10 @@ 聊天档案 No comment provided by engineer. + + Chat colors + No comment provided by engineer. + Chat console 聊天控制台 @@ -1193,6 +1244,10 @@ 聊天偏好设置 No comment provided by engineer. + + Chat theme + No comment provided by engineer. + Chats 聊天 @@ -1222,6 +1277,18 @@ 从库中选择 No comment provided by engineer. + + Chunks deleted + No comment provided by engineer. + + + Chunks downloaded + No comment provided by engineer. + + + Chunks uploaded + No comment provided by engineer. + Clear 清除 @@ -1247,9 +1314,8 @@ 清除验证 No comment provided by engineer. - - Colors - 颜色 + + Color mode No comment provided by engineer. @@ -1262,6 +1328,10 @@ 与您的联系人比较安全码。 No comment provided by engineer. + + Completed + No comment provided by engineer. + Configure ICE servers 配置 ICE 服务器 @@ -1364,16 +1434,28 @@ This is your own one-time link! Connect with %@ No comment provided by engineer. + + Connected + No comment provided by engineer. + Connected desktop 已连接的桌面 No comment provided by engineer. + + Connected servers + No comment provided by engineer. + Connected to desktop 已连接到桌面 No comment provided by engineer. + + Connecting + No comment provided by engineer. + Connecting to server… 连接服务器中…… @@ -1419,6 +1501,18 @@ This is your own one-time link! 连接超时 No comment provided by engineer. + + Connection with desktop stopped + No comment provided by engineer. + + + Connections + No comment provided by engineer. + + + Connections subscribed + No comment provided by engineer. + Contact allows 联系人允许 @@ -1472,7 +1566,11 @@ This is your own one-time link! Copy 复制 - chat item action + No comment provided by engineer. + + + Copy error + No comment provided by engineer. Core version: v%@ @@ -1548,6 +1646,10 @@ This is your own one-time link! 创建您的资料 No comment provided by engineer. + + Created + No comment provided by engineer. + Created at 创建于 @@ -1582,6 +1684,10 @@ This is your own one-time link! 现有密码…… No comment provided by engineer. + + Current user + No comment provided by engineer. + Currently maximum supported file size is %@. 目前支持的最大文件大小为 %@。 @@ -1592,11 +1698,19 @@ This is your own one-time link! 自定义时间 No comment provided by engineer. + + Customize theme + No comment provided by engineer. + Dark 深色 No comment provided by engineer. + + Dark mode colors + No comment provided by engineer. + Database ID 数据库 ID @@ -1898,6 +2012,10 @@ This cannot be undone! 删除用户资料? No comment provided by engineer. + + Deleted + No comment provided by engineer. + Deleted at 已删除于 @@ -1908,6 +2026,10 @@ This cannot be undone! 已删除于:%@ copied message info + + Deletion errors + No comment provided by engineer. + Delivery 传送 @@ -1946,6 +2068,14 @@ This cannot be undone! Destination server error: %@ snd error text + + Detailed statistics + No comment provided by engineer. + + + Details + No comment provided by engineer. + Develop 开发 @@ -2099,6 +2229,10 @@ This cannot be undone! 下载 chat item action + + Download errors + No comment provided by engineer. + Download failed 下载失败了 @@ -2109,6 +2243,14 @@ This cannot be undone! 下载文件 server test step + + Downloaded + No comment provided by engineer. + + + Downloaded files + No comment provided by engineer. + Downloading archive 正在下载存档 @@ -2476,6 +2618,10 @@ This cannot be undone! 导出聊天数据库错误 No comment provided by engineer. + + Error exporting theme: %@ + No comment provided by engineer. + Error importing chat database 导入聊天数据库错误 @@ -2500,11 +2646,23 @@ This cannot be undone! 接收文件错误 No comment provided by engineer. + + Error reconnecting server + No comment provided by engineer. + + + Error reconnecting servers + No comment provided by engineer. + Error removing member 删除成员错误 No comment provided by engineer. + + Error resetting statistics + No comment provided by engineer. + Error saving %@ servers 保存 %@ 服务器错误 @@ -2622,7 +2780,8 @@ This cannot be undone! Error: %@ 错误: %@ - snd error text + file error text + snd error text Error: URL is invalid @@ -2634,6 +2793,10 @@ This cannot be undone! 错误:没有数据库文件 No comment provided by engineer. + + Errors + No comment provided by engineer. + Even when disabled in the conversation. 即使在对话中被禁用。 @@ -2659,6 +2822,10 @@ This cannot be undone! 导出错误: No comment provided by engineer. + + Export theme + No comment provided by engineer. + Exported database archive. 导出数据库归档。 @@ -2694,6 +2861,26 @@ This cannot be undone! 最喜欢 No comment provided by engineer. + + File error + No comment provided by engineer. + + + File not found - most likely file was deleted or cancelled. + file error text + + + File server error: %@ + file error text + + + File status + No comment provided by engineer. + + + File status: %@ + copied message info + File will be deleted from servers. 文件将从服务器中删除。 @@ -2878,6 +3065,14 @@ Error: %2$@ GIF 和贴纸 No comment provided by engineer. + + Good afternoon! + message preview + + + Good morning! + message preview + Group 群组 @@ -3156,6 +3351,10 @@ Error: %2$@ 导入失败了 No comment provided by engineer. + + Import theme + No comment provided by engineer. + Importing archive 正在导入存档 @@ -3278,6 +3477,10 @@ Error: %2$@ 界面 No comment provided by engineer. + + Interface colors + No comment provided by engineer. + Invalid QR code 无效的二维码 @@ -3631,6 +3834,10 @@ This is your link for group %@! 成员将被移出群组——此操作无法撤消! No comment provided by engineer. + + Menus + No comment provided by engineer. + Message delivery error 消息传递错误 @@ -3682,6 +3889,18 @@ This is your link for group %@! 消息来源保持私密。 No comment provided by engineer. + + Message status + No comment provided by engineer. + + + Message status: %@ + copied message info + + + Message subscriptions + No comment provided by engineer. + Message text 消息正文 @@ -3706,6 +3925,14 @@ This is your link for group %@! Messages from %@ will be shown! No comment provided by engineer. + + Messages received + No comment provided by engineer. + + + Messages sent + No comment provided by engineer. + Messages, files and calls are protected by **end-to-end encryption** with perfect forward secrecy, repudiation and break-in recovery. No comment provided by engineer. @@ -3953,6 +4180,10 @@ This is your link for group %@! 无历史记录 No comment provided by engineer. + + No info, try to reload + No comment provided by engineer. + No network connection 无网络连接 @@ -4136,6 +4367,10 @@ This is your link for group %@! Open migration to another device authentication reason + + Open server settings + No comment provided by engineer. + Open user profiles 打开用户个人资料 @@ -4239,6 +4474,10 @@ This is your link for group %@! 粘贴您收到的链接 No comment provided by engineer. + + Pending + No comment provided by engineer. + People can connect to you only via the links you share. 人们只能通过您共享的链接与您建立联系。 @@ -4264,6 +4503,11 @@ This is your link for group %@! 请让您的联系人启用发送语音消息。 No comment provided by engineer. + + Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection. +Please share any other issues with the developers. + No comment provided by engineer. + Please check that you used the correct link or ask your contact to send you another one. 请检查您使用的链接是否正确,或者让您的联系人给您发送另一个链接。 @@ -4359,6 +4603,10 @@ Error: %@ 预览 No comment provided by engineer. + + Previously connected servers + No comment provided by engineer. + Privacy & security 隐私和安全 @@ -4420,6 +4668,10 @@ Error: %@ 个人资料密码 No comment provided by engineer. + + Profile theme + No comment provided by engineer. + Profile update will be sent to your contacts. 个人资料更新将被发送给您的联系人。 @@ -4498,6 +4750,14 @@ Enable in *Network & servers* settings. 每 KB 协议超时 No comment provided by engineer. + + Proxied + No comment provided by engineer. + + + Proxied servers + No comment provided by engineer. + Push notifications 推送通知 @@ -4562,6 +4822,10 @@ Enable in *Network & servers* settings. 回执已禁用 No comment provided by engineer. + + Receive errors + No comment provided by engineer. + Received at 已收到于 @@ -4582,6 +4846,18 @@ Enable in *Network & servers* settings. 收到的信息 message info title + + Received messages + No comment provided by engineer. + + + Received reply + No comment provided by engineer. + + + Received total + No comment provided by engineer. + Receiving address will be changed to a different server. Address change will complete after sender comes online. 接收地址将变更到不同的服务器。地址更改将在发件人上线后完成。 @@ -4611,11 +4887,31 @@ Enable in *Network & servers* settings. 对方会在您键入时看到更新。 No comment provided by engineer. + + Reconnect + No comment provided by engineer. + Reconnect all connected servers to force message delivery. It uses additional traffic. 重新连接所有已连接的服务器以强制发送信息。这会耗费更多流量。 No comment provided by engineer. + + Reconnect all servers + No comment provided by engineer. + + + Reconnect all servers? + No comment provided by engineer. + + + Reconnect server to force message delivery. It uses additional traffic. + No comment provided by engineer. + + + Reconnect server? + No comment provided by engineer. + Reconnect servers? 是否重新连接服务器? @@ -4666,6 +4962,10 @@ Enable in *Network & servers* settings. 移除 No comment provided by engineer. + + Remove image + No comment provided by engineer. + Remove member 删除成员 @@ -4736,16 +5036,32 @@ Enable in *Network & servers* settings. 重置 No comment provided by engineer. + + Reset all statistics + No comment provided by engineer. + + + Reset all statistics? + No comment provided by engineer. + Reset colors 重置颜色 No comment provided by engineer. + + Reset to app theme + No comment provided by engineer. + Reset to defaults 重置为默认 No comment provided by engineer. + + Reset to user theme + No comment provided by engineer. + Restart the app to create a new chat profile 重新启动应用程序以创建新的聊天资料 @@ -4816,6 +5132,10 @@ Enable in *Network & servers* settings. 运行聊天程序 No comment provided by engineer. + + SMP server + No comment provided by engineer. + SMP servers SMP 服务器 @@ -4930,6 +5250,14 @@ Enable in *Network & servers* settings. 已保存的消息 message info title + + Scale + No comment provided by engineer. + + + Scan / Paste link + No comment provided by engineer. + Scan QR code 扫描二维码 @@ -4970,11 +5298,19 @@ Enable in *Network & servers* settings. 搜索或粘贴 SimpleX 链接 No comment provided by engineer. + + Secondary + No comment provided by engineer. + Secure queue 保护队列 server test step + + Secured + No comment provided by engineer. + Security assessment 安全评估 @@ -4990,6 +5326,10 @@ Enable in *Network & servers* settings. 选择 No comment provided by engineer. + + Selected chat preferences prohibit this message. + No comment provided by engineer. + Self-destruct 自毁 @@ -5040,6 +5380,10 @@ Enable in *Network & servers* settings. 发送限时消息中 No comment provided by engineer. + + Send errors + No comment provided by engineer. + Send link previews 发送链接预览 @@ -5148,6 +5492,10 @@ Enable in *Network & servers* settings. 已发送于:%@ copied message info + + Sent directly + No comment provided by engineer. + Sent file event 已发送文件项目 @@ -5158,11 +5506,31 @@ Enable in *Network & servers* settings. 已发信息 message info title + + Sent messages + No comment provided by engineer. + Sent messages will be deleted after set time. 已发送的消息将在设定的时间后被删除。 No comment provided by engineer. + + Sent reply + No comment provided by engineer. + + + Sent total + No comment provided by engineer. + + + Sent via proxy + No comment provided by engineer. + + + Server address + No comment provided by engineer. + Server address is incompatible with network settings. srv error text. @@ -5182,6 +5550,10 @@ Enable in *Network & servers* settings. 服务器测试失败! No comment provided by engineer. + + Server type + No comment provided by engineer. + Server version is incompatible with network settings. srv error text @@ -5191,6 +5563,14 @@ Enable in *Network & servers* settings. 服务器 No comment provided by engineer. + + Servers info + No comment provided by engineer. + + + Servers statistics will be reset - this cannot be undone! + No comment provided by engineer. + Session code 会话码 @@ -5206,6 +5586,10 @@ Enable in *Network & servers* settings. 设置联系人姓名…… No comment provided by engineer. + + Set default theme + No comment provided by engineer. + Set group preferences 设置群组偏好设置 @@ -5324,6 +5708,10 @@ Enable in *Network & servers* settings. 显示: No comment provided by engineer. + + SimpleX + No comment provided by engineer. + SimpleX Address SimpleX 地址 @@ -5399,6 +5787,10 @@ Enable in *Network & servers* settings. 简化的隐身模式 No comment provided by engineer. + + Size + No comment provided by engineer. + Skip 跳过 @@ -5444,6 +5836,14 @@ Enable in *Network & servers* settings. 开始迁移 No comment provided by engineer. + + Starting from %@. + No comment provided by engineer. + + + Statistics + No comment provided by engineer. + Stop 停止 @@ -5509,6 +5909,22 @@ Enable in *Network & servers* settings. 提交 No comment provided by engineer. + + Subscribed + No comment provided by engineer. + + + Subscription errors + No comment provided by engineer. + + + Subscription percentage + No comment provided by engineer. + + + Subscriptions ignored + No comment provided by engineer. + Support SimpleX Chat 支持 SimpleX Chat @@ -5589,6 +6005,10 @@ Enable in *Network & servers* settings. 点击开始一个新聊天 No comment provided by engineer. + + Temporary file error + No comment provided by engineer. + Test failed at step %@. 在步骤 %@ 上测试失败。 @@ -5725,9 +6145,8 @@ It can happen because of some bug or when the connection is compromised.您粘贴的文本不是 SimpleX 链接。 No comment provided by engineer. - - Theme - 主题 + + Themes No comment provided by engineer. @@ -5795,11 +6214,19 @@ It can happen because of some bug or when the connection is compromised.这是你自己的一次性链接! No comment provided by engineer. + + This link was used with another mobile device, please create a new link on the desktop. + No comment provided by engineer. + This setting applies to messages in your current chat profile **%@**. 此设置适用于您当前聊天资料 **%@** 中的消息。 No comment provided by engineer. + + Title + No comment provided by engineer. + To ask any questions and to receive updates: 要提出任何问题并接收更新,请: @@ -5866,11 +6293,19 @@ You will be prompted to complete authentication before this feature is enabled.< 在连接时切换隐身模式。 No comment provided by engineer. + + Total + No comment provided by engineer. + Transport isolation 传输隔离 No comment provided by engineer. + + Transport sessions + No comment provided by engineer. + Trying to connect to the server used to receive messages from this contact (error: %@). 正在尝试连接到用于从该联系人接收消息的服务器(错误:%@)。 @@ -6061,6 +6496,10 @@ To connect, please ask your contact to create another connection link and check 升级并打开聊天 No comment provided by engineer. + + Upload errors + No comment provided by engineer. + Upload failed 上传失败了 @@ -6071,6 +6510,14 @@ To connect, please ask your contact to create another connection link and check 上传文件 server test step + + Uploaded + No comment provided by engineer. + + + Uploaded files + No comment provided by engineer. + Uploading archive 正在上传存档 @@ -6143,6 +6590,10 @@ To connect, please ask your contact to create another connection link and check 用户资料 No comment provided by engineer. + + User selection + No comment provided by engineer. + Using .onion hosts requires compatible VPN provider. 使用 .onion 主机需要兼容的 VPN 提供商。 @@ -6277,6 +6728,14 @@ To connect, please ask your contact to create another connection link and check 等待视频中 No comment provided by engineer. + + Wallpaper accent + No comment provided by engineer. + + + Wallpaper background + No comment provided by engineer. + Warning: starting chat on multiple devices is not supported and will cause message delivery failures 警告:不支持在多部设备上启动聊天,这么做会导致消息传送失败。 @@ -6379,11 +6838,19 @@ To connect, please ask your contact to create another connection link and check Wrong key or unknown connection - most likely this connection is deleted. snd error text + + Wrong key or unknown file chunk address - most likely file is deleted. + file error text + Wrong passphrase! 密码错误! No comment provided by engineer. + + XFTP server + No comment provided by engineer. + XFTP servers XFTP 服务器 @@ -6459,6 +6926,10 @@ Repeat join request? 您被邀请加入群组 No comment provided by engineer. + + You are not connected to these servers. Private routing is used to deliver messages to them. + No comment provided by engineer. + You can accept calls from lock screen, without device and app authentication. 您可以从锁屏上接听电话,无需设备和应用程序的认证。 @@ -6860,6 +7331,10 @@ SimpleX 服务器无法看到您的资料。 and %lld other events No comment provided by engineer. + + attempts + No comment provided by engineer. + audio call (not e2e encrypted) 语音通话(非端到端加密) @@ -6893,7 +7368,7 @@ SimpleX 服务器无法看到您的资料。 blocked by admin 由管理员封禁 - marked deleted chat item preview text + blocked chat item bold @@ -7049,6 +7524,10 @@ SimpleX 服务器无法看到您的资料。 time unit + + decryption errors + No comment provided by engineer. + default (%@) 默认 (%@) @@ -7099,6 +7578,10 @@ SimpleX 服务器无法看到您的资料。 重复的消息 integrity error chat item + + duplicates + No comment provided by engineer. + e2e encrypted 端到端加密 @@ -7179,6 +7662,10 @@ SimpleX 服务器无法看到您的资料。 发生的事 No comment provided by engineer. + + expired + No comment provided by engineer. + forwarded 已转发 @@ -7385,6 +7872,14 @@ SimpleX 服务器无法看到您的资料。 开启 group pref value + + other + No comment provided by engineer. + + + other errors + No comment provided by engineer. + owner 群主 @@ -7687,7 +8182,7 @@ last received msg: %2$@
    - +
    @@ -7723,7 +8218,7 @@ last received msg: %2$@
    - +
    diff --git a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/contents.json b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/contents.json index 807a15f96c..6416a2d8fa 100644 --- a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/contents.json +++ b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/contents.json @@ -3,10 +3,10 @@ "project" : "SimpleX.xcodeproj", "targetLocale" : "zh-Hans", "toolInfo" : { - "toolBuildNumber" : "15A240d", + "toolBuildNumber" : "15F31d", "toolID" : "com.apple.dt.xcode", "toolName" : "Xcode", - "toolVersion" : "15.0" + "toolVersion" : "15.4" }, "version" : "1.0" } \ No newline at end of file From 63393eaf0bd7ba099ed5ec9be35eeaf92049f453 Mon Sep 17 00:00:00 2001 From: Arturs Krumins Date: Fri, 5 Jul 2024 14:34:03 +0200 Subject: [PATCH 33/43] ios: make theme wallpaper visible on iOS15, further improve scrolling (#4408) --- apps/ios/Shared/Model/ChatModel.swift | 4 ++-- apps/ios/Shared/Views/Chat/ChatView.swift | 6 +++--- apps/ios/Shared/Views/Chat/ReverseList.swift | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index 02a31ecda4..141e6d5c42 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -702,7 +702,7 @@ final class ChatModel: ObservableObject { } i += 1 } - return UnreadChatItemCounts(totalBelow: totalBelow, unreadBelow: unreadBelow) + return UnreadChatItemCounts(isNearBottom: totalBelow < 16, unreadBelow: unreadBelow) } func topItemInView(itemsInView: Set) -> ChatItem? { @@ -740,7 +740,7 @@ struct NTFContactRequest { } struct UnreadChatItemCounts: Equatable { - var totalBelow: Int + var isNearBottom: Bool var unreadBelow: Int } diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index 40c97202b4..d0e73adccd 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -410,7 +410,7 @@ struct ChatView: View { init() { unreadChatItemCounts = UnreadChatItemCounts( - totalBelow: .zero, + isNearBottom: true, unreadBelow: .zero ) events @@ -425,9 +425,9 @@ struct ChatView: View { itemsInView } } - .throttle(for: .seconds(0.2), scheduler: DispatchQueue.main, latest: true) .map { ChatModel.shared.unreadChatItemCounts(itemsInView: $0) } .removeDuplicates() + .throttle(for: .seconds(0.2), scheduler: DispatchQueue.main, latest: true) .assign(to: \.unreadChatItemCounts, on: self) .store(in: &bag) } @@ -479,7 +479,7 @@ struct ChatView: View { scrollModel.scrollToItem(id: latestUnreadItem.id) } } - } else if counts.totalBelow > 16 { + } else if !counts.isNearBottom { circleButton { Image(systemName: "chevron.down") .foregroundColor(theme.colors.primary) diff --git a/apps/ios/Shared/Views/Chat/ReverseList.swift b/apps/ios/Shared/Views/Chat/ReverseList.swift index d8a362e847..ae6d900eb6 100644 --- a/apps/ios/Shared/Views/Chat/ReverseList.swift +++ b/apps/ios/Shared/Views/Chat/ReverseList.swift @@ -181,6 +181,7 @@ struct ReverseList: UIV /// Updates content of the cell /// For reference: https://noahgilmore.com/blog/swiftui-self-sizing-cells/ func set(content: Hosted, parent: UIViewController) { + hostingController.view.backgroundColor = .clear hostingController.rootView = content if let hostingView = hostingController.view { hostingView.invalidateIntrinsicContentSize() From 71ce598355b10d75cc09a14919095dc72cde0248 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Fri, 5 Jul 2024 14:43:36 +0100 Subject: [PATCH 34/43] ios: make message corners rounded in theme preview (#4410) Co-authored-by: Levitating Pineapple --- apps/ios/Shared/Views/Helpers/ChatItemClipShape.swift | 11 ++++++++--- .../Views/UserSettings/AppearanceSettings.swift | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/ios/Shared/Views/Helpers/ChatItemClipShape.swift b/apps/ios/Shared/Views/Helpers/ChatItemClipShape.swift index 3e5200f281..477dc567eb 100644 --- a/apps/ios/Shared/Views/Helpers/ChatItemClipShape.swift +++ b/apps/ios/Shared/Views/Helpers/ChatItemClipShape.swift @@ -38,12 +38,17 @@ struct ChatItemClipped: ViewModifier { switch chatItem.content { case .sndMsgContent, - .rcvMsgContent, + .rcvMsgContent, + .rcvDecryptionError, + .rcvGroupInvitation, + .sndGroupInvitation, .sndDeleted, - .rcvDeleted, + .rcvDeleted, + .rcvIntegrityError, .sndModerated, .rcvModerated, - .rcvBlocked: 18 + .rcvBlocked, + .invalidJSON: 18 default: 8 } }() diff --git a/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift b/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift index 89f8c12423..18cf5fa199 100644 --- a/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift +++ b/apps/ios/Shared/Views/UserSettings/AppearanceSettings.swift @@ -305,13 +305,16 @@ struct ChatThemePreview: View { let view = VStack { if withMessages { let alice = ChatItem.getSample(1, CIDirection.directRcv, Date.now, NSLocalizedString("Good afternoon!", comment: "message preview")) + let bob = ChatItem.getSample(2, CIDirection.directSnd, Date.now, NSLocalizedString("Good morning!", comment: "message preview"), quotedItem: CIQuote.getSample(alice.id, alice.meta.itemTs, alice.content.text, chatDir: alice.chatDir)) HStack { ChatItemView(chat: Chat.sampleData, chatItem: alice, revealed: Binding.constant(false)) + .modifier(ChatItemClipped()) Spacer() } HStack { Spacer() - ChatItemView(chat: Chat.sampleData, chatItem: ChatItem.getSample(2, CIDirection.directSnd, Date.now, NSLocalizedString("Good morning!", comment: "message preview"), quotedItem: CIQuote.getSample(alice.id, alice.meta.itemTs, alice.content.text, chatDir: alice.chatDir)), revealed: Binding.constant(false)) + ChatItemView(chat: Chat.sampleData, chatItem: bob, revealed: Binding.constant(false)) + .modifier(ChatItemClipped()) .frame(alignment: .trailing) } } else { From acd3467d10dceeb4261c3d47b54d808f0d999229 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Tue, 9 Jul 2024 03:23:25 +0700 Subject: [PATCH 35/43] desktop: change libffi dependency (#4416) --- scripts/desktop/build-lib-linux.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/desktop/build-lib-linux.sh b/scripts/desktop/build-lib-linux.sh index c27b672e40..da645c6e86 100755 --- a/scripts/desktop/build-lib-linux.sh +++ b/scripts/desktop/build-lib-linux.sh @@ -29,6 +29,11 @@ cabal build lib:simplex-chat --ghc-options='-optl-Wl,-rpath,$ORIGIN -flink-rts - cd $BUILD_DIR/build #patchelf --add-needed libHSrts_thr-ghc${GHC_VERSION}.so libHSsimplex-chat-*-inplace-ghc${GHC_VERSION}.so #patchelf --add-rpath '$ORIGIN' libHSsimplex-chat-*-inplace-ghc${GHC_VERSION}.so + +# GitHub's Ubuntu 20.04 runner started to set libffi.so.7 as a dependency while Ubuntu 20.04 on user's devices may not have it +# but libffi.so.8 is shipped as an external library with other libs +patchelf --replace-needed "libffi.so.7" "libffi.so.8" libHSsimplex-chat-*-inplace-ghc${GHC_VERSION}.so + mkdir deps 2> /dev/null || true ldd libHSsimplex-chat-*-inplace-ghc${GHC_VERSION}.so | grep "ghc" | cut -d' ' -f 3 | xargs -I {} cp {} ./deps/ From 3e623684bc9dd5221872841f018b17bf9457e077 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Tue, 9 Jul 2024 15:45:09 +0400 Subject: [PATCH 36/43] android, desktop: servers summary (#4398) * multiplatform: subscription icon (#4397) * multiplatform: added network setting to control display of subscription percentage * multiplatform: moved filter to search bar and scan to button * multiplatform: added types and calls for new apis * Update apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> * chore: minor changes in API connections and usage * fix: removed show sub setting from net cfg * multiplatform: added subscription status to chats screen * multiplatform: added reconnect all servers api * multiplatform: added basic view for single user messages * multiplatform: added basic xftp server info view * multiplatform: added detailed stats view for SMP server * multiplatform: added detailed stats view for XFTP server * multiplatform: added individual server view for XFTP servers * multiplatform: added individual server view for SMP servers * multiplatform: added custom coloring for connections * multiplatform: added all translation strings * multiplatform: added support for multi user in serve summary * multiplatform: added missing translations * multiplatform: added share button to servers info * better type safety for server summaries * multiplatform: fixed action arrow paddings in server summary views * multiplatform: serverSummaryView padding and icon fixes * multiplatform: reused shared section divider * move and rename * remove tab icons, text * colors * filter button * paddings * fix translation keys * text * fix buttons clickable area, alerts * stats view * remove chevrons * colors * remove id, fix open server button * don't log terminal items * desktop left modal * single timer, pass state variable * remove unused * fix no summary view * net cfg * ability to hide servers screen by clicking outside servers screen * addressed review feedback * move user/all users selector under tabs * disable horizontal scroll on desktop --------- Co-authored-by: Diogo Cunha Co-authored-by: Avently <7953703+avently@users.noreply.github.com> Co-authored-by: Evgeny Poberezkin --- .../kotlin/chat/simplex/common/App.kt | 2 +- .../chat/simplex/common/model/SimpleXAPI.kt | 205 +++- .../common/views/chatlist/ChatListView.kt | 136 ++- .../views/chatlist/ServersSummaryView.kt | 977 ++++++++++++++++++ .../simplex/common/views/helpers/ModalView.kt | 3 + .../simplex/common/views/helpers/Section.kt | 59 +- .../views/helpers/SubscriptionStatusIcon.kt | 41 + .../common/views/newchat/NewChatSheet.kt | 12 +- .../common/views/newchat/NewChatView.kt | 2 +- .../views/usersettings/NetworkAndServers.kt | 10 + .../commonMain/resources/MR/base/strings.xml | 83 ++ .../images/ic_radiowaves_up_forward_1_bar.svg | 6 + .../images/ic_radiowaves_up_forward_2_bar.svg | 6 + .../images/ic_radiowaves_up_forward_3_bar.svg | 6 + .../images/ic_radiowaves_up_forward_4_bar.svg | 6 + 15 files changed, 1486 insertions(+), 68 deletions(-) create mode 100644 apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ServersSummaryView.kt create mode 100644 apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/SubscriptionStatusIcon.kt create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_1_bar.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_2_bar.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_3_bar.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_4_bar.svg diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt index e7dda42ade..b215b2b6cd 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt @@ -353,7 +353,7 @@ fun DesktopScreen(settingsState: SettingsViewState) { } val (userPickerState, scaffoldState ) = settingsState val scope = rememberCoroutineScope() - if (scaffoldState.drawerState.isOpen) { + if (scaffoldState.drawerState.isOpen || (ModalManager.start.hasModalsOpen && !ModalManager.center.hasModalsOpen)) { Box( Modifier .fillMaxSize() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index 9367fe5f71..0a42541c75 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -127,6 +127,7 @@ class AppPreferences { val showSlowApiCalls = mkBoolPreference(SHARED_PREFS_SHOW_SLOW_API_CALLS, false) val terminalAlwaysVisible = mkBoolPreference(SHARED_PREFS_TERMINAL_ALWAYS_VISIBLE, false) val networkUseSocksProxy = mkBoolPreference(SHARED_PREFS_NETWORK_USE_SOCKS_PROXY, false) + val networkShowSubscriptionPercentage = mkBoolPreference(SHARED_PREFS_NETWORK_SHOW_SUBSCRIPTION_PERCENTAGE, false) val networkProxyHostPort = mkStrPreference(SHARED_PREFS_NETWORK_PROXY_HOST_PORT, "localhost:9050") private val _networkSessionMode = mkStrPreference(SHARED_PREFS_NETWORK_SESSION_MODE, TransportSessionMode.default.name) val networkSessionMode: SharedPreference = SharedPreference( @@ -338,6 +339,7 @@ class AppPreferences { private const val SHARED_PREFS_SHOW_SLOW_API_CALLS = "ShowSlowApiCalls" private const val SHARED_PREFS_TERMINAL_ALWAYS_VISIBLE = "TerminalAlwaysVisible" private const val SHARED_PREFS_NETWORK_USE_SOCKS_PROXY = "NetworkUseSocksProxy" + private const val SHARED_PREFS_NETWORK_SHOW_SUBSCRIPTION_PERCENTAGE = "ShowSubscriptionPercentage" private const val SHARED_PREFS_NETWORK_PROXY_HOST_PORT = "NetworkProxyHostPort" private const val SHARED_PREFS_NETWORK_SESSION_MODE = "NetworkSessionMode" private const val SHARED_PREFS_NETWORK_SMP_PROXY_MODE = "NetworkSMPProxyMode" @@ -411,6 +413,18 @@ object ChatController { fun hasChatCtrl() = ctrl != -1L && ctrl != null + suspend fun getAgentServersSummary(rh: Long?): PresentedServersSummary? { + val userId = currentUserId("getAgentServersSummary") + + val r = sendCmd(rh, CC.GetAgentServersSummary(userId), log = false) + + if (r is CR.AgentServersSummary) return r.serversSummary + Log.e(TAG, "getAgentServersSummary bad response: ${r.responseType} ${r.details}") + return null + } + + suspend fun resetAgentServersStats(rh: Long?): Boolean = sendCommandOkResp(rh, CC.ResetAgentServersStats()) + private suspend fun currentUserId(funcName: String): Long = changingActiveUserMutex.withLock { val userId = chatModel.currentUser.value?.userId if (userId == null) { @@ -569,20 +583,24 @@ object ChatController { } } - suspend fun sendCmd(rhId: Long?, cmd: CC, otherCtrl: ChatCtrl? = null): CR { + suspend fun sendCmd(rhId: Long?, cmd: CC, otherCtrl: ChatCtrl? = null, log: Boolean = true): CR { val ctrl = otherCtrl ?: ctrl ?: throw Exception("Controller is not initialized") return withContext(Dispatchers.IO) { val c = cmd.cmdString - chatModel.addTerminalItem(TerminalItem.cmd(rhId, cmd.obfuscated)) - Log.d(TAG, "sendCmd: ${cmd.cmdType}") + if (log) { + chatModel.addTerminalItem(TerminalItem.cmd(rhId, cmd.obfuscated)) + Log.d(TAG, "sendCmd: ${cmd.cmdType}") + } val json = if (rhId == null) chatSendCmd(ctrl, c) else chatSendRemoteCmd(ctrl, rhId.toInt(), c) val r = APIResponse.decodeStr(json) - Log.d(TAG, "sendCmd response type ${r.resp.responseType}") - if (r.resp is CR.Response || r.resp is CR.Invalid) { - Log.d(TAG, "sendCmd response json $json") + if (log) { + Log.d(TAG, "sendCmd response type ${r.resp.responseType}") + if (r.resp is CR.Response || r.resp is CR.Invalid) { + Log.d(TAG, "sendCmd response json $json") + } + chatModel.addTerminalItem(TerminalItem.resp(rhId, r.resp)) } - chatModel.addTerminalItem(TerminalItem.resp(rhId, r.resp)) r.resp } } @@ -920,6 +938,14 @@ object ChatController { } } + suspend fun reconnectServer(rh: Long?, server: String): Boolean { + val userId = currentUserId("reconnectServer") + + return sendCommandOkResp(rh, CC.ReconnectServer(userId, server)) + } + + suspend fun reconnectAllServers(rh: Long?): Boolean = sendCommandOkResp(rh, CC.ReconnectAllServers()) + suspend fun apiSetSettings(rh: Long?, type: ChatType, id: Long, settings: ChatSettings): Boolean { val r = sendCmd(rh, CC.APISetChatSettings(type, id, settings)) return when (r) { @@ -2577,6 +2603,8 @@ sealed class CC { class APISetNetworkConfig(val networkConfig: NetCfg): CC() class APIGetNetworkConfig: CC() class APISetNetworkInfo(val networkInfo: UserNetworkInfo): CC() + class ReconnectServer(val userId: Long, val server: String): CC() + class ReconnectAllServers: CC() class APISetChatSettings(val type: ChatType, val id: Long, val chatSettings: ChatSettings): CC() class ApiSetMemberSettings(val groupId: Long, val groupMemberId: Long, val memberSettings: GroupMemberSettings): CC() class APIContactInfo(val contactId: Long): CC() @@ -2648,6 +2676,8 @@ sealed class CC { class ApiStandaloneFileInfo(val url: String): CC() // misc class ShowVersion(): CC() + class ResetAgentServersStats(): CC() + class GetAgentServersSummary(val userId: Long): CC() val cmdString: String get() = when (this) { is Console -> cmd @@ -2724,6 +2754,8 @@ sealed class CC { is APISetNetworkConfig -> "/_network ${json.encodeToString(networkConfig)}" is APIGetNetworkConfig -> "/network" is APISetNetworkInfo -> "/_network info ${json.encodeToString(networkInfo)}" + is ReconnectServer -> "/reconnect $userId $server" + is ReconnectAllServers -> "/reconnect" is APISetChatSettings -> "/_settings ${chatRef(type, id)} ${json.encodeToString(chatSettings)}" is ApiSetMemberSettings -> "/_member settings #$groupId $groupMemberId ${json.encodeToString(memberSettings)}" is APIContactInfo -> "/_info @$contactId" @@ -2804,6 +2836,8 @@ sealed class CC { is ApiDownloadStandaloneFile -> "/_download $userId $url ${file.filePath}" is ApiStandaloneFileInfo -> "/_download info $url" is ShowVersion -> "/version" + is ResetAgentServersStats -> "/reset servers stats" + is GetAgentServersSummary -> "/get servers summary $userId" } val cmdType: String get() = when (this) { @@ -2864,6 +2898,8 @@ sealed class CC { is APISetNetworkConfig -> "apiSetNetworkConfig" is APIGetNetworkConfig -> "apiGetNetworkConfig" is APISetNetworkInfo -> "apiSetNetworkInfo" + is ReconnectServer -> "reconnectServer" + is ReconnectAllServers -> "reconnectAllServers" is APISetChatSettings -> "apiSetChatSettings" is ApiSetMemberSettings -> "apiSetMemberSettings" is APIContactInfo -> "apiContactInfo" @@ -2933,6 +2969,8 @@ sealed class CC { is ApiDownloadStandaloneFile -> "apiDownloadStandaloneFile" is ApiStandaloneFileInfo -> "apiStandaloneFileInfo" is ShowVersion -> "showVersion" + is ResetAgentServersStats -> "resetAgentServersStats" + is GetAgentServersSummary -> "getAgentServersSummary" } class ItemRange(val from: Long, val to: Long) @@ -3203,7 +3241,7 @@ data class NetCfg( val tcpKeepAlive: KeepAliveOpts?, val smpPingInterval: Long, // microseconds val smpPingCount: Int, - val logTLSErrors: Boolean = false + val logTLSErrors: Boolean = false, ) { val useSocksProxy: Boolean get() = socksProxy != null val enableKeepAlive: Boolean get() = tcpKeepAlive != null @@ -3428,6 +3466,154 @@ data class TimedMessagesPreference( } } +@Serializable +data class PresentedServersSummary( + val statsStartedAt: Instant, + val allUsersSMP: SMPServersSummary, + val allUsersXFTP: XFTPServersSummary, + val currentUserSMP: SMPServersSummary, + val currentUserXFTP: XFTPServersSummary +) + +@Serializable +data class SMPServersSummary( + val smpTotals: SMPTotals, + val currentlyUsedSMPServers: List, + val previouslyUsedSMPServers: List, + val onlyProxiedSMPServers: List +) + +@Serializable +data class SMPTotals( + val sessions: ServerSessions, + val subs: SMPServerSubs, + val stats: AgentSMPServerStatsData +) + +@Serializable +data class SMPServerSummary( + val smpServer: String, + val known: Boolean? = null, + val sessions: ServerSessions? = null, + val subs: SMPServerSubs? = null, + val stats: AgentSMPServerStatsData? = null +) { + val hasSubs: Boolean + get() = subs != null + + val sessionsOrNew: ServerSessions + get() = sessions ?: ServerSessions.newServerSessions + + val subsOrNew: SMPServerSubs + get() = subs ?: SMPServerSubs.newSMPServerSubs +} + +@Serializable +data class ServerSessions( + val ssConnected: Int, + val ssErrors: Int, + val ssConnecting: Int +) { + companion object { + val newServerSessions = ServerSessions( + ssConnected = 0, + ssErrors = 0, + ssConnecting = 0 + ) + } +} + +@Serializable +data class SMPServerSubs( + val ssActive: Int, + val ssPending: Int +) { + companion object { + val newSMPServerSubs = SMPServerSubs( + ssActive = 0, + ssPending = 0 + ) + } + + val total: Int + get() = ssActive + ssPending + + val shareOfActive: Float + get() = if (total != 0) ssActive.toFloat() / total else 0f +} + +@Serializable +data class AgentSMPServerStatsData( + val _sentDirect: Int, + val _sentViaProxy: Int, + val _sentProxied: Int, + val _sentDirectAttempts: Int, + val _sentViaProxyAttempts: Int, + val _sentProxiedAttempts: Int, + val _sentAuthErrs: Int, + val _sentQuotaErrs: Int, + val _sentExpiredErrs: Int, + val _sentOtherErrs: Int, + val _recvMsgs: Int, + val _recvDuplicates: Int, + val _recvCryptoErrs: Int, + val _recvErrs: Int, + val _ackMsgs: Int, + val _ackAttempts: Int, + val _ackNoMsgErrs: Int, + val _ackOtherErrs: Int, + val _connCreated: Int, + val _connSecured: Int, + val _connCompleted: Int, + val _connDeleted: Int, + val _connDelAttempts: Int, + val _connDelErrs: Int, + val _connSubscribed: Int, + val _connSubAttempts: Int, + val _connSubIgnored: Int, + val _connSubErrs: Int +) + +@Serializable +data class XFTPServersSummary( + val xftpTotals: XFTPTotals, + val currentlyUsedXFTPServers: List, + val previouslyUsedXFTPServers: List +) + +@Serializable +data class XFTPTotals( + val sessions: ServerSessions, + val stats: AgentXFTPServerStatsData +) + +@Serializable +data class XFTPServerSummary( + val xftpServer: String, + val known: Boolean? = null, + val sessions: ServerSessions? = null, + val stats: AgentXFTPServerStatsData? = null, + val rcvInProgress: Boolean, + val sndInProgress: Boolean, + val delInProgress: Boolean +) {} + +@Serializable +data class AgentXFTPServerStatsData( + val _uploads: Int, + val _uploadsSize: Long, + val _uploadAttempts: Int, + val _uploadErrs: Int, + val _downloads: Int, + val _downloadsSize: Long, + val _downloadAttempts: Int, + val _downloadAuthErrs: Int, + val _downloadErrs: Int, + val _deletions: Int, + val _deleteAttempts: Int, + val _deleteErrs: Int +) + sealed class CustomTimeUnit { object Second: CustomTimeUnit() object Minute: CustomTimeUnit() @@ -4439,6 +4625,7 @@ sealed class CR { @Serializable @SerialName("chatError") class ChatRespError(val user_: UserRef?, val chatError: ChatError): CR() @Serializable @SerialName("archiveImported") class ArchiveImported(val archiveErrors: List): CR() @Serializable @SerialName("appSettings") class AppSettingsR(val appSettings: AppSettings): CR() + @Serializable @SerialName("agentServersSummary") class AgentServersSummary(val user: UserRef, val serversSummary: PresentedServersSummary): CR() // general @Serializable class Response(val type: String, val json: String): CR() @Serializable class Invalid(val str: String): CR() @@ -4598,6 +4785,7 @@ sealed class CR { is ContactPQAllowed -> "contactPQAllowed" is ContactPQEnabled -> "contactPQEnabled" is VersionInfo -> "versionInfo" + is AgentServersSummary -> "agentServersSummary" is CmdOk -> "cmdOk" is ChatCmdError -> "chatCmdError" is ChatRespError -> "chatError" @@ -4776,6 +4964,7 @@ sealed class CR { is RemoteCtrlStopped -> "rcsState: $rcsState\nrcsStopReason: $rcStopReason" is ContactPQAllowed -> withUser(user, "contact: ${contact.id}\npqEncryption: $pqEncryption") is ContactPQEnabled -> withUser(user, "contact: ${contact.id}\npqEnabled: $pqEnabled") + is AgentServersSummary -> withUser(user, json.encodeToString(serversSummary)) is VersionInfo -> "version ${json.encodeToString(versionInfo)}\n\n" + "chat migrations: ${json.encodeToString(chatMigrations.map { it.upName })}\n\n" + "agent migrations: ${json.encodeToString(agentMigrations.map { it.upName })}" diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt index d03b8a708d..3417333370 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt @@ -35,7 +35,10 @@ import chat.simplex.res.MR import kotlinx.coroutines.* import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.serialization.json.Json import java.net.URI +import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds @Composable fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerformLA: (Boolean) -> Unit, stopped: Boolean) { @@ -69,7 +72,7 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf val searchText = rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue("")) } val scope = rememberCoroutineScope() val (userPickerState, scaffoldState ) = settingsState - Scaffold(topBar = { Box(Modifier.padding(end = endPadding)) { ChatListToolbar(searchText, scaffoldState.drawerState, userPickerState, stopped)} }, + Scaffold(topBar = { Box(Modifier.padding(end = endPadding)) { ChatListToolbar(scaffoldState.drawerState, userPickerState, stopped)} }, scaffoldState = scaffoldState, drawerContent = { tryOrShowError("Settings", error = { ErrorSettingsView() }) { @@ -181,8 +184,10 @@ private fun ConnectButton(text: String, onClick: () -> Unit) { } @Composable -private fun ChatListToolbar(searchInList: State, drawerState: DrawerState, userPickerState: MutableStateFlow, stopped: Boolean) { +private fun ChatListToolbar(drawerState: DrawerState, userPickerState: MutableStateFlow, stopped: Boolean) { + val serversSummary: MutableState = remember { mutableStateOf(null) } val barButtons = arrayListOf<@Composable RowScope.() -> Unit>() + if (stopped) { barButtons.add { IconButton(onClick = { @@ -200,6 +205,7 @@ private fun ChatListToolbar(searchInList: State, drawerState: Dr } } val scope = rememberCoroutineScope() + val clipboard = LocalClipboardManager.current DefaultTopAppBar( navigationButton = { if (chatModel.users.isEmpty() && !chatModel.desktopNoUserNoRemote) { @@ -219,20 +225,33 @@ private fun ChatListToolbar(searchInList: State, drawerState: Dr } }, title = { - Row(verticalAlignment = Alignment.CenterVertically) { + Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(DEFAULT_SPACE_AFTER_ICON)) { Text( stringResource(MR.strings.your_chats), color = MaterialTheme.colors.onBackground, fontWeight = FontWeight.SemiBold, ) - if (chatModel.chats.size > 0) { - val enabled = remember { derivedStateOf { searchInList.value.text.isEmpty() } } - if (enabled.value) { - ToggleFilterEnabledButton() - } else { - ToggleFilterDisabledButton() + SubscriptionStatusIndicator( + serversSummary = serversSummary, + click = { + ModalManager.start.closeModals() + ModalManager.start.showModalCloseable( + endButtons = { + val summary = serversSummary.value + if (summary != null) { + ShareButton { + val json = Json { + prettyPrint = true + } + + val text = json.encodeToString(PresentedServersSummary.serializer(), summary) + clipboard.shareText(text) + } + } + } + ) { ServersSummaryView(chatModel.currentRemoteHost.value, serversSummary) } } - } + ) } }, onTitleClick = null, @@ -243,6 +262,53 @@ private fun ChatListToolbar(searchInList: State, drawerState: Dr Divider(Modifier.padding(top = AppBarHeight)) } +@Composable +fun SubscriptionStatusIndicator(serversSummary: MutableState, click: (() -> Unit)) { + var subs by remember { mutableStateOf(SMPServerSubs.newSMPServerSubs) } + var sess by remember { mutableStateOf(ServerSessions.newServerSessions) } + var timer: Job? by remember { mutableStateOf(null) } + + val fetchInterval: Duration = 1.seconds + + val scope = rememberCoroutineScope() + + fun setServersSummary() { + withBGApi { + serversSummary.value = chatModel.controller.getAgentServersSummary(chatModel.remoteHostId()) + + serversSummary.value?.let { + subs = it.allUsersSMP.smpTotals.subs + sess = it.allUsersSMP.smpTotals.sessions + } + } + } + + LaunchedEffect(Unit) { + setServersSummary() + timer = timer ?: scope.launch { + while (true) { + delay(fetchInterval.inWholeMilliseconds) + setServersSummary() + } + } + } + + fun stopTimer() { + timer?.cancel() + timer = null + } + + DisposableEffect(Unit) { + onDispose { + stopTimer() + } + } + + SimpleButtonFrame(click = click) { + SubscriptionStatusIndicatorView(subs = subs, sess = sess) + } +} + @Composable fun UserProfileButton(image: String?, allRead: Boolean, onButtonClicked: () -> Unit) { Row(verticalAlignment = Alignment.CenterVertically) { @@ -292,27 +358,11 @@ private fun ToggleFilterEnabledButton() { Icon( painterResource(MR.images.ic_filter_list), null, - tint = if (pref.state.value) MaterialTheme.colors.background else MaterialTheme.colors.primary, + tint = if (pref.state.value) MaterialTheme.colors.background else MaterialTheme.colors.secondary, modifier = Modifier .padding(3.dp) .background(color = if (pref.state.value) MaterialTheme.colors.primary else Color.Unspecified, shape = RoundedCornerShape(50)) - .border(width = 1.dp, color = MaterialTheme.colors.primary, shape = RoundedCornerShape(50)) - .padding(3.dp) - .size(16.dp) - ) - } -} - -@Composable -private fun ToggleFilterDisabledButton() { - IconButton({}, enabled = false) { - Icon( - painterResource(MR.images.ic_filter_list), - null, - tint = MaterialTheme.colors.secondary, - modifier = Modifier - .padding(3.dp) - .border(width = 1.dp, color = MaterialTheme.colors.secondary, shape = RoundedCornerShape(50)) + .border(width = 1.dp, color = if (pref.state.value) MaterialTheme.colors.primary else Color.Unspecified, shape = RoundedCornerShape(50)) .padding(3.dp) .size(16.dp) ) @@ -357,33 +407,11 @@ private fun ChatListSearchBar(listState: LazyListState, searchText: MutableState hideSearchOnBack() } } else { - Row { - val padding = if (appPlatform.isDesktop) 0.dp else 7.dp - val clipboard = LocalClipboardManager.current - val clipboardHasText = remember(focused) { chatModel.clipboardHasText }.value - if (clipboardHasText) { - IconButton( - onClick = { searchText.value = searchText.value.copy(clipboard.getText()?.text ?: return@IconButton) }, - Modifier.size(30.dp).desktopPointerHoverIconHand() - ) { - Icon(painterResource(MR.images.ic_article), null, tint = MaterialTheme.colors.secondary) - } - } - Spacer(Modifier.width(padding)) - IconButton( - onClick = { - val fixedRhId = chatModel.currentRemoteHost.value - ModalManager.center.closeModals() - ModalManager.center.showModalCloseable { close -> - NewChatView(fixedRhId, selection = NewChatOption.CONNECT, showQRCodeScanner = true, close = close) - } - }, - Modifier.size(30.dp).desktopPointerHoverIconHand() - ) { - Icon(painterResource(MR.images.ic_qr_code), null, tint = MaterialTheme.colors.secondary) - } - Spacer(Modifier.width(padding)) + val padding = if (appPlatform.isDesktop) 0.dp else 7.dp + if (chatModel.chats.size > 0) { + ToggleFilterEnabledButton() } + Spacer(Modifier.width(padding)) } val focusManager = LocalFocusManager.current val keyboardState = getKeyboardState() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ServersSummaryView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ServersSummaryView.kt new file mode 100644 index 0000000000..22478c18f9 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ServersSummaryView.kt @@ -0,0 +1,977 @@ +package chat.simplex.common.views.chatlist + +import InfoRow +import InfoRowTwoValues +import SectionBottomSpacer +import SectionDividerSpaced +import SectionItemView +import SectionTextFooter +import SectionView +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.foundation.text.selection.SelectionContainer +import androidx.compose.material.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +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.model.AgentSMPServerStatsData +import chat.simplex.common.model.AgentXFTPServerStatsData +import chat.simplex.common.model.ChatController.chatModel +import chat.simplex.common.model.ChatModel.controller +import chat.simplex.common.model.PresentedServersSummary +import chat.simplex.common.model.RemoteHostInfo +import chat.simplex.common.model.SMPServerSubs +import chat.simplex.common.model.SMPServerSummary +import chat.simplex.common.model.SMPTotals +import chat.simplex.common.model.ServerAddress.Companion.parseServerAddress +import chat.simplex.common.model.ServerProtocol +import chat.simplex.common.model.ServerSessions +import chat.simplex.common.model.XFTPServerSummary +import chat.simplex.common.model.localTimestamp +import chat.simplex.common.platform.ColumnWithScrollBar +import chat.simplex.common.platform.appPlatform +import chat.simplex.common.ui.theme.* +import chat.simplex.common.views.helpers.* +import chat.simplex.common.views.usersettings.ProtocolServersView +import chat.simplex.res.MR +import dev.icerock.moko.resources.compose.painterResource +import dev.icerock.moko.resources.compose.stringResource +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.datetime.Instant +import numOrDash +import java.text.DecimalFormat +import kotlin.math.floor +import kotlin.math.roundToInt + +enum class SubscriptionColorType { + ACTIVE, ACTIVE_SOCKS_PROXY, DISCONNECTED, ACTIVE_DISCONNECTED +} + +data class SubscriptionStatus( + val color: SubscriptionColorType, + val variableValue: Float, + val opacity: Float, + val statusPercent: Float +) + +fun subscriptionStatusColorAndPercentage( + online: Boolean, + socksProxy: String?, + subs: SMPServerSubs, + sess: ServerSessions +): SubscriptionStatus { + + fun roundedToQuarter(n: Float): Float = when { + n >= 1 -> 1f + n <= 0 -> 0f + else -> (n * 4).roundToInt() / 4f + } + + val activeColor: SubscriptionColorType = if (socksProxy != null) SubscriptionColorType.ACTIVE_SOCKS_PROXY else SubscriptionColorType.ACTIVE + val noConnColorAndPercent = SubscriptionStatus(SubscriptionColorType.DISCONNECTED, 1f, 1f, 0f) + val activeSubsRounded = roundedToQuarter(subs.shareOfActive) + + return if (online && subs.total > 0) { + if (subs.ssActive == 0) { + if (sess.ssConnected == 0) + noConnColorAndPercent + else + SubscriptionStatus(activeColor, activeSubsRounded, subs.shareOfActive, subs.shareOfActive) + } else { // ssActive > 0 + if (sess.ssConnected == 0) + // This would mean implementation error + SubscriptionStatus(SubscriptionColorType.ACTIVE_DISCONNECTED, activeSubsRounded, subs.shareOfActive, subs.shareOfActive) + else + SubscriptionStatus(activeColor, activeSubsRounded, subs.shareOfActive, subs.shareOfActive) + } + } else noConnColorAndPercent +} + +@Composable +private fun SubscriptionStatusIndicatorPercentage(percentageText: String) { + Text( + percentageText, + color = MaterialTheme.colors.secondary, + fontSize = 12.sp, + style = MaterialTheme.typography.caption + ) +} + +@Composable +fun SubscriptionStatusIndicatorView(subs: SMPServerSubs, sess: ServerSessions, leadingPercentage: Boolean = false) { + val netCfg = rememberUpdatedState(chatModel.controller.getNetCfg()) + val statusColorAndPercentage = subscriptionStatusColorAndPercentage(chatModel.networkInfo.value.online, netCfg.value.socksProxy, subs, sess) + val pref = remember { chatModel.controller.appPrefs.networkShowSubscriptionPercentage } + val percentageText = "${(floor(statusColorAndPercentage.statusPercent * 100)).toInt()}%" + + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(DEFAULT_SPACE_AFTER_ICON) + ) { + if (pref.state.value && leadingPercentage) SubscriptionStatusIndicatorPercentage(percentageText) + SubscriptionStatusIcon( + color = when(statusColorAndPercentage.color) { + SubscriptionColorType.ACTIVE -> MaterialTheme.colors.primary + SubscriptionColorType.ACTIVE_SOCKS_PROXY -> Indigo + SubscriptionColorType.ACTIVE_DISCONNECTED -> WarningOrange + SubscriptionColorType.DISCONNECTED -> MaterialTheme.colors.secondary + }, + modifier = Modifier.size(16.dp), + variableValue = statusColorAndPercentage.variableValue) + if (pref.state.value && !leadingPercentage) SubscriptionStatusIndicatorPercentage(percentageText) + } +} + +enum class PresentedUserCategory { + CURRENT_USER, ALL_USERS +} + +enum class PresentedServerType { + SMP, XFTP +} + +@Composable +private fun ServerSessionsView(sess: ServerSessions) { + SectionView(generalGetString(MR.strings.servers_info_transport_sessions_section_header).uppercase()) { + InfoRow( + generalGetString(MR.strings.servers_info_sessions_connected), + numOrDash(sess.ssConnected) + ) + InfoRow( + generalGetString(MR.strings.servers_info_sessions_errors), + numOrDash(sess.ssErrors) + ) + InfoRow( + generalGetString(MR.strings.servers_info_sessions_connecting), + numOrDash(sess.ssConnecting) + ) + } +} + +private fun serverAddress(server: String): String { + val address = parseServerAddress(server) + + return address?.hostnames?.first() ?: server +} + +@Composable +private fun SMPServerView(srvSumm: SMPServerSummary, statsStartedAt: Instant, rh: RemoteHostInfo?) { + SectionItemView( + click = { + ModalManager.start.showCustomModal { close -> + SMPServerSummaryView( + rh = rh, + close = close, + summary = srvSumm, + statsStartedAt = statsStartedAt + ) + } + } + ) { + Text( + serverAddress(srvSumm.smpServer), + modifier = Modifier.weight(10f, fill = true) + ) + if (srvSumm.subs != null) { + Spacer(Modifier.fillMaxWidth().weight(1f)) + SubscriptionStatusIndicatorView(subs = srvSumm.subs, sess = srvSumm.sessionsOrNew, leadingPercentage = true) + } else if (srvSumm.sessions != null) { + Spacer(Modifier.fillMaxWidth().weight(1f)) + Icon(painterResource(MR.images.ic_arrow_upward), contentDescription = null, tint = SessIconColor(srvSumm.sessions)) + } + } +} + +@Composable +private fun SessIconColor(sess: ServerSessions): Color { + val online = chatModel.networkInfo.value.online + return if (online && sess.ssConnected > 0) SessionActiveColor() else MaterialTheme.colors.secondary +} + +@Composable +private fun SessionActiveColor(): Color { + val netCfg = rememberUpdatedState(chatModel.controller.getNetCfg()) + return if (netCfg.value.socksProxy != null) Indigo else MaterialTheme.colors.primary +} + +@Composable +private fun SMPServersListView(servers: List, statsStartedAt: Instant, header: String? = null, footer: String? = null, rh: RemoteHostInfo?) { + val sortedServers = servers.sortedWith(compareBy { !it.hasSubs } + .thenBy { serverAddress(it.smpServer) }) + + SectionView(header) { + sortedServers.map { svr -> SMPServerView(srvSumm = svr, statsStartedAt = statsStartedAt, rh = rh) } + } + if (footer != null) { + SectionTextFooter( + footer + ) + } +} + +fun prettySize(sizeInKB: Long): String { + if (sizeInKB == 0L) { + return "-" + } + + val sizeInBytes = sizeInKB * 1024 + val units = arrayOf("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") + var size = sizeInBytes.toDouble() + var unitIndex = 0 + + while (size >= 1024 && unitIndex < units.size - 1) { + size /= 1024 + unitIndex++ + } + + val formatter = DecimalFormat("#,##0.#") + return "${formatter.format(size)} ${units[unitIndex]}" +} + +@Composable +private fun XFTPServerView(srvSumm: XFTPServerSummary, statsStartedAt: Instant, rh: RemoteHostInfo?) { + SectionItemView( + click = { + ModalManager.start.showCustomModal { close -> + XFTPServerSummaryView( + rh = rh, + close = close, + summary = srvSumm, + statsStartedAt = statsStartedAt + ) + } + } + ) { + Text( + serverAddress(srvSumm.xftpServer), + modifier = Modifier.weight(10f, fill = true) + ) + if (srvSumm.rcvInProgress || srvSumm.sndInProgress || srvSumm.delInProgress) { + Spacer(Modifier.fillMaxWidth().weight(1f)) + XFTPServerInProgressIcon(srvSumm) + } + } +} + +@Composable +private fun XFTPServerInProgressIcon(srvSumm: XFTPServerSummary) { + return when { + srvSumm.rcvInProgress && !srvSumm.sndInProgress && !srvSumm.delInProgress -> Icon(painterResource(MR.images.ic_arrow_downward),"download", tint = SessionActiveColor()) + !srvSumm.rcvInProgress && srvSumm.sndInProgress && !srvSumm.delInProgress -> Icon(painterResource(MR.images.ic_arrow_upward), "upload", tint = SessionActiveColor()) + !srvSumm.rcvInProgress && !srvSumm.sndInProgress && srvSumm.delInProgress -> Icon(painterResource(MR.images.ic_delete), "deletion", tint = SessionActiveColor()) + else -> Icon(painterResource(MR.images.ic_expand_all), "upload and download", tint = SessionActiveColor()) + } +} + +@Composable +private fun XFTPServersListView(servers: List, statsStartedAt: Instant, header: String? = null, rh: RemoteHostInfo?) { + val sortedServers = servers.sortedBy { serverAddress(it.xftpServer) } + + SectionView(header) { + sortedServers.map { svr -> XFTPServerView(svr, statsStartedAt, rh) } + } +} + +@Composable +private fun SMPStatsView(stats: AgentSMPServerStatsData, statsStartedAt: Instant, remoteHostInfo: RemoteHostInfo?) { + SectionView(generalGetString(MR.strings.servers_info_statistics_section_header).uppercase()) { + InfoRow( + generalGetString(MR.strings.servers_info_messages_sent), + numOrDash(stats._sentDirect + stats._sentViaProxy) + ) + InfoRow( + generalGetString(MR.strings.servers_info_messages_received), + numOrDash(stats._recvMsgs) + ) + SectionItemView( + click = { + ModalManager.start.showCustomModal { close -> DetailedSMPStatsView( + rh = remoteHostInfo, + close = close, + stats = stats, + statsStartedAt = statsStartedAt) + } + } + ) { + Text(text = generalGetString(MR.strings.servers_info_details), color = MaterialTheme.colors.onBackground) + } + } + SectionTextFooter( + String.format(stringResource(MR.strings.servers_info_private_data_disclaimer), localTimestamp(statsStartedAt)) + ) +} + +@Composable +private fun SMPSubscriptionsSection(totals: SMPTotals) { + Column { + Row( + Modifier.padding(start = DEFAULT_PADDING, bottom = 5.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(DEFAULT_SPACE_AFTER_ICON * 2) + ) { + Text( + generalGetString(MR.strings.servers_info_subscriptions_section_header).uppercase(), + color = MaterialTheme.colors.secondary, + style = MaterialTheme.typography.body2, + fontSize = 12.sp + ) + SubscriptionStatusIndicatorView(totals.subs, totals.sessions) + } + Column(Modifier.padding(PaddingValues()).fillMaxWidth()) { + InfoRow( + generalGetString(MR.strings.servers_info_subscriptions_connections_subscribed), + numOrDash(totals.subs.ssActive) + ) + InfoRow( + generalGetString(MR.strings.servers_info_subscriptions_total), + numOrDash(totals.subs.total) + ) + } + } +} + +@Composable +private fun SMPSubscriptionsSection(subs: SMPServerSubs, summary: SMPServerSummary, rh: RemoteHostInfo?) { + Column { + Row( + Modifier.padding(start = DEFAULT_PADDING, bottom = 5.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(DEFAULT_SPACE_AFTER_ICON * 2) + ) { + Text( + generalGetString(MR.strings.servers_info_subscriptions_section_header).uppercase(), + color = MaterialTheme.colors.secondary, + style = MaterialTheme.typography.body2, + fontSize = 12.sp + ) + SubscriptionStatusIndicatorView(subs, summary.sessionsOrNew) + } + Column(Modifier.padding(PaddingValues()).fillMaxWidth()) { + InfoRow( + generalGetString(MR.strings.servers_info_subscriptions_connections_subscribed), + numOrDash(subs.ssActive) + ) + InfoRow( + generalGetString(MR.strings.servers_info_subscriptions_connections_pending), + numOrDash(subs.ssPending) + ) + InfoRow( + generalGetString(MR.strings.servers_info_subscriptions_total), + numOrDash(subs.total) + ) + ReconnectServerButton(rh, summary.smpServer) + } + } +} + +@Composable +private fun ReconnectServerButton(rh: RemoteHostInfo?, server: String) { + SectionItemView(click = { reconnectServerAlert(rh, server) }) { + Text( + stringResource(MR.strings.reconnect), + color = MaterialTheme.colors.primary + ) + } +} + +private fun reconnectServerAlert(rh: RemoteHostInfo?, server: String) { + AlertManager.shared.showAlertDialog( + title = generalGetString(MR.strings.servers_info_reconnect_server_title), + text = generalGetString(MR.strings.servers_info_reconnect_server_message), + onConfirm = { + withBGApi { + val success = controller.reconnectServer(rh?.remoteHostId, server) + + if (!success) { + AlertManager.shared.showAlertMsg( + title = generalGetString(MR.strings.servers_info_modal_error_title), + text = generalGetString(MR.strings.servers_info_reconnect_server_error) + ) + } + } + } + ) +} + +@Composable +fun XFTPStatsView(stats: AgentXFTPServerStatsData, statsStartedAt: Instant, rh: RemoteHostInfo?) { + SectionView(generalGetString(MR.strings.servers_info_statistics_section_header).uppercase()) { + InfoRow( + generalGetString(MR.strings.servers_info_uploaded), + prettySize(stats._uploadsSize) + ) + InfoRow( + generalGetString(MR.strings.servers_info_downloaded), + prettySize(stats._downloadsSize) + ) + SectionItemView ( + click = { + ModalManager.start.showCustomModal { close -> DetailedXFTPStatsView( + rh = rh, + close = close, + stats = stats, + statsStartedAt = statsStartedAt) + } + } + ) { + Text(text = generalGetString(MR.strings.servers_info_details), color = MaterialTheme.colors.onBackground) + } + } + SectionTextFooter( + String.format(stringResource(MR.strings.servers_info_private_data_disclaimer), localTimestamp(statsStartedAt)) + ) +} + +@Composable +private fun IndentedInfoRow(title: String, desc: String) { + InfoRow(title, desc, padding = PaddingValues(start = 24.dp + DEFAULT_PADDING, end = DEFAULT_PADDING)) +} + +@Composable +fun DetailedSMPStatsLayout(stats: AgentSMPServerStatsData, statsStartedAt: Instant) { + SectionView(generalGetString(MR.strings.servers_info_detailed_statistics_sent_messages_header).uppercase()) { + InfoRow(generalGetString(MR.strings.servers_info_detailed_statistics_sent_messages_total), numOrDash(stats._sentDirect + stats._sentViaProxy)) + InfoRowTwoValues(generalGetString(MR.strings.sent_directly), generalGetString(MR.strings.attempts_label), stats._sentDirect, stats._sentDirectAttempts) + InfoRowTwoValues(generalGetString(MR.strings.sent_via_proxy), generalGetString(MR.strings.attempts_label), stats._sentViaProxy, stats._sentViaProxyAttempts) + InfoRowTwoValues(generalGetString(MR.strings.proxied), generalGetString(MR.strings.attempts_label), stats._sentProxied, stats._sentProxiedAttempts) + SectionItemView { + Text(generalGetString(MR.strings.send_errors), color = MaterialTheme.colors.onBackground) + } + IndentedInfoRow("AUTH", numOrDash(stats._sentAuthErrs)) + IndentedInfoRow("QUOTA", numOrDash(stats._sentQuotaErrs)) + IndentedInfoRow(generalGetString(MR.strings.expired_label), numOrDash(stats._sentExpiredErrs)) + IndentedInfoRow(generalGetString(MR.strings.other_label), numOrDash(stats._sentOtherErrs)) + } + + SectionDividerSpaced() + + SectionView(generalGetString(MR.strings.servers_info_detailed_statistics_received_messages_header).uppercase()) { + InfoRow(generalGetString(MR.strings.servers_info_detailed_statistics_received_total), numOrDash(stats._recvMsgs)) + SectionItemView { + Text(generalGetString(MR.strings.servers_info_detailed_statistics_receive_errors), color = MaterialTheme.colors.onBackground) + } + IndentedInfoRow(generalGetString(MR.strings.duplicates_label), numOrDash(stats._recvDuplicates)) + IndentedInfoRow(generalGetString(MR.strings.decryption_errors), numOrDash(stats._recvCryptoErrs)) + IndentedInfoRow(generalGetString(MR.strings.other_errors), numOrDash(stats._recvErrs)) + InfoRowTwoValues(generalGetString(MR.strings.acknowledged), generalGetString(MR.strings.attempts_label), stats._ackMsgs, stats._ackAttempts) + SectionItemView { + Text(generalGetString(MR.strings.acknowledgement_errors), color = MaterialTheme.colors.onBackground) + } + IndentedInfoRow("NO_MSG errors", numOrDash(stats._ackNoMsgErrs)) + IndentedInfoRow(generalGetString(MR.strings.other_errors), numOrDash(stats._ackOtherErrs)) + } + + SectionDividerSpaced() + + SectionView(generalGetString(MR.strings.connections).uppercase()) { + InfoRow(generalGetString(MR.strings.created), numOrDash(stats._connCreated)) + InfoRow(generalGetString(MR.strings.secured), numOrDash(stats._connSecured)) + InfoRow(generalGetString(MR.strings.completed), numOrDash(stats._connCompleted)) + InfoRowTwoValues(generalGetString(MR.strings.deleted), generalGetString(MR.strings.attempts_label), stats._connDeleted, stats._connDelAttempts) + InfoRow(generalGetString(MR.strings.deletion_errors), numOrDash(stats._connDelErrs)) + InfoRowTwoValues(generalGetString(MR.strings.subscribed), generalGetString(MR.strings.attempts_label), stats._connSubscribed, stats._connSubAttempts) + InfoRow(generalGetString(MR.strings.subscription_results_ignored), numOrDash(stats._connSubIgnored)) + InfoRow(generalGetString(MR.strings.subscription_errors), numOrDash(stats._connSubErrs)) + } + SectionTextFooter( + String.format(stringResource(MR.strings.servers_info_starting_from), localTimestamp(statsStartedAt)) + ) + + SectionBottomSpacer() +} + +@Composable +fun DetailedXFTPStatsLayout(stats: AgentXFTPServerStatsData, statsStartedAt: Instant) { + SectionView(generalGetString(MR.strings.uploaded_files).uppercase()) { + InfoRow(generalGetString(MR.strings.size), prettySize(stats._uploadsSize)) + InfoRowTwoValues(generalGetString(MR.strings.chunks_uploaded), generalGetString(MR.strings.attempts_label), stats._uploads, stats._uploadAttempts) + InfoRow(generalGetString(MR.strings.upload_errors), numOrDash(stats._uploadErrs)) + InfoRowTwoValues(generalGetString(MR.strings.chunks_deleted), generalGetString(MR.strings.attempts_label), stats._deletions, stats._deleteAttempts) + InfoRow(generalGetString(MR.strings.deletion_errors), numOrDash(stats._deleteErrs)) + } + SectionDividerSpaced() + SectionView(generalGetString(MR.strings.downloaded_files).uppercase()) { + InfoRow(generalGetString(MR.strings.size), prettySize(stats._downloadsSize)) + InfoRowTwoValues(generalGetString(MR.strings.chunks_downloaded), generalGetString(MR.strings.attempts_label), stats._downloads, stats._downloadAttempts) + SectionItemView { + Text(generalGetString(MR.strings.download_errors), color = MaterialTheme.colors.onBackground) + } + IndentedInfoRow("AUTH", numOrDash(stats._downloadAuthErrs)) + IndentedInfoRow(generalGetString(MR.strings.other_label), numOrDash(stats._downloadErrs)) + } + SectionTextFooter( + String.format(stringResource(MR.strings.servers_info_starting_from), localTimestamp(statsStartedAt)) + ) + + SectionBottomSpacer() +} + +@Composable +fun XFTPServerSummaryLayout(summary: XFTPServerSummary, statsStartedAt: Instant, rh: RemoteHostInfo?) { + SectionView(generalGetString(MR.strings.server_address).uppercase()) { + SelectionContainer { + Text( + summary.xftpServer, + Modifier.padding(start = DEFAULT_PADDING, top = 5.dp, end = DEFAULT_PADDING, bottom = 10.dp), + style = TextStyle( + fontFamily = FontFamily.Monospace, fontSize = 16.sp, + color = MaterialTheme.colors.secondary + ) + ) + } + if (summary.known == true) { + SectionItemView(click = { + ModalManager.start.showCustomModal { close -> ProtocolServersView(chatModel, rhId = rh?.remoteHostId, ServerProtocol.XFTP, close) } + }) { + Text(generalGetString(MR.strings.open_server_settings_button)) + } + } + + if (summary.stats != null) { + SectionDividerSpaced() + XFTPStatsView(stats = summary.stats, rh = rh, statsStartedAt = statsStartedAt) + } + + if (summary.sessions != null) { + SectionDividerSpaced() + ServerSessionsView(summary.sessions) + } + } + + SectionBottomSpacer() +} + +@Composable +fun SMPServerSummaryLayout(summary: SMPServerSummary, statsStartedAt: Instant, rh: RemoteHostInfo?) { + SectionView(generalGetString(MR.strings.server_address).uppercase()) { + SelectionContainer { + Text( + summary.smpServer, + Modifier.padding(start = DEFAULT_PADDING, top = 5.dp, end = DEFAULT_PADDING, bottom = 10.dp), + style = TextStyle( + fontFamily = FontFamily.Monospace, fontSize = 16.sp, + color = MaterialTheme.colors.secondary + ) + ) + } + if (summary.known == true) { + SectionItemView(click = { + ModalManager.start.showCustomModal { close -> ProtocolServersView(chatModel, rhId = rh?.remoteHostId, ServerProtocol.SMP, close) } + }) { + Text(generalGetString(MR.strings.open_server_settings_button)) + } + } + + if (summary.stats != null) { + SectionDividerSpaced() + SMPStatsView(stats = summary.stats, remoteHostInfo = rh, statsStartedAt = statsStartedAt) + } + + if (summary.subs != null) { + SectionDividerSpaced() + SMPSubscriptionsSection(subs = summary.subs, summary = summary, rh = rh) + } + + if (summary.sessions != null) { + SectionDividerSpaced() + ServerSessionsView(summary.sessions) + } + } + + SectionBottomSpacer() +} + +@Composable +fun ModalData.SMPServerSummaryView( + rh: RemoteHostInfo?, + close: () -> Unit, + summary: SMPServerSummary, + statsStartedAt: Instant +) { + ModalView( + close = close + ) { + ColumnWithScrollBar( + Modifier.fillMaxSize(), + ) { + Box(contentAlignment = Alignment.Center) { + val bottomPadding = DEFAULT_PADDING + AppBarTitle( + stringResource(MR.strings.smp_server), + hostDevice(rh?.remoteHostId), + bottomPadding = bottomPadding + ) + } + SMPServerSummaryLayout(summary, statsStartedAt, rh) + } + } +} + + +@Composable +fun ModalData.DetailedXFTPStatsView( + rh: RemoteHostInfo?, + close: () -> Unit, + stats: AgentXFTPServerStatsData, + statsStartedAt: Instant +) { + ModalView( + close = close + ) { + ColumnWithScrollBar( + Modifier.fillMaxSize(), + ) { + Box(contentAlignment = Alignment.Center) { + val bottomPadding = DEFAULT_PADDING + AppBarTitle( + stringResource(MR.strings.servers_info_detailed_statistics), + hostDevice(rh?.remoteHostId), + bottomPadding = bottomPadding + ) + } + DetailedXFTPStatsLayout(stats, statsStartedAt) + } + } +} + +@Composable +fun ModalData.DetailedSMPStatsView( + rh: RemoteHostInfo?, + close: () -> Unit, + stats: AgentSMPServerStatsData, + statsStartedAt: Instant +) { + ModalView( + close = close + ) { + ColumnWithScrollBar( + Modifier.fillMaxSize(), + ) { + Box(contentAlignment = Alignment.Center) { + val bottomPadding = DEFAULT_PADDING + AppBarTitle( + stringResource(MR.strings.servers_info_detailed_statistics), + hostDevice(rh?.remoteHostId), + bottomPadding = bottomPadding + ) + } + DetailedSMPStatsLayout(stats, statsStartedAt) + } + } +} + +@Composable +fun ModalData.XFTPServerSummaryView( + rh: RemoteHostInfo?, + close: () -> Unit, + summary: XFTPServerSummary, + statsStartedAt: Instant +) { + ModalView( + close = close + ) { + ColumnWithScrollBar( + Modifier.fillMaxSize(), + ) { + Box(contentAlignment = Alignment.Center) { + val bottomPadding = DEFAULT_PADDING + AppBarTitle( + stringResource(MR.strings.xftp_server), + hostDevice(rh?.remoteHostId), + bottomPadding = bottomPadding + ) + } + XFTPServerSummaryLayout(summary, statsStartedAt, rh) + } + } +} + +@Composable +fun ModalData.ServersSummaryView(rh: RemoteHostInfo?, serversSummary: MutableState) { + Column( + Modifier.fillMaxSize(), + ) { + var showUserSelection by remember { mutableStateOf(false) } + val selectedUserCategory = + remember { stateGetOrPut("selectedUserCategory") { PresentedUserCategory.ALL_USERS } } + val selectedServerType = + remember { stateGetOrPut("serverTypeSelection") { PresentedServerType.SMP } } + val scope = rememberCoroutineScope() + + LaunchedEffect(Unit) { + if (chatModel.users.count { u -> u.user.activeUser || !u.user.hidden } == 1 + ) { + selectedUserCategory.value = PresentedUserCategory.CURRENT_USER + } else { + showUserSelection = true + } + } + + Column( + Modifier.fillMaxSize(), + ) { + Box(contentAlignment = Alignment.Center) { + val bottomPadding = DEFAULT_PADDING + AppBarTitle( + stringResource(MR.strings.servers_info), + hostDevice(rh?.remoteHostId), + bottomPadding = bottomPadding + ) + } + if (serversSummary.value == null) { + Box( + modifier = Modifier + .fillMaxSize() + ) { + Text(generalGetString(MR.strings.servers_info_missing), Modifier.align(Alignment.Center), color = MaterialTheme.colors.secondary) + } + } else { + val userOptions by remember { + mutableStateOf( + listOf( + PresentedUserCategory.ALL_USERS to generalGetString(MR.strings.all_users), + PresentedUserCategory.CURRENT_USER to generalGetString(MR.strings.current_user), + ) + ) + } + val serverTypeTabTitles = PresentedServerType.entries.map { + when (it) { + PresentedServerType.SMP -> + stringResource(MR.strings.messages_section_title) + + PresentedServerType.XFTP -> + stringResource(MR.strings.servers_info_files_tab) + } + } + val serverTypePagerState = rememberPagerState( + initialPage = selectedServerType.value.ordinal, + initialPageOffsetFraction = 0f + ) { PresentedServerType.entries.size } + + KeyChangeEffect(serverTypePagerState.currentPage) { + selectedServerType.value = PresentedServerType.values()[serverTypePagerState.currentPage] + } + TabRow( + selectedTabIndex = serverTypePagerState.currentPage, + backgroundColor = Color.Transparent, + contentColor = MaterialTheme.colors.primary, + ) { + serverTypeTabTitles.forEachIndexed { index, it -> + Tab( + selected = serverTypePagerState.currentPage == index, + onClick = { + scope.launch { + serverTypePagerState.animateScrollToPage(index) + } + }, + text = { Text(it, fontSize = 13.sp) }, + selectedContentColor = MaterialTheme.colors.primary, + unselectedContentColor = MaterialTheme.colors.secondary, + ) + } + } + + HorizontalPager( + state = serverTypePagerState, + Modifier.fillMaxSize(), + verticalAlignment = Alignment.Top, + userScrollEnabled = appPlatform.isAndroid + ) { index -> + ColumnWithScrollBar( + Modifier + .fillMaxSize(), + verticalArrangement = Arrangement.Top + ) { + Spacer(Modifier.height(DEFAULT_PADDING)) + if (showUserSelection) { + ExposedDropDownSettingRow( + generalGetString(MR.strings.servers_info_target), + userOptions, + selectedUserCategory, + icon = null, + enabled = remember { mutableStateOf(true) }, + onSelected = { + selectedUserCategory.value = it + } + ) + SectionDividerSpaced() + } + when (index) { + PresentedServerType.SMP.ordinal -> { + serversSummary.value?.let { + val smpSummary = + if (selectedUserCategory.value == PresentedUserCategory.CURRENT_USER) it.currentUserSMP else it.allUsersSMP; + val totals = smpSummary.smpTotals + val currentlyUsedSMPServers = smpSummary.currentlyUsedSMPServers + val previouslyUsedSMPServers = smpSummary.previouslyUsedSMPServers + val proxySMPServers = smpSummary.onlyProxiedSMPServers + val statsStartedAt = it.statsStartedAt + + SMPStatsView(totals.stats, statsStartedAt, rh) + SectionDividerSpaced() + SMPSubscriptionsSection(totals) + SectionDividerSpaced() + + if (currentlyUsedSMPServers.isNotEmpty()) { + SMPServersListView( + servers = currentlyUsedSMPServers, + statsStartedAt = statsStartedAt, + header = generalGetString(MR.strings.servers_info_connected_servers_section_header).uppercase(), + rh = rh + ) + SectionDividerSpaced() + } + + if (previouslyUsedSMPServers.isNotEmpty()) { + SMPServersListView( + servers = previouslyUsedSMPServers, + statsStartedAt = statsStartedAt, + header = generalGetString(MR.strings.servers_info_previously_connected_servers_section_header).uppercase(), + rh = rh + ) + SectionDividerSpaced() + } + + if (proxySMPServers.isNotEmpty()) { + SMPServersListView( + servers = proxySMPServers, + statsStartedAt = statsStartedAt, + header = generalGetString(MR.strings.servers_info_proxied_servers_section_header).uppercase(), + footer = generalGetString(MR.strings.servers_info_proxied_servers_section_footer), + rh = rh + ) + SectionDividerSpaced() + } + + ServerSessionsView(totals.sessions) + } + } + + PresentedServerType.XFTP.ordinal -> { + serversSummary.value?.let { + val xftpSummary = + if (selectedUserCategory.value == PresentedUserCategory.CURRENT_USER) it.currentUserXFTP else it.allUsersXFTP + val totals = xftpSummary.xftpTotals + val statsStartedAt = it.statsStartedAt + val currentlyUsedXFTPServers = xftpSummary.currentlyUsedXFTPServers + val previouslyUsedXFTPServers = xftpSummary.previouslyUsedXFTPServers + + XFTPStatsView(totals.stats, statsStartedAt, rh) + SectionDividerSpaced() + + if (currentlyUsedXFTPServers.isNotEmpty()) { + XFTPServersListView( + currentlyUsedXFTPServers, + statsStartedAt, + generalGetString(MR.strings.servers_info_connected_servers_section_header).uppercase(), + rh + ) + SectionDividerSpaced() + } + + if (previouslyUsedXFTPServers.isNotEmpty()) { + XFTPServersListView( + previouslyUsedXFTPServers, + statsStartedAt, + generalGetString(MR.strings.servers_info_previously_connected_servers_section_header).uppercase(), + rh + ) + SectionDividerSpaced() + } + + ServerSessionsView(totals.sessions) + } + } + } + + SectionDividerSpaced() + + SectionView { + ReconnectAllServersButton(rh) + ResetStatisticsButton(rh) + } + + SectionBottomSpacer() + } + } + } + } + } +} + +@Composable +private fun ReconnectAllServersButton(rh: RemoteHostInfo?) { + SectionItemView(click = { reconnectAllServersAlert(rh) }) { + Text( + stringResource(MR.strings.servers_info_reconnect_all_servers_button), + color = MaterialTheme.colors.primary + ) + } +} + +private fun reconnectAllServersAlert(rh: RemoteHostInfo?) { + AlertManager.shared.showAlertDialog( + title = generalGetString(MR.strings.servers_info_reconnect_servers_title), + text = generalGetString(MR.strings.servers_info_reconnect_servers_message), + onConfirm = { + withBGApi { + val success = controller.reconnectAllServers(rh?.remoteHostId) + + if (!success) { + AlertManager.shared.showAlertMsg( + title = generalGetString(MR.strings.servers_info_modal_error_title), + text = generalGetString(MR.strings.servers_info_reconnect_servers_error) + ) + } + } + } + ) +} + +@Composable +private fun ResetStatisticsButton(rh: RemoteHostInfo?) { + SectionItemView(click = { resetStatisticsAlert(rh) }) { + Text( + stringResource(MR.strings.servers_info_reset_stats), + color = MaterialTheme.colors.primary + ) + } +} + +private fun resetStatisticsAlert(rh: RemoteHostInfo?) { + AlertManager.shared.showAlertDialog( + title = generalGetString(MR.strings.servers_info_reset_stats_alert_title), + text = generalGetString(MR.strings.servers_info_reset_stats_alert_message), + confirmText = generalGetString(MR.strings.servers_info_reset_stats_alert_confirm), + destructive = true, + onConfirm = { + withBGApi { + val success = controller.resetAgentServersStats(rh?.remoteHostId) + + if (!success) { + AlertManager.shared.showAlertMsg( + title = generalGetString(MR.strings.servers_info_modal_error_title), + text = generalGetString(MR.strings.servers_info_reset_stats_alert_error_title) + ) + } + } + } + ) +} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt index 6ee60c4596..d7116d11b6 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt @@ -100,6 +100,9 @@ class ModalManager(private val placement: ModalPlacement? = null) { fun hasModalsOpen() = modalCount.value > 0 + val hasModalsOpen: Boolean + @Composable get () = remember { modalCount }.value > 0 + fun closeModal() { if (modalViews.isNotEmpty()) { if (modalViews.lastOrNull()?.first == false) modalViews.removeAt(modalViews.lastIndex) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Section.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Section.kt index 94affad0e7..d3a3a0ff9c 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Section.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Section.kt @@ -276,8 +276,8 @@ fun TextIconSpaced(extraPadding: Boolean = false) { } @Composable -fun InfoRow(title: String, value: String, icon: Painter? = null, iconTint: Color? = null, textColor: Color = MaterialTheme.colors.onBackground) { - SectionItemViewSpaceBetween { +fun InfoRow(title: String, value: String, icon: Painter? = null, iconTint: Color? = null, textColor: Color = MaterialTheme.colors.onBackground, padding: PaddingValues = PaddingValues(horizontal = DEFAULT_PADDING)) { + SectionItemViewSpaceBetween(padding = padding) { Row { val iconSize = with(LocalDensity.current) { 21.sp.toDp() } if (icon != null) Icon(icon, title, Modifier.padding(end = 8.dp).size(iconSize), tint = iconTint ?: MaterialTheme.colors.secondary) @@ -287,6 +287,61 @@ fun InfoRow(title: String, value: String, icon: Painter? = null, iconTint: Color } } +fun numOrDash(n: Number): String = if (n.toLong() == 0L) "-" else n.toString() + +@Composable +fun InfoRowTwoValues( + title: String, + title2: String, + value: Int, + value2: Int, + textColor: Color = MaterialTheme.colors.onBackground +) { + SectionItemViewSpaceBetween { + Row( + verticalAlignment = Alignment.Bottom + ) { + Text( + text = title, + color = textColor, + ) + Text( + text = " / ", + fontSize = 12.sp, + ) + Text( + text = title2, + color = textColor, + fontSize = 12.sp, + ) + } + Row(verticalAlignment = Alignment.Bottom) { + if (value == 0 && value2 == 0) { + Text( + text = "-", + color = MaterialTheme.colors.secondary + ) + } else { + Text( + text = numOrDash(value), + color = MaterialTheme.colors.secondary, + ) + Text( + text = " / ", + color = MaterialTheme.colors.secondary, + fontSize = 12.sp, + ) + Text( + text = numOrDash(value2), + color = MaterialTheme.colors.secondary, + fontSize = 12.sp, + ) + } + } + } +} + + @Composable fun InfoRowEllipsis(title: String, value: String, onClick: () -> Unit) { SectionItemViewSpaceBetween(onClick) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/SubscriptionStatusIcon.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/SubscriptionStatusIcon.kt new file mode 100644 index 0000000000..e0e61b598e --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/SubscriptionStatusIcon.kt @@ -0,0 +1,41 @@ +package chat.simplex.common.views.helpers + +import androidx.compose.foundation.layout.Box +import androidx.compose.material.Icon +import androidx.compose.ui.graphics.Color +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import chat.simplex.res.MR +import dev.icerock.moko.resources.compose.painterResource + +@Composable +fun SubscriptionStatusIcon( + color: Color, + variableValue: Float, + modifier: Modifier = Modifier +) { + @Composable + fun ZeroIcon() { + Icon(painterResource(MR.images.ic_radiowaves_up_forward_4_bar), null, tint = color.copy(alpha = 0.33f), modifier = modifier) + } + + when { + variableValue <= 0f -> ZeroIcon() + variableValue > 0f && variableValue <= 0.25f -> Box { + ZeroIcon() + Icon(painterResource(MR.images.ic_radiowaves_up_forward_1_bar), null, tint = color, modifier = modifier) + } + + variableValue > 0.25f && variableValue <= 0.5f -> Box { + ZeroIcon() + Icon(painterResource(MR.images.ic_radiowaves_up_forward_2_bar), null, tint = color, modifier = modifier) + } + + variableValue > 0.5f && variableValue <= 0.75f -> Box { + ZeroIcon() + Icon(painterResource(MR.images.ic_radiowaves_up_forward_3_bar), null, tint = color, modifier = modifier) + } + + else -> Icon(painterResource(MR.images.ic_radiowaves_up_forward_4_bar), null, tint = color, modifier = modifier) + } +} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt index 26c5422623..9f47a5cdf9 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt @@ -44,6 +44,11 @@ fun NewChatSheet(chatModel: ChatModel, newChatSheetState: StateFlow NewChatView(chatModel.currentRemoteHost.value, NewChatOption.INVITE, close = close) } }, + scanPaste = { + closeNewChatSheet(false) + ModalManager.center.closeModals() + ModalManager.center.showModalCloseable { close -> NewChatView(chatModel.currentRemoteHost.value, NewChatOption.CONNECT, showQRCodeScanner = true, close = close) } + }, createGroup = { closeNewChatSheet(false) ModalManager.center.closeModals() @@ -55,15 +60,17 @@ fun NewChatSheet(chatModel: ChatModel, newChatSheetState: StateFlow, stopped: Boolean, addContact: () -> Unit, + scanPaste: () -> Unit, createGroup: () -> Unit, closeNewChatSheet: (animated: Boolean) -> Unit, ) { @@ -102,7 +109,7 @@ private fun NewChatSheetLayout( verticalArrangement = Arrangement.Bottom, horizontalAlignment = Alignment.End ) { - val actions = remember { listOf(addContact, createGroup) } + val actions = remember { listOf(addContact, scanPaste, createGroup) } val backgroundColor = if (isInDarkTheme()) blendARGB(MaterialTheme.colors.primary, Color.Black, 0.7F) else @@ -264,6 +271,7 @@ private fun PreviewNewChatSheet() { MutableStateFlow(AnimatedViewState.VISIBLE), stopped = false, addContact = {}, + scanPaste = {}, createGroup = {}, closeNewChatSheet = {}, ) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatView.kt index f341d59305..a877e123b3 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatView.kt @@ -140,7 +140,7 @@ fun ModalData.NewChatView(rh: RemoteHostInfo?, selection: NewChatOption, showQRC } } - HorizontalPager(state = pagerState, Modifier.fillMaxSize(), verticalAlignment = Alignment.Top) { index -> + HorizontalPager(state = pagerState, Modifier.fillMaxSize(), verticalAlignment = Alignment.Top, userScrollEnabled = appPlatform.isAndroid) { index -> // LALAL SCROLLBAR DOESN'T WORK ColumnWithScrollBar( Modifier diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt index 61c8e1b75f..e7033e88f4 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt @@ -42,6 +42,7 @@ fun NetworkAndServersView() { // It's not a state, just a one-time value. Shouldn't be used in any state-related situations val netCfg = remember { chatModel.controller.getNetCfg() } val networkUseSocksProxy: MutableState = remember { mutableStateOf(netCfg.useSocksProxy) } + val networkShowSubscriptionPercentage: MutableState = remember { mutableStateOf(chatModel.controller.appPrefs.networkShowSubscriptionPercentage.get()) } val developerTools = chatModel.controller.appPrefs.developerTools.get() val onionHosts = remember { mutableStateOf(netCfg.onionHosts) } val sessionMode = remember { mutableStateOf(netCfg.sessionMode) } @@ -53,6 +54,7 @@ fun NetworkAndServersView() { currentRemoteHost = currentRemoteHost, developerTools = developerTools, networkUseSocksProxy = networkUseSocksProxy, + networkShowSubscriptionPercentage = networkShowSubscriptionPercentage, onionHosts = onionHosts, sessionMode = sessionMode, smpProxyMode = smpProxyMode, @@ -117,6 +119,9 @@ fun NetworkAndServersView() { ) } }, + toggleNetworkShowSubscriptionPercentage = { enable -> + networkShowSubscriptionPercentage.value = enable + }, useOnion = { if (onionHosts.value == it) return@NetworkAndServersLayout val prevValue = onionHosts.value @@ -230,12 +235,14 @@ fun NetworkAndServersView() { currentRemoteHost: RemoteHostInfo?, developerTools: Boolean, networkUseSocksProxy: MutableState, + networkShowSubscriptionPercentage: MutableState, onionHosts: MutableState, sessionMode: MutableState, smpProxyMode: MutableState, smpProxyFallback: MutableState, proxyPort: State, toggleSocksProxy: (Boolean) -> Unit, + toggleNetworkShowSubscriptionPercentage: (Boolean) -> Unit, useOnion: (OnionHosts) -> Unit, updateSessionMode: (TransportSessionMode) -> Unit, updateSMPProxyMode: (SMPProxyMode) -> Unit, @@ -256,6 +263,7 @@ fun NetworkAndServersView() { SettingsActionItem(painterResource(MR.images.ic_dns), stringResource(MR.strings.xftp_servers), { ModalManager.start.showCustomModal { close -> ProtocolServersView(m, m.remoteHostId, ServerProtocol.XFTP, close) } }) if (currentRemoteHost == null) { + SettingsPreferenceItem(painterResource(MR.images.ic_radiowaves_up_forward_4_bar),stringResource(MR.strings.subscription_percentage), chatModel.controller.appPrefs.networkShowSubscriptionPercentage) UseSocksProxySwitch(networkUseSocksProxy, proxyPort, toggleSocksProxy, showModal, chatModel.controller.appPrefs.networkProxyHostPort, false) UseOnionHosts(onionHosts, networkUseSocksProxy, showModal, useOnion) if (developerTools) { @@ -677,8 +685,10 @@ fun PreviewNetworkAndServersLayout() { currentRemoteHost = null, developerTools = true, networkUseSocksProxy = remember { mutableStateOf(true) }, + networkShowSubscriptionPercentage = remember { mutableStateOf(false) }, proxyPort = remember { mutableStateOf(9050) }, toggleSocksProxy = {}, + toggleNetworkShowSubscriptionPercentage = {}, onionHosts = remember { mutableStateOf(OnionHosts.PREFER) }, sessionMode = remember { mutableStateOf(TransportSessionMode.User) }, smpProxyMode = remember { mutableStateOf(SMPProxyMode.Never) }, diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index 996ecb11da..24c94a5ddc 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -617,6 +617,7 @@ New chat Add contact + Scan / Paste link One-time invitation link 1-time link SimpleX address @@ -685,6 +686,7 @@ The servers for new connections of your current chat profile Save servers? XFTP servers + Subscription percentage Install SimpleX Chat for terminal Star on GitHub Contribute @@ -2075,4 +2077,85 @@ WiFi Wired ethernet Other + + + Servers info + Files + No info, try to reload + Showing info for + All users + Current user + Transport sessions + Connected + Connecting + Errors + Statistics + Messages sent + Messages received + Details + Starting from %s.\nAll data is private to your device. + Messages subscriptions + Connections subscribed + Pending + Total + Connected servers + Previously connected servers + Proxied servers + You are not connected to these servers. Private routing is used to deliver messages to them. + Reconnect servers? + Reconnect all connected servers to force message delivery. It uses additional traffic. + Reconnect server? + Reconnect server to force message delivery. It uses additional traffic. + Error reconnecting servers + Error reconnecting server + Error + Reconnect all servers + Reset all statistics + Reset all statistics? + Servers statistics will be reset - this cannot be undone! + Reset + Error resetting statistics + Uploaded + Downloaded + Detailed statistics + Sent messages + Sent total + Received messages + Received total + Receive errors + Starting from %s. + SMP server + XFTP server + Reconnect + attempts + Sent directly + Sent via proxy + Proxied + Send errors + expired + other + duplicates + decryption errors + other errors + Acknowledged + Acknowledgement errors + Connections + Created + Secured + Completed + Deleted + Deletion errors + Subscribed + Subscriptions ignored + Subscription errors + Uploaded files + Size + Chunks uploaded + Upload errors + Chunks deleted + Chunks downloaded + Downloaded files + Download errors + Server address + Open server settings \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_1_bar.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_1_bar.svg new file mode 100644 index 0000000000..db1cb48d53 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_1_bar.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_2_bar.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_2_bar.svg new file mode 100644 index 0000000000..6f9a3211dd --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_2_bar.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_3_bar.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_3_bar.svg new file mode 100644 index 0000000000..1962851519 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_3_bar.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_4_bar.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_4_bar.svg new file mode 100644 index 0000000000..ff7a146284 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_radiowaves_up_forward_4_bar.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From a9d2535292d54f6e68c36cf0a2c45fbc15e5729f Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Tue, 9 Jul 2024 21:29:36 +0400 Subject: [PATCH 37/43] core: differentiate inactive and forwarded group snd statuses (#4420) * core: GroupSndStatus * rfc * encoding, db apis * pending, forwarded statuses * encoding --- docs/rfcs/2024-07-09-group-snd-status.md | 47 ++++++++++++++++ src/Simplex/Chat.hs | 68 +++++++++++++++--------- src/Simplex/Chat/Messages.hs | 57 ++++++++++++++++++-- src/Simplex/Chat/Store/Messages.hs | 8 +-- 4 files changed, 146 insertions(+), 34 deletions(-) create mode 100644 docs/rfcs/2024-07-09-group-snd-status.md diff --git a/docs/rfcs/2024-07-09-group-snd-status.md b/docs/rfcs/2024-07-09-group-snd-status.md new file mode 100644 index 0000000000..43f491880d --- /dev/null +++ b/docs/rfcs/2024-07-09-group-snd-status.md @@ -0,0 +1,47 @@ +# Group messages sending status + +## Problem + +Currently in UI chat item info: +- There's no differentiation between sent messages and pending messages. +- There's no differentiation between pending messages reasons (establishing connection or member inactivity). + - Since the former is usually not a case due to group forwarding, this can be ignored. +- Messages to be forwarded by admin are not accounted. + +## Solution + +Differentiate new statuses for group sending in chat item info: +- forwarded +- inactive / pending + +Option 1 is to add statuses to CIStatus / ACIStatus types. + +Pros: +- simple. + +Cons: +- further muddies type of statuses for chat item with impossible states / different dimension, as it's not applicable directly to chat item but a technicality of group sending process. + +Option 2 is to create a new type, GroupSndStatus. + +```haskell +data GroupSndStatus + = GSSNew + | GSSForwarded + | GSSInactive + | GSSSent + | GSSRcvd {msgRcptStatus :: MsgReceiptStatus} + | GSSError {agentError :: SndError} + | GSSWarning {agentError :: SndError} + | GSSInvalid {text :: Text} +``` + +Most statuses repeat CIStatus sending statuses, with addition of forwarded and inactive for group sending process. + +Pros: +- separates concerns of chat item presentation from group sending process. +- allows future extension without further muddying CIStatus types. + +Cons: +- more work. +- requires backwards compatible decoding with ACIStatus to read previous data from db. diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index 131fbb7089..786f065ae0 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -2786,14 +2786,19 @@ processChatCommand' vr = \case (fInv_, ciFile_) <- L.unzip <$> setupSndFileTransfer g (length $ filter memberCurrent ms) timed_ <- sndGroupCITimed live gInfo itemTTL (msgContainer, quotedItem_) <- prepareGroupMsg user gInfo mc quotedItemId_ itemForwarded fInv_ timed_ live - (msg, sentToMembers) <- sendGroupMessage user gInfo ms (XMsgNew msgContainer) + (msg, groupSndResult) <- sendGroupMessage user gInfo ms (XMsgNew msgContainer) ci <- saveSndChatItem' user (CDGroupSnd gInfo) msg (CISndMsgContent mc) ciFile_ quotedItem_ itemForwarded timed_ live - withStore' $ \db -> - forM_ sentToMembers $ \GroupMember {groupMemberId} -> - createGroupSndStatus db (chatItemId' ci) groupMemberId CISSndNew + withStore' $ \db -> do + let GroupSndResult {sentTo, pending, forwarded} = groupSndResult + createMemberSndStatuses db ci sentTo GSSNew + createMemberSndStatuses db ci forwarded GSSForwarded + createMemberSndStatuses db ci pending GSSInactive forM_ (timed_ >>= timedDeleteAt') $ startProximateTimedItemThread user (ChatRef CTGroup groupId, chatItemId' ci) pure $ CRNewChatItem user (AChatItem SCTGroup SMDSnd (GroupChat gInfo) ci) + where + createMemberSndStatuses db ci ms' gss = + forM_ ms' $ \GroupMember {groupMemberId} -> createGroupSndStatus db (chatItemId' ci) groupMemberId gss notAllowedError f = pure $ chatCmdError (Just user) ("feature not allowed " <> T.unpack (groupFeatureNameText f)) setupSndFileTransfer :: Group -> Int -> CM (Maybe (FileInvitation, CIFile 'MDSnd)) setupSndFileTransfer g n = forM file_ $ \file -> do @@ -4574,7 +4579,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = continued <- continueSending connEntity conn sentMsgDeliveryEvent conn msgId checkSndInlineFTComplete conn msgId - updateGroupItemStatus gInfo m conn msgId (CISSndSent SSPComplete) (Just $ isJust proxy) + updateGroupItemStatus gInfo m conn msgId GSSSent (Just $ isJust proxy) when continued $ sendPendingGroupMessages user m conn SWITCH qd phase cStats -> do toView $ CRGroupMemberSwitch user gInfo m (SwitchProgress qd phase cStats) @@ -4615,15 +4620,15 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = continued <- continueSending connEntity conn when continued $ sendPendingGroupMessages user m conn MWARN msgId err -> do - withStore' $ \db -> updateGroupItemErrorStatus db msgId (groupMemberId' m) (CISSndWarning $ agentSndError err) + withStore' $ \db -> updateGroupItemErrorStatus db msgId (groupMemberId' m) (GSSWarning $ agentSndError err) processConnMWARN connEntity conn err MERR msgId err -> do - withStore' $ \db -> updateGroupItemErrorStatus db msgId (groupMemberId' m) (CISSndError $ agentSndError err) + withStore' $ \db -> updateGroupItemErrorStatus db msgId (groupMemberId' m) (GSSError $ agentSndError err) -- group errors are silenced to reduce load on UI event log -- toView $ CRChatError (Just user) (ChatErrorAgent err $ Just connEntity) processConnMERR connEntity conn err MERRS msgIds err -> do - let newStatus = CISSndError $ agentSndError err + let newStatus = GSSError $ agentSndError err -- error cannot be AUTH error here withStore' $ \db -> forM_ msgIds $ \msgId -> updateGroupItemErrorStatus db msgId (groupMemberId' m) newStatus `catchAll_` pure () @@ -4634,7 +4639,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = -- TODO add debugging output _ -> pure () where - updateGroupItemErrorStatus :: DB.Connection -> AgentMsgId -> GroupMemberId -> CIStatus 'MDSnd -> IO () + updateGroupItemErrorStatus :: DB.Connection -> AgentMsgId -> GroupMemberId -> GroupSndStatus -> IO () updateGroupItemErrorStatus db msgId groupMemberId newStatus = do chatItemId_ <- getChatItemIdByAgentMsgId db connId msgId forM_ chatItemId_ $ \itemId -> updateGroupMemSndStatus' db itemId groupMemberId newStatus @@ -6290,7 +6295,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = checkIntegrityCreateItem (CDGroupRcv gInfo m) msgMeta `catchChatError` \_ -> pure () forM_ msgRcpts $ \MsgReceipt {agentMsgId, msgRcptStatus} -> do withStore' $ \db -> updateSndMsgDeliveryStatus db connId agentMsgId $ MDSSndRcvd msgRcptStatus - updateGroupItemStatus gInfo m conn agentMsgId (CISSndRcvd msgRcptStatus SSPComplete) Nothing + updateGroupItemStatus gInfo m conn agentMsgId (GSSRcvd msgRcptStatus) Nothing updateDirectItemsStatus :: Contact -> Connection -> [AgentMsgId] -> CIStatus 'MDSnd -> CM () updateDirectItemsStatus ct conn msgIds newStatus = do @@ -6314,20 +6319,20 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage = | otherwise -> Just <$> updateDirectChatItemStatus db user ct itemId newStatus _ -> pure Nothing - updateGroupMemSndStatus :: ChatItemId -> GroupMemberId -> CIStatus 'MDSnd -> CM Bool + updateGroupMemSndStatus :: ChatItemId -> GroupMemberId -> GroupSndStatus -> CM Bool updateGroupMemSndStatus itemId groupMemberId newStatus = withStore' $ \db -> updateGroupMemSndStatus' db itemId groupMemberId newStatus - updateGroupMemSndStatus' :: DB.Connection -> ChatItemId -> GroupMemberId -> CIStatus 'MDSnd -> IO Bool + updateGroupMemSndStatus' :: DB.Connection -> ChatItemId -> GroupMemberId -> GroupSndStatus -> IO Bool updateGroupMemSndStatus' db itemId groupMemberId newStatus = runExceptT (getGroupSndStatus db itemId groupMemberId) >>= \case - Right (CISSndRcvd _ _) -> pure False + Right (GSSRcvd _) -> pure False Right memStatus | memStatus == newStatus -> pure False | otherwise -> updateGroupSndStatus db itemId groupMemberId newStatus $> True _ -> pure False - updateGroupItemStatus :: GroupInfo -> GroupMember -> Connection -> AgentMsgId -> CIStatus 'MDSnd -> Maybe Bool -> CM () + updateGroupItemStatus :: GroupInfo -> GroupMember -> Connection -> AgentMsgId -> GroupSndStatus -> Maybe Bool -> CM () updateGroupItemStatus gInfo@GroupInfo {groupId} GroupMember {groupMemberId} Connection {connId} msgId newMemStatus viaProxy_ = withStore' (\db -> getGroupChatItemByAgentMsgId db user groupId connId msgId) >>= \case Just (CChatItem SMDSnd ChatItem {meta = CIMeta {itemStatus = CISSndRcvd _ SSPComplete}}) -> pure () @@ -6778,7 +6783,7 @@ deliverMessagesB msgReqs = do -- TODO combine profile update and message into one batch -- Take into account that it may not fit, and that we currently don't support sending multiple messages to the same connection in one call. -sendGroupMessage :: MsgEncodingI e => User -> GroupInfo -> [GroupMember] -> ChatMsgEvent e -> CM (SndMessage, [GroupMember]) +sendGroupMessage :: MsgEncodingI e => User -> GroupInfo -> [GroupMember] -> ChatMsgEvent e -> CM (SndMessage, GroupSndResult) sendGroupMessage user gInfo members chatMsgEvent = do when shouldSendProfileUpdate $ sendProfileUpdate `catchChatError` (\e -> toView (CRChatError (Just user) e)) @@ -6800,12 +6805,18 @@ sendGroupMessage user gInfo members chatMsgEvent = do currentTs <- liftIO getCurrentTime withStore' $ \db -> updateUserMemberProfileSentAt db user gInfo currentTs -sendGroupMessage' :: MsgEncodingI e => User -> GroupInfo -> [GroupMember] -> ChatMsgEvent e -> CM (SndMessage, [GroupMember]) +data GroupSndResult = GroupSndResult + { sentTo :: [GroupMember], + pending :: [GroupMember], + forwarded :: [GroupMember] + } + +sendGroupMessage' :: MsgEncodingI e => User -> GroupInfo -> [GroupMember] -> ChatMsgEvent e -> CM (SndMessage, GroupSndResult) sendGroupMessage' user GroupInfo {groupId} members chatMsgEvent = do msg@SndMessage {msgId, msgBody} <- createSndMessage chatMsgEvent (GroupId groupId) recipientMembers <- liftIO $ shuffleMembers (filter memberCurrent members) let msgFlags = MsgFlags {notification = hasNotification $ toCMEventTag chatMsgEvent} - (toSend, pending, _, dups) = foldr addMember ([], [], S.empty, 0 :: Int) recipientMembers + (toSend, pending, forwarded, _, dups) = foldr addMember ([], [], [], S.empty, 0 :: Int) recipientMembers -- TODO PQ either somehow ensure that group members connections cannot have pqSupport/pqEncryption or pass Off's here msgReqs = map (\(_, conn) -> (conn, msgFlags, msgBody, msgId)) toSend when (dups /= 0) $ logError $ "sendGroupMessage: " <> tshow dups <> " duplicate members" @@ -6813,8 +6824,13 @@ sendGroupMessage' user GroupInfo {groupId} members chatMsgEvent = do let errors = lefts delivered unless (null errors) $ toView $ CRChatErrors (Just user) errors stored <- lift . withStoreBatch' $ \db -> map (\m -> createPendingGroupMessage db (groupMemberId' m) msgId Nothing) pending - let sentToMembers = filterSent delivered toSend fst <> filterSent stored pending id - pure (msg, sentToMembers) + let gsr = + GroupSndResult + { sentTo = filterSent delivered toSend fst, + pending = filterSent stored pending id, + forwarded + } + pure (msg, gsr) where shuffleMembers :: [GroupMember] -> IO [GroupMember] shuffleMembers ms = do @@ -6822,12 +6838,13 @@ sendGroupMessage' user GroupInfo {groupId} members chatMsgEvent = do liftM2 (<>) (shuffle adminMs) (shuffle otherMs) where isAdmin GroupMember {memberRole} = memberRole >= GRAdmin - addMember m acc@(toSend, pending, !mIds, !dups) = case memberSendAction chatMsgEvent members m of + addMember m acc@(toSend, pending, forwarded, !mIds, !dups) = case memberSendAction chatMsgEvent members m of Just a - | mId `S.member` mIds -> (toSend, pending, mIds, dups + 1) + | mId `S.member` mIds -> (toSend, pending, forwarded, mIds, dups + 1) | otherwise -> case a of - MSASend conn -> ((m, conn) : toSend, pending, mIds', dups) - MSAPending -> (toSend, m : pending, mIds', dups) + MSASend conn -> ((m, conn) : toSend, pending, forwarded, mIds', dups) + MSAPending -> (toSend, m : pending, forwarded, mIds', dups) + MSAForwarded -> (toSend, pending, m : forwarded, mIds', dups) Nothing -> acc where mId = groupMemberId' m @@ -6835,7 +6852,7 @@ sendGroupMessage' user GroupInfo {groupId} members chatMsgEvent = do filterSent :: [Either ChatError a] -> [mem] -> (mem -> GroupMember) -> [GroupMember] filterSent rs ms mem = [mem m | (Right _, m) <- zip rs ms] -data MemberSendAction = MSASend Connection | MSAPending +data MemberSendAction = MSASend Connection | MSAPending | MSAForwarded memberSendAction :: ChatMsgEvent e -> [GroupMember] -> GroupMember -> Maybe MemberSendAction memberSendAction chatMsgEvent members m@GroupMember {invitedByGroupMemberId} = case memberConn m of @@ -6847,7 +6864,7 @@ memberSendAction chatMsgEvent members m@GroupMember {invitedByGroupMemberId} = c | otherwise -> pendingOrForwarded where pendingOrForwarded - | forwardSupported && isForwardedGroupMsg chatMsgEvent = Nothing + | forwardSupported && isForwardedGroupMsg chatMsgEvent = Just MSAForwarded | isXGrpMsgForward chatMsgEvent = Nothing | otherwise = Just MSAPending where @@ -6872,6 +6889,7 @@ sendGroupMemberMessage user m@GroupMember {groupMemberId} chatMsgEvent groupId i messageMember SndMessage {msgId, msgBody} = forM_ (memberSendAction chatMsgEvent [m] m) $ \case MSASend conn -> deliverMessage conn (toCMEventTag chatMsgEvent) msgBody msgId >> postDeliver MSAPending -> withStore' $ \db -> createPendingGroupMessage db groupMemberId msgId introId_ + MSAForwarded -> pure () -- TODO ensure order - pending messages interleave with user input messages sendPendingGroupMessages :: User -> GroupMember -> Connection -> CM () diff --git a/src/Simplex/Chat/Messages.hs b/src/Simplex/Chat/Messages.hs index 9e0eccbbde..e59429b7ea 100644 --- a/src/Simplex/Chat/Messages.hs +++ b/src/Simplex/Chat/Messages.hs @@ -873,7 +873,7 @@ ciCreateStatus content = case msgDirection @d of SMDSnd -> ciStatusNew SMDRcv -> if ciRequiresAttention content then ciStatusNew else CISRcvRead -membersGroupItemStatus :: [(CIStatus 'MDSnd, Int)] -> CIStatus 'MDSnd +membersGroupItemStatus :: [(GroupSndStatus, Int)] -> CIStatus 'MDSnd membersGroupItemStatus memStatusCounts | rcvdOk == total = CISSndRcvd MROk SSPComplete | rcvdOk + rcvdBad == total = CISSndRcvd MRBadMsgHash SSPComplete @@ -884,9 +884,9 @@ membersGroupItemStatus memStatusCounts | otherwise = CISSndNew where total = sum $ map snd memStatusCounts - rcvdOk = fromMaybe 0 $ lookup (CISSndRcvd MROk SSPComplete) memStatusCounts - rcvdBad = fromMaybe 0 $ lookup (CISSndRcvd MRBadMsgHash SSPComplete) memStatusCounts - sent = fromMaybe 0 $ lookup (CISSndSent SSPComplete) memStatusCounts + rcvdOk = fromMaybe 0 $ lookup (GSSRcvd MROk) memStatusCounts + rcvdBad = fromMaybe 0 $ lookup (GSSRcvd MRBadMsgHash) memStatusCounts + sent = fromMaybe 0 $ lookup GSSSent memStatusCounts data SndCIStatusProgress = SSPPartial @@ -903,6 +903,47 @@ instance StrEncoding SndCIStatusProgress where "complete" -> pure SSPComplete _ -> fail "bad SndCIStatusProgress" +data GroupSndStatus + = GSSNew + | GSSForwarded + | GSSInactive + | GSSSent + | GSSRcvd {msgRcptStatus :: MsgReceiptStatus} + | GSSError {agentError :: SndError} + | GSSWarning {agentError :: SndError} + | GSSInvalid {text :: Text} + +deriving instance Eq GroupSndStatus + +deriving instance Show GroupSndStatus + +-- Preserve CIStatus encoding for backwards compatibility +instance StrEncoding GroupSndStatus where + strEncode = \case + GSSNew -> "snd_new" + GSSForwarded -> "snd_forwarded" + GSSInactive -> "snd_inactive" + GSSSent -> "snd_sent complete" + GSSRcvd msgRcptStatus -> "snd_rcvd " <> strEncode msgRcptStatus <> " complete" + GSSError sndErr -> "snd_error " <> strEncode sndErr + GSSWarning sndErr -> "snd_warning " <> strEncode sndErr + GSSInvalid {} -> "invalid" + strP = + (statusP <* A.endOfInput) -- see ACIStatus decoding + <|> (GSSInvalid . safeDecodeUtf8 <$> A.takeByteString) + where + statusP = + A.takeTill (== ' ') >>= \case + "snd_new" -> pure GSSNew + "snd_forwarded" -> pure GSSForwarded + "snd_inactive" -> pure GSSInactive + "snd_sent" -> GSSSent <$ " complete" + "snd_rcvd" -> GSSRcvd <$> (_strP <* " complete") + "snd_error_auth" -> pure $ GSSError SndErrAuth + "snd_error" -> GSSError <$> (A.space *> strP) + "snd_warning" -> GSSWarning <$> (A.space *> strP) + _ -> fail "bad status" + type ChatItemId = Int64 type ChatItemTs = UTCTime @@ -1176,7 +1217,7 @@ mkItemVersion ChatItem {content, meta} = version <$> ciMsgContent content data MemberDeliveryStatus = MemberDeliveryStatus { groupMemberId :: GroupMemberId, - memberDeliveryStatus :: CIStatus 'MDSnd, + memberDeliveryStatus :: GroupSndStatus, sentViaProxy :: Maybe Bool } deriving (Eq, Show) @@ -1234,6 +1275,12 @@ instance (Typeable d, MsgDirectionI d) => FromField (CIStatus d) where fromField instance FromField ACIStatus where fromField = fromTextField_ $ eitherToMaybe . strDecode . encodeUtf8 +$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "GSS") ''GroupSndStatus) + +instance ToField GroupSndStatus where toField = toField . decodeLatin1 . strEncode + +instance FromField GroupSndStatus where fromField = fromTextField_ $ eitherToMaybe . strDecode . encodeUtf8 + $(JQ.deriveJSON defaultJSON ''MemberDeliveryStatus) $(JQ.deriveJSON defaultJSON ''ChatItemVersion) diff --git a/src/Simplex/Chat/Store/Messages.hs b/src/Simplex/Chat/Store/Messages.hs index 853d34995a..5d9f5a7619 100644 --- a/src/Simplex/Chat/Store/Messages.hs +++ b/src/Simplex/Chat/Store/Messages.hs @@ -2531,14 +2531,14 @@ deleteCIModeration db GroupInfo {groupId} itemMemberId (Just sharedMsgId) = "DELETE FROM chat_item_moderations WHERE group_id = ? AND item_member_id = ? AND shared_msg_id = ?" (groupId, itemMemberId, sharedMsgId) -createGroupSndStatus :: DB.Connection -> ChatItemId -> GroupMemberId -> CIStatus 'MDSnd -> IO () +createGroupSndStatus :: DB.Connection -> ChatItemId -> GroupMemberId -> GroupSndStatus -> IO () createGroupSndStatus db itemId memberId status = DB.execute db "INSERT INTO group_snd_item_statuses (chat_item_id, group_member_id, group_snd_item_status) VALUES (?,?,?)" (itemId, memberId, status) -getGroupSndStatus :: DB.Connection -> ChatItemId -> GroupMemberId -> ExceptT StoreError IO (CIStatus 'MDSnd) +getGroupSndStatus :: DB.Connection -> ChatItemId -> GroupMemberId -> ExceptT StoreError IO GroupSndStatus getGroupSndStatus db itemId memberId = ExceptT . firstRow fromOnly (SENoGroupSndStatus itemId memberId) $ DB.query @@ -2551,7 +2551,7 @@ getGroupSndStatus db itemId memberId = |] (itemId, memberId) -updateGroupSndStatus :: DB.Connection -> ChatItemId -> GroupMemberId -> CIStatus 'MDSnd -> IO () +updateGroupSndStatus :: DB.Connection -> ChatItemId -> GroupMemberId -> GroupSndStatus -> IO () updateGroupSndStatus db itemId memberId status = do currentTs <- liftIO getCurrentTime DB.execute @@ -2589,7 +2589,7 @@ getGroupSndStatuses db itemId = memStatus (groupMemberId, memberDeliveryStatus, sentViaProxy) = MemberDeliveryStatus {groupMemberId, memberDeliveryStatus, sentViaProxy} -getGroupSndStatusCounts :: DB.Connection -> ChatItemId -> IO [(CIStatus 'MDSnd, Int)] +getGroupSndStatusCounts :: DB.Connection -> ChatItemId -> IO [(GroupSndStatus, Int)] getGroupSndStatusCounts db itemId = DB.query db From f4be0278b6c5bfa1dbc33393e27fa89f6cf7f83c Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Wed, 10 Jul 2024 00:41:23 +0700 Subject: [PATCH 38/43] desktop: zoom and font size (#4421) * desktop: font scale * new line * moved to slider * default value highlighting * clickable * more places with adapted scale * attachment and edit icons * verified * icons in chat view * zoom * new chat button size * preview icons * android support * preview * text scale in chat view's text field * paddings --------- Co-authored-by: Evgeny Poberezkin --- .../platform/PlatformTextField.android.kt | 5 +- .../common/views/call/CallView.android.kt | 2 +- .../views/usersettings/Appearance.android.kt | 3 + .../kotlin/chat/simplex/common/App.kt | 14 ++-- .../chat/simplex/common/model/SimpleXAPI.kt | 4 ++ .../chat/simplex/common/ui/theme/Theme.kt | 4 ++ .../simplex/common/views/chat/ChatView.kt | 12 ++-- .../simplex/common/views/chat/ComposeView.kt | 4 +- .../simplex/common/views/chat/SendMsgView.kt | 4 +- .../common/views/chatlist/ChatListView.kt | 13 ++-- .../common/views/chatlist/ChatPreviewView.kt | 42 +++++++----- .../views/chatlist/ServersSummaryView.kt | 4 +- .../common/views/chatlist/UserPicker.kt | 18 ++--- .../common/views/helpers/CloseSheetBar.kt | 8 +-- .../common/views/helpers/DefaultTopAppBar.kt | 7 +- .../simplex/common/views/helpers/ModalView.kt | 4 +- .../simplex/common/views/helpers/Utils.kt | 10 +++ .../views/migration/MigrateFromDevice.kt | 5 +- .../common/views/newchat/NewChatSheet.kt | 12 ++-- .../common/views/usersettings/Appearance.kt | 65 ++++++++++++++++++- .../common/views/usersettings/SettingsView.kt | 7 +- .../commonMain/resources/MR/base/strings.xml | 2 + .../kotlin/chat/simplex/common/DesktopApp.kt | 5 +- .../views/usersettings/Appearance.desktop.kt | 61 +++++++++++++++++ 24 files changed, 245 insertions(+), 70 deletions(-) diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/PlatformTextField.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/PlatformTextField.android.kt index 9e28c4f2bc..f49196c64a 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/PlatformTextField.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/PlatformTextField.android.kt @@ -29,6 +29,7 @@ import androidx.core.widget.doAfterTextChanged import androidx.core.widget.doOnTextChanged import chat.simplex.common.R import chat.simplex.common.helpers.toURI +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.model.ChatModel import chat.simplex.common.ui.theme.CurrentColors import chat.simplex.common.views.chat.* @@ -107,7 +108,7 @@ actual fun PlatformTextField( editText.maxLines = 16 editText.inputType = InputType.TYPE_TEXT_FLAG_CAP_SENTENCES or editText.inputType editText.setTextColor(textColor.toArgb()) - editText.textSize = textStyle.value.fontSize.value + editText.textSize = textStyle.value.fontSize.value * appPrefs.fontScale.get() val drawable = androidAppContext.getDrawable(R.drawable.send_msg_view_background)!! DrawableCompat.setTint(drawable, tintColor.toArgb()) editText.background = drawable @@ -135,7 +136,7 @@ actual fun PlatformTextField( editText }) { it.setTextColor(textColor.toArgb()) - it.textSize = textStyle.value.fontSize.value + it.textSize = textStyle.value.fontSize.value * appPrefs.fontScale.get() DrawableCompat.setTint(it.background, tintColor.toArgb()) it.isFocusable = composeState.value.preview !is ComposePreview.VoicePreview it.isFocusableInTouchMode = it.isFocusable diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt index d6af35432d..8d4ab3206a 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt @@ -554,7 +554,7 @@ fun CallPermissionsView(pipActive: Boolean, hasVideo: Boolean, cancel: () -> Uni } } else { ColumnWithScrollBar(Modifier.fillMaxSize()) { - Spacer(Modifier.height(AppBarHeight)) + Spacer(Modifier.height(AppBarHeight * fontSizeSqrtMultiplier)) AppBarTitle(stringResource(MR.strings.permissions_required)) Spacer(Modifier.weight(1f)) diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt index 7cb5c77f6e..9601152773 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt @@ -137,6 +137,9 @@ fun AppearanceScope.AppearanceLayout( } } + SectionDividerSpaced(maxBottomPadding = true) + FontScaleSection() + SectionBottomSpacer() } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt index b215b2b6cd..bd35594ac0 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt @@ -18,6 +18,7 @@ import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.unit.dp import chat.simplex.common.views.usersettings.SetDeliveryReceiptsView import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* import chat.simplex.common.views.CreateFirstProfile @@ -36,6 +37,7 @@ import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import kotlinx.coroutines.* import kotlinx.coroutines.flow.* +import kotlin.math.sqrt data class SettingsViewState( val userPickerState: MutableStateFlow, @@ -333,21 +335,21 @@ fun EndPartOfScreen() { fun DesktopScreen(settingsState: SettingsViewState) { Box { // 56.dp is a size of unused space of settings drawer - Box(Modifier.width(DEFAULT_START_MODAL_WIDTH + 56.dp)) { + Box(Modifier.width(DEFAULT_START_MODAL_WIDTH * fontSizeSqrtMultiplier + 56.dp)) { StartPartOfScreen(settingsState) } - Box(Modifier.widthIn(max = DEFAULT_START_MODAL_WIDTH)) { + Box(Modifier.widthIn(max = DEFAULT_START_MODAL_WIDTH * fontSizeSqrtMultiplier)) { ModalManager.start.showInView() SwitchingUsersView() } - Row(Modifier.padding(start = DEFAULT_START_MODAL_WIDTH).clipToBounds()) { + Row(Modifier.padding(start = DEFAULT_START_MODAL_WIDTH * fontSizeSqrtMultiplier).clipToBounds()) { Box(Modifier.widthIn(min = DEFAULT_MIN_CENTER_MODAL_WIDTH).weight(1f)) { CenterPartOfScreen() } if (ModalManager.end.hasModalsOpen()) { VerticalDivider() } - Box(Modifier.widthIn(max = DEFAULT_END_MODAL_WIDTH).clipToBounds()) { + Box(Modifier.widthIn(max = DEFAULT_END_MODAL_WIDTH * fontSizeSqrtMultiplier).clipToBounds()) { EndPartOfScreen() } } @@ -357,14 +359,14 @@ fun DesktopScreen(settingsState: SettingsViewState) { Box( Modifier .fillMaxSize() - .padding(start = DEFAULT_START_MODAL_WIDTH) + .padding(start = DEFAULT_START_MODAL_WIDTH * fontSizeSqrtMultiplier) .clickable(interactionSource = remember { MutableInteractionSource() }, indication = null, onClick = { ModalManager.start.closeModals() scope.launch { settingsState.scaffoldState.drawerState.close() } }) ) } - VerticalDivider(Modifier.padding(start = DEFAULT_START_MODAL_WIDTH)) + VerticalDivider(Modifier.padding(start = DEFAULT_START_MODAL_WIDTH * fontSizeSqrtMultiplier)) tryOrShowError("UserPicker", error = {}) { UserPicker(chatModel, userPickerState) { scope.launch { if (scaffoldState.drawerState.isOpen) scaffoldState.drawerState.close() else scaffoldState.drawerState.open() } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index 0a42541c75..7633b0c808 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -198,6 +198,8 @@ class AppPreferences { }, settingsThemes) val themeOverrides = mkThemeOverridesPreference() val profileImageCornerRadius = mkFloatPreference(SHARED_PREFS_PROFILE_IMAGE_CORNER_RADIUS, 22.5f) + val fontScale = mkFloatPreference(SHARED_PREFS_FONT_SCALE, 1f) + val densityScale = mkFloatPreference(SHARED_PREFS_DENSITY_SCALE, 1f) val whatsNewVersion = mkStrPreference(SHARED_PREFS_WHATS_NEW_VERSION, null) val lastMigratedVersionCode = mkIntPreference(SHARED_PREFS_LAST_MIGRATED_VERSION_CODE, 0) @@ -380,6 +382,8 @@ class AppPreferences { private const val SHARED_PREFS_THEMES_OLD = "Themes" private const val SHARED_PREFS_THEME_OVERRIDES = "ThemeOverrides" private const val SHARED_PREFS_PROFILE_IMAGE_CORNER_RADIUS = "ProfileImageCornerRadius" + private const val SHARED_PREFS_FONT_SCALE = "FontScale" + private const val SHARED_PREFS_DENSITY_SCALE = "DensityScale" private const val SHARED_PREFS_WHATS_NEW_VERSION = "WhatsNewVersion" private const val SHARED_PREFS_LAST_MIGRATED_VERSION_CODE = "LastMigratedVersionCode" private const val SHARED_PREFS_CUSTOM_DISAPPEARING_MESSAGE_TIME = "CustomDisappearingMessageTime" diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt index f6e113ea13..fb922fe52b 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt @@ -6,6 +6,8 @@ import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.* +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp import chat.simplex.common.model.ChatController import chat.simplex.common.model.ChatController.appPrefs @@ -777,6 +779,7 @@ fun SimpleXTheme(darkTheme: Boolean? = null, content: @Composable () -> Unit) { typography = Typography, shapes = Shapes, content = { + val density = Density(LocalDensity.current.density * desktopDensityScaleMultiplier, LocalDensity.current.fontScale * fontSizeMultiplier) val rememberedAppColors = remember { // Explicitly creating a new object here so we don't mutate the initial [appColors] // provided, and overwrite the values set in it. @@ -791,6 +794,7 @@ fun SimpleXTheme(darkTheme: Boolean? = null, content: @Composable () -> Unit) { LocalContentColor provides MaterialTheme.colors.onBackground, LocalAppColors provides rememberedAppColors, LocalAppWallpaper provides rememberedWallpaper, + LocalDensity provides density, content = content) } ) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt index af9d77b1d0..ec34a73d31 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt @@ -821,9 +821,9 @@ fun ChatInfoToolbar( buttons = barButtons ) - Divider(Modifier.padding(top = AppBarHeight)) + Divider(Modifier.padding(top = AppBarHeight * fontSizeSqrtMultiplier)) - Box(Modifier.fillMaxWidth().wrapContentSize(Alignment.TopEnd).offset(y = AppBarHeight)) { + Box(Modifier.fillMaxWidth().wrapContentSize(Alignment.TopEnd).offset(y = AppBarHeight * fontSizeSqrtMultiplier)) { DefaultDropdownMenu(showMenu) { menuItems.forEach { it() } } @@ -837,9 +837,9 @@ fun ChatInfoToolbarTitle(cInfo: ChatInfo, imageSize: Dp = 40.dp, iconColor: Colo verticalAlignment = Alignment.CenterVertically ) { if (cInfo.incognito) { - IncognitoImage(size = 36.dp, Indigo) + IncognitoImage(size = 36.dp * fontSizeSqrtMultiplier, Indigo) } - ChatInfoImage(cInfo, size = imageSize, iconColor) + ChatInfoImage(cInfo, size = imageSize * fontSizeSqrtMultiplier, iconColor) Column( Modifier.padding(start = 8.dp), horizontalAlignment = Alignment.CenterHorizontally @@ -865,7 +865,7 @@ fun ChatInfoToolbarTitle(cInfo: ChatInfo, imageSize: Dp = 40.dp, iconColor: Colo @Composable private fun ContactVerifiedShield() { - Icon(painterResource(MR.images.ic_verified_user), null, Modifier.size(18.dp).padding(end = 3.dp, top = 1.dp), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_verified_user), null, Modifier.size(18.dp * fontSizeSqrtMultiplier).padding(end = 3.dp, top = 1.dp), tint = MaterialTheme.colors.secondary) } data class CIListState(val scrolled: Boolean, val itemCount: Int, val keyboardState: KeyboardState) @@ -1283,7 +1283,7 @@ val MEMBER_IMAGE_SIZE: Dp = 38.dp @Composable fun MemberImage(member: GroupMember) { - ProfileImage(MEMBER_IMAGE_SIZE, member.memberProfile.image, backgroundColor = MaterialTheme.colors.background) + ProfileImage(MEMBER_IMAGE_SIZE * fontSizeSqrtMultiplier, member.memberProfile.image, backgroundColor = MaterialTheme.colors.background) } @Composable diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt index 24533247ba..a0e1bf8107 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt @@ -13,10 +13,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.font.FontStyle import dev.icerock.moko.resources.compose.painterResource 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.model.ChatModel.controller import chat.simplex.common.model.ChatModel.filesToDelete @@ -884,7 +886,7 @@ fun ComposeView( && !nextSendGrpInv.value IconButton( attachmentClicked, - Modifier.padding(bottom = if (appPlatform.isAndroid) 0.dp else 7.dp), + Modifier.padding(bottom = if (appPlatform.isAndroid) 0.dp else with(LocalDensity.current) { 7.sp.toDp() }), enabled = attachmentEnabled ) { Icon( diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/SendMsgView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/SendMsgView.kt index 779371a07c..192f1b005f 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/SendMsgView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/SendMsgView.kt @@ -15,10 +15,12 @@ import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.* import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.semantics.Role import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.* import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.ui.theme.* import chat.simplex.common.views.chat.item.ItemAction import chat.simplex.common.views.helpers.* @@ -99,7 +101,7 @@ fun SendMsgView( if (showDeleteTextButton.value) { DeleteTextButton(composeState) } - Box(Modifier.align(Alignment.BottomEnd).padding(bottom = if (appPlatform.isAndroid) 0.dp else 5.dp)) { + Box(Modifier.align(Alignment.BottomEnd).padding(bottom = if (appPlatform.isAndroid) 0.dp else with(LocalDensity.current) { 5.sp.toDp() } * fontSizeSqrtMultiplier)) { val sendButtonSize = remember { Animatable(36f) } val sendButtonAlpha = remember { Animatable(1f) } val scope = rememberCoroutineScope() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt index 3417333370..13e88c3b2f 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt @@ -91,7 +91,7 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf if (newChatSheetState.value.isVisible()) hideNewChatSheet(true) else showNewChatSheet() } }, - Modifier.padding(end = DEFAULT_PADDING - 16.dp + endPadding, bottom = DEFAULT_PADDING - 16.dp), + Modifier.padding(end = DEFAULT_PADDING - 16.dp + endPadding, bottom = DEFAULT_PADDING - 16.dp).size(AppBarHeight * fontSizeSqrtMultiplier), elevation = FloatingActionButtonDefaults.elevation( defaultElevation = 0.dp, pressedElevation = 0.dp, @@ -101,7 +101,7 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf backgroundColor = if (!stopped) MaterialTheme.colors.primary else MaterialTheme.colors.secondary, contentColor = Color.White ) { - Icon(if (!newChatSheetState.collectAsState().value.isVisible()) painterResource(MR.images.ic_edit_filled) else painterResource(MR.images.ic_close), stringResource(MR.strings.add_contact_or_create_group)) + Icon(if (!newChatSheetState.collectAsState().value.isVisible()) painterResource(MR.images.ic_edit_filled) else painterResource(MR.images.ic_close), stringResource(MR.strings.add_contact_or_create_group), Modifier.size(24.dp * fontSizeSqrtMultiplier)) } } } @@ -259,7 +259,7 @@ private fun ChatListToolbar(drawerState: DrawerState, userPickerState: MutableSt onSearchValueChanged = {}, buttons = barButtons ) - Divider(Modifier.padding(top = AppBarHeight)) + Divider(Modifier.padding(top = AppBarHeight * fontSizeSqrtMultiplier)) } @Composable @@ -316,7 +316,7 @@ fun UserProfileButton(image: String?, allRead: Boolean, onButtonClicked: () -> U Box { ProfileImage( image = image, - size = 37.dp, + size = 37.dp * fontSizeSqrtMultiplier, color = MaterialTheme.colors.secondaryVariant.mixWith(MaterialTheme.colors.onBackground, 0.97f) ) if (!allRead) { @@ -355,6 +355,7 @@ private fun BoxScope.unreadBadge(text: String? = "") { private fun ToggleFilterEnabledButton() { val pref = remember { ChatController.appPrefs.showUnreadAndFavorites } IconButton(onClick = { pref.set(!pref.get()) }) { + val sp16 = with(LocalDensity.current) { 16.sp.toDp() } Icon( painterResource(MR.images.ic_filter_list), null, @@ -364,7 +365,7 @@ private fun ToggleFilterEnabledButton() { .background(color = if (pref.state.value) MaterialTheme.colors.primary else Color.Unspecified, shape = RoundedCornerShape(50)) .border(width = 1.dp, color = if (pref.state.value) MaterialTheme.colors.primary else Color.Unspecified, shape = RoundedCornerShape(50)) .padding(3.dp) - .size(16.dp) + .size(sp16) ) } } @@ -388,7 +389,7 @@ private fun ChatListSearchBar(listState: LazyListState, searchText: MutableState Row(verticalAlignment = Alignment.CenterVertically) { val focusRequester = remember { FocusRequester() } var focused by remember { mutableStateOf(false) } - Icon(painterResource(MR.images.ic_search), null, Modifier.padding(horizontal = DEFAULT_PADDING_HALF), tint = MaterialTheme.colors.secondary) + Icon(painterResource(MR.images.ic_search), null, Modifier.padding(horizontal = DEFAULT_PADDING_HALF).size(24.dp * fontSizeSqrtMultiplier), tint = MaterialTheme.colors.secondary) SearchTextField( Modifier.weight(1f).onFocusChanged { focused = it.hasFocus }.focusRequester(focusRequester), placeholder = stringResource(MR.strings.search_or_paste_simplex_link), diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatPreviewView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatPreviewView.kt index 336d104d2d..0e215724f7 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatPreviewView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatPreviewView.kt @@ -47,10 +47,11 @@ fun ChatPreviewView( @Composable fun inactiveIcon() { + val sp18 = with(LocalDensity.current) { 18.sp.toDp() } Icon( painterResource(MR.images.ic_cancel_filled), stringResource(MR.strings.icon_descr_group_inactive), - Modifier.size(18.dp).background(MaterialTheme.colors.background, CircleShape), + Modifier.size(sp18).background(MaterialTheme.colors.background, CircleShape), tint = MaterialTheme.colors.secondary ) } @@ -87,10 +88,11 @@ fun ChatPreviewView( @Composable fun VerifiedIcon() { - Icon(painterResource(MR.images.ic_verified_user), null, Modifier.size(19.dp).padding(end = 3.dp, top = 1.dp), tint = MaterialTheme.colors.secondary) + val sp19 = with(LocalDensity.current) { 19.sp.toDp() } + Icon(painterResource(MR.images.ic_verified_user), null, Modifier.size(sp19).padding(end = 3.dp, top = 1.dp), tint = MaterialTheme.colors.secondary) } - fun messageDraft(draft: ComposeState): Pair Unit, Map> { + fun messageDraft(draft: ComposeState, sp20: Dp): Pair Unit, Map> { fun attachment(): Pair? = when (draft.preview) { is ComposePreview.FilePreview -> MR.images.ic_draft_filled to draft.preview.fileName @@ -115,12 +117,12 @@ fun ChatPreviewView( "editIcon" to InlineTextContent( Placeholder(20.sp, 20.sp, PlaceholderVerticalAlign.TextCenter) ) { - Icon(painterResource(MR.images.ic_edit_note), null, tint = MaterialTheme.colors.primary) + Icon(painterResource(MR.images.ic_edit_note), null, Modifier.size(sp20), tint = MaterialTheme.colors.primary) }, "attachmentIcon" to InlineTextContent( Placeholder(20.sp, 20.sp, PlaceholderVerticalAlign.TextCenter) ) { - Icon(if (attachment?.first != null) painterResource(attachment.first) else painterResource(MR.images.ic_edit_note), null, tint = MaterialTheme.colors.secondary) + Icon(if (attachment?.first != null) painterResource(attachment.first) else painterResource(MR.images.ic_edit_note), null, Modifier.size(sp20), tint = MaterialTheme.colors.secondary) } ) return inlineContentBuilder to inlineContent @@ -167,8 +169,9 @@ fun ChatPreviewView( val ci = chat.chatItems.lastOrNull() if (ci != null) { if (showChatPreviews || (chatModelDraftChatId == chat.id && chatModelDraft != null)) { + val sp20 = with(LocalDensity.current) { 20.sp.toDp() } val (text: CharSequence, inlineTextContent) = when { - chatModelDraftChatId == chat.id && chatModelDraft != null -> remember(chatModelDraft) { chatModelDraft.message to messageDraft(chatModelDraft) } + chatModelDraftChatId == chat.id && chatModelDraft != null -> remember(chatModelDraft) { chatModelDraft.message to messageDraft(chatModelDraft, sp20) } ci.meta.itemDeleted == null -> ci.text to null else -> markedDeletedText(ci.meta) to null } @@ -220,10 +223,11 @@ fun ChatPreviewView( @Composable fun progressView() { + val sp15 = with(LocalDensity.current) { 15.sp.toDp() } CircularProgressIndicator( Modifier .padding(horizontal = 2.dp) - .size(15.dp), + .size(sp15), color = MaterialTheme.colors.secondary, strokeWidth = 1.5.dp ) @@ -231,6 +235,7 @@ fun ChatPreviewView( @Composable fun chatStatusImage() { + val sp19 = with(LocalDensity.current) { 19.sp.toDp() } if (cInfo is ChatInfo.Direct) { if (cInfo.contact.active && cInfo.contact.activeConn != null) { val descr = contactNetworkStatus?.statusString @@ -244,7 +249,7 @@ fun ChatPreviewView( contentDescription = descr, tint = MaterialTheme.colors.secondary, modifier = Modifier - .size(19.dp) + .size(sp19) ) else -> @@ -266,7 +271,7 @@ fun ChatPreviewView( Row { Box(contentAlignment = Alignment.BottomEnd) { - ChatInfoImage(cInfo, size = 72.dp) + ChatInfoImage(cInfo, size = 72.dp * fontSizeSqrtMultiplier) Box(Modifier.padding(end = 6.dp, bottom = 6.dp)) { chatPreviewImageOverlayIcon() } @@ -295,9 +300,13 @@ fun ChatPreviewView( ) val n = chat.chatStats.unreadCount val showNtfsIcon = !chat.chatInfo.ntfsEnabled && (chat.chatInfo is ChatInfo.Direct || chat.chatInfo is ChatInfo.Group) + val sp17 = with(LocalDensity.current) { 17.sp.toDp() } + val sp21 = with(LocalDensity.current) { 21.sp.toDp() } + val sp23 = with(LocalDensity.current) { 23.sp.toDp() } + val sp46 = with(LocalDensity.current) { 46.sp.toDp() } if (n > 0 || chat.chatStats.unreadChat) { Box( - Modifier.padding(top = 24.dp), + Modifier.padding(top = sp23, end = with(LocalDensity.current) { 3.sp.toDp() }), contentAlignment = Alignment.Center ) { Text( @@ -313,7 +322,7 @@ fun ChatPreviewView( } } else if (showNtfsIcon) { Box( - Modifier.padding(top = 24.dp), + Modifier.padding(top = sp21), contentAlignment = Alignment.Center ) { Icon( @@ -323,12 +332,12 @@ fun ChatPreviewView( modifier = Modifier .padding(horizontal = 3.dp) .padding(vertical = 1.dp) - .size(17.dp) + .size(sp17) ) } } else if (chat.chatInfo.chatSettings?.favorite == true) { Box( - Modifier.padding(top = 24.dp), + Modifier.padding(top = sp21), contentAlignment = Alignment.Center ) { Icon( @@ -338,12 +347,12 @@ fun ChatPreviewView( modifier = Modifier .padding(horizontal = 3.dp) .padding(vertical = 1.dp) - .size(17.dp) + .size(sp17) ) } } Box( - Modifier.padding(top = 50.dp), + Modifier.padding(top = sp46), contentAlignment = Alignment.Center ) { chatStatusImage() @@ -355,12 +364,13 @@ fun ChatPreviewView( @Composable fun IncognitoIcon(incognito: Boolean) { if (incognito) { + val sp21 = with(LocalDensity.current) { 21.sp.toDp() } Icon( painterResource(MR.images.ic_theater_comedy), contentDescription = null, tint = MaterialTheme.colors.secondary, modifier = Modifier - .size(21.dp) + .size(sp21) ) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ServersSummaryView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ServersSummaryView.kt index 22478c18f9..5a3f09919e 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ServersSummaryView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ServersSummaryView.kt @@ -26,6 +26,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp @@ -126,6 +127,7 @@ fun SubscriptionStatusIndicatorView(subs: SMPServerSubs, sess: ServerSessions, l horizontalArrangement = Arrangement.spacedBy(DEFAULT_SPACE_AFTER_ICON) ) { if (pref.state.value && leadingPercentage) SubscriptionStatusIndicatorPercentage(percentageText) + val sp16 = with(LocalDensity.current) { 16.sp.toDp() } SubscriptionStatusIcon( color = when(statusColorAndPercentage.color) { SubscriptionColorType.ACTIVE -> MaterialTheme.colors.primary @@ -133,7 +135,7 @@ fun SubscriptionStatusIndicatorView(subs: SMPServerSubs, sess: ServerSessions, l SubscriptionColorType.ACTIVE_DISCONNECTED -> WarningOrange SubscriptionColorType.DISCONNECTED -> MaterialTheme.colors.secondary }, - modifier = Modifier.size(16.dp), + modifier = Modifier.size(sp16), variableValue = statusColorAndPercentage.variableValue) if (pref.state.value && !leadingPercentage) SubscriptionStatusIndicatorPercentage(percentageText) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/UserPicker.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/UserPicker.kt index 23272fcc0c..8199a3f2d6 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/UserPicker.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/UserPicker.kt @@ -309,7 +309,7 @@ fun UserProfileRow(u: User, enabled: Boolean = chatModel.chatRunning.value == tr ) { ProfileImage( image = u.image, - size = 54.dp + size = 54.dp * fontSizeSqrtMultiplier ) Text( u.displayName, @@ -354,7 +354,7 @@ fun RemoteHostRow(h: RemoteHostInfo) { .padding(start = 17.dp), verticalAlignment = Alignment.CenterVertically ) { - Icon(painterResource(MR.images.ic_smartphone_300), h.hostDeviceName, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) + Icon(painterResource(MR.images.ic_smartphone_300), h.hostDeviceName, Modifier.size(20.dp * fontSizeSqrtMultiplier), tint = MaterialTheme.colors.onBackground) Text( h.hostDeviceName, modifier = Modifier.padding(start = 26.dp, end = 8.dp), @@ -395,7 +395,7 @@ fun LocalDeviceRow(active: Boolean) { .padding(start = 17.dp, end = DEFAULT_PADDING), verticalAlignment = Alignment.CenterVertically ) { - Icon(painterResource(MR.images.ic_desktop), stringResource(MR.strings.this_device), Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) + Icon(painterResource(MR.images.ic_desktop), stringResource(MR.strings.this_device), Modifier.size(20.dp * fontSizeSqrtMultiplier), tint = MaterialTheme.colors.onBackground) Text( stringResource(MR.strings.this_device), modifier = Modifier.padding(start = 26.dp, end = 8.dp), @@ -409,7 +409,7 @@ fun LocalDeviceRow(active: Boolean) { private fun UseFromDesktopPickerItem(onClick: () -> Unit) { SectionItemView(onClick, padding = PaddingValues(start = DEFAULT_PADDING + 7.dp, end = DEFAULT_PADDING), minHeight = 68.dp) { val text = generalGetString(MR.strings.settings_section_title_use_from_desktop).lowercase().capitalize(Locale.current) - Icon(painterResource(MR.images.ic_desktop), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) + Icon(painterResource(MR.images.ic_desktop), text, Modifier.size(20.dp * fontSizeSqrtMultiplier), tint = MaterialTheme.colors.onBackground) Spacer(Modifier.width(DEFAULT_PADDING + 6.dp)) Text(text, color = MenuTextColor) } @@ -419,7 +419,7 @@ private fun UseFromDesktopPickerItem(onClick: () -> Unit) { private fun LinkAMobilePickerItem(onClick: () -> Unit) { SectionItemView(onClick, padding = PaddingValues(start = DEFAULT_PADDING + 7.dp, end = DEFAULT_PADDING), minHeight = 68.dp) { val text = generalGetString(MR.strings.link_a_mobile) - Icon(painterResource(MR.images.ic_smartphone_300), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) + Icon(painterResource(MR.images.ic_smartphone_300), text, Modifier.size(20.dp * fontSizeSqrtMultiplier), tint = MaterialTheme.colors.onBackground) Spacer(Modifier.width(DEFAULT_PADDING + 6.dp)) Text(text, color = MenuTextColor) } @@ -429,7 +429,7 @@ private fun LinkAMobilePickerItem(onClick: () -> Unit) { private fun CreateInitialProfile(onClick: () -> Unit) { SectionItemView(onClick, padding = PaddingValues(start = DEFAULT_PADDING + 7.dp, end = DEFAULT_PADDING), minHeight = 68.dp) { val text = generalGetString(MR.strings.create_chat_profile) - Icon(painterResource(MR.images.ic_manage_accounts), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) + Icon(painterResource(MR.images.ic_manage_accounts), text, Modifier.size(20.dp * fontSizeSqrtMultiplier), tint = MaterialTheme.colors.onBackground) Spacer(Modifier.width(DEFAULT_PADDING + 6.dp)) Text(text, color = MenuTextColor) } @@ -439,7 +439,7 @@ private fun CreateInitialProfile(onClick: () -> Unit) { private fun SettingsPickerItem(onClick: () -> Unit) { SectionItemView(onClick, padding = PaddingValues(start = DEFAULT_PADDING + 7.dp, end = DEFAULT_PADDING), minHeight = 68.dp) { val text = generalGetString(MR.strings.settings_section_title_settings).lowercase().capitalize(Locale.current) - Icon(painterResource(MR.images.ic_settings), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) + Icon(painterResource(MR.images.ic_settings), text, Modifier.size(20.dp * fontSizeSqrtMultiplier), tint = MaterialTheme.colors.onBackground) Spacer(Modifier.width(DEFAULT_PADDING + 6.dp)) Text(text, color = MenuTextColor) } @@ -449,7 +449,7 @@ private fun SettingsPickerItem(onClick: () -> Unit) { private fun CancelPickerItem(onClick: () -> Unit) { SectionItemView(onClick, padding = PaddingValues(start = DEFAULT_PADDING + 7.dp, end = DEFAULT_PADDING), minHeight = 68.dp) { val text = generalGetString(MR.strings.cancel_verb) - Icon(painterResource(MR.images.ic_close), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) + Icon(painterResource(MR.images.ic_close), text, Modifier.size(20.dp * fontSizeSqrtMultiplier), tint = MaterialTheme.colors.onBackground) Spacer(Modifier.width(DEFAULT_PADDING + 6.dp)) Text(text, color = MenuTextColor) } @@ -459,7 +459,7 @@ private fun CancelPickerItem(onClick: () -> Unit) { fun HostDisconnectButton(onClick: (() -> Unit)?) { val interactionSource = remember { MutableInteractionSource() } val hovered = interactionSource.collectIsHoveredAsState().value - IconButton(onClick ?: {}, Modifier.requiredSize(20.dp), enabled = onClick != null) { + IconButton(onClick ?: {}, Modifier.requiredSize(20.dp * fontSizeSqrtMultiplier), enabled = onClick != null) { Icon( painterResource(if (onClick == null) MR.images.ic_desktop else if (hovered) MR.images.ic_wifi_off else MR.images.ic_wifi), null, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/CloseSheetBar.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/CloseSheetBar.kt index b26a047b0e..d92dccddc2 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/CloseSheetBar.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/CloseSheetBar.kt @@ -22,15 +22,13 @@ fun CloseSheetBar(close: (() -> Unit)?, showClose: Boolean = true, tintColor: Co Column( Modifier .fillMaxWidth() - .heightIn(min = AppBarHeight) - .padding(horizontal = AppBarHorizontalPadding), + .heightIn(min = AppBarHeight * fontSizeSqrtMultiplier) + .padding(horizontal = AppBarHorizontalPadding) ) { Row( - Modifier - .padding(top = 4.dp), // Like in DefaultAppBar content = { Row( - Modifier.fillMaxWidth().height(TextFieldDefaults.MinHeight), + Modifier.fillMaxWidth().height(AppBarHeight * fontSizeSqrtMultiplier), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/DefaultTopAppBar.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/DefaultTopAppBar.kt index 577411c7e3..3d6d242832 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/DefaultTopAppBar.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/DefaultTopAppBar.kt @@ -7,6 +7,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.* +import androidx.compose.ui.unit.Dp import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp @@ -44,10 +45,10 @@ fun DefaultTopAppBar( } @Composable -fun NavigationButtonBack(onButtonClicked: (() -> Unit)?, tintColor: Color = if (onButtonClicked != null) MaterialTheme.colors.primary else MaterialTheme.colors.secondary) { +fun NavigationButtonBack(onButtonClicked: (() -> Unit)?, tintColor: Color = if (onButtonClicked != null) MaterialTheme.colors.primary else MaterialTheme.colors.secondary, height: Dp = 24.dp) { IconButton(onButtonClicked ?: {}, enabled = onButtonClicked != null) { Icon( - painterResource(MR.images.ic_arrow_back_ios_new), stringResource(MR.strings.back), tint = tintColor + painterResource(MR.images.ic_arrow_back_ios_new), stringResource(MR.strings.back), Modifier.height(height), tint = tintColor ) } } @@ -84,7 +85,7 @@ private fun TopAppBar( Box( modifier .fillMaxWidth() - .height(AppBarHeight) + .height(AppBarHeight * fontSizeSqrtMultiplier) .background(backgroundColor) .padding(horizontal = 4.dp), contentAlignment = Alignment.CenterStart, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt index d7116d11b6..4acb18561a 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt @@ -8,12 +8,14 @@ import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.model.ChatModel import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* import kotlinx.coroutines.flow.MutableStateFlow import java.util.concurrent.atomic.AtomicBoolean import kotlin.math.min +import kotlin.math.sqrt @Composable fun ModalView( @@ -89,7 +91,7 @@ class ModalManager(private val placement: ModalPlacement? = null) { if (placement == ModalPlacement.CENTER) { ChatModel.chatId.value = null } else if (placement == ModalPlacement.END) { - desktopExpandWindowToWidth(DEFAULT_START_MODAL_WIDTH + DEFAULT_MIN_CENTER_MODAL_WIDTH + DEFAULT_END_MODAL_WIDTH) + desktopExpandWindowToWidth(DEFAULT_START_MODAL_WIDTH * sqrt(appPrefs.fontScale.get()) + DEFAULT_MIN_CENTER_MODAL_WIDTH + DEFAULT_END_MODAL_WIDTH * sqrt(appPrefs.fontScale.get())) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt index 884551f600..ccef86c343 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt @@ -8,6 +8,7 @@ import androidx.compose.ui.platform.* import androidx.compose.ui.text.* import androidx.compose.ui.unit.* import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.ThemeOverrides import chat.simplex.common.views.chatlist.connectIfOpenedViaUri @@ -519,6 +520,15 @@ fun includeMoreFailedComposables() { lastExecutedComposables.clear() } +val fontSizeMultiplier: Float + @Composable get() = remember { appPrefs.fontScale.state }.value + +val fontSizeSqrtMultiplier: Float + @Composable get() = sqrt(remember { appPrefs.fontScale.state }.value) + +val desktopDensityScaleMultiplier: Float + @Composable get() = if (appPlatform.isDesktop) remember { appPrefs.densityScale.state }.value else 1f + @Composable fun DisposableEffectOnGone(always: () -> Unit = {}, whenDispose: () -> Unit = {}, whenGone: () -> Unit) { DisposableEffect(Unit) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt index f8e3d48625..3cc5468bbb 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.model.ChatController.getNetCfg import chat.simplex.common.model.ChatController.startChat import chat.simplex.common.model.ChatController.startChatWithTemporaryDatabase @@ -38,6 +39,7 @@ import kotlinx.serialization.* import java.io.File import java.net.URLEncoder import kotlin.math.max +import kotlin.math.sqrt @Serializable data class MigrationFileLinkData( @@ -426,7 +428,8 @@ fun LargeProgressView(value: Float, title: String, description: String) { Box(Modifier.padding(DEFAULT_PADDING).fillMaxSize(), contentAlignment = Alignment.Center) { CircularProgressIndicator( progress = value, - (if (appPlatform.isDesktop) Modifier.size(DEFAULT_START_MODAL_WIDTH) else Modifier.size(windowWidth() - DEFAULT_PADDING * 2)) + (if (appPlatform.isDesktop) Modifier.size(DEFAULT_START_MODAL_WIDTH * fontSizeSqrtMultiplier) else Modifier.size(windowWidth() - DEFAULT_PADDING * + 2)) .rotate(-90f), color = MaterialTheme.colors.primary, strokeWidth = 25.dp diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt index 9f47a5cdf9..9faee4532a 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt @@ -125,11 +125,11 @@ private fun NewChatSheetLayout( Box(contentAlignment = Alignment.CenterEnd) { Button( actions[index], - shape = RoundedCornerShape(21.dp), + shape = RoundedCornerShape(21.dp * fontSizeSqrtMultiplier), colors = ButtonDefaults.textButtonColors(backgroundColor = backgroundColor), elevation = null, contentPadding = PaddingValues(horizontal = DEFAULT_PADDING_HALF, vertical = DEFAULT_PADDING_HALF), - modifier = Modifier.height(42.dp) + modifier = Modifier.height(42.dp * fontSizeSqrtMultiplier) ) { Text( stringResource(titles[index]), @@ -140,7 +140,7 @@ private fun NewChatSheetLayout( Icon( painterResource(icons[index]), stringResource(titles[index]), - Modifier.size(42.dp), + Modifier.size(42.dp * fontSizeSqrtMultiplier), tint = if (isInDarkTheme()) MaterialTheme.colors.primary else MaterialTheme.colors.primary ) } @@ -152,7 +152,7 @@ private fun NewChatSheetLayout( } FloatingActionButton( onClick = { if (!stopped) closeNewChatSheet(true) }, - Modifier.padding(end = DEFAULT_PADDING, bottom = DEFAULT_PADDING), + Modifier.padding(end = DEFAULT_PADDING, bottom = DEFAULT_PADDING).size(AppBarHeight * fontSizeSqrtMultiplier), elevation = FloatingActionButtonDefaults.elevation( defaultElevation = 0.dp, pressedElevation = 0.dp, @@ -164,11 +164,11 @@ private fun NewChatSheetLayout( ) { Icon( painterResource(MR.images.ic_edit_filled), stringResource(MR.strings.add_contact_or_create_group), - Modifier.graphicsLayer { alpha = 1 - animatedFloat.value } + Modifier.graphicsLayer { alpha = 1 - animatedFloat.value }.size(24.dp * fontSizeSqrtMultiplier) ) Icon( painterResource(MR.images.ic_close), stringResource(MR.strings.add_contact_or_create_group), - Modifier.graphicsLayer { alpha = animatedFloat.value } + Modifier.graphicsLayer { alpha = animatedFloat.value }.size(24.dp * fontSizeSqrtMultiplier) ) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt index 84fe333ba8..5fda4b7d1d 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt @@ -19,6 +19,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.* import androidx.compose.ui.graphics.* import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.* import dev.icerock.moko.resources.compose.painterResource @@ -82,6 +83,66 @@ object AppearanceScope { } } + @Composable + fun FontScaleSection() { + val localFontScale = remember { mutableStateOf(appPrefs.fontScale.get()) } + SectionView(stringResource(MR.strings.appearance_font_size).uppercase(), padding = PaddingValues(horizontal = DEFAULT_PADDING)) { + Row(Modifier.padding(top = 10.dp), verticalAlignment = Alignment.CenterVertically) { + Box(Modifier.size(60.dp) + .background(MaterialTheme.colors.surface, RoundedCornerShape(percent = 22)) + .clip(RoundedCornerShape(percent = 22)) + .clickable { + localFontScale.value = 1f + appPrefs.fontScale.set(localFontScale.value) + }, + contentAlignment = Alignment.Center) { + CompositionLocalProvider( + LocalDensity provides Density(LocalDensity.current.density, localFontScale.value) + ) { + Text("Aa", color = if (localFontScale.value == 1f) MaterialTheme.colors.primary else MaterialTheme.colors.onBackground) + } + } + Spacer(Modifier.width(10.dp)) + // Text("${(localFontScale.value * 100).roundToInt()}%", Modifier.width(70.dp), textAlign = TextAlign.Center, fontSize = 12.sp) + if (appPlatform.isAndroid) { + Slider( + localFontScale.value, + valueRange = 0.75f..1.25f, + steps = 11, + onValueChange = { + val diff = it % 0.05f + localFontScale.value = String.format(Locale.US, "%.2f", it + (if (diff >= 0.025f) -diff + 0.05f else -diff)).toFloatOrNull() ?: 1f + }, + onValueChangeFinished = { + appPrefs.fontScale.set(localFontScale.value) + }, + colors = SliderDefaults.colors( + activeTickColor = Color.Transparent, + inactiveTickColor = Color.Transparent, + ) + ) + } else { + Slider( + localFontScale.value, + valueRange = 0.7f..1.5f, + steps = 9, + onValueChange = { + val diff = it % 0.1f + localFontScale.value = String.format(Locale.US, "%.1f", it + (if (diff >= 0.05f) -diff + 0.1f else -diff)).toFloatOrNull() ?: 1f + }, + onValueChangeFinished = { + appPrefs.fontScale.set(localFontScale.value) + }, + colors = SliderDefaults.colors( + activeTickColor = Color.Transparent, + inactiveTickColor = Color.Transparent, + ) + ) + } + } + } + } + @Composable fun ChatThemePreview( theme: DefaultTheme, @@ -225,8 +286,8 @@ object AppearanceScope { } if (appPlatform.isDesktop) { - val itemWidth = (DEFAULT_START_MODAL_WIDTH - DEFAULT_PADDING * 2 - DEFAULT_PADDING_HALF * 3) / 4 - val itemHeight = (DEFAULT_START_MODAL_WIDTH - DEFAULT_PADDING * 2) / 4 + val itemWidth = (DEFAULT_START_MODAL_WIDTH * fontSizeSqrtMultiplier - DEFAULT_PADDING * 2 - DEFAULT_PADDING_HALF * 3) / 4 + val itemHeight = (DEFAULT_START_MODAL_WIDTH * fontSizeSqrtMultiplier - DEFAULT_PADDING * 2) / 4 val rows = ceil((PresetWallpaper.entries.size + 2) / 4f).roundToInt() LazyVerticalGrid( columns = GridCells.Fixed(4), diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt index 0b5033aca3..cef457de2e 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt @@ -174,11 +174,14 @@ fun SettingsLayout( Box( Modifier .fillMaxWidth() + .height(AppBarHeight * fontSizeSqrtMultiplier) .background(MaterialTheme.colors.background) .background(if (isInDarkTheme()) ToolbarDark else ToolbarLight) - .padding(start = 4.dp, top = 8.dp) + .padding(start = 4.dp, top = 8.dp), + contentAlignment = Alignment.CenterStart ) { - NavigationButtonBack(closeSettings) + val sp24 = with(LocalDensity.current) { 24.sp.toDp() } + NavigationButtonBack(closeSettings, height = sp24) } } } diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index 24c94a5ddc..3452e6ff60 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -1606,6 +1606,8 @@ Wallpaper background Wallpaper accent Remove image + Font size + Zoom Good afternoon! diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/DesktopApp.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/DesktopApp.kt index 4128982f78..df8887c4e1 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/DesktopApp.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/DesktopApp.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.dp import androidx.compose.ui.window.* import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.DEFAULT_START_MODAL_WIDTH import chat.simplex.common.ui.theme.SimpleXTheme @@ -26,6 +27,7 @@ import kotlinx.coroutines.* import java.awt.event.WindowEvent import java.awt.event.WindowFocusListener import java.io.File +import kotlin.math.sqrt import kotlin.system.exitProcess val simplexWindowState = SimplexWindowState() @@ -195,7 +197,8 @@ private fun ApplicationScope.AppWindow(closedByError: MutableState) { if (remember { ChatController.appPrefs.developerTools.state }.value && remember { ChatController.appPrefs.terminalAlwaysVisible.state }.value && remember { ChatController.appPrefs.appLanguage.state }.value != "") { var hiddenUntilRestart by remember { mutableStateOf(false) } if (!hiddenUntilRestart) { - val cWindowState = rememberWindowState(placement = WindowPlacement.Floating, width = DEFAULT_START_MODAL_WIDTH, height = 768.dp) + val cWindowState = rememberWindowState(placement = WindowPlacement.Floating, width = DEFAULT_START_MODAL_WIDTH * fontSizeSqrtMultiplier, height = + 768.dp) Window(state = cWindowState, onCloseRequest = { hiddenUntilRestart = true }, title = stringResource(MR.strings.chat_console)) { SimpleXTheme { TerminalView(ChatModel) { hiddenUntilRestart = true } diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt index 669dd1949d..9f7f613835 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt @@ -3,18 +3,29 @@ package chat.simplex.common.views.usersettings import SectionBottomSpacer import SectionDividerSpaced import SectionView +import androidx.compose.foundation.* import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +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.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.model.ChatModel import chat.simplex.common.model.SharedPreference import chat.simplex.common.platform.* +import chat.simplex.common.ui.theme.DEFAULT_PADDING import chat.simplex.common.views.helpers.* import chat.simplex.res.MR import dev.icerock.moko.resources.compose.stringResource import kotlinx.coroutines.delay import java.util.Locale +import kotlin.math.roundToInt @Composable actual fun AppearanceView(m: ChatModel) { @@ -55,6 +66,56 @@ fun AppearanceScope.AppearanceLayout( SectionDividerSpaced(maxTopPadding = true) ProfileImageSection() + SectionDividerSpaced(maxBottomPadding = true) + FontScaleSection() + + SectionDividerSpaced(maxBottomPadding = true) + DensityScaleSection() + SectionBottomSpacer() } } + +@Composable +fun DensityScaleSection() { + val localDensityScale = remember { mutableStateOf(appPrefs.densityScale.get()) } + SectionView(stringResource(MR.strings.appearance_zoom).uppercase(), padding = PaddingValues(horizontal = DEFAULT_PADDING)) { + Row(Modifier.padding(top = 10.dp), verticalAlignment = Alignment.CenterVertically) { + Box(Modifier.size(60.dp) + .background(MaterialTheme.colors.surface, RoundedCornerShape(percent = 22)) + .clip(RoundedCornerShape(percent = 22)) + .clickable { + localDensityScale.value = 1f + appPrefs.densityScale.set(localDensityScale.value) + }, + contentAlignment = Alignment.Center) { + CompositionLocalProvider( + LocalDensity provides Density(LocalDensity.current.density * localDensityScale.value, LocalDensity.current.fontScale) + ) { + Text("${localDensityScale.value}", + color = if (localDensityScale.value == 1f) MaterialTheme.colors.primary else MaterialTheme.colors.onBackground, + fontSize = 12.sp, + maxLines = 1 + ) + } + } + Spacer(Modifier.width(10.dp)) + Slider( + localDensityScale.value, + valueRange = 1f..2f, + steps = 11, + onValueChange = { + val diff = it % 0.1f + localDensityScale.value = String.format(Locale.US, "%.1f", it + (if (diff >= 0.05f) -diff + 0.1f else -diff)).toFloatOrNull() ?: 1f + }, + onValueChangeFinished = { + appPrefs.densityScale.set(localDensityScale.value) + }, + colors = SliderDefaults.colors( + activeTickColor = Color.Transparent, + inactiveTickColor = Color.Transparent, + ) + ) + } + } +} From e6ee5df158e92cfe216c1165a4af451b43d56934 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Tue, 9 Jul 2024 19:07:44 +0100 Subject: [PATCH 39/43] core: update simplexmq 6.0.0.0 --- cabal.project | 2 +- scripts/nix/sha256map.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cabal.project b/cabal.project index 4efa8ad2fd..dbf6fd8556 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: 9d0774a58e3307892e0b38500fe96fb5d15d9def + tag: 017469b2de65c7e3ef1d680c2da466b320d1b061 source-repository-package type: git diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index 06ecfab261..126ed9af03 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."9d0774a58e3307892e0b38500fe96fb5d15d9def" = "1g8794xspbvlsk0qdv76xjpi7ippa2l87mvkiz0ryks6j7zzcrw0"; + "https://github.com/simplex-chat/simplexmq.git"."017469b2de65c7e3ef1d680c2da466b320d1b061" = "1c6aap31sa4wdv7x771q2l8bs499qg58rrnx80blj33y2zl877c9"; "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"; From 49c29c74df073baab0db3cdeefc5423d7124a5e9 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Tue, 9 Jul 2024 19:41:42 +0100 Subject: [PATCH 40/43] core: 6.0.0.0 --- package.yaml | 2 +- simplex-chat.cabal | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.yaml b/package.yaml index 0bf1c1e858..82ab5a7447 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: simplex-chat -version: 5.8.2.0 +version: 6.0.0.0 #synopsis: #description: homepage: https://github.com/simplex-chat/simplex-chat#readme diff --git a/simplex-chat.cabal b/simplex-chat.cabal index 48cd8a67d4..ee154eceac 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: simplex-chat -version: 5.8.2.0 +version: 6.0.0.0 category: Web, System, Services, Cryptography homepage: https://github.com/simplex-chat/simplex-chat#readme author: simplex.chat From 93a4c0854e3278d92b9b4b033cc208e0d7526da2 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Wed, 10 Jul 2024 00:28:01 +0400 Subject: [PATCH 41/43] desktop, android: show inactive and forwarded group message status; show inactive members (#4426) * multiplatform: differentiate inactive and forwarded group snd statuses; show member connection disabled/inactive * forward icon --------- Co-authored-by: Evgeny Poberezkin --- .../chat/simplex/common/model/ChatModel.kt | 52 +++++++++++++++++-- .../common/views/chat/ChatItemInfoView.kt | 25 +++------ .../views/chat/group/GroupChatInfoView.kt | 14 ++++- .../views/chat/group/GroupMemberInfoView.kt | 14 ++--- .../commonMain/resources/MR/base/strings.xml | 7 +++ .../MR/images/ic_chevron_right_2.svg | 10 ++++ .../resources/MR/images/ic_person_off.svg | 1 + 7 files changed, 94 insertions(+), 29 deletions(-) create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_chevron_right_2.svg create mode 100644 apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person_off.svg diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index c155010a28..795baece0c 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -1172,18 +1172,22 @@ data class Connection( val pqSndEnabled: Boolean? = null, val pqRcvEnabled: Boolean? = null, val connectionStats: ConnectionStats? = null, - val authErrCounter: Int + val authErrCounter: Int, + val quotaErrCounter: Int ) { val id: ChatId get() = ":$connId" val connDisabled: Boolean get() = authErrCounter >= 10 // authErrDisableCount in core + val connInactive: Boolean + get() = quotaErrCounter >= 5 // quotaErrInactiveCount in core + val connPQEnabled: Boolean get() = pqSndEnabled == true && pqRcvEnabled == true companion object { - val sampleData = Connection(connId = 1, agentConnId = "abc", connStatus = ConnStatus.Ready, connLevel = 0, viaGroupLink = false, peerChatVRange = VersionRange(1, 1), customUserProfileId = null, pqSupport = false, pqEncryption = false, authErrCounter = 0) + val sampleData = Connection(connId = 1, agentConnId = "abc", connStatus = ConnStatus.Ready, connLevel = 0, viaGroupLink = false, peerChatVRange = VersionRange(1, 1), customUserProfileId = null, pqSupport = false, pqEncryption = false, authErrCounter = 0, quotaErrCounter = 0) } } @@ -2352,6 +2356,48 @@ enum class SndCIStatusProgress { @SerialName("complete") Complete; } +@Serializable +sealed class GroupSndStatus { + @Serializable @SerialName("new") class New: GroupSndStatus() + @Serializable @SerialName("forwarded") class Forwarded: GroupSndStatus() + @Serializable @SerialName("inactive") class Inactive: GroupSndStatus() + @Serializable @SerialName("sent") class Sent: GroupSndStatus() + @Serializable @SerialName("rcvd") class Rcvd(val msgRcptStatus: MsgReceiptStatus): GroupSndStatus() + @Serializable @SerialName("error") class Error(val agentError: SndError): GroupSndStatus() + @Serializable @SerialName("warning") class Warning(val agentError: SndError): GroupSndStatus() + @Serializable @SerialName("invalid") class Invalid(val text: String): GroupSndStatus() + + fun statusIcon( + primaryColor: Color, + metaColor: Color = CurrentColors.value.colors.secondary, + paleMetaColor: Color = CurrentColors.value.colors.secondary + ): Pair = + when (this) { + is New -> MR.images.ic_more_horiz to metaColor + is Forwarded -> MR.images.ic_chevron_right_2 to metaColor + is Inactive -> MR.images.ic_person_off to metaColor + is Sent -> MR.images.ic_check_filled to metaColor + is Rcvd -> when(this.msgRcptStatus) { + MsgReceiptStatus.Ok -> MR.images.ic_double_check to metaColor + MsgReceiptStatus.BadMsgHash -> MR.images.ic_double_check to Color.Red + } + is Error -> MR.images.ic_close to Color.Red + is Warning -> MR.images.ic_warning_filled to WarningOrange + is Invalid -> MR.images.ic_question_mark to metaColor + } + + val statusInto: Pair? get() = when (this) { + is New -> null + is Forwarded -> generalGetString(MR.strings.message_forwarded_title) to generalGetString(MR.strings.message_forwarded_desc) + is Inactive -> generalGetString(MR.strings.member_inactive_title) to generalGetString(MR.strings.member_inactive_desc) + is Sent -> null + is Rcvd -> null + is Error -> generalGetString(MR.strings.message_delivery_error_title) to agentError.errorInfo + is Warning -> generalGetString(MR.strings.message_delivery_warning_title) to agentError.errorInfo + is Invalid -> "Invalid status" to this.text + } +} + @Serializable sealed class CIDeleted { @Serializable @SerialName("deleted") class Deleted(val deletedTs: Instant?): CIDeleted() @@ -3466,7 +3512,7 @@ data class ChatItemVersion( @Serializable data class MemberDeliveryStatus( val groupMemberId: Long, - val memberDeliveryStatus: CIStatus, + val memberDeliveryStatus: GroupSndStatus, val sentViaProxy: Boolean? ) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt index c23a6ad00e..797d8e66b8 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt @@ -330,7 +330,7 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools } @Composable - fun MemberDeliveryStatusView(member: GroupMember, status: CIStatus, sentViaProxy: Boolean?) { + fun MemberDeliveryStatusView(member: GroupMember, status: GroupSndStatus, sentViaProxy: Boolean?) { SectionItemView( padding = PaddingValues(horizontal = 0.dp) ) { @@ -355,7 +355,7 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools ) } } - val statusIcon = status.statusIcon(MaterialTheme.colors.primary, CurrentColors.value.colors.secondary) + val (icon, statusColor) = status.statusIcon(MaterialTheme.colors.primary, CurrentColors.value.colors.secondary) var modifier = Modifier.size(36.dp).clip(RoundedCornerShape(20.dp)) val info = status.statusInto if (info != null) { @@ -367,20 +367,11 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools } } Box(modifier, contentAlignment = Alignment.Center) { - if (statusIcon != null) { - val (icon, statusColor) = statusIcon - Icon( - painterResource(icon), - contentDescription = null, - tint = statusColor - ) - } else { - Icon( - painterResource(MR.images.ic_more_horiz), - contentDescription = null, - tint = CurrentColors.value.colors.secondary - ) - } + Icon( + painterResource(icon), + contentDescription = null, + tint = statusColor + ) } } } @@ -520,7 +511,7 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools } } -private fun membersStatuses(chatModel: ChatModel, memberDeliveryStatuses: List): List> { +private fun membersStatuses(chatModel: ChatModel, memberDeliveryStatuses: List): List> { return memberDeliveryStatuses.mapNotNull { mds -> chatModel.getGroupMember(mds.groupMemberId)?.let { mem -> Triple(mem, mds.memberDeliveryStatus, mds.sentViaProxy) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt index b60c1f2496..c91bc3bcfc 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt @@ -390,6 +390,16 @@ private fun MemberRow(member: GroupMember, user: Boolean = false, onClick: (() - } } + fun memberConnStatus(): String { + return if (member.activeConn?.connDisabled == true) { + generalGetString(MR.strings.member_info_member_disabled) + } else if (member.activeConn?.connDisabled == true) { + generalGetString(MR.strings.member_info_member_inactive) + } else { + member.memberStatus.shortText + } + } + Row( Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, @@ -412,8 +422,8 @@ private fun MemberRow(member: GroupMember, user: Boolean = false, onClick: (() - color = if (member.memberIncognito) Indigo else Color.Unspecified ) } - val s = member.memberStatus.shortText - val statusDescr = if (user) String.format(generalGetString(MR.strings.group_info_member_you), s) else s + val statusDescr = + if (user) String.format(generalGetString(MR.strings.group_info_member_you), member.memberStatus.shortText) else memberConnStatus() Text( statusDescr, color = MaterialTheme.colors.secondary, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt index 2799904b71..98b9ca729f 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt @@ -358,13 +358,6 @@ fun GroupMemberInfoLayout( } else { InfoRow(stringResource(MR.strings.role_in_group), member.memberRole.text) } - val conn = member.activeConn - if (conn != null) { - val connLevelDesc = - if (conn.connLevel == 0) stringResource(MR.strings.conn_level_desc_direct) - else String.format(generalGetString(MR.strings.conn_level_desc_indirect), conn.connLevel) - InfoRow(stringResource(MR.strings.info_row_connection), connLevelDesc) - } } if (cStats != null) { SectionDividerSpaced() @@ -401,6 +394,13 @@ fun GroupMemberInfoLayout( SectionView(title = stringResource(MR.strings.section_title_for_console)) { InfoRow(stringResource(MR.strings.info_row_local_name), member.localDisplayName) InfoRow(stringResource(MR.strings.info_row_database_id), member.groupMemberId.toString()) + val conn = member.activeConn + if (conn != null) { + val connLevelDesc = + if (conn.connLevel == 0) stringResource(MR.strings.conn_level_desc_direct) + else String.format(generalGetString(MR.strings.conn_level_desc_indirect), conn.connLevel) + InfoRow(stringResource(MR.strings.info_row_connection), connLevelDesc) + } SectionItemView({ withBGApi { val info = controller.apiGroupMemberQueueInfo(rhId, groupInfo.apiId, member.groupMemberId) diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index 3452e6ff60..f3d78eef20 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -324,6 +324,11 @@ Forward Download + Message forwarded + Connection is not established yet, message is forwarded by group admin. + Member inactive + Message is pending delivery when member becomes active. + edited sent @@ -1461,6 +1466,8 @@ Messages from %s will be shown! Blocked by admin blocked + disabled + inactive MEMBER Role Change role diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_chevron_right_2.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_chevron_right_2.svg new file mode 100644 index 0000000000..ef2a9e9865 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_chevron_right_2.svg @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person_off.svg b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person_off.svg new file mode 100644 index 0000000000..a583950023 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/resources/MR/images/ic_person_off.svg @@ -0,0 +1 @@ + \ No newline at end of file From c4f8a50f0d60df9ad2556439e468841802762a8f Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Wed, 10 Jul 2024 00:52:33 +0400 Subject: [PATCH 42/43] ios: show inactive and forwarded group message status; show inactive members (#4423) * ios: differentiate inactive and forwarded group snd statuses; show member connection disabled/inactive * lazy * simplify * Update apps/ios/SimpleXChat/ChatTypes.swift * export localizations, update strings --------- Co-authored-by: Evgeny Poberezkin --- .../Shared/Views/Chat/ChatItemInfoView.swift | 32 ++++----- .../Views/Chat/Group/GroupChatInfoView.swift | 13 +++- .../Chat/Group/GroupMemberInfoView.swift | 10 ++- .../bg.xcloc/Localized Contents/bg.xliff | 20 ++++++ .../cs.xcloc/Localized Contents/cs.xliff | 20 ++++++ .../de.xcloc/Localized Contents/de.xliff | 20 ++++++ .../en.xcloc/Localized Contents/en.xliff | 25 +++++++ .../es.xcloc/Localized Contents/es.xliff | 20 ++++++ .../fi.xcloc/Localized Contents/fi.xliff | 20 ++++++ .../fr.xcloc/Localized Contents/fr.xliff | 20 ++++++ .../hu.xcloc/Localized Contents/hu.xliff | 20 ++++++ .../it.xcloc/Localized Contents/it.xliff | 20 ++++++ .../ja.xcloc/Localized Contents/ja.xliff | 20 ++++++ .../nl.xcloc/Localized Contents/nl.xliff | 20 ++++++ .../pl.xcloc/Localized Contents/pl.xliff | 20 ++++++ .../ru.xcloc/Localized Contents/ru.xliff | 20 ++++++ .../th.xcloc/Localized Contents/th.xliff | 20 ++++++ .../tr.xcloc/Localized Contents/tr.xliff | 20 ++++++ .../uk.xcloc/Localized Contents/uk.xliff | 20 ++++++ .../Localized Contents/zh-Hans.xliff | 20 ++++++ apps/ios/SimpleXChat/ChatTypes.swift | 68 ++++++++++++++++++- .../commonMain/resources/MR/base/strings.xml | 4 +- 22 files changed, 441 insertions(+), 31 deletions(-) diff --git a/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift b/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift index 3312833ccc..a46cf03bdf 100644 --- a/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift @@ -415,7 +415,7 @@ struct ChatItemInfoView: View { } @ViewBuilder private func memberDeliveryStatusesView(_ memberDeliveryStatuses: [MemberDeliveryStatus]) -> some View { - VStack(alignment: .leading, spacing: 12) { + LazyVStack(alignment: .leading, spacing: 12) { let mss = membersStatuses(memberDeliveryStatuses) if !mss.isEmpty { ForEach(mss, id: \.0.groupMemberId) { memberStatus in @@ -428,7 +428,7 @@ struct ChatItemInfoView: View { } } - private func membersStatuses(_ memberDeliveryStatuses: [MemberDeliveryStatus]) -> [(GroupMember, CIStatus, Bool?)] { + private func membersStatuses(_ memberDeliveryStatuses: [MemberDeliveryStatus]) -> [(GroupMember, GroupSndStatus, Bool?)] { memberDeliveryStatuses.compactMap({ mds in if let mem = chatModel.getGroupMember(mds.groupMemberId) { return (mem.wrapped, mds.memberDeliveryStatus, mds.sentViaProxy) @@ -438,7 +438,7 @@ struct ChatItemInfoView: View { }) } - private func memberDeliveryStatusView(_ member: GroupMember, _ status: CIStatus, _ sentViaProxy: Bool?) -> some View { + private func memberDeliveryStatusView(_ member: GroupMember, _ status: GroupSndStatus, _ sentViaProxy: Bool?) -> some View { HStack{ ProfileImage(imageStr: member.image, size: 30) .padding(.trailing, 2) @@ -450,23 +450,19 @@ struct ChatItemInfoView: View { .foregroundColor(theme.colors.secondary).opacity(0.67) } let v = Group { - if let (icon, statusColor) = status.statusIcon(theme.colors.secondary, theme.colors.primary) { - switch status { - case .sndRcvd: - ZStack(alignment: .trailing) { - Image(systemName: icon) - .foregroundColor(statusColor.opacity(0.67)) - .padding(.trailing, 6) - Image(systemName: icon) - .foregroundColor(statusColor.opacity(0.67)) - } - default: + let (icon, statusColor) = status.statusIcon(theme.colors.secondary, theme.colors.primary) + switch status { + case .rcvd: + ZStack(alignment: .trailing) { Image(systemName: icon) - .foregroundColor(statusColor) + .foregroundColor(statusColor.opacity(0.67)) + .padding(.trailing, 6) + Image(systemName: icon) + .foregroundColor(statusColor.opacity(0.67)) } - } else { - Image(systemName: "ellipsis") - .foregroundColor(Color.secondary) + default: + Image(systemName: icon) + .foregroundColor(statusColor) } } diff --git a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift index 8fff94871e..eabf7ad8c9 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift @@ -232,8 +232,7 @@ struct GroupChatInfoView: View { let t = Text(member.chatViewName).foregroundColor(member.memberIncognito ? .indigo : theme.colors.onBackground) (member.verified ? memberVerifiedShield + t : t) .lineLimit(1) - let s = Text(member.memberStatus.shortText) - (user ? Text ("you: ") + s : s) + (user ? Text ("you: ") + Text(member.memberStatus.shortText) : Text(memberConnStatus(member))) .lineLimit(1) .font(.caption) .foregroundColor(theme.colors.secondary) @@ -266,6 +265,16 @@ struct GroupChatInfoView: View { } } + private func memberConnStatus(_ member: GroupMember) -> LocalizedStringKey { + if member.activeConn?.connDisabled ?? false { + return "disabled" + } else if member.activeConn?.connInactive ?? false { + return "inactive" + } else { + return member.memberStatus.shortText + } + } + @ViewBuilder private func memberInfo(_ member: GroupMember) -> some View { if member.blocked { Text("blocked") diff --git a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift index deabf1137e..c04ac6ead9 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift @@ -141,12 +141,6 @@ struct GroupMemberInfoView: View { } else { infoRow("Role", member.memberRole.text) } - - // TODO invited by - need to get contact by contact id - if let conn = member.activeConn { - let connLevelDesc = conn.connLevel == 0 ? NSLocalizedString("direct", comment: "connection level description") : String.localizedStringWithFormat(NSLocalizedString("indirect (%d)", comment: "connection level description"), conn.connLevel) - infoRow("Connection", connLevelDesc) - } } if let connStats = connectionStats { @@ -183,6 +177,10 @@ struct GroupMemberInfoView: View { Section(header: Text("For console").foregroundColor(theme.colors.secondary)) { infoRow("Local name", member.localDisplayName) infoRow("Database ID", "\(member.groupMemberId)") + if let conn = member.activeConn { + let connLevelDesc = conn.connLevel == 0 ? NSLocalizedString("direct", comment: "connection level description") : String.localizedStringWithFormat(NSLocalizedString("indirect (%d)", comment: "connection level description"), conn.connLevel) + infoRow("Connection", connLevelDesc) + } Button ("Debug delivery") { Task { do { diff --git a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff index 3d2a5ffb59..7ac1db1557 100644 --- a/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff +++ b/apps/ios/SimpleX Localizations/bg.xcloc/Localized Contents/bg.xliff @@ -3857,6 +3857,10 @@ This is your link for group %@! Член No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. Ролята на члена ще бъде променена на "%@". Всички членове на групата ще бъдат уведомени. @@ -3895,6 +3899,14 @@ This is your link for group %@! Чернова на съобщение No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4206,6 +4218,10 @@ This is your link for group %@! Няма токен за устройство! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats Няма филтрирани чатове @@ -7762,6 +7778,10 @@ SimpleX сървърите не могат да видят вашия профи iOS Keychain ще се използва за сигурно съхраняване на паролата, след като рестартирате приложението или промените паролата - това ще позволи получаването на push известия. No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link инкогнито чрез линк с адрес за контакт diff --git a/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff b/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff index 7feb1a7b27..392b9cf70d 100644 --- a/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff +++ b/apps/ios/SimpleX Localizations/cs.xcloc/Localized Contents/cs.xliff @@ -3714,6 +3714,10 @@ This is your link for group %@! Člen No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. Role člena se změní na "%@". Všichni členové skupiny budou upozorněni. @@ -3752,6 +3756,14 @@ This is your link for group %@! Návrh zprávy No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4047,6 +4059,10 @@ This is your link for group %@! Žádný token zařízení! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats Žádné filtrované chaty @@ -7477,6 +7493,10 @@ Servery SimpleX nevidí váš profil. Klíčenka pro iOS bude použita k bezpečnému uložení přístupové fráze po restartování aplikace nebo změně přístupové fráze – umožní příjem oznámení push. No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link inkognito přes odkaz na kontaktní adresu diff --git a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff index a33fb400c7..cc2773d5e4 100644 --- a/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff +++ b/apps/ios/SimpleX Localizations/de.xcloc/Localized Contents/de.xliff @@ -3869,6 +3869,10 @@ Das ist Ihr Link für die Gruppe %@! Mitglied No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. Die Mitgliederrolle wird auf "%@" geändert. Alle Mitglieder der Gruppe werden benachrichtigt. @@ -3908,6 +3912,14 @@ Das ist Ihr Link für die Gruppe %@! Nachrichtenentwurf No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4222,6 +4234,10 @@ Das ist Ihr Link für die Gruppe %@! Kein Geräte-Token! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats Keine gefilterten Chats @@ -7799,6 +7815,10 @@ SimpleX-Server können Ihr Profil nicht einsehen. Für die sichere Speicherung des Passworts nach dem Neustart der App und dem Wechsel des Passworts wird der iOS Schlüsselbund verwendet - dies erlaubt den Empfang von Push-Benachrichtigungen. No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link Inkognito über einen Kontaktadressen-Link diff --git a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff index 30ee4a179a..08e1255199 100644 --- a/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff +++ b/apps/ios/SimpleX Localizations/en.xcloc/Localized Contents/en.xliff @@ -3923,6 +3923,11 @@ This is your link for group %@! Member No comment provided by engineer. + + Member inactive + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. Member role will be changed to "%@". All group members will be notified. @@ -3963,6 +3968,16 @@ This is your link for group %@! Message draft No comment provided by engineer. + + Message forwarded + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + Message may be delivered later if member becomes active. + item status description + Message queue info Message queue info @@ -4283,6 +4298,11 @@ This is your link for group %@! No device token! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats No filtered chats @@ -7927,6 +7947,11 @@ SimpleX servers cannot see your profile. iOS Keychain will be used to securely store passphrase after you restart the app or change passphrase - it will allow receiving push notifications. No comment provided by engineer. + + inactive + inactive + No comment provided by engineer. + incognito via contact address link incognito via contact address link diff --git a/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff b/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff index 7a2e73ae39..3e37e6c6d5 100644 --- a/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff +++ b/apps/ios/SimpleX Localizations/es.xcloc/Localized Contents/es.xliff @@ -3869,6 +3869,10 @@ This is your link for group %@! Miembro No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. El rol del miembro cambiará a "%@" y se notificará al grupo. @@ -3908,6 +3912,14 @@ This is your link for group %@! Borrador de mensaje No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4222,6 +4234,10 @@ This is your link for group %@! ¡Sin dispositivo token! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats Sin chats filtrados @@ -7800,6 +7816,10 @@ Los servidores de SimpleX no pueden ver tu perfil. iOS Keychain se usará para almacenar la contraseña de forma segura después de reiniciar la aplicación o cambiar la contraseña. Esto permitirá recibir notificaciones automáticas. No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link en modo incógnito mediante enlace de dirección del contacto diff --git a/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff b/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff index 552af207a7..71e0f0796a 100644 --- a/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff +++ b/apps/ios/SimpleX Localizations/fi.xcloc/Localized Contents/fi.xliff @@ -3704,6 +3704,10 @@ This is your link for group %@! Jäsen No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. Jäsenen rooli muuttuu muotoon "%@". Kaikille ryhmän jäsenille ilmoitetaan asiasta. @@ -3742,6 +3746,14 @@ This is your link for group %@! Viestiluonnos No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4036,6 +4048,10 @@ This is your link for group %@! Ei laitetunnusta! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats Ei suodatettuja keskusteluja @@ -7462,6 +7478,10 @@ SimpleX-palvelimet eivät näe profiiliasi. iOS-Avainnippua käytetään tunnuslauseen turvalliseen tallentamiseen sen muuttamisen tai sovelluksen uudelleen käynnistämisen jälkeen - se mahdollistaa push-ilmoitusten vastaanottamisen. No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link incognito kontaktilinkin kautta diff --git a/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff b/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff index 39bb04a814..4f618f26b0 100644 --- a/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff +++ b/apps/ios/SimpleX Localizations/fr.xcloc/Localized Contents/fr.xliff @@ -3869,6 +3869,10 @@ Voici votre lien pour le groupe %@ ! Membre No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. Le rôle du membre sera changé pour "%@". Tous les membres du groupe en seront informés. @@ -3908,6 +3912,14 @@ Voici votre lien pour le groupe %@ ! Brouillon de message No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4222,6 +4234,10 @@ Voici votre lien pour le groupe %@ ! Pas de token d'appareil ! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats Aucune discussion filtrés @@ -7799,6 +7815,10 @@ Les serveurs SimpleX ne peuvent pas voir votre profil. La keychain d'iOS sera utilisée pour stocker en toute sécurité la phrase secrète après le redémarrage de l'app ou la modification de la phrase secrète - il permettra de recevoir les notifications push. No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link mode incognito via le lien d'adresse du contact diff --git a/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff b/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff index f3374f2efb..ecc0610115 100644 --- a/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff +++ b/apps/ios/SimpleX Localizations/hu.xcloc/Localized Contents/hu.xliff @@ -3869,6 +3869,10 @@ Ez az ön hivatkozása a(z) %@ csoporthoz! Tag No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. A tag szerepköre meg fog változni erre: "%@". A csoport minden tagja értesítést kap róla. @@ -3908,6 +3912,14 @@ Ez az ön hivatkozása a(z) %@ csoporthoz! Üzenetvázlat No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4222,6 +4234,10 @@ Ez az ön hivatkozása a(z) %@ csoporthoz! Nincs eszköztoken! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats Nincsenek szűrt csevegések @@ -7799,6 +7815,10 @@ A SimpleX kiszolgálók nem látjhatják profilját. Az iOS kulcstár az alkalmazás újraindítása, vagy a jelmondat módosítása után a jelmondat biztonságos tárolására szolgál - lehetővé teszi a push-értesítések fogadását. No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link inkognitó a kapcsolattartási hivatkozáson keresztül diff --git a/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff b/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff index 2929cc41dc..8d311a803c 100644 --- a/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff +++ b/apps/ios/SimpleX Localizations/it.xcloc/Localized Contents/it.xliff @@ -3869,6 +3869,10 @@ Questo è il tuo link per il gruppo %@! Membro No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. Il ruolo del membro verrà cambiato in "%@". Tutti i membri del gruppo verranno avvisati. @@ -3908,6 +3912,14 @@ Questo è il tuo link per il gruppo %@! Bozza dei messaggi No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4222,6 +4234,10 @@ Questo è il tuo link per il gruppo %@! Nessun token del dispositivo! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats Nessuna chat filtrata @@ -7799,6 +7815,10 @@ I server di SimpleX non possono vedere il tuo profilo. Il portachiavi di iOS verrà usato per archiviare in modo sicuro la password dopo il riavvio dell'app o la modifica della password; consentirà di ricevere notifiche push. No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link incognito via link indirizzo del contatto diff --git a/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff b/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff index 929a6692bc..43f0f8f6cd 100644 --- a/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff +++ b/apps/ios/SimpleX Localizations/ja.xcloc/Localized Contents/ja.xliff @@ -3729,6 +3729,10 @@ This is your link for group %@! メンバー No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. メンバーの役割が "%@" に変更されます。 グループメンバー全員に通知されます。 @@ -3766,6 +3770,14 @@ This is your link for group %@! メッセージの下書き No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4061,6 +4073,10 @@ This is your link for group %@! デバイストークンがありません! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats フィルタされたチャットはありません @@ -7480,6 +7496,10 @@ SimpleX サーバーはあなたのプロファイルを参照できません。 iOS キーチェーンは、アプリを再起動するかパスフレーズを変更した後にパスフレーズを安全に保存するために使用され、プッシュ通知を受信できるようになります。 No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link 連絡先リンク経由でシークレットモード diff --git a/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff b/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff index 129dda6187..fdfd49c3d3 100644 --- a/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff +++ b/apps/ios/SimpleX Localizations/nl.xcloc/Localized Contents/nl.xliff @@ -3869,6 +3869,10 @@ Dit is jouw link voor groep %@! Lid No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. De rol van lid wordt gewijzigd in "%@". Alle groepsleden worden op de hoogte gebracht. @@ -3908,6 +3912,14 @@ Dit is jouw link voor groep %@! Concept bericht No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4222,6 +4234,10 @@ Dit is jouw link voor groep %@! Geen apparaattoken! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats Geen gefilterde gesprekken @@ -7799,6 +7815,10 @@ SimpleX servers kunnen uw profiel niet zien. iOS-keychain wordt gebruikt om het wachtwoord veilig op te slaan nadat u de app opnieuw hebt opgestart of het wachtwoord hebt gewijzigd, hiermee kunt u push meldingen ontvangen. No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link incognito via contact adres link diff --git a/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff b/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff index 31a6874e77..9da2b6bd82 100644 --- a/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff +++ b/apps/ios/SimpleX Localizations/pl.xcloc/Localized Contents/pl.xliff @@ -3869,6 +3869,10 @@ To jest twój link do grupy %@! Członek No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. Rola członka grupy zostanie zmieniona na "%@". Wszyscy członkowie grupy zostaną powiadomieni. @@ -3908,6 +3912,14 @@ To jest twój link do grupy %@! Wersja robocza wiadomości No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4222,6 +4234,10 @@ To jest twój link do grupy %@! Brak tokenu urządzenia! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats Brak filtrowanych czatów @@ -7799,6 +7815,10 @@ Serwery SimpleX nie mogą zobaczyć Twojego profilu. iOS Keychain będzie używany do bezpiecznego przechowywania hasła po ponownym uruchomieniu aplikacji lub zmianie hasła - pozwoli to na otrzymywanie powiadomień push. No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link incognito poprzez link adresu kontaktowego diff --git a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff index 0ae6e7ae24..db7f5bfb9e 100644 --- a/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff +++ b/apps/ios/SimpleX Localizations/ru.xcloc/Localized Contents/ru.xliff @@ -3869,6 +3869,10 @@ This is your link for group %@! Член группы No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. Роль члена группы будет изменена на "%@". Все члены группы получат сообщение. @@ -3908,6 +3912,14 @@ This is your link for group %@! Черновик сообщения No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4222,6 +4234,10 @@ This is your link for group %@! Отсутствует токен устройства! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats Нет отфильтрованных разговоров @@ -7799,6 +7815,10 @@ SimpleX серверы не могут получить доступ к Ваше Пароль базы данных будет безопасно сохранен в iOS Keychain после запуска чата или изменения пароля - это позволит получать мгновенные уведомления. No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link инкогнито через ссылку-контакт diff --git a/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff b/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff index bf2d6b8bed..a71061d578 100644 --- a/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff +++ b/apps/ios/SimpleX Localizations/th.xcloc/Localized Contents/th.xliff @@ -3687,6 +3687,10 @@ This is your link for group %@! สมาชิก No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. บทบาทของสมาชิกจะถูกเปลี่ยนเป็น "%@" สมาชิกกลุ่มทั้งหมดจะได้รับแจ้ง @@ -3725,6 +3729,14 @@ This is your link for group %@! ร่างข้อความ No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4017,6 +4029,10 @@ This is your link for group %@! ไม่มีโทเค็นอุปกรณ์! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats ไม่มีการกรองการแชท @@ -7430,6 +7446,10 @@ SimpleX servers cannot see your profile. iOS Keychain จะใช้เพื่อจัดเก็บรหัสผ่านอย่างปลอดภัยหลังจากที่คุณรีสตาร์ทแอปหรือเปลี่ยนรหัสผ่าน ซึ่งจะช่วยให้รับการแจ้งเตือนแบบทันทีได้ No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link ไม่ระบุตัวตนผ่านลิงค์ที่อยู่ติดต่อ diff --git a/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff b/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff index 482c3a038f..66f24d5bb7 100644 --- a/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff +++ b/apps/ios/SimpleX Localizations/tr.xcloc/Localized Contents/tr.xliff @@ -3869,6 +3869,10 @@ Bu senin grup için bağlantın %@! Kişi No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. Üye rolü "%@" olarak değiştirilecektir. Ve tüm grup üyeleri bilgilendirilecektir. @@ -3908,6 +3912,14 @@ Bu senin grup için bağlantın %@! Mesaj taslağı No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4222,6 +4234,10 @@ Bu senin grup için bağlantın %@! Cihaz tokeni yok! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats Filtrelenmiş sohbetler yok @@ -7799,6 +7815,10 @@ SimpleX sunucuları profilinizi göremez. iOS Anahtar Zinciri, uygulamayı yeniden başlattıktan veya parolayı değiştirdikten sonra parolayı güvenli bir şekilde saklamak için kullanılacaktır - anlık bildirimlerin alınmasına izin verecektir. No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link kişi bağlantı linki aracılığıyla gizli diff --git a/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff b/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff index 7e19da7cbd..bf0b5718f7 100644 --- a/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff +++ b/apps/ios/SimpleX Localizations/uk.xcloc/Localized Contents/uk.xliff @@ -3869,6 +3869,10 @@ This is your link for group %@! Учасник No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. Роль учасника буде змінено на "%@". Всі учасники групи будуть повідомлені про це. @@ -3908,6 +3912,14 @@ This is your link for group %@! Чернетка повідомлення No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4222,6 +4234,10 @@ This is your link for group %@! Токен пристрою відсутній! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats Немає фільтрованих чатів @@ -7799,6 +7815,10 @@ SimpleX servers cannot see your profile. Пароль бази даних буде безпечно збережено в iOS Keychain після запуску чату або зміни пароля - це дасть змогу отримувати миттєві повідомлення. No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link інкогніто за посиланням на контактну адресу diff --git a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff index 2ba735b08d..5d1852b0b4 100644 --- a/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff +++ b/apps/ios/SimpleX Localizations/zh-Hans.xcloc/Localized Contents/zh-Hans.xliff @@ -3819,6 +3819,10 @@ This is your link for group %@! 成员 No comment provided by engineer. + + Member inactive + item status text + Member role will be changed to "%@". All group members will be notified. 成员角色将更改为 "%@"。所有群成员将收到通知。 @@ -3857,6 +3861,14 @@ This is your link for group %@! 消息草稿 No comment provided by engineer. + + Message forwarded + item status text + + + Message may be delivered later if member becomes active. + item status description + Message queue info No comment provided by engineer. @@ -4165,6 +4177,10 @@ This is your link for group %@! 无设备令牌! No comment provided by engineer. + + No direct connection yet, message is forwarded by admin. + item status description + No filtered chats 无过滤聊天 @@ -7696,6 +7712,10 @@ SimpleX 服务器无法看到您的资料。 在您重启应用或改变密码后,iOS钥匙串将被用来安全地存储密码——它将允许接收推送通知。 No comment provided by engineer. + + inactive + No comment provided by engineer. + incognito via contact address link 通过联系人地址链接隐身聊天 diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index eb92deb4e9..b84e4bb3a0 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -1611,11 +1611,12 @@ public struct Connection: Decodable, Hashable { public var pqSndEnabled: Bool? public var pqRcvEnabled: Bool? public var authErrCounter: Int + public var quotaErrCounter: Int public var connectionStats: ConnectionStats? = nil private enum CodingKeys: String, CodingKey { - case connId, agentConnId, peerChatVRange, connStatus, connLevel, viaGroupLink, customUserProfileId, connectionCode, pqSupport, pqEncryption, pqSndEnabled, pqRcvEnabled, authErrCounter + case connId, agentConnId, peerChatVRange, connStatus, connLevel, viaGroupLink, customUserProfileId, connectionCode, pqSupport, pqEncryption, pqSndEnabled, pqRcvEnabled, authErrCounter, quotaErrCounter } public var id: ChatId { get { ":\(connId)" } } @@ -1624,6 +1625,10 @@ public struct Connection: Decodable, Hashable { authErrCounter >= 10 // authErrDisableCount in core } + public var connInactive: Bool { + quotaErrCounter >= 5 // quotaErrInactiveCount in core + } + public var connPQEnabled: Bool { pqSndEnabled == true && pqRcvEnabled == true } @@ -1637,7 +1642,8 @@ public struct Connection: Decodable, Hashable { viaGroupLink: false, pqSupport: false, pqEncryption: false, - authErrCounter: 0 + authErrCounter: 0, + quotaErrCounter: 0 ) } @@ -2846,6 +2852,62 @@ public enum SndCIStatusProgress: String, Decodable, Hashable { case complete } +public enum GroupSndStatus: Decodable, Hashable { + case new + case forwarded + case inactive + case sent + case rcvd(msgRcptStatus: MsgReceiptStatus) + case error(agentError: SndError) + case warning(agentError: SndError) + case invalid(text: String) + + public func statusIcon(_ metaColor: Color/* = .secondary*/, _ primaryColor: Color = .accentColor) -> (String, Color) { + switch self { + case .new: return ("ellipsis", metaColor) + case .forwarded: return ("chevron.forward.2", metaColor) + case .inactive: return ("person.badge.minus", metaColor) + case .sent: return ("checkmark", metaColor) + case let .rcvd(msgRcptStatus): + switch msgRcptStatus { + case .ok: return ("checkmark", metaColor) + case .badMsgHash: return ("checkmark", .red) + } + case .error: return ("multiply", .red) + case .warning: return ("exclamationmark.triangle.fill", .orange) + case .invalid: return ("questionmark", metaColor) + } + } + + public var statusInfo: (String, String)? { + switch self { + case .new: return nil + case .forwarded: return ( + NSLocalizedString("Message forwarded", comment: "item status text"), + NSLocalizedString("No direct connection yet, message is forwarded by admin.", comment: "item status description") + ) + case .inactive: return ( + NSLocalizedString("Member inactive", comment: "item status text"), + NSLocalizedString("Message may be delivered later if member becomes active.", comment: "item status description") + ) + case .sent: return nil + case .rcvd: return nil + case let .error(agentError): return ( + NSLocalizedString("Message delivery error", comment: "item status text"), + agentError.errorInfo + ) + case let .warning(agentError): return ( + NSLocalizedString("Message delivery warning", comment: "item status text"), + agentError.errorInfo + ) + case let .invalid(text): return ( + NSLocalizedString("Invalid status", comment: "item status text"), + text + ) + } + } +} + public enum CIDeleted: Decodable, Hashable { case deleted(deletedTs: Date?) case blocked(deletedTs: Date?) @@ -4012,6 +4074,6 @@ public struct ChatItemVersion: Decodable, Hashable { public struct MemberDeliveryStatus: Decodable, Hashable { public var groupMemberId: Int64 - public var memberDeliveryStatus: CIStatus + public var memberDeliveryStatus: GroupSndStatus public var sentViaProxy: Bool? } diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index f3d78eef20..e2d10ae5ae 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -325,9 +325,9 @@ Download Message forwarded - Connection is not established yet, message is forwarded by group admin. + No direct connection yet, message is forwarded by admin. Member inactive - Message is pending delivery when member becomes active. + Message may be delivered later if member becomes active. edited From 64a0f509f72979f5797119cc9bf34d6e1dd91d7e Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Tue, 9 Jul 2024 22:38:08 +0100 Subject: [PATCH 43/43] 6.0-beta.0: ios 227, android 225, desktop 56 --- apps/ios/SimpleX.xcodeproj/project.pbxproj | 72 ++++++++++++---------- apps/multiplatform/gradle.properties | 8 +-- 2 files changed, 44 insertions(+), 36 deletions(-) diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 1c5c032e11..9bd72ff5a9 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -203,11 +203,12 @@ D741547A29AF90B00022400A /* PushKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D741547929AF90B00022400A /* PushKit.framework */; }; D77B92DC2952372200A5A1CC /* SwiftyGif in Frameworks */ = {isa = PBXBuildFile; productRef = D77B92DB2952372200A5A1CC /* SwiftyGif */; }; D7F0E33929964E7E0068AF69 /* LZString in Frameworks */ = {isa = PBXBuildFile; productRef = D7F0E33829964E7E0068AF69 /* LZString */; }; - E52FF8DA2C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D52C34676600BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a */; }; - E52FF8DB2C34676700BF81EB /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D62C34676600BF81EB /* libgmpxx.a */; }; - E52FF8DC2C34676700BF81EB /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D72C34676700BF81EB /* libffi.a */; }; - E52FF8DD2C34676700BF81EB /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D82C34676700BF81EB /* libgmp.a */; }; - E52FF8DE2C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E52FF8D92C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a */; }; + E50581002C3DDD7F009C3F71 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E50580FB2C3DDD7F009C3F71 /* libffi.a */; }; + E50581012C3DDD7F009C3F71 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E50580FC2C3DDD7F009C3F71 /* libgmp.a */; }; + E50581022C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E50580FD2C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN-ghc9.6.3.a */; }; + E50581032C3DDD7F009C3F71 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E50580FE2C3DDD7F009C3F71 /* libgmpxx.a */; }; + E50581042C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E50580FF2C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN.a */; }; + E50581062C3DDD9D009C3F71 /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = E50581052C3DDD9D009C3F71 /* Yams */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -508,11 +509,11 @@ D741547729AF89AF0022400A /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/StoreKit.framework; sourceTree = DEVELOPER_DIR; }; D741547929AF90B00022400A /* PushKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PushKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk/System/Library/Frameworks/PushKit.framework; sourceTree = DEVELOPER_DIR; }; D7AA2C3429A936B400737B40 /* MediaEncryption.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; name = MediaEncryption.playground; path = Shared/MediaEncryption.playground; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - E52FF8D52C34676600BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a"; sourceTree = ""; }; - E52FF8D62C34676600BF81EB /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; - E52FF8D72C34676700BF81EB /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; - E52FF8D82C34676700BF81EB /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; - E52FF8D92C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a"; sourceTree = ""; }; + E50580FB2C3DDD7F009C3F71 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; + E50580FC2C3DDD7F009C3F71 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; + E50580FD2C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN-ghc9.6.3.a"; sourceTree = ""; }; + E50580FE2C3DDD7F009C3F71 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; + E50580FF2C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN.a"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -551,13 +552,14 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E52FF8DE2C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a in Frameworks */, - E52FF8DB2C34676700BF81EB /* libgmpxx.a in Frameworks */, + E50581032C3DDD7F009C3F71 /* libgmpxx.a in Frameworks */, 5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */, + E50581002C3DDD7F009C3F71 /* libffi.a in Frameworks */, + E50581012C3DDD7F009C3F71 /* libgmp.a in Frameworks */, 5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */, - E52FF8DC2C34676700BF81EB /* libffi.a in Frameworks */, - E52FF8DD2C34676700BF81EB /* libgmp.a in Frameworks */, - E52FF8DA2C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a in Frameworks */, + E50581022C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN-ghc9.6.3.a in Frameworks */, + E50581062C3DDD9D009C3F71 /* Yams in Frameworks */, + E50581042C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -624,11 +626,11 @@ 5C764E5C279C70B7000C6508 /* Libraries */ = { isa = PBXGroup; children = ( - E52FF8D72C34676700BF81EB /* libffi.a */, - E52FF8D82C34676700BF81EB /* libgmp.a */, - E52FF8D62C34676600BF81EB /* libgmpxx.a */, - E52FF8D52C34676600BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7-ghc9.6.3.a */, - E52FF8D92C34676700BF81EB /* libHSsimplex-chat-5.8.2.0-D50x9PQRTdqAAO9AQK2dA7.a */, + E50580FB2C3DDD7F009C3F71 /* libffi.a */, + E50580FC2C3DDD7F009C3F71 /* libgmp.a */, + E50580FE2C3DDD7F009C3F71 /* libgmpxx.a */, + E50580FD2C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN-ghc9.6.3.a */, + E50580FF2C3DDD7F009C3F71 /* libHSsimplex-chat-6.0.0.0-IhofDzGnTMcDdW5i3Fb7xN.a */, ); path = Libraries; sourceTree = ""; @@ -1065,6 +1067,7 @@ ); name = SimpleXChat; packageProductDependencies = ( + E50581052C3DDD9D009C3F71 /* Yams */, ); productName = SimpleXChat; productReference = 5CE2BA682845308900EC33A6 /* SimpleXChat.framework */; @@ -1612,7 +1615,7 @@ CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 226; + CURRENT_PROJECT_VERSION = 227; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; @@ -1637,7 +1640,7 @@ "@executable_path/Frameworks", ); LLVM_LTO = YES_THIN; - MARKETING_VERSION = 5.8.2; + MARKETING_VERSION = 6.0; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_NAME = SimpleX; SDKROOT = iphoneos; @@ -1661,7 +1664,7 @@ CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 226; + CURRENT_PROJECT_VERSION = 227; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; @@ -1686,7 +1689,7 @@ "@executable_path/Frameworks", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.8.2; + MARKETING_VERSION = 6.0; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_NAME = SimpleX; SDKROOT = iphoneos; @@ -1747,7 +1750,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 226; + CURRENT_PROJECT_VERSION = 227; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; GCC_OPTIMIZATION_LEVEL = s; @@ -1762,7 +1765,7 @@ "@executable_path/../../Frameworks", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.8.2; + MARKETING_VERSION = 6.0; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1784,7 +1787,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 226; + CURRENT_PROJECT_VERSION = 227; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; ENABLE_CODE_COVERAGE = NO; @@ -1799,7 +1802,7 @@ "@executable_path/../../Frameworks", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.8.2; + MARKETING_VERSION = 6.0; PRODUCT_BUNDLE_IDENTIFIER = "chat.simplex.app.SimpleX-NSE"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1821,7 +1824,7 @@ CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 226; + CURRENT_PROJECT_VERSION = 227; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1847,7 +1850,7 @@ "$(PROJECT_DIR)/Libraries/sim", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.8.2; + MARKETING_VERSION = 6.0; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; @@ -1872,7 +1875,7 @@ CLANG_TIDY_BUGPRONE_REDUNDANT_BRANCH_CONDITION = YES; CLANG_TIDY_MISC_REDUNDANT_EXPRESSION = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 226; + CURRENT_PROJECT_VERSION = 227; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1898,7 +1901,7 @@ "$(PROJECT_DIR)/Libraries/sim", ); LLVM_LTO = YES; - MARKETING_VERSION = 5.8.2; + MARKETING_VERSION = 6.0; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.SimpleXChat; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; @@ -2035,6 +2038,11 @@ package = D7F0E33729964E7D0068AF69 /* XCRemoteSwiftPackageReference "lzstring-swift" */; productName = LZString; }; + E50581052C3DDD9D009C3F71 /* Yams */ = { + isa = XCSwiftPackageProductDependency; + package = 8C73C1162C21E17B00892670 /* XCRemoteSwiftPackageReference "Yams" */; + productName = Yams; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 5CA059BE279559F40002BEB4 /* Project object */; diff --git a/apps/multiplatform/gradle.properties b/apps/multiplatform/gradle.properties index d87b70cc56..2923c39742 100644 --- a/apps/multiplatform/gradle.properties +++ b/apps/multiplatform/gradle.properties @@ -26,11 +26,11 @@ android.enableJetifier=true kotlin.mpp.androidSourceSetLayoutVersion=2 kotlin.jvm.target=11 -android.version_name=5.8.2 -android.version_code=223 +android.version_name=6.0-beta.0 +android.version_code=225 -desktop.version_name=5.8.2 -desktop.version_code=55 +desktop.version_name=6.0-beta.0 +desktop.version_code=56 kotlin.version=1.9.23 gradle.plugin.version=8.2.0

    VUQX`8OjR>vQE+KljCB0Ag?ZM)AGjNF-G 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 literal 0 HcmV?d00001 diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_school.imageset/wallpaper_school@2x.png b/apps/ios/Shared/Assets.xcassets/wallpaper_school.imageset/wallpaper_school@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..81a3a3d94d5106b4d45c8391539972129dd08e7d GIT binary patch literal 253494 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 z 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 bj_3S8P2nyz7mcJs00000NkvXXu0mjfTieUa literal 0 HcmV?d00001 diff --git a/apps/ios/Shared/Assets.xcassets/wallpaper_school.imageset/wallpaper_school@3x.png b/apps/ios/Shared/Assets.xcassets/wallpaper_school.imageset/wallpaper_school@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f6e1cce38315d6ababea563acebd8623bef01dd4 GIT binary patch literal 238390 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