Skip to content

Commit ed48986

Browse files
committed
Merge branch 'release/0.2'
2 parents 9edfd96 + a46be14 commit ed48986

30 files changed

+786
-226
lines changed

Adamant.xcodeproj/project.pbxproj

Lines changed: 89 additions & 38 deletions
Large diffs are not rendered by default.

Adamant.xcodeproj/xcshareddata/xcschemes/Adamant.Dev.xcscheme

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,14 @@
5656
buildConfiguration = "Debug"
5757
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
5858
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
59-
language = ""
59+
language = "ru"
6060
launchStyle = "0"
6161
useCustomWorkingDirectory = "NO"
6262
ignoresPersistentStateOnLaunch = "NO"
6363
debugDocumentVersioning = "YES"
6464
debugServiceExtension = "internal"
65-
allowLocationSimulation = "YES">
65+
allowLocationSimulation = "YES"
66+
showNonLocalizedStrings = "YES">
6667
<BuildableProductRunnable
6768
runnableDebuggingMode = "0">
6869
<BuildableReference

Adamant/AppDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
3131

3232
// MARK: 2. Prepare UI
3333
self.window = UIWindow(frame: UIScreen.main.bounds)
34-
self.window!.rootViewController = SwinjectStoryboard.create(name: "Main", bundle: nil).instantiateInitialViewController()
34+
self.window!.rootViewController = UITabBarController()
3535
self.window!.rootViewController?.view.backgroundColor = .white
3636
self.window!.makeKeyAndVisible()
3737

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/* (No Comment) */
2+
"CFBundleDisplayName" = "Адамант";
3+
4+
/* (No Comment) */
5+
"CFBundleName" = "";
6+
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
/* Product name */
2+
"ADAMANT" = "АДАМАНТ";
3+
4+
/* Wallet page: Account section title. */
5+
"Account" = "Аккаунт";
6+
7+
/* ApiService: Account not found error, appending account info. */
8+
"Account not found: %@" = "Аккаунт не найден: %@";
9+
10+
/* Wallet page: Actions section title */
11+
"Actions" = "Действия";
12+
13+
/* Transfer: recipient address */
14+
"Address" = "Адрес";
15+
16+
/* New chat: Notify user that specified address (%@) not found */
17+
"Address %@ not found" = "Адрес %@ не найден";
18+
19+
/* Transfer: Address not found error */
20+
"Address not found" = "Такой адрес не найден";
21+
22+
/* Transaction details: amount row.
23+
Transfer: amount of adamant to transfer. */
24+
"Amount" = "Количество";
25+
26+
/* Config: Application Info section */
27+
"Application info" = "Приложение";
28+
29+
/* Transfer: logged user balance.
30+
Wallet page: Balance row title */
31+
"Balance" = "Баланс";
32+
33+
/* Transaction details: Block id row. */
34+
"Block" = "Блок";
35+
36+
/* Shared alert 'Cancel' button. Used anywhere */
37+
"Cancel" = "Отмена";
38+
39+
/* Transaction details: confirmations row. */
40+
"Confirmations" = "Подтверждений";
41+
42+
/* Shared alert notification: message about item copied to pasteboard. */
43+
"Copied to Pasteboard" = "Скопировано!";
44+
45+
/* Shared alert 'Copy' button. Used anywhere. Used for copy-paste info. */
46+
"Copy to Pasteboard" = "Копировать";
47+
48+
/* Transaction details: date row. */
49+
"Date" = "Дата";
50+
51+
/* Login: notify user that he is trying to login without a passphrase */
52+
"Enter a passphrase!" = "Введите пароль";
53+
54+
/* Chat: input bar: Estimated fee. */
55+
"Estimated fee: %f" = "Ориентировочная комиссия: %f";
56+
57+
/* Transaction details: fee row. */
58+
"Fee" = "Комиссия";
59+
60+
/* Transaction details: sender row. */
61+
"From" = "Отправитель";
62+
63+
/* Transfer: Tokens transfered successfully message */
64+
"Funds sended!" = "Токены переведены!";
65+
66+
/* Login: generate new passphrase button */
67+
"Generate new passphrase" = "Создать новый";
68+
69+
/* Transaction details: Id row. */
70+
"Id" = "Номер";
71+
72+
/* Wallet page: 'Invest in ICO' button */
73+
"Invest in ICO" = "Инвестировать в ICO";
74+
75+
/* Login: notify user that we a logging in. */
76+
"Logging in" = "Входим...";
77+
78+
/* Login: Login button
79+
Login: login with existing passphrase section */
80+
"Login" = "Вход";
81+
82+
/* Wallet page: 'Logout' button
83+
Wallet page: Confirm logout alert: Logout (Ok) button */
84+
"Logout" = "Выход";
85+
86+
/* Wallet page: Confirm logout alert */
87+
"Logout from %@?" = "Выйти из %@?";
88+
89+
/* Transfer: maximum amount to transfer: available account money substracting transfer fee. */
90+
"Max to transfer" = "Доступно для перевода";
91+
92+
/* Chat: Notify user that message cannot be empty */
93+
"Message is empty" = "Сообщение пусто!";
94+
95+
/* Chat: Message is too long */
96+
"Message is too long" = "Сообщение слишком длинное";
97+
98+
/* Login: Create new account section */
99+
"New account" = "Новый аккаунт";
100+
101+
/* ApiService: No connection message. Generally bad network. */
102+
"No connection" = "Нет соединения с интернетом";
103+
104+
/* Login: No network error. */
105+
"No connection with The Internet" = "Нет соединения с сетью";
106+
107+
/* Shared alert 'Ok' button. Used anywhere */
108+
"Ok" = "Ок";
109+
110+
/* Transaction details: 'Open transaction in explorer' row. */
111+
"Open in Explorer" = "Открыть в Explorer";
112+
113+
/* Transfer: Address validation error */
114+
"Please enter a valid recipient address" = "Введите корректный адрес получателя";
115+
116+
/* New chat: Notify user that he did enter invalid address */
117+
"Please specify valid recipient address" = "Неверный адрес";
118+
119+
/* Shared alert 'Save' button. Used anywhere */
120+
"Save" = "Сохранить";
121+
122+
/* Login: security alert, notify user that he must save his new passphrase */
123+
"Save the passphrase for new Wallet and Messenger account. There is no login to enter Wallet, only the passphrase needed. If lost, no way to recover it" = "Это пароль для нового Кошелька и Мессенджера. Сохраните его! Для входа в Кошелек не нужно логина, только этот пароль. Восстановление пароля невозможно.";
124+
125+
/* Transfer: Confirm transfer alert: Send tokens button */
126+
"Send" = "Отправить";
127+
128+
/* Transfer: Confirm transfer X tokens to Y message. Note two variables: at runtime %1$@ will be amount (with ADM suffix), and %2$@ will be recipient address. You can use address before amount with this so called 'position tokens'. */
129+
"Send %1$@ to %2$@?" = "Отправить %1$@ получателю %2$@?";
130+
131+
/* Transfer: Send button */
132+
"Send Funds" = "Отправить токены";
133+
134+
/* Wallet page: 'Send tokens' button */
135+
"Send Tokens" = "Отправить токены";
136+
137+
/* Transfer: Processing message */
138+
"Sending funds..." = "Отправляем токены...";
139+
140+
/* Shared alert 'Share' button. Used anywhere for presenting standart iOS 'Share' menu. */
141+
"Share" = "Поделиться";
142+
143+
/* Export transaction: 'Share transaction summary' button */
144+
"Summary" = "Сводка";
145+
146+
/* Login: a small hint for a user, that he can tap on passphrase to save it */
147+
"Tap to save" = "Нажмите для сохранения";
148+
149+
/* Transaction details: recipient row. */
150+
"To" = "Получатель";
151+
152+
/* Transfer: total amount of transaction: money to transfer adding fee */
153+
"Total" = "Итого";
154+
155+
/* Transfer: transfer fee */
156+
"Transaction fee" = "Комиссия";
157+
158+
/* Transfer: 'Transfer info' section */
159+
"Transfer Info" = "Перевод";
160+
161+
/* Unknown internal error */
162+
"Unknown error" = "Неизвестная ошибка";
163+
164+
/* Config: Version row */
165+
"Version" = "Версия";
166+
167+
/* Wallet page: Wallet section title */
168+
"Wallet" = "Кошелёк";
169+
170+
/* Login: user typed in wrong passphrase. */
171+
"Wrong passphrase!" = "Неправильный пароль";
172+
173+
/* Chat: Notify user that he doesn't have money to pay a message fee */
174+
"You don't have enough money to send a message" = "Недостаточно токенов для отправки сообщения";
175+
176+
/* Transfer: Amount is hiegher that user's total money notification */
177+
"You don't have that much money" = "У вас нет столько токенов";
178+
179+
/* New chat: Notify user that he can't start chat with himself */
180+
"You don't need an encrypted anonymous chat to talk to yourself" = "Вам не нужен анонимный чат, чтобы говорить с самим собой";
181+
182+
/* Transfer: Amount is zero, or even negative notification */
183+
"You should send more money" = "Нужно отправить больше токенов";
184+
185+
/* Transfer: 'Your wallet' section */
186+
"Your wallet" = "Ваш кошелёк";
187+
188+
/* Transfer: recipient address placeholder */
189+
"of the recipient" = "получателя";
190+
191+
/* Login: Passphrase placeholder */
192+
"passphrase" = "Пароль";
193+
194+
/* Transfer: transfer amount placeholder */
195+
"to send" = "для перевода";
196+

Adamant/Base.lproj/Main.storyboard

Lines changed: 0 additions & 27 deletions
This file was deleted.

Adamant/Helpers/AdamantUtilities.swift

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ extension AdamantUtilities {
6464

6565
// MARK: - Validating Addresses and Passphrases
6666
extension AdamantUtilities {
67-
static let addressRegex = "^U([0-9]{6,20})$"
68-
static let passphraseRegex = "^([a-z]* ){11}([a-z]*)$"
69-
67+
static let addressRegexString = "^U([0-9]{6,20})$"
68+
static let passphraseRegexString = "^([a-z]* ){11}([a-z]*)$"
69+
static let passphraseRegex = try! NSRegularExpression(pattern: passphraseRegexString, options: [])
70+
static let addressRegex = try! NSRegularExpression(pattern: addressRegexString, options: [])
7071

7172
/// Rules are simple:
7273
///
@@ -90,15 +91,10 @@ extension AdamantUtilities {
9091
return validate(string: passphrase, with: passphraseRegex)
9192
}
9293

93-
private static func validate(string: String, with regex: String) -> Bool {
94-
if let regex = try? NSRegularExpression(pattern: regex, options: []) {
95-
let matches = regex.matches(in: string, options: [], range: NSRange(location: 0, length: string.count))
96-
97-
return matches.count == 1
98-
} else {
99-
print("Wrong passphrase regex: \(regex)")
100-
return false
101-
}
94+
private static func validate(string: String, with regex: NSRegularExpression) -> Bool {
95+
let matches = passphraseRegex.matches(in: string, options: [], range: NSRange(location: 0, length: string.count))
96+
97+
return matches.count == 1
10298
}
10399
}
104100

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//
2+
// String+localized.swift
3+
// Adamant
4+
//
5+
// Created by Anokhov Pavel on 14.02.2018.
6+
// Copyright © 2018 Adamant. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
extension String {
12+
public struct adamantLocalized {
13+
struct shared {
14+
static let productName = NSLocalizedString("ADAMANT", comment: "Product name")
15+
16+
private init() {}
17+
}
18+
19+
struct alert {
20+
static let cancel = NSLocalizedString("Cancel", comment: "Shared alert 'Cancel' button. Used anywhere")
21+
static let ok = NSLocalizedString("Ok", comment: "Shared alert 'Ok' button. Used anywhere")
22+
static let save = NSLocalizedString("Save", comment: "Shared alert 'Save' button. Used anywhere")
23+
static let copyToPasteboard = NSLocalizedString("Copy to Pasteboard", comment: "Shared alert 'Copy' button. Used anywhere. Used for copy-paste info.")
24+
static let copiedToPasteboardNotification = NSLocalizedString("Copied to Pasteboard", comment: "Shared alert notification: message about item copied to pasteboard.")
25+
static let share = NSLocalizedString("Share", comment: "Shared alert 'Share' button. Used anywhere for presenting standart iOS 'Share' menu.")
26+
}
27+
28+
private init() { }
29+
}
30+
31+
}

Adamant/Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
<key>CFBundlePackageType</key>
1818
<string>APPL</string>
1919
<key>CFBundleShortVersionString</key>
20-
<string>0.1.5</string>
20+
<string>0.2</string>
2121
<key>CFBundleVersion</key>
22-
<string>6</string>
22+
<string>7</string>
2323
<key>LSRequiresIPhoneOS</key>
2424
<true/>
2525
<key>UIAppFonts</key>

Adamant/ServiceProtocols/ApiService.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,32 @@ enum ApiServiceError: Error {
1919
case serverError(error: String)
2020
case internalError(message: String, error: Error?)
2121
case networkError(error: Error)
22+
23+
var localized: String {
24+
switch self {
25+
case .notLogged:
26+
return NSLocalizedString("User not logged", comment: "ApiService: User not logged error")
27+
28+
case .accountNotFound:
29+
return NSLocalizedString("Account not found: %@", comment: "ApiService: Account not found error, appending account info.")
30+
31+
case .serverError(error: let error):
32+
return String.localizedStringWithFormat(NSLocalizedString("Remote Server error: %@", comment: "ApiService: Remote server returned an error"), error)
33+
34+
case .internalError(_, let error):
35+
let message: String
36+
if let apiError = error as? ApiServiceError {
37+
message = apiError.localized
38+
} else {
39+
message = String(describing: error)
40+
}
41+
42+
return String.localizedStringWithFormat(NSLocalizedString("Internal error: %@, report this as a bug", comment: "ApiService: Bad internal application error, report a bug"), message)
43+
44+
case .networkError(error: _):
45+
return NSLocalizedString("No connection", comment: "ApiService: No connection message. Generally bad network.")
46+
}
47+
}
2248
}
2349

2450
protocol ApiService {

Adamant/Services/AdamantDialogService.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,20 +85,20 @@ extension AdamantDialogService {
8585
for type in types {
8686
switch type {
8787
case .copyToPasteboard:
88-
alert.addAction(UIAlertAction(title: "Copy To Pasteboard", style: .default, handler: { _ in
88+
alert.addAction(UIAlertAction(title: String.adamantLocalized.alert.copyToPasteboard, style: .default) { _ in
8989
UIPasteboard.general.string = string
90-
self.showToastMessage("\(string)\nCopied To Pasteboard!")
91-
}))
90+
self.showToastMessage(String.adamantLocalized.alert.copiedToPasteboardNotification)
91+
})
9292

9393
case .share:
94-
alert.addAction(UIAlertAction(title: "Share", style: .default, handler: { _ in
94+
alert.addAction(UIAlertAction(title: String.adamantLocalized.alert.share, style: .default) { _ in
9595
let vc = UIActivityViewController(activityItems: [string], applicationActivities: nil)
9696
self.presentModallyViewController(vc, animated: true, completion: completion)
97-
}))
97+
})
9898
}
9999
}
100100

101-
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
101+
alert.addAction(UIAlertAction(title: String.adamantLocalized.alert.cancel, style: .cancel, handler: nil))
102102

103103
presentModallyViewController(alert, animated: animated, completion: completion)
104104
}

0 commit comments

Comments
 (0)