Skip to content

Commit ec4b606

Browse files
Merge pull request #528 from Adamant-im/dev/trello.com/c/Qa3Dx6EI
[trello.com/c/Qa3Dx6EI] Release 3.8.0
2 parents f6d0b76 + 2fecd44 commit ec4b606

File tree

162 files changed

+9161
-168
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

162 files changed

+9161
-168
lines changed

Adamant.xcodeproj/project.pbxproj

+232-6
Large diffs are not rendered by default.

Adamant.xcworkspace/contents.xcworkspacedata

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Adamant/App/AppDelegate.swift

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Swinject
1111
import CryptoSwift
1212
import CoreData
1313
import CommonKit
14+
import FilesStorageKit
1415

1516
// MARK: - Constants
1617
extension String.adamant {

Adamant/App/DI/AppAssembly.swift

+44
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,22 @@
99
import Swinject
1010
import BitcoinKit
1111
import CommonKit
12+
import FilesStorageKit
13+
import FilesPickerKit
1214

1315
struct AppAssembly: Assembly {
1416
func assemble(container: Container) {
1517
// MARK: - Standalone services
1618
// MARK: AdamantCore
1719
container.register(AdamantCore.self) { _ in NativeAdamantCore() }.inObjectScope(.container)
1820

21+
// MARK: FilesStorageProtocol
22+
container.register(FilesStorageProtocol.self) { _ in FilesStorageKit() }.inObjectScope(.container)
23+
24+
container.register(FilesPickerProtocol.self) { r in
25+
FilesPickerKit(storageKit: r.resolve(FilesStorageProtocol.self)!)
26+
}
27+
1928
// MARK: CellFactory
2029
container.register(CellFactory.self) { _ in AdamantCellFactory() }.inObjectScope(.container)
2130

@@ -120,6 +129,23 @@ struct AppAssembly: Assembly {
120129
)
121130
}.inObjectScope(.container)
122131

132+
// MARK: IPFSApiService
133+
container.register(IPFSApiService.self) { r in
134+
IPFSApiService(
135+
healthCheckWrapper: .init(
136+
service: .init(apiCore: r.resolve(APICoreProtocol.self)!),
137+
nodesStorage: r.resolve(NodesStorageProtocol.self)!,
138+
nodesAdditionalParamsStorage: r.resolve(NodesAdditionalParamsStorageProtocol.self)!,
139+
nodeGroup: .ipfs
140+
)
141+
)
142+
}.inObjectScope(.container)
143+
144+
// MARK: FilesNetworkManagerProtocol
145+
container.register(FilesNetworkManagerProtocol.self) { r in
146+
FilesNetworkManager(ipfsService: r.resolve(IPFSApiService.self)!)
147+
}.inObjectScope(.container)
148+
123149
// MARK: BtcApiService
124150
container.register(BtcApiService.self) { r in
125151
BtcApiService(api: .init(
@@ -264,6 +290,24 @@ struct AppAssembly: Assembly {
264290
)
265291
}.inObjectScope(.container)
266292

293+
// MARK: ChatFileService
294+
container.register(ChatFileProtocol.self) { r in
295+
ChatFileService(
296+
accountService: r.resolve(AccountService.self)!,
297+
filesStorage: r.resolve(FilesStorageProtocol.self)!,
298+
chatsProvider: r.resolve(ChatsProvider.self)!,
299+
filesNetworkManager: r.resolve(FilesNetworkManagerProtocol.self)!,
300+
adamantCore: r.resolve(AdamantCore.self)!
301+
)
302+
}.inObjectScope(.container)
303+
304+
// MARK: FilesStorageProprietiesService
305+
container.register(FilesStorageProprietiesProtocol.self) { r in
306+
FilesStorageProprietiesService(
307+
securedStore: r.resolve(SecuredStore.self)!
308+
)
309+
}.inObjectScope(.container)
310+
267311
// MARK: Chats
268312
container.register(ChatsProvider.self) { r in
269313
AdamantChatsProvider(

Adamant/Debug.entitlements

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@
88
<array>
99
<string>applinks:msg.adamant.im</string>
1010
</array>
11+
<key>com.apple.developer.icloud-container-identifiers</key>
12+
<array/>
13+
<key>com.apple.developer.icloud-services</key>
14+
<array>
15+
<string>CloudDocuments</string>
16+
</array>
17+
<key>com.apple.developer.ubiquity-container-identifiers</key>
18+
<array/>
19+
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
20+
<string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>
1121
<key>com.apple.security.app-sandbox</key>
1222
<true/>
1323
<key>com.apple.security.device.camera</key>

Adamant/Helpers/EdgeInsetLabel.swift

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// EdgeInsetLabel.swift
3+
// Adamant
4+
//
5+
// Created by Stanislav Jelezoglo on 16.07.2024.
6+
// Copyright © 2024 Adamant. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import UIKit
11+
12+
final class EdgeInsetLabel: UILabel {
13+
var textInsets = UIEdgeInsets.zero {
14+
didSet { invalidateIntrinsicContentSize() }
15+
}
16+
17+
override func textRect(
18+
forBounds bounds: CGRect,
19+
limitedToNumberOfLines numberOfLines: Int
20+
) -> CGRect {
21+
let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)
22+
let invertedInsets = UIEdgeInsets(
23+
top: -textInsets.top,
24+
left: -textInsets.left,
25+
bottom: -textInsets.bottom,
26+
right: -textInsets.right
27+
)
28+
return textRect.inset(by: invertedInsets)
29+
}
30+
31+
override func drawText(in rect: CGRect) {
32+
super.drawText(in: rect.inset(by: textInsets))
33+
}
34+
}

Adamant/Helpers/Markdown+Adamant.swift

+48
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,51 @@ final class MarkdownCodeAdamant: MarkdownCommonElement {
226226
addAttributes(attributedString, range: match.range)
227227
}
228228
}
229+
230+
// MARK: Detect file emoji & count
231+
// - ex: 📄2
232+
final class MarkdownFileRaw: MarkdownElement {
233+
private let emoji: String
234+
private let matchFont: UIFont
235+
236+
init(
237+
emoji: String,
238+
font: UIFont
239+
) {
240+
self.emoji = emoji
241+
self.matchFont = font
242+
}
243+
244+
var regex: String {
245+
return "\(emoji)\\d{0,2}"
246+
}
247+
248+
func regularExpression() throws -> NSRegularExpression {
249+
try NSRegularExpression(pattern: regex, options: .dotMatchesLineSeparators)
250+
}
251+
252+
func match(_ match: NSTextCheckingResult, attributedString: NSMutableAttributedString) {
253+
let attributesColor: [NSAttributedString.Key : Any] = [
254+
.foregroundColor: UIColor.lightGray,
255+
.font: matchFont,
256+
.baselineOffset: -3.0
257+
]
258+
259+
let nsString = (attributedString.string as NSString)
260+
let matchText = nsString.substring(with: match.range)
261+
262+
let textWithoutEmoji = matchText.replacingOccurrences(of: emoji, with: "")
263+
let countRange = (matchText as NSString).range(of: textWithoutEmoji)
264+
let emojiRange = (matchText as NSString).range(of: emoji)
265+
266+
let range = NSRange(
267+
location: match.range.location + emojiRange.length,
268+
length: countRange.length
269+
)
270+
271+
attributedString.addAttributes(
272+
attributesColor,
273+
range: range
274+
)
275+
}
276+
}

Adamant/Helpers/NodeGroup+Constants.swift

+10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ public extension NodeGroup {
2525
return DogeWalletService.healthCheckParameters.onScreenUpdateInterval
2626
case .dash:
2727
return DashWalletService.healthCheckParameters.onScreenUpdateInterval
28+
case .ipfs:
29+
return IPFSApiService.healthCheckParameters.onScreenUpdateInterval
2830
}
2931
}
3032

@@ -44,6 +46,8 @@ public extension NodeGroup {
4446
return DogeWalletService.healthCheckParameters.crucialUpdateInterval
4547
case .dash:
4648
return DashWalletService.healthCheckParameters.crucialUpdateInterval
49+
case .ipfs:
50+
return IPFSApiService.healthCheckParameters.crucialUpdateInterval
4751
}
4852
}
4953

@@ -63,6 +67,8 @@ public extension NodeGroup {
6367
return DogeWalletService.healthCheckParameters.threshold
6468
case .dash:
6569
return DashWalletService.healthCheckParameters.threshold
70+
case .ipfs:
71+
return IPFSApiService.healthCheckParameters.threshold
6672
}
6773
}
6874

@@ -82,6 +88,8 @@ public extension NodeGroup {
8288
return DogeWalletService.healthCheckParameters.normalUpdateInterval
8389
case .dash:
8490
return DashWalletService.healthCheckParameters.normalUpdateInterval
91+
case .ipfs:
92+
return IPFSApiService.healthCheckParameters.normalUpdateInterval
8593
}
8694
}
8795

@@ -102,6 +110,8 @@ public extension NodeGroup {
102110
minNodeVersion = DogeWalletService.minNodeVersion
103111
case .dash:
104112
minNodeVersion = DashWalletService.minNodeVersion
113+
case .ipfs:
114+
minNodeVersion = nil
105115
}
106116

107117
guard let versionNumber = Node.stringToDouble(minNodeVersion) else {

Adamant/Helpers/UIFont+adamant.swift

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ extension UIFont {
4040
return UIFont(name: name, size: size) ?? .systemFont(ofSize: size, weight: weight)
4141
}
4242

43+
static var adamantChatFileRawDefault = UIFont.systemFont(ofSize: 8)
4344
static var adamantChatDefault = UIFont.systemFont(ofSize: 17)
4445
static var adamantCodeDefault = UIFont.adamantMono(ofSize: 15, weight: .regular)
4546
static var adamantChatReplyDefault = UIFont.systemFont(ofSize: 14)

Adamant/Helpers/UITextField+adamant.swift

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
import UIKit
10+
import CommonKit
1011

1112
extension UITextField {
1213

Adamant/Models/ApiServiceError.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ enum ApiServiceError: LocalizedError, Error {
3434
let message = error?.localizedDescription ?? msg
3535
return String.adamant.sharedErrors.internalError(message: message)
3636

37-
case .networkError(error: _):
38-
return String.adamant.sharedErrors.networkError
37+
case let .networkError(error):
38+
return error.localizedDescription
3939

4040
case .requestCancelled:
4141
return String.adamant.sharedErrors.requestCancelled

Adamant/Models/ApiServiceResult.swift

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@
77
//
88

99
typealias ApiServiceResult<Success> = Result<Success, ApiServiceError>
10+
typealias FileApiServiceResult<Success> = Result<Success, FileManagerError>

Adamant/Models/CoreData/Chatroom+CoreDataClass.swift

+8
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ public class Chatroom: NSManagedObject {
4747
return result?.checkAndReplaceSystemWallets()
4848
}
4949

50+
@MainActor func hasPartnerName(addressBookService: AddressBookService) -> Bool {
51+
guard let partner = partner else { return false }
52+
53+
return partner.address.flatMap { addressBookService.getName(for: $0) } != nil
54+
|| title != nil
55+
|| partner.name != nil
56+
}
57+
5058
private let semaphore = DispatchSemaphore(value: 1)
5159

5260
func updateLastTransaction() {

Adamant/Models/CoreData/RichMessageTransaction+CoreDataProperties.swift

+25-2
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,36 @@ extension RichMessageTransaction {
2828
return richContent?[RichContentKeys.reply.replyMessage] is [String: String]
2929
}
3030

31+
func isFileReply() -> Bool {
32+
let replyMessage = richContent?[RichContentKeys.reply.replyMessage] as? [String: Any]
33+
return replyMessage?[RichContentKeys.file.files] is [[String: Any]]
34+
}
35+
3136
func getRichValue(for key: String) -> String? {
3237
if let value = richContent?[key] as? String {
3338
return value
3439
}
3540

36-
if let content = richContent?[RichContentKeys.reply.replyMessage] as? [String: String],
37-
let value = content[key] {
41+
if let content = richContent?[RichContentKeys.reply.replyMessage] as? [String: Any],
42+
let value = content[key] as? String {
43+
return value
44+
}
45+
46+
return nil
47+
}
48+
49+
func getRichValue<T>(for key: String) -> T? {
50+
if let value = richContent?[key] as? T {
51+
return value
52+
}
53+
54+
if let content = richContent?[RichContentKeys.file.files] as? [String: Any],
55+
let value = content[key] as? T {
56+
return value
57+
}
58+
59+
if let content = richContent?[RichContentKeys.reply.replyMessage] as? [String: Any],
60+
let value = content[key] as? T {
3861
return value
3962
}
4063

Adamant/Models/DownloadPolicy.swift

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// DownloadPolicy.swift
3+
// Adamant
4+
//
5+
// Created by Stanislav Jelezoglo on 13.08.2024.
6+
// Copyright © 2024 Adamant. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import CommonKit
11+
12+
extension Notification.Name {
13+
struct Storage {
14+
public static let storageClear = Notification.Name("adamant.storage.clear")
15+
public static let storageProprietiesUpdated = Notification.Name("adamant.storage.ProprietiesUpdated")
16+
}
17+
}
18+
19+
enum DownloadPolicy: String {
20+
case everybody
21+
case nobody
22+
case contacts
23+
24+
var title: String {
25+
switch self {
26+
case .everybody:
27+
return .localized("Storage.DownloadPolicy.Everybody.Title")
28+
case .nobody:
29+
return .localized("Storage.DownloadPolicy.Nobody.Title")
30+
case .contacts:
31+
return .localized("Storage.DownloadPolicy.Contacts.Title")
32+
}
33+
}
34+
}

Adamant/Models/IPFSNodeStatus.swift

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//
2+
// IPFSNodeStatus.swift
3+
// Adamant
4+
//
5+
// Created by Stanislav Jelezoglo on 19.08.2024.
6+
// Copyright © 2024 Adamant. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
struct IPFSNodeStatus: Codable {
12+
let version: String
13+
}
14+
15+
/* JSON
16+
17+
{
18+
"version":"0.0.1",
19+
"timestamp":1724085764840,
20+
"heliaStatus":"started",
21+
"peerId":"12D3KooWGMp6SaKon2UKwJsDEf3chLAGRzsjdAfDGN9zcwt6ydqJ",
22+
"multiAddresses":[
23+
"/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWGMp6SaKon2UKwJsDEf3chLAGRzsjdAfDGN9zcwt6ydqJ",
24+
"/ip4/95.216.45.88/tcp/4001/p2p/12D3KooWGMp6SaKon2UKwJsDEf3chLAGRzsjdAfDGN9zcwt6ydqJ"
25+
],
26+
"blockstoreSizeMb":5053.823321342468,
27+
"datastoreSizeMb":0.135406494140625,
28+
"availableSizeInMb":943942
29+
}
30+
31+
*/

0 commit comments

Comments
 (0)