Skip to content
Snippets Groups Projects
Commit 026ec744 authored by Bruno Muniz's avatar Bruno Muniz :apple:
Browse files

refactoring several parts of the application

parent 9093380d
No related branches found
No related tags found
1 merge request!66Using new client wrapper
Showing
with 955 additions and 529 deletions
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1410"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "AppCore"
BuildableName = "AppCore"
BlueprintName = "AppCore"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "AppCore"
BuildableName = "AppCore"
BlueprintName = "AppCore"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1410"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BackupFeature"
BuildableName = "BackupFeature"
BlueprintName = "BackupFeature"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BackupFeature"
BuildableName = "BackupFeature"
BlueprintName = "BackupFeature"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1410"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "Countries"
BuildableName = "Countries"
BlueprintName = "Countries"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "Countries"
BuildableName = "Countries"
BlueprintName = "Countries"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1410"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "LaunchFeature"
BuildableName = "LaunchFeature"
BlueprintName = "LaunchFeature"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "LaunchFeature"
BuildableName = "LaunchFeature"
BlueprintName = "LaunchFeature"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1410"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "OnboardingFeature"
BuildableName = "OnboardingFeature"
BlueprintName = "OnboardingFeature"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "OnboardingFeature"
BuildableName = "OnboardingFeature"
BlueprintName = "OnboardingFeature"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1410"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "StatusBarFeature"
BuildableName = "StatusBarFeature"
BlueprintName = "StatusBarFeature"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "StatusBarFeature"
BuildableName = "StatusBarFeature"
BlueprintName = "StatusBarFeature"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
...@@ -13,10 +13,10 @@ ...@@ -13,10 +13,10 @@
02FDD07021EDA39B000F1286 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 02FDD06E21EDA39B000F1286 /* LaunchScreen.storyboard */; }; 02FDD07021EDA39B000F1286 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 02FDD06E21EDA39B000F1286 /* LaunchScreen.storyboard */; };
32179BA826410149008B26EC /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32179BA726410149008B26EC /* NotificationService.swift */; }; 32179BA826410149008B26EC /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32179BA726410149008B26EC /* NotificationService.swift */; };
32179BAC26410149008B26EC /* NotificationExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 32179BA526410149008B26EC /* NotificationExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 32179BAC26410149008B26EC /* NotificationExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 32179BA526410149008B26EC /* NotificationExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
3273327126C7391D0027D79D /* App in Frameworks */ = {isa = PBXBuildFile; productRef = 3273327026C7391D0027D79D /* App */; }; 3242BD412921DC950045E647 /* AppFeature in Frameworks */ = {isa = PBXBuildFile; productRef = 3242BD402921DC950045E647 /* AppFeature */; };
3242BD432921DC9E0045E647 /* AppFeature in Frameworks */ = {isa = PBXBuildFile; productRef = 3242BD422921DC9E0045E647 /* AppFeature */; };
32C194E02808C65500876917 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 32C194DF2808C65500876917 /* GoogleService-Info.plist */; }; 32C194E02808C65500876917 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 32C194DF2808C65500876917 /* GoogleService-Info.plist */; };
32C194E12808C65500876917 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 32C194DF2808C65500876917 /* GoogleService-Info.plist */; }; 32C194E12808C65500876917 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 32C194DF2808C65500876917 /* GoogleService-Info.plist */; };
32CAAFAE2845836100446BB9 /* App in Frameworks */ = {isa = PBXBuildFile; productRef = 32CAAFAD2845836100446BB9 /* App */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
...@@ -64,8 +64,8 @@ ...@@ -64,8 +64,8 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
3273327126C7391D0027D79D /* App in Frameworks */,
026135B321F2729900038B5E /* libsqlite3.tbd in Frameworks */, 026135B321F2729900038B5E /* libsqlite3.tbd in Frameworks */,
3242BD432921DC9E0045E647 /* AppFeature in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
32CAAFAE2845836100446BB9 /* App in Frameworks */, 3242BD412921DC950045E647 /* AppFeature in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
...@@ -159,7 +159,7 @@ ...@@ -159,7 +159,7 @@
); );
name = "client-ios"; name = "client-ios";
packageProductDependencies = ( packageProductDependencies = (
3273327026C7391D0027D79D /* App */, 3242BD422921DC9E0045E647 /* AppFeature */,
); );
productName = "client-ios"; productName = "client-ios";
productReference = 02FDD06221EDA39A000F1286 /* client-ios.app */; productReference = 02FDD06221EDA39A000F1286 /* client-ios.app */;
...@@ -179,7 +179,7 @@ ...@@ -179,7 +179,7 @@
); );
name = NotificationExtension; name = NotificationExtension;
packageProductDependencies = ( packageProductDependencies = (
32CAAFAD2845836100446BB9 /* App */, 3242BD402921DC950045E647 /* AppFeature */,
); );
productName = NotificationExtension; productName = NotificationExtension;
productReference = 32179BA526410149008B26EC /* NotificationExtension.appex */; productReference = 32179BA526410149008B26EC /* NotificationExtension.appex */;
...@@ -610,13 +610,13 @@ ...@@ -610,13 +610,13 @@
/* End XCConfigurationList section */ /* End XCConfigurationList section */
/* Begin XCSwiftPackageProductDependency section */ /* Begin XCSwiftPackageProductDependency section */
3273327026C7391D0027D79D /* App */ = { 3242BD402921DC950045E647 /* AppFeature */ = {
isa = XCSwiftPackageProductDependency; isa = XCSwiftPackageProductDependency;
productName = App; productName = AppFeature;
}; };
32CAAFAD2845836100446BB9 /* App */ = { 3242BD422921DC9E0045E647 /* AppFeature */ = {
isa = XCSwiftPackageProductDependency; isa = XCSwiftPackageProductDependency;
productName = App; productName = AppFeature;
}; };
/* End XCSwiftPackageProductDependency section */ /* End XCSwiftPackageProductDependency section */
}; };
......
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CLIENT_ID</key> <key>CLIENT_ID</key>
<string>662236151640-herpu89qikpfs9m4kvbi9bs5fpdji5de.apps.googleusercontent.com</string> <string>662236151640-r1lrlppqdcmhb4p8urq32fo7784cdoal.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key> <key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.662236151640-herpu89qikpfs9m4kvbi9bs5fpdji5de</string> <string>com.googleusercontent.apps.662236151640-r1lrlppqdcmhb4p8urq32fo7784cdoal</string>
<key>ANDROID_CLIENT_ID</key> <key>ANDROID_CLIENT_ID</key>
<string>662236151640-2ughgo2dvc59dm4o39b45lbdungp2mct.apps.googleusercontent.com</string> <string>662236151640-2ughgo2dvc59dm4o39b45lbdungp2mct.apps.googleusercontent.com</string>
<key>API_KEY</key> <key>API_KEY</key>
...@@ -21,15 +21,15 @@ ...@@ -21,15 +21,15 @@
<key>STORAGE_BUCKET</key> <key>STORAGE_BUCKET</key>
<string>xx-messenger-6e03e.appspot.com</string> <string>xx-messenger-6e03e.appspot.com</string>
<key>IS_ADS_ENABLED</key> <key>IS_ADS_ENABLED</key>
<false></false> <false/>
<key>IS_ANALYTICS_ENABLED</key> <key>IS_ANALYTICS_ENABLED</key>
<false></false> <false/>
<key>IS_APPINVITE_ENABLED</key> <key>IS_APPINVITE_ENABLED</key>
<true></true> <true/>
<key>IS_GCM_ENABLED</key> <key>IS_GCM_ENABLED</key>
<true></true> <true/>
<key>IS_SIGNIN_ENABLED</key> <key>IS_SIGNIN_ENABLED</key>
<true></true> <true/>
<key>GOOGLE_APP_ID</key> <key>GOOGLE_APP_ID</key>
<string>1:662236151640:ios:24badb58ab07515d8cef2d</string> <string>1:662236151640:ios:24badb58ab07515d8cef2d</string>
</dict> </dict>
......
import App
import UIKit import UIKit
import AppFeature
let appDelegate: String? = let appDelegate: String? =
NSClassFromString("XCTestCase") == nil NSClassFromString("XCTestCase") == nil
......
...@@ -8,40 +8,38 @@ let package = Package( ...@@ -8,40 +8,38 @@ let package = Package(
.iOS(.v14), .iOS(.v14),
], ],
products: [ products: [
.library(name: "App", targets: ["App"]),
.library(name: "Shared", targets: ["Shared"]), .library(name: "Shared", targets: ["Shared"]),
.library(name: "XXLogger", targets: ["XXLogger"]), .library(name: "AppCore", targets: ["AppCore"]),
.library(name: "Defaults", targets: ["Defaults"]), .library(name: "Defaults", targets: ["Defaults"]),
.library(name: "Keychain", targets: ["Keychain"]), .library(name: "Keychain", targets: ["Keychain"]),
.library(name: "Voxophone", targets: ["Voxophone"]), .library(name: "AppFeature", targets: ["AppFeature"]),
.library(name: "Countries", targets: ["Countries"]),
.library(name: "InputField", targets: ["InputField"]), .library(name: "InputField", targets: ["InputField"]),
.library(name: "ScanFeature", targets: ["ScanFeature"]), .library(name: "ScanFeature", targets: ["ScanFeature"]),
.library(name: "Permissions", targets: ["Permissions"]),
.library(name: "MenuFeature", targets: ["MenuFeature"]), .library(name: "MenuFeature", targets: ["MenuFeature"]),
.library(name: "ChatFeature", targets: ["ChatFeature"]), .library(name: "ChatFeature", targets: ["ChatFeature"]),
.library(name: "PushFeature", targets: ["PushFeature"]), .library(name: "PushFeature", targets: ["PushFeature"]),
.library(name: "AppResources", targets: ["AppResources"]),
.library(name: "CrashService", targets: ["CrashService"]), .library(name: "CrashService", targets: ["CrashService"]),
.library(name: "TermsFeature", targets: ["TermsFeature"]), .library(name: "TermsFeature", targets: ["TermsFeature"]),
.library(name: "Presentation", targets: ["Presentation"]),
.library(name: "BackupFeature", targets: ["BackupFeature"]), .library(name: "BackupFeature", targets: ["BackupFeature"]),
.library(name: "LaunchFeature", targets: ["LaunchFeature"]), .library(name: "LaunchFeature", targets: ["LaunchFeature"]),
.library(name: "SearchFeature", targets: ["SearchFeature"]), .library(name: "SearchFeature", targets: ["SearchFeature"]),
.library(name: "DrawerFeature", targets: ["DrawerFeature"]), .library(name: "DrawerFeature", targets: ["DrawerFeature"]),
.library(name: "CollectionView", targets: ["CollectionView"]),
.library(name: "RestoreFeature", targets: ["RestoreFeature"]), .library(name: "RestoreFeature", targets: ["RestoreFeature"]),
.library(name: "CrashReporting", targets: ["CrashReporting"]), .library(name: "CrashReporting", targets: ["CrashReporting"]),
.library(name: "ProfileFeature", targets: ["ProfileFeature"]), .library(name: "ProfileFeature", targets: ["ProfileFeature"]),
.library(name: "ContactFeature", targets: ["ContactFeature"]), .library(name: "ContactFeature", targets: ["ContactFeature"]),
.library(name: "NetworkMonitor", targets: ["NetworkMonitor"]),
.library(name: "VersionChecking", targets: ["VersionChecking"]),
.library(name: "SettingsFeature", targets: ["SettingsFeature"]), .library(name: "SettingsFeature", targets: ["SettingsFeature"]),
.library(name: "ChatListFeature", targets: ["ChatListFeature"]), .library(name: "ChatListFeature", targets: ["ChatListFeature"]),
.library(name: "RequestsFeature", targets: ["RequestsFeature"]), .library(name: "RequestsFeature", targets: ["RequestsFeature"]),
.library(name: "ReportingFeature", targets: ["ReportingFeature"]),
.library(name: "StatusBarFeature", targets: ["StatusBarFeature"]),
.library(name: "ChatInputFeature", targets: ["ChatInputFeature"]), .library(name: "ChatInputFeature", targets: ["ChatInputFeature"]),
.library(name: "OnboardingFeature", targets: ["OnboardingFeature"]), .library(name: "OnboardingFeature", targets: ["OnboardingFeature"]),
.library(name: "CountryListFeature", targets: ["CountryListFeature"]),
.library(name: "PermissionsFeature", targets: ["PermissionsFeature"]),
.library(name: "ContactListFeature", targets: ["ContactListFeature"]), .library(name: "ContactListFeature", targets: ["ContactListFeature"]),
.library(name: "ReportingFeature", targets: ["ReportingFeature"]) .library(name: "RequestPermissionFeature", targets: ["RequestPermissionFeature"]),
], ],
dependencies: [ dependencies: [
.package( .package(
...@@ -72,10 +70,6 @@ let package = Package( ...@@ -72,10 +70,6 @@ let package = Package(
url: "https://github.com/apple/swift-protobuf", url: "https://github.com/apple/swift-protobuf",
.upToNextMajor(from: "1.14.0") .upToNextMajor(from: "1.14.0")
), ),
.package(
url: "https://github.com/SwiftyBeaver/SwiftyBeaver.git",
.upToNextMajor(from: "1.9.5")
),
.package( .package(
url: "https://github.com/darrarski/ScrollViewController", url: "https://github.com/darrarski/ScrollViewController",
.upToNextMajor(from: "1.2.0") .upToNextMajor(from: "1.2.0")
...@@ -106,7 +100,7 @@ let package = Package( ...@@ -106,7 +100,7 @@ let package = Package(
), ),
.package( .package(
url: "https://github.com/pointfreeco/swift-composable-architecture.git", url: "https://github.com/pointfreeco/swift-composable-architecture.git",
.upToNextMajor(from: "0.32.0") .upToNextMajor(from: "0.43.0")
), ),
.package( .package(
url: "https://github.com/pointfreeco/swift-custom-dump.git", url: "https://github.com/pointfreeco/swift-custom-dump.git",
...@@ -116,25 +110,28 @@ let package = Package( ...@@ -116,25 +110,28 @@ let package = Package(
url: "https://github.com/swiftcsv/SwiftCSV.git", url: "https://github.com/swiftcsv/SwiftCSV.git",
from: "0.8.0" from: "0.8.0"
), ),
.package(
url: "https://github.com/apple/swift-log.git",
.upToNextMajor(from: "1.4.4")
),
.package( .package(
url: "https://github.com/pointfreeco/xctest-dynamic-overlay.git", url: "https://github.com/pointfreeco/xctest-dynamic-overlay.git",
.upToNextMajor(from: "0.3.3") .upToNextMajor(from: "0.3.3")
), ),
.package( .package(
url: "https://git.xx.network/elixxir/xxm-di.git", path: "../xxm-navigation"
.upToNextMajor(from: "1.0.0")
), ),
.package( .package(
path: "../xxm-navigation" url: "https://git.xx.network/elixxir/xxm-di",
.upToNextMajor(from: "1.0.0")
) )
], ],
targets: [ targets: [
.target( .target(
name: "App", name: "AppFeature",
dependencies: [ dependencies: [
.target(name: "AppCore"),
.target(name: "Keychain"), .target(name: "Keychain"),
.target(name: "Voxophone"),
.target(name: "Permissions"),
.target(name: "ScanFeature"), .target(name: "ScanFeature"),
.target(name: "ChatFeature"), .target(name: "ChatFeature"),
.target(name: "MenuFeature"), .target(name: "MenuFeature"),
...@@ -154,26 +151,66 @@ let package = Package( ...@@ -154,26 +151,66 @@ let package = Package(
.target(name: "ReportingFeature"), .target(name: "ReportingFeature"),
.target(name: "OnboardingFeature"), .target(name: "OnboardingFeature"),
.target(name: "ContactListFeature"), .target(name: "ContactListFeature"),
.target(name: "RequestPermissionFeature"),
.product(name: "DependencyInjection", package: "xxm-di"), .product(name: "DependencyInjection", package: "xxm-di"),
] ]
), ),
.testTarget( .testTarget(
name: "AppTests", name: "AppFeatureTests",
dependencies: [
.target(name: "AppFeature"),
]
),
.target(
name: "AppCore",
dependencies: [ dependencies: [
.target(name: "App"), .target(name: "Shared"),
.target(name: "AppResources"),
.target(name: "StatusBarFeature"),
.product(name: "SnapKit", package: "SnapKit"),
.product(name: "Logging", package: "swift-log"),
.product(name: "XXModels", package: "client-ios-db"),
.product(name: "XXDatabase", package: "client-ios-db"),
.product(name: "XXClient", package: "elixxir-dapps-sdk-swift"),
.product(name: "XXMessengerClient", package: "elixxir-dapps-sdk-swift"),
.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"),
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
] ]
), ),
.target( .target(
name: "CrashReporting" name: "CrashReporting"
), ),
.target( .target(
name: "NetworkMonitor", name: "PermissionsFeature",
dependencies: [ dependencies: [
.product(name: "XXClient", package: "elixxir-dapps-sdk-swift"), .product(
name: "XCTestDynamicOverlay",
package: "xctest-dynamic-overlay"
),
.product(
name: "ComposableArchitecture",
package: "swift-composable-architecture"
),
] ]
), ),
.target( .target(
name: "VersionChecking" name: "StatusBarFeature",
dependencies: [
.product(
name: "XCTestDynamicOverlay",
package: "xctest-dynamic-overlay"
),
.product(
name: "ComposableArchitecture",
package: "swift-composable-architecture"
),
]
),
.target(
name: "AppResources",
resources: [
.process("Resources")
]
), ),
.target( .target(
name: "InputField", name: "InputField",
...@@ -182,11 +219,15 @@ let package = Package( ...@@ -182,11 +219,15 @@ let package = Package(
] ]
), ),
.target( .target(
name: "Permissions", name: "RequestPermissionFeature",
dependencies: [ dependencies: [
.target(name: "Shared"), .target(name: "Shared"),
.product(name: "Navigation", package: "xxm-navigation"), .target(name: "AppResources"),
.product(name: "DependencyInjection", package: "xxm-di"), .target(name: "PermissionsFeature"),
.product(
name: "ComposableArchitecture",
package: "swift-composable-architecture"
),
] ]
), ),
.target( .target(
...@@ -206,12 +247,6 @@ let package = Package( ...@@ -206,12 +247,6 @@ let package = Package(
.product(name: "KeychainAccess", package: "KeychainAccess"), .product(name: "KeychainAccess", package: "KeychainAccess"),
] ]
), ),
.target(
name: "Voxophone",
dependencies: [
.target(name: "Shared"),
]
),
.target( .target(
name: "Defaults", name: "Defaults",
dependencies: [ dependencies: [
...@@ -226,10 +261,10 @@ let package = Package( ...@@ -226,10 +261,10 @@ let package = Package(
] ]
), ),
.target( .target(
name: "Countries", name: "CountryListFeature",
dependencies: [ dependencies: [
.target(name: "Shared"), .target(name: "Shared"),
.product(name: "DependencyInjection", package: "xxm-di"), .target(name: "StatusBarFeature")
] ]
), ),
.target( .target(
...@@ -240,12 +275,6 @@ let package = Package( ...@@ -240,12 +275,6 @@ let package = Package(
.product(name: "ScrollViewController", package: "ScrollViewController"), .product(name: "ScrollViewController", package: "ScrollViewController"),
] ]
), ),
.target(
name: "XXLogger",
dependencies: [
.product(name: "SwiftyBeaver", package: "SwiftyBeaver"),
]
),
.target( .target(
name: "Shared", name: "Shared",
dependencies: [ dependencies: [
...@@ -261,33 +290,19 @@ let package = Package( ...@@ -261,33 +290,19 @@ let package = Package(
.process("Resources"), .process("Resources"),
] ]
), ),
.target(
name: "Presentation",
dependencies: [
.target(name: "Shared"),
.product(name: "SnapKit", package: "SnapKit"),
]
),
.testTarget(
name: "PresentationTests",
dependencies: [
.target(name: "Presentation"),
.product(name: "Quick", package: "Quick"),
.product(name: "Nimble", package: "Nimble"),
]
),
.target( .target(
name: "ChatInputFeature", name: "ChatInputFeature",
dependencies: [ dependencies: [
.target(name: "Voxophone"), .product(
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"), name: "ComposableArchitecture",
package: "swift-composable-architecture"
),
] ]
), ),
.target( .target(
name: "RestoreFeature", name: "RestoreFeature",
dependencies: [ dependencies: [
.target(name: "Shared"), .target(name: "Shared"),
.target(name: "Presentation"),
.product(name: "XXDatabase", package: "client-ios-db"), .product(name: "XXDatabase", package: "client-ios-db"),
.product(name: "Navigation", package: "xxm-navigation"), .product(name: "Navigation", package: "xxm-navigation"),
.product(name: "DependencyInjection", package: "xxm-di"), .product(name: "DependencyInjection", package: "xxm-di"),
...@@ -304,7 +319,6 @@ let package = Package( ...@@ -304,7 +319,6 @@ let package = Package(
.target(name: "Shared"), .target(name: "Shared"),
.target(name: "InputField"), .target(name: "InputField"),
.target(name: "ChatFeature"), .target(name: "ChatFeature"),
.target(name: "Presentation"),
.product(name: "CombineSchedulers", package: "combine-schedulers"), .product(name: "CombineSchedulers", package: "combine-schedulers"),
.product(name: "ScrollViewController", package: "ScrollViewController"), .product(name: "ScrollViewController", package: "ScrollViewController"),
] ]
...@@ -315,29 +329,26 @@ let package = Package( ...@@ -315,29 +329,26 @@ let package = Package(
.target(name: "Shared"), .target(name: "Shared"),
.target(name: "Defaults"), .target(name: "Defaults"),
.target(name: "Keychain"), .target(name: "Keychain"),
.target(name: "Voxophone"),
.target(name: "Permissions"),
.target(name: "Presentation"),
.target(name: "DrawerFeature"), .target(name: "DrawerFeature"),
.target(name: "ChatInputFeature"), .target(name: "ChatInputFeature"),
.target(name: "ReportingFeature"), .target(name: "ReportingFeature"),
.target(name: "RequestPermissionFeature"),
.product(name: "DependencyInjection", package: "xxm-di"), .product(name: "DependencyInjection", package: "xxm-di"),
.product(name: "ChatLayout", package: "ChatLayout"), .product(name: "ChatLayout", package: "ChatLayout"),
.product(name: "DifferenceKit", package: "DifferenceKit"), .product(name: "DifferenceKit", package: "DifferenceKit"),
.product(name: "XXClient", package: "elixxir-dapps-sdk-swift"), .product(name: "XXClient", package: "elixxir-dapps-sdk-swift"),
.product(name: "XXMessengerClient", package: "elixxir-dapps-sdk-swift"), .product(name: "XXMessengerClient", package: "elixxir-dapps-sdk-swift"),
.product(name: "ScrollViewController", package: "ScrollViewController"), .product(name: "ScrollViewController", package: "ScrollViewController"),
.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"),
] ]
), ),
.target( .target(
name: "SearchFeature", name: "SearchFeature",
dependencies: [ dependencies: [
.target(name: "Shared"), .target(name: "Shared"),
.target(name: "Countries"),
.target(name: "PushFeature"), .target(name: "PushFeature"),
.target(name: "Presentation"),
.target(name: "ContactFeature"), .target(name: "ContactFeature"),
.target(name: "NetworkMonitor"), .target(name: "CountryListFeature"),
.product(name: "Retry", package: "Retry"), .product(name: "Retry", package: "Retry"),
.product(name: "XXDatabase", package: "client-ios-db"), .product(name: "XXDatabase", package: "client-ios-db"),
.product(name: "DependencyInjection", package: "xxm-di"), .product(name: "DependencyInjection", package: "xxm-di"),
...@@ -349,11 +360,9 @@ let package = Package( ...@@ -349,11 +360,9 @@ let package = Package(
.target(name: "Shared"), .target(name: "Shared"),
.target(name: "Defaults"), .target(name: "Defaults"),
.target(name: "PushFeature"), .target(name: "PushFeature"),
.target(name: "Permissions"),
.target(name: "BackupFeature"), .target(name: "BackupFeature"),
.target(name: "VersionChecking"),
.target(name: "ReportingFeature"), .target(name: "ReportingFeature"),
.product(name: "DependencyInjection", package: "xxm-di"), .target(name: "RequestPermissionFeature"),
.product(name: "XXClient", package: "elixxir-dapps-sdk-swift"), .product(name: "XXClient", package: "elixxir-dapps-sdk-swift"),
.product(name: "CloudFilesSFTP", package: "xxm-cloud-providers"), .product(name: "CloudFilesSFTP", package: "xxm-cloud-providers"),
.product(name: "CombineSchedulers", package: "combine-schedulers"), .product(name: "CombineSchedulers", package: "combine-schedulers"),
...@@ -367,7 +376,6 @@ let package = Package( ...@@ -367,7 +376,6 @@ let package = Package(
dependencies: [ dependencies: [
.target(name: "Shared"), .target(name: "Shared"),
.target(name: "Defaults"), .target(name: "Defaults"),
.target(name: "Presentation"),
.product(name: "Navigation", package: "xxm-navigation"), .product(name: "Navigation", package: "xxm-navigation"),
] ]
), ),
...@@ -386,13 +394,12 @@ let package = Package( ...@@ -386,13 +394,12 @@ let package = Package(
.target(name: "Shared"), .target(name: "Shared"),
.target(name: "Keychain"), .target(name: "Keychain"),
.target(name: "Defaults"), .target(name: "Defaults"),
.target(name: "Countries"),
.target(name: "InputField"), .target(name: "InputField"),
.target(name: "MenuFeature"), .target(name: "MenuFeature"),
.target(name: "Permissions"),
.target(name: "Presentation"),
.target(name: "DrawerFeature"), .target(name: "DrawerFeature"),
.target(name: "BackupFeature"), .target(name: "BackupFeature"),
.target(name: "CountryListFeature"),
.target(name: "RequestPermissionFeature"),
.product(name: "Navigation", package: "xxm-navigation"), .product(name: "Navigation", package: "xxm-navigation"),
.product(name: "DependencyInjection", package: "xxm-di"), .product(name: "DependencyInjection", package: "xxm-di"),
.product(name: "CombineSchedulers", package: "combine-schedulers"), .product(name: "CombineSchedulers", package: "combine-schedulers"),
...@@ -419,18 +426,17 @@ let package = Package( ...@@ -419,18 +426,17 @@ let package = Package(
name: "OnboardingFeature", name: "OnboardingFeature",
dependencies: [ dependencies: [
.target(name: "Shared"), .target(name: "Shared"),
.target(name: "AppCore"),
.target(name: "Defaults"), .target(name: "Defaults"),
.target(name: "Keychain"), .target(name: "Keychain"),
.target(name: "Countries"),
.target(name: "InputField"), .target(name: "InputField"),
.target(name: "Permissions"),
.target(name: "PushFeature"), .target(name: "PushFeature"),
.target(name: "Presentation"),
.target(name: "DrawerFeature"), .target(name: "DrawerFeature"),
.target(name: "VersionChecking"), .target(name: "CountryListFeature"),
.product(name: "DependencyInjection", package: "xxm-di"), .target(name: "RequestPermissionFeature"),
.product(name: "CombineSchedulers", package: "combine-schedulers"), .product(name: "CombineSchedulers", package: "combine-schedulers"),
.product(name: "ScrollViewController", package: "ScrollViewController"), .product(name: "ScrollViewController", package: "ScrollViewController"),
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
] ]
), ),
.target( .target(
...@@ -438,7 +444,6 @@ let package = Package( ...@@ -438,7 +444,6 @@ let package = Package(
dependencies: [ dependencies: [
.target(name: "Shared"), .target(name: "Shared"),
.target(name: "Defaults"), .target(name: "Defaults"),
.target(name: "Presentation"),
.target(name: "DrawerFeature"), .target(name: "DrawerFeature"),
.target(name: "ReportingFeature"), .target(name: "ReportingFeature"),
.product(name: "Navigation", package: "xxm-navigation"), .product(name: "Navigation", package: "xxm-navigation"),
...@@ -450,29 +455,50 @@ let package = Package( ...@@ -450,29 +455,50 @@ let package = Package(
name: "BackupFeature", name: "BackupFeature",
dependencies: [ dependencies: [
.target(name: "Shared"), .target(name: "Shared"),
.target(name: "AppCore"),
.target(name: "InputField"), .target(name: "InputField"),
.target(name: "Presentation"),
.target(name: "DrawerFeature"), .target(name: "DrawerFeature"),
.target(name: "NetworkMonitor"), .product(
.product(name: "Navigation", package: "xxm-navigation"), name: "Navigation",
.product(name: "DependencyInjection", package: "xxm-di"), package: "xxm-navigation"
.product(name: "XXClient", package: "elixxir-dapps-sdk-swift"), ),
.product(name: "CloudFilesSFTP", package: "xxm-cloud-providers"), .product(
.product(name: "CloudFilesDrive", package: "xxm-cloud-providers"), name: "XXClient",
.product(name: "CloudFilesICloud", package: "xxm-cloud-providers"), package: "elixxir-dapps-sdk-swift"
.product(name: "CloudFilesDropbox", package: "xxm-cloud-providers"), ),
.product(name: "XXMessengerClient", package: "elixxir-dapps-sdk-swift"), .product(
name: "CloudFilesSFTP",
package: "xxm-cloud-providers"
),
.product(
name: "CloudFilesDrive",
package: "xxm-cloud-providers"
),
.product(
name: "CloudFilesICloud",
package: "xxm-cloud-providers"
),
.product(
name: "CloudFilesDropbox",
package: "xxm-cloud-providers"
),
.product(
name: "XXMessengerClient",
package: "elixxir-dapps-sdk-swift"
),
.product(
name: "ComposableArchitecture",
package: "swift-composable-architecture"
),
] ]
), ),
.target( .target(
name: "ScanFeature", name: "ScanFeature",
dependencies: [ dependencies: [
.target(name: "Shared"), .target(name: "Shared"),
.target(name: "Countries"),
.target(name: "Permissions"),
.target(name: "Presentation"),
.target(name: "ContactFeature"), .target(name: "ContactFeature"),
.target(name: "NetworkMonitor"), .target(name: "CountryListFeature"),
.target(name: "RequestPermissionFeature"),
.product(name: "DependencyInjection", package: "xxm-di"), .product(name: "DependencyInjection", package: "xxm-di"),
.product(name: "SnapKit", package: "SnapKit"), .product(name: "SnapKit", package: "SnapKit"),
] ]
...@@ -481,7 +507,6 @@ let package = Package( ...@@ -481,7 +507,6 @@ let package = Package(
name: "ContactListFeature", name: "ContactListFeature",
dependencies: [ dependencies: [
.target(name: "Shared"), .target(name: "Shared"),
.target(name: "Presentation"),
.target(name: "ContactFeature"), .target(name: "ContactFeature"),
.product(name: "DependencyInjection", package: "xxm-di"), .product(name: "DependencyInjection", package: "xxm-di"),
.product(name: "DifferenceKit", package: "DifferenceKit"), .product(name: "DifferenceKit", package: "DifferenceKit"),
...@@ -493,32 +518,16 @@ let package = Package( ...@@ -493,32 +518,16 @@ let package = Package(
.target(name: "Shared"), .target(name: "Shared"),
.target(name: "Defaults"), .target(name: "Defaults"),
.target(name: "Keychain"), .target(name: "Keychain"),
.target(name: "XXLogger"),
.target(name: "InputField"), .target(name: "InputField"),
.target(name: "PushFeature"), .target(name: "PushFeature"),
.target(name: "Permissions"),
.target(name: "MenuFeature"), .target(name: "MenuFeature"),
.target(name: "Presentation"),
.target(name: "DrawerFeature"), .target(name: "DrawerFeature"),
.target(name: "RequestPermissionFeature"),
.product(name: "DependencyInjection", package: "xxm-di"), .product(name: "DependencyInjection", package: "xxm-di"),
.product(name: "CombineSchedulers", package: "combine-schedulers"), .product(name: "CombineSchedulers", package: "combine-schedulers"),
.product(name: "ScrollViewController", package: "ScrollViewController"), .product(name: "ScrollViewController", package: "ScrollViewController"),
] ]
), ),
.target(
name: "CollectionView",
dependencies: [
.product(name: "ChatLayout", package: "ChatLayout"),
.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"),
]
),
.testTarget(
name: "CollectionViewTests",
dependencies: [
.target(name: "CollectionView"),
.product(name: "CustomDump", package: "swift-custom-dump"),
]
),
.target( .target(
name: "ReportingFeature", name: "ReportingFeature",
dependencies: [ dependencies: [
......
// MARK: SDK
import UIKit
import Network
import QuickLook
import MobileCoreServices
// MARK: Isolated features
import Bindings
import XXLogger
import Keychain
import Defaults
import Countries
import Voxophone
import Permissions
import PushFeature
import CrashService
import CrashReporting
import NetworkMonitor
import VersionChecking
import ReportingFeature
import DI
// MARK: UI Features
import ScanFeature
import ChatFeature
import MenuFeature
import TermsFeature
import BackupFeature
import DrawerFeature
import SearchFeature
import LaunchFeature
import RestoreFeature
import ContactFeature
import ProfileFeature
import ChatListFeature
import SettingsFeature
import RequestsFeature
import OnboardingFeature
import ContactListFeature
import Shared
import XXClient
import Navigation
import KeychainAccess
import XXMessengerClient
struct DependencyRegistrator {
static private let container = DI.Container.shared
static func registerDependencies() {
#if DEBUG
DependencyRegistrator.registerForMock()
#else
DependencyRegistrator.registerForLive()
#endif
}
// MARK: MOCK
static func registerForMock() {
container.register(XXLogger.noop)
container.register(VersionCheck.mock)
container.register(CrashReporter.noop)
container.register(ReportingStatus.mock())
container.register(SendReport.mock())
container.register(MockNetworkMonitor() as NetworkMonitoring)
container.register(KeyObjectStore.userDefaults)
container.register(MockPushHandler() as PushHandling)
container.register(MockKeychainHandler() as KeychainHandling)
container.register(MockPermissionHandler() as PermissionHandling)
registerCommonDependencies()
}
// MARK: LIVE
static func registerForLive() {
let cMixManager = CMixManager.live(passwordStorage: .keychain)
container.register(cMixManager)
container.register(GetIdFromContact.live)
container.register(GetFactsFromContact.live)
container.register(KeyObjectStore.userDefaults)
container.register(XXLogger.live())
container.register(VersionCheck.live)
container.register(CrashReporter.live)
container.register(ReportingStatus.live())
container.register(SendReport.live)
container.register(NetworkMonitor() as NetworkMonitoring)
container.register(PushHandler() as PushHandling)
container.register(KeychainHandler() as KeychainHandling)
container.register(PermissionHandler() as PermissionHandling)
registerCommonDependencies()
}
// MARK: COMMON
static public func registerNavigators(_ navController: UINavigationController) {
container.register(CombinedNavigator(
PresentModalNavigator(),
DismissModalNavigator(),
PushNavigator(),
PopToRootNavigator(),
PopToNavigator(),
SetStackNavigator(),
OpenUpNavigator(),
OpenLeftNavigator(),
PresentOnboardingStartNavigator(
screen: OnboardingStartController.init,
navigationController: { navController }
),
PresentChatListNavigator(
screen: ChatListController.init,
navigationController: { navController }
),
PresentTermsAndConditionsNavigator(
screen: TermsConditionsController.init,
navigationController: { navController }
),
PresentSearchNavigator(
screen: SearchContainerController.init(_:),
navigationController: { navController }
),
PresentRequestsNavigator(
screen: RequestsContainerController.init,
navigationController: { navController }
),
PresentChatNavigator(
screen: SingleChatController.init(_:),
navigationController: { navController }
),
PresentGroupChatNavigator(
screen: GroupChatController.init(_:),
navigationController: { navController }
),
PresentOnboardingWelcomeNavigator(
screen: OnboardingWelcomeController.init,
navigationController: { navController }
),
PresentOnboardingUsernameNavigator(
screen: OnboardingUsernameController.init,
navigationController: { navController }
),
PresentRestoreListNavigator(
screen: RestoreListController.init,
navigationController: { navController }
),
PresentOnboardingEmailNavigator(
screen: OnboardingEmailController.init,
navigationController: { navController }
),
PresentOnboardingPhoneNavigator(
screen: OnboardingPhoneController.init,
navigationController: { navController }
),
PresentOnboardingCodeNavigator(
screen: OnboardingCodeController.init(_:_:_:),
navigationController: { navController }
),
PresentDrawerNavigator(
screen: DrawerController.init(_:),
navigationController: { navController }
),
PresentContactListNavigator(
screen: ContactListController.init,
navigationController: { navController }
),
PresentMenuNavigator(
screen: MenuController.init(_:),
navigationController: { navController }
),
PresentScanNavigator(
screen: ScanContainerController.init,
navigationController: { navController }
),
PresentNewGroupNavigator(
screen: CreateGroupController.init,
navigationController: { navController }
),
PresentCountryListNavigator(
screen: CountryListController.init(_:),
navigationController: { navController }
),
PresentProfileNavigator(
screen: ProfileController.init,
navigationController: { navController }
),
PresentSettingsNavigator(
screen: SettingsController.init,
navigationController: { navController }
),
PresentSettingsAdvancedNavigator(
screen: SettingsAdvancedController.init,
navigationController: { navController }
),
PresentSettingsBackupNavigator(
screen: BackupController.init,
navigationController: { navController }
),
PresentSettingsAccountDeleteNavigator(
screen: AccountDeleteController.init,
navigationController: { navController }
),
PresentContactNavigator(
screen: ContactController.init(_:),
navigationController: { navController }
),
PresentActivitySheetNavigator(
screen: { UIActivityViewController(
activityItems: $0,
applicationActivities: nil
)},
navigationController: { navController }
),
PresentProfileEmailNavigator(
screen: ProfileEmailController.init,
navigationController: { navController }
),
PresentProfilePhoneNavigator(
screen: ProfilePhoneController.init,
navigationController: { navController }
),
PresentPermissionRequestNavigator(
screen: RequestPermissionController.init,
navigationController: { navController }
),
PresentPhotoLibraryNavigator(
screen: UIImagePickerController.init,
navigationController: { navController }
),
PresentProfileCodeNavigator(
screen: ProfileCodeController.init(_:_:_:),
navigationController: { navController }
)
) as Navigator)
}
static private func registerCommonDependencies() {
var environment: MessengerEnvironment = .live()
environment.ndfEnvironment = .mainnet
environment.serviceList = .userDefaults(
key: "preImage",
userDefaults: UserDefaults(suiteName: "group.elixxir.messenger")!
)
environment.udEnvironment = .init(
address: AlternativeUDConstants.address,
cert: AlternativeUDConstants.cert.data(using: .utf8)!,
contact: AlternativeUDConstants.contact.data(using: .utf8)!
)
container.register(Messenger.live(environment))
container.register(Voxophone())
container.register(BackupService())
container.register(MakeAppScreenshot.live)
container.register(FetchBannedList.live)
container.register(ProcessBannedList.live)
container.register(MakeReportDrawer.live)
// MARK: Isolated
container.register(HUDController())
container.register(ToastController())
container.register(StatusBarStylist())
}
}
extension PasswordStorage {
static let keychain: PasswordStorage = {
let keychain = KeychainAccess.Keychain(
service: "XXM"
)
return PasswordStorage(
save: { password in keychain[data: "password"] = password},
load: { try keychain[data: "password"] ?? { throw MissingPasswordError() }() },
remove: { try keychain.remove("password") }
)
}()
}
private enum AlternativeUDConstants {
static let address = "46.101.98.49:18001"
static let cert = """
-----BEGIN CERTIFICATE-----
MIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx
GzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJp
cDAeFw0xOTAzMDUxODM1NDNaFw0yOTAzMDIxODM1NDNaMGgxCzAJBgNVBAYTAlVT
MRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNV
BAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPP0WyVkfZA/CEd2DgKpcudn0oDh
Dwsjmx8LBDWsUgQzyLrFiVigfUmUefknUH3dTJjmiJtGqLsayCnWdqWLHPJYvFfs
WYW0IGF93UG/4N5UAWO4okC3CYgKSi4ekpfw2zgZq0gmbzTnXcHF9gfmQ7jJUKSE
tJPSNzXq+PZeJTC9zJAb4Lj8QzH18rDM8DaL2y1ns0Y2Hu0edBFn/OqavBJKb/uA
m3AEjqeOhC7EQUjVamWlTBPt40+B/6aFJX5BYm2JFkRsGBIyBVL46MvC02MgzTT9
bJIJfwqmBaTruwemNgzGu7Jk03hqqS1TUEvSI6/x8bVoba3orcKkf9HsDjECAwEA
AaMZMBcwFQYDVR0RBA4wDIIKKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEA
neUocN4AbcQAC1+b3To8u5UGdaGxhcGyZBlAoenRVdjXK3lTjsMdMWb4QctgNfIf
U/zuUn2mxTmF/ekP0gCCgtleZr9+DYKU5hlXk8K10uKxGD6EvoiXZzlfeUuotgp2
qvI3ysOm/hvCfyEkqhfHtbxjV7j7v7eQFPbvNaXbLa0yr4C4vMK/Z09Ui9JrZ/Z4
cyIkxfC6/rOqAirSdIp09EGiw7GM8guHyggE4IiZrDslT8V3xIl985cbCxSxeW1R
tgH4rdEXuVe9+31oJhmXOE9ux2jCop9tEJMgWg7HStrJ5plPbb+HmjoX3nBO04E5
6m52PyzMNV+2N21IPppKwA==
-----END CERTIFICATE-----
"""
static let contact = """
<xxc(2)7mbKFLE201WzH4SGxAOpHjjehwztIV+KGifi5L/PYPcDkAZiB9kZo+Dl3Vc7dD2SdZCFMOJVgwqGzfYRDkjc8RGEllBqNxq2sRRX09iQVef0kJQUgJCHNCOcvm6Ki0JJwvjLceyFh36iwK8oLbhLgqEZY86UScdACTyBCzBIab3ob5mBthYc3mheV88yq5PGF2DQ+dEvueUm+QhOSfwzppAJA/rpW9Wq9xzYcQzaqc3ztAGYfm2BBAHS7HVmkCbvZ/K07Xrl4EBPGHJYq12tWAN/C3mcbbBYUOQXyEzbSl/mO7sL3ORr0B4FMuqCi8EdlD6RO52pVhY+Cg6roRH1t5Ng1JxPt8Mv1yyjbifPhZ5fLKwxBz8UiFORfk0/jnhwgm25LRHqtNRRUlYXLvhv0HhqyYTUt17WNtCLATSVbqLrFGdy2EGadn8mP+kQNHp93f27d/uHgBNNe7LpuYCJMdWpoG6bOqmHEftxt0/MIQA8fTtTm3jJzv+7/QjZJDvQIv0SNdp8HFogpuwde+GuS4BcY7v5xz+ArGWcRR63ct2z83MqQEn9ODr1/gAAAgA7szRpDDQIdFUQo9mkWg8xBA==xxc>
"""
}
import UIKit
import PushFeature
import ChatFeature
import SearchFeature
import LaunchFeature
import ChatListFeature
import RequestsFeature
import DI
import XXModels
import XXMessengerClient
extension PushRouter {
static func live(navigationController: UINavigationController) -> PushRouter {
PushRouter { route, completion in
if let launchController = navigationController.viewControllers.last as? LaunchController {
launchController.pendingPushRoute = route
} else {
switch route {
case .requests:
if !(navigationController.viewControllers.last is RequestsContainerController) {
navigationController.setViewControllers([RequestsContainerController()], animated: true)
}
case .search(username: let username):
if let messenger = try? DI.Container.shared.resolve() as Messenger,
let _ = try? messenger.ud.get()?.getContact() {
if !(navigationController.viewControllers.last is SearchContainerController) {
navigationController.setViewControllers([
ChatListController(),
SearchContainerController(username)
], animated: true)
} else {
(navigationController.viewControllers.last as? SearchContainerController)?.startSearchingFor(username)
}
}
case .contactChat(id: let id):
if let database: Database = try? DI.Container.shared.resolve(),
let contact = try? database.fetchContacts(.init(id: [id])).first {
navigationController.setViewControllers([
ChatListController(),
SingleChatController(contact)
], animated: true)
}
case .groupChat(id: let id):
if let database: Database = try? DI.Container.shared.resolve(),
let info = try? database.fetchGroupInfos(.init(groupId: id)).first {
navigationController.setViewControllers([
ChatListController(),
GroupChatController(info)
], animated: true)
}
}
}
completion()
}
}
}
import Foundation
import XXMessengerClient
import XCTestDynamicOverlay
import ComposableArchitecture
public struct AppDependencies {
public var networkMonitor: NetworkMonitorManager
public var toastManager: ToastManager
public var hudManager: HUDManager
public var dbManager: DBManager
public var messenger: Messenger
public var authHandler: AuthCallbackHandler
public var backupStorage: BackupStorage
public var mainQueue: AnySchedulerOf<DispatchQueue>
public var bgQueue: AnySchedulerOf<DispatchQueue>
public var now: () -> Date
public var sendMessage: SendMessage
public var sendImage: SendImage
public var messageListener: MessageListenerHandler
public var receiveFileHandler: ReceiveFileHandler
public var log: Logger
public var loadData: URLDataLoader
}
extension AppDependencies {
public static func live() -> AppDependencies {
let dbManager = DBManager.live()
var messengerEnv = MessengerEnvironment.live()
messengerEnv.udEnvironment = .init(
address: Constants.address,
cert: Constants.cert.data(using: .utf8)!,
contact: Constants.contact.data(using: .utf8)!
)
messengerEnv.serviceList = .userDefaults(
key: "preImage",
userDefaults: UserDefaults(suiteName: "group.elixxir.messenger")!
)
let messenger = Messenger.live(messengerEnv)
let now: () -> Date = Date.init
return AppDependencies(
networkMonitor: .live(),
toastManager: .live(),
hudManager: .live(),
dbManager: dbManager,
messenger: messenger,
authHandler: .live(
messenger: messenger,
handleRequest: .live(db: dbManager.getDB, now: now),
handleConfirm: .live(db: dbManager.getDB),
handleReset: .live(db: dbManager.getDB)
),
backupStorage: .onDisk(),
mainQueue: DispatchQueue.main.eraseToAnyScheduler(),
bgQueue: DispatchQueue.global(qos: .background).eraseToAnyScheduler(),
now: now,
sendMessage: .live(
messenger: messenger,
db: dbManager.getDB,
now: now
),
sendImage: .live(
messenger: messenger,
db: dbManager.getDB,
now: now
),
messageListener: .live(
messenger: messenger,
db: dbManager.getDB
),
receiveFileHandler: .live(
messenger: messenger,
db: dbManager.getDB,
now: now
),
log: .live(),
loadData: .live
)
}
public static let unimplemented = AppDependencies(
networkMonitor: .unimplemented,
toastManager: .unimplemented,
hudManager: .unimplemented,
dbManager: .unimplemented,
messenger: .unimplemented,
authHandler: .unimplemented,
backupStorage: .unimplemented,
mainQueue: .unimplemented,
bgQueue: .unimplemented,
now: XCTestDynamicOverlay.unimplemented(
"\(Self.self)",
placeholder: Date(timeIntervalSince1970: 0)
),
sendMessage: .unimplemented,
sendImage: .unimplemented,
messageListener: .unimplemented,
receiveFileHandler: .unimplemented,
log: .unimplemented,
loadData: .unimplemented
)
}
private enum AppDependenciesKey: DependencyKey {
static let liveValue: AppDependencies = .live()
static let testValue: AppDependencies = .unimplemented
}
extension DependencyValues {
public var app: AppDependencies {
get { self[AppDependenciesKey.self] }
set { self[AppDependenciesKey.self] = newValue }
}
}
private enum Constants {
static let address = "46.101.98.49:18001"
static let cert = """
-----BEGIN CERTIFICATE-----
MIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx
GzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJp
cDAeFw0xOTAzMDUxODM1NDNaFw0yOTAzMDIxODM1NDNaMGgxCzAJBgNVBAYTAlVT
MRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNV
BAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPP0WyVkfZA/CEd2DgKpcudn0oDh
Dwsjmx8LBDWsUgQzyLrFiVigfUmUefknUH3dTJjmiJtGqLsayCnWdqWLHPJYvFfs
WYW0IGF93UG/4N5UAWO4okC3CYgKSi4ekpfw2zgZq0gmbzTnXcHF9gfmQ7jJUKSE
tJPSNzXq+PZeJTC9zJAb4Lj8QzH18rDM8DaL2y1ns0Y2Hu0edBFn/OqavBJKb/uA
m3AEjqeOhC7EQUjVamWlTBPt40+B/6aFJX5BYm2JFkRsGBIyBVL46MvC02MgzTT9
bJIJfwqmBaTruwemNgzGu7Jk03hqqS1TUEvSI6/x8bVoba3orcKkf9HsDjECAwEA
AaMZMBcwFQYDVR0RBA4wDIIKKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEA
neUocN4AbcQAC1+b3To8u5UGdaGxhcGyZBlAoenRVdjXK3lTjsMdMWb4QctgNfIf
U/zuUn2mxTmF/ekP0gCCgtleZr9+DYKU5hlXk8K10uKxGD6EvoiXZzlfeUuotgp2
qvI3ysOm/hvCfyEkqhfHtbxjV7j7v7eQFPbvNaXbLa0yr4C4vMK/Z09Ui9JrZ/Z4
cyIkxfC6/rOqAirSdIp09EGiw7GM8guHyggE4IiZrDslT8V3xIl985cbCxSxeW1R
tgH4rdEXuVe9+31oJhmXOE9ux2jCop9tEJMgWg7HStrJ5plPbb+HmjoX3nBO04E5
6m52PyzMNV+2N21IPppKwA==
-----END CERTIFICATE-----
"""
static let contact = """
<xxc(2)7mbKFLE201WzH4SGxAOpHjjehwztIV+KGifi5L/PYPcDkAZiB9kZo+Dl3Vc7dD2SdZCFMOJVgwqGzfYRDkjc8RGEllBqNxq2sRRX09iQVef0kJQUgJCHNCOcvm6Ki0JJwvjLceyFh36iwK8oLbhLgqEZY86UScdACTyBCzBIab3ob5mBthYc3mheV88yq5PGF2DQ+dEvueUm+QhOSfwzppAJA/rpW9Wq9xzYcQzaqc3ztAGYfm2BBAHS7HVmkCbvZ/K07Xrl4EBPGHJYq12tWAN/C3mcbbBYUOQXyEzbSl/mO7sL3ORr0B4FMuqCi8EdlD6RO52pVhY+Cg6roRH1t5Ng1JxPt8Mv1yyjbifPhZ5fLKwxBz8UiFORfk0/jnhwgm25LRHqtNRRUlYXLvhv0HhqyYTUt17WNtCLATSVbqLrFGdy2EGadn8mP+kQNHp93f27d/uHgBNNe7LpuYCJMdWpoG6bOqmHEftxt0/MIQA8fTtTm3jJzv+7/QjZJDvQIv0SNdp8HFogpuwde+GuS4BcY7v5xz+ArGWcRR63ct2z83MqQEn9ODr1/gAAAgA7szRpDDQIdFUQo9mkWg8xBA==xxc>
"""
}
import Foundation
import XCTestDynamicOverlay
import XXClient
import XXMessengerClient
import XXModels
public struct AuthCallbackHandler {
public typealias OnError = (Error) -> Void
public var run: (@escaping OnError) -> Cancellable
public func callAsFunction(onError: @escaping OnError) -> Cancellable {
run(onError)
}
}
extension AuthCallbackHandler {
public static func live(
messenger: Messenger,
handleRequest: AuthCallbackHandlerRequest,
handleConfirm: AuthCallbackHandlerConfirm,
handleReset: AuthCallbackHandlerReset
) -> AuthCallbackHandler {
AuthCallbackHandler { onError in
messenger.registerAuthCallbacks(.init { callback in
do {
switch callback {
case .request(let contact, _, _, _):
try handleRequest(contact)
case .confirm(let contact, _, _, _):
try handleConfirm(contact)
case .reset(let contact, _, _, _):
try handleReset(contact)
}
} catch {
onError(error)
}
})
}
}
}
extension AuthCallbackHandler {
public static let unimplemented = AuthCallbackHandler(
run: XCTUnimplemented("\(Self.self)", placeholder: Cancellable {})
)
}
import Foundation
import XCTestDynamicOverlay
import XXClient
import XXModels
public struct AuthCallbackHandlerConfirm {
public var run: (XXClient.Contact) throws -> Void
public func callAsFunction(_ contact: XXClient.Contact) throws {
try run(contact)
}
}
extension AuthCallbackHandlerConfirm {
public static func live(db: DBManagerGetDB) -> AuthCallbackHandlerConfirm {
AuthCallbackHandlerConfirm { xxContact in
let id = try xxContact.getId()
guard var dbContact = try db().fetchContacts(.init(id: [id])).first else {
return
}
dbContact.authStatus = .friend
dbContact = try db().saveContact(dbContact)
}
}
}
extension AuthCallbackHandlerConfirm {
public static let unimplemented = AuthCallbackHandlerConfirm(
run: XCTUnimplemented("\(Self.self)")
)
}
import Foundation
import XCTestDynamicOverlay
import XXClient
import XXMessengerClient
import XXModels
public struct AuthCallbackHandlerRequest {
public var run: (XXClient.Contact) throws -> Void
public func callAsFunction(_ contact: XXClient.Contact) throws {
try run(contact)
}
}
extension AuthCallbackHandlerRequest {
public static func live(
db: DBManagerGetDB,
now: @escaping () -> Date
) -> AuthCallbackHandlerRequest {
AuthCallbackHandlerRequest { xxContact in
let id = try xxContact.getId()
guard try db().fetchContacts(.init(id: [id])).isEmpty else {
return
}
var dbContact = XXModels.Contact(id: id)
dbContact.marshaled = xxContact.data
dbContact.username = try xxContact.getFact(.username)?.value
dbContact.email = try xxContact.getFact(.email)?.value
dbContact.phone = try xxContact.getFact(.phone)?.value
dbContact.authStatus = .stranger
dbContact.createdAt = now()
dbContact = try db().saveContact(dbContact)
}
}
}
extension AuthCallbackHandlerRequest {
public static let unimplemented = AuthCallbackHandlerRequest(
run: XCTUnimplemented("\(Self.self)")
)
}
import Foundation
import XCTestDynamicOverlay
import XXClient
import XXModels
public struct AuthCallbackHandlerReset {
public var run: (XXClient.Contact) throws -> Void
public func callAsFunction(_ contact: XXClient.Contact) throws {
try run(contact)
}
}
extension AuthCallbackHandlerReset {
public static func live(db: DBManagerGetDB) -> AuthCallbackHandlerReset {
AuthCallbackHandlerReset { xxContact in
let id = try xxContact.getId()
guard var dbContact = try db().fetchContacts(.init(id: [id])).first else {
return
}
dbContact.authStatus = .friend
dbContact = try db().saveContact(dbContact)
}
}
}
extension AuthCallbackHandlerReset {
public static let unimplemented = AuthCallbackHandlerReset(
run: XCTUnimplemented("\(Self.self)")
)
}
import XXModels
import Foundation
public struct DBManager {
public var hasDB: DBManagerHasDB
public var makeDB: DBManagerMakeDB
public var getDB: DBManagerGetDB
public var removeDB: DBManagerRemoveDB
}
extension DBManager {
public static func live(
url: URL = FileManager.default
.urls(for: .applicationSupportDirectory, in: .userDomainMask)
.first!
.appendingPathComponent("database")
) -> DBManager {
class Container {
var db: Database?
}
let container = Container()
return DBManager(
hasDB: .init { container.db != nil },
makeDB: .live(url: url, setDB: { container.db = $0 }),
getDB: .live(getDB: { container.db }),
removeDB: .live(url: url, getDB: { container.db }, unsetDB: { container.db = nil })
)
}
}
extension DBManager {
public static let unimplemented = DBManager(
hasDB: .unimplemented,
makeDB: .unimplemented,
getDB: .unimplemented,
removeDB: .unimplemented
)
}
import XXModels
import XCTestDynamicOverlay
public struct DBManagerGetDB {
public enum Error: Swift.Error, Equatable {
case missingDB
}
public var run: () throws -> Database
public func callAsFunction() throws -> Database {
try run()
}
}
extension DBManagerGetDB {
public static func live(
getDB: @escaping () -> Database?
) -> DBManagerGetDB {
DBManagerGetDB {
guard let db = getDB() else {
throw Error.missingDB
}
return db
}
}
}
extension DBManagerGetDB {
public static let unimplemented = DBManagerGetDB(
run: XCTUnimplemented("\(Self.self)")
)
}
import XCTestDynamicOverlay
public struct DBManagerHasDB {
init(run: @escaping () -> Bool) {
self.run = run
}
public var run: () -> Bool
public func callAsFunction() -> Bool {
run()
}
}
extension DBManagerHasDB {
public static let unimplemented = DBManagerHasDB(
run: XCTUnimplemented("\(Self.self)")
)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment