Skip to content
Snippets Groups Projects
Commit 497b2005 authored by Silbino Goncalves Matado's avatar Silbino Goncalves Matado
Browse files

Smartlist: Add the conversations list for received messages

Add adapter and service for messages (send, receive and statuses)

Add the smartlist to see the users that sent messages

Add lookup address into NameService to get the user name from the
RingId

Change-Id: I512bfafc7d3e77888a3560a183a085434220337b
parent 435a705b
No related branches found
No related tags found
No related merge requests found
Showing
with 726 additions and 15 deletions
github "ReactiveX/RxSwift" == 3.0.1
github "RxSwiftCommunity/RxDataSources" ~> 1.0
github "pkluz/PKHUD" ~> 4.0
github "pkluz/PKHUD" "4.2.1"
github "ReactiveX/RxSwift" "3.0.1"
github "RxSwiftCommunity/RxDataSources" "1.0.3"
github "pkluz/PKHUD" "4.2.3"
......@@ -115,6 +115,7 @@
564C44601E943C37000F92B1 /* NameRegistrationAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 564C445F1E943C37000F92B1 /* NameRegistrationAdapter.mm */; };
564C44621E943DE6000F92B1 /* NameService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564C44611E943DE6000F92B1 /* NameService.swift */; };
564C44641E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564C44631E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift */; };
56559B171EEED50D00BF20E1 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56559B161EEED50D00BF20E1 /* Colors.swift */; };
5669A7FA1EA904AF003C7B93 /* SwitchCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5669A7F91EA904AF003C7B93 /* SwitchCell.xib */; };
5669A7FC1EA904D2003C7B93 /* TextFieldCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5669A7FB1EA904D2003C7B93 /* TextFieldCell.xib */; };
5669A7FE1EA904E4003C7B93 /* TextCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5669A7FD1EA904E4003C7B93 /* TextCell.xib */; };
......@@ -126,8 +127,23 @@
56AC64E11E80542300EA1AA9 /* TextFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64E01E80542300EA1AA9 /* TextFieldCell.swift */; };
56AC64E31E805F0200EA1AA9 /* TextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64E21E805F0200EA1AA9 /* TextCell.swift */; };
56AC650E1E85694D00EA1AA9 /* RoundedTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC650D1E85694D00EA1AA9 /* RoundedTextField.swift */; };
56BBC99F1ED714CB00CDAF8B /* MessagesAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC99E1ED714CB00CDAF8B /* MessagesAdapter.mm */; };
56BBC9A21ED714DF00CDAF8B /* MessagesAdapterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9A01ED714DF00CDAF8B /* MessagesAdapterDelegate.swift */; };
56BBC9A31ED714DF00CDAF8B /* ConversationsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9A11ED714DF00CDAF8B /* ConversationsService.swift */; };
56BBC9A61ED7151500CDAF8B /* MessageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9A51ED7151500CDAF8B /* MessageModel.swift */; };
56BBC9A81ED7152300CDAF8B /* SmartlistViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9A71ED7152300CDAF8B /* SmartlistViewController.swift */; };
56BBC9AA1ED7153800CDAF8B /* Global.strings in Resources */ = {isa = PBXBuildFile; fileRef = 56BBC9A91ED7153800CDAF8B /* Global.strings */; };
56BBC9AC1ED7154300CDAF8B /* Smartlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 56BBC9AB1ED7154300CDAF8B /* Smartlist.strings */; };
56BBC9B01ED7155700CDAF8B /* ConversationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9AE1ED7155700CDAF8B /* ConversationModel.swift */; };
56BBC9B41ED7156500CDAF8B /* ConversationCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9B21ED7156500CDAF8B /* ConversationCell.swift */; };
56BBC9B51ED7156500CDAF8B /* ConversationCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 56BBC9B31ED7156500CDAF8B /* ConversationCell.xib */; };
56BBC9B91ED715FE00CDAF8B /* ContactModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9B71ED715FE00CDAF8B /* ContactModel.swift */; };
56BBC9BA1ED715FE00CDAF8B /* ContactHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9B81ED715FE00CDAF8B /* ContactHelper.swift */; };
56BBC9BC1ED7161200CDAF8B /* Date+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9BB1ED7161200CDAF8B /* Date+Helpers.swift */; };
56BBC9BF1ED7168400CDAF8B /* SmartlistViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9BE1ED7168400CDAF8B /* SmartlistViewModel.swift */; };
56BBC9C51ED8BF3300CDAF8B /* libargon2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 56BBC9C41ED8BF3300CDAF8B /* libargon2.a */; };
56BBC9DA1EDDC0B400CDAF8B /* LookupNameResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9D91EDDC0B400CDAF8B /* LookupNameResponse.m */; };
56BBC9DB1EDDC7F700CDAF8B /* LookupNameResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9D91EDDC0B400CDAF8B /* LookupNameResponse.m */; };
56BBC9DC1EDDC82600CDAF8B /* ConversationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9AF1ED7155700CDAF8B /* ConversationViewModel.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
......@@ -269,6 +285,7 @@
564C445F1E943C37000F92B1 /* NameRegistrationAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NameRegistrationAdapter.mm; sourceTree = "<group>"; };
564C44611E943DE6000F92B1 /* NameService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NameService.swift; sourceTree = "<group>"; };
564C44631E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NameRegistrationAdapterDelegate.swift; sourceTree = "<group>"; };
56559B161EEED50D00BF20E1 /* Colors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
5669A7F91EA904AF003C7B93 /* SwitchCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SwitchCell.xib; sourceTree = "<group>"; };
5669A7FB1EA904D2003C7B93 /* TextFieldCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TextFieldCell.xib; sourceTree = "<group>"; };
5669A7FD1EA904E4003C7B93 /* TextCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TextCell.xib; sourceTree = "<group>"; };
......@@ -280,6 +297,22 @@
56AC64E01E80542300EA1AA9 /* TextFieldCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldCell.swift; sourceTree = "<group>"; };
56AC64E21E805F0200EA1AA9 /* TextCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextCell.swift; sourceTree = "<group>"; };
56AC650D1E85694D00EA1AA9 /* RoundedTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoundedTextField.swift; sourceTree = "<group>"; };
56BBC99D1ED714CB00CDAF8B /* MessagesAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessagesAdapter.h; sourceTree = "<group>"; };
56BBC99E1ED714CB00CDAF8B /* MessagesAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MessagesAdapter.mm; sourceTree = "<group>"; };
56BBC9A01ED714DF00CDAF8B /* MessagesAdapterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessagesAdapterDelegate.swift; sourceTree = "<group>"; };
56BBC9A11ED714DF00CDAF8B /* ConversationsService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationsService.swift; sourceTree = "<group>"; };
56BBC9A51ED7151500CDAF8B /* MessageModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageModel.swift; sourceTree = "<group>"; };
56BBC9A71ED7152300CDAF8B /* SmartlistViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartlistViewController.swift; sourceTree = "<group>"; };
56BBC9A91ED7153800CDAF8B /* Global.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Global.strings; sourceTree = "<group>"; };
56BBC9AB1ED7154300CDAF8B /* Smartlist.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Smartlist.strings; sourceTree = "<group>"; };
56BBC9AE1ED7155700CDAF8B /* ConversationModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationModel.swift; sourceTree = "<group>"; };
56BBC9AF1ED7155700CDAF8B /* ConversationViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationViewModel.swift; sourceTree = "<group>"; };
56BBC9B21ED7156500CDAF8B /* ConversationCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationCell.swift; sourceTree = "<group>"; };
56BBC9B31ED7156500CDAF8B /* ConversationCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ConversationCell.xib; sourceTree = "<group>"; };
56BBC9B71ED715FE00CDAF8B /* ContactModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactModel.swift; sourceTree = "<group>"; };
56BBC9B81ED715FE00CDAF8B /* ContactHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactHelper.swift; sourceTree = "<group>"; };
56BBC9BB1ED7161200CDAF8B /* Date+Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Date+Helpers.swift"; path = "Extensions/Date+Helpers.swift"; sourceTree = "<group>"; };
56BBC9BE1ED7168400CDAF8B /* SmartlistViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartlistViewModel.swift; sourceTree = "<group>"; };
56BBC9C41ED8BF3300CDAF8B /* libargon2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libargon2.a; path = ../fat/lib/libargon2.a; sourceTree = "<group>"; };
56BBC9D81EDDC0B400CDAF8B /* LookupNameResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LookupNameResponse.h; sourceTree = "<group>"; };
56BBC9D91EDDC0B400CDAF8B /* LookupNameResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LookupNameResponse.m; sourceTree = "<group>"; };
......@@ -427,6 +460,8 @@
02E1A0261DDE4C2E00D75B59 /* Services */ = {
isa = PBXGroup;
children = (
56BBC9A01ED714DF00CDAF8B /* MessagesAdapterDelegate.swift */,
56BBC9A11ED714DF00CDAF8B /* ConversationsService.swift */,
02B22E081DF7585F000358C9 /* DaemonService.swift */,
02B22DFE1DF755DB000358C9 /* AccountsService.swift */,
0273C2FE1E0C438F00CF00BA /* AccountAdapterDelegate.swift */,
......@@ -453,6 +488,8 @@
02EFCACF1E0C3DD600FD8ED1 /* Bridging */ = {
isa = PBXGroup;
children = (
56BBC99D1ED714CB00CDAF8B /* MessagesAdapter.h */,
56BBC99E1ED714CB00CDAF8B /* MessagesAdapter.mm */,
04399AA91D1C304300E99CD9 /* Ring-Bridging-Header.h */,
557086501E8ADB9D001A7CE4 /* SystemAdapter.h */,
557086511E8ADB9D001A7CE4 /* SystemAdapter.mm */,
......@@ -497,6 +534,7 @@
043866391D2307C000E06CE2 /* Extensions */ = {
isa = PBXGroup;
children = (
56BBC9BB1ED7161200CDAF8B /* Date+Helpers.swift */,
043866371D2304A700E06CE2 /* BoolStringExtension.swift */,
);
name = Extensions;
......@@ -529,6 +567,10 @@
043999F51D1C2D9D00E99CD9 /* Ring */ = {
isa = PBXGroup;
children = (
56BBC9BD1ED7165800CDAF8B /* Smartlist */,
56BBC9B61ED7158600CDAF8B /* Contacts */,
56BBC9AD1ED7154800CDAF8B /* Conversations */,
56BBC9A41ED7150200CDAF8B /* Messages */,
564C44571E8D7F68000F92B1 /* Constants */,
56AC64D61E80121200EA1AA9 /* Internationalization */,
0273C3021E0C689600CF00BA /* Walkthrough */,
......@@ -671,6 +713,7 @@
children = (
564C44581E8D7F8F000F92B1 /* LocalizedStringTableNames.swift */,
564C445A1E8EA44E000F92B1 /* Durations.swift */,
56559B161EEED50D00BF20E1 /* Colors.swift */,
);
name = Constants;
sourceTree = "<group>";
......@@ -678,6 +721,8 @@
56AC64D61E80121200EA1AA9 /* Internationalization */ = {
isa = PBXGroup;
children = (
56BBC9AB1ED7154300CDAF8B /* Smartlist.strings */,
56BBC9A91ED7153800CDAF8B /* Global.strings */,
56AC64DB1E8012CA00EA1AA9 /* Walkthrough.strings */,
);
name = Internationalization;
......@@ -696,6 +741,43 @@
name = Cells;
sourceTree = "<group>";
};
56BBC9A41ED7150200CDAF8B /* Messages */ = {
isa = PBXGroup;
children = (
56BBC9A51ED7151500CDAF8B /* MessageModel.swift */,
);
name = Messages;
sourceTree = "<group>";
};
56BBC9AD1ED7154800CDAF8B /* Conversations */ = {
isa = PBXGroup;
children = (
56BBC9B21ED7156500CDAF8B /* ConversationCell.swift */,
56BBC9B31ED7156500CDAF8B /* ConversationCell.xib */,
56BBC9AE1ED7155700CDAF8B /* ConversationModel.swift */,
56BBC9AF1ED7155700CDAF8B /* ConversationViewModel.swift */,
);
name = Conversations;
sourceTree = "<group>";
};
56BBC9B61ED7158600CDAF8B /* Contacts */ = {
isa = PBXGroup;
children = (
56BBC9B71ED715FE00CDAF8B /* ContactModel.swift */,
56BBC9B81ED715FE00CDAF8B /* ContactHelper.swift */,
);
name = Contacts;
sourceTree = "<group>";
};
56BBC9BD1ED7165800CDAF8B /* Smartlist */ = {
isa = PBXGroup;
children = (
56BBC9BE1ED7168400CDAF8B /* SmartlistViewModel.swift */,
56BBC9A71ED7152300CDAF8B /* SmartlistViewController.swift */,
);
name = Smartlist;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
......@@ -809,9 +891,12 @@
02B22E031DF755F7000358C9 /* WalkthroughStoryboard.storyboard in Resources */,
5669A7FE1EA904E4003C7B93 /* TextCell.xib in Resources */,
04399A061D1C2D9D00E99CD9 /* LaunchScreen.storyboard in Resources */,
56BBC9AC1ED7154300CDAF8B /* Smartlist.strings in Resources */,
56BBC9AA1ED7153800CDAF8B /* Global.strings in Resources */,
04399A031D1C2D9D00E99CD9 /* Assets.xcassets in Resources */,
04399A011D1C2D9D00E99CD9 /* Main.storyboard in Resources */,
5669A7FA1EA904AF003C7B93 /* SwitchCell.xib in Resources */,
56BBC9B51ED7156500CDAF8B /* ConversationCell.xib in Resources */,
5669A7FC1EA904D2003C7B93 /* TextFieldCell.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
......@@ -856,41 +941,54 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
56BBC9DC1EDDC82600CDAF8B /* ConversationViewModel.swift in Sources */,
557086521E8ADB9D001A7CE4 /* SystemAdapter.mm in Sources */,
5669A8031EAA58E6003C7B93 /* LinkDeviceToAccountViewController.swift in Sources */,
0273C3051E0C68B100CF00BA /* CreateProfileViewController.swift in Sources */,
02E1A0251DDE4ABA00D75B59 /* BoolStringExtension.swift in Sources */,
04399AAC1D1C304300E99CD9 /* AccountAdapter.mm in Sources */,
02DD80C81E1EAD70009A3510 /* AccountConfigModel.swift in Sources */,
56BBC9DA1EDDC0B400CDAF8B /* LookupNameResponse.m in Sources */,
02B22E091DF7585F000358C9 /* DaemonService.swift in Sources */,
0273C3061E0C68B100CF00BA /* CreateRingAccountViewController.swift in Sources */,
56BBC99F1ED714CB00CDAF8B /* MessagesAdapter.mm in Sources */,
02C9B63F1E1D4E8C00F82F0C /* ServiceEvent.swift in Sources */,
02DD80CD1E1EB2E4009A3510 /* ConfigKeyModel.swift in Sources */,
56BBC9A81ED7152300CDAF8B /* SmartlistViewController.swift in Sources */,
5516C29F1E71CEFF009D3D2D /* AccountModelHelper.swift in Sources */,
56308BA71EA00E5700660275 /* NameRegistrationResponse.m in Sources */,
56AC64E11E80542300EA1AA9 /* TextFieldCell.swift in Sources */,
56AC64E31E805F0200EA1AA9 /* TextCell.swift in Sources */,
56AC650E1E85694D00EA1AA9 /* RoundedTextField.swift in Sources */,
56BBC9BF1ED7168400CDAF8B /* SmartlistViewModel.swift in Sources */,
02B22E011DF755E5000358C9 /* MainTabBarViewController.swift in Sources */,
56BBC9DB1EDDC7F700CDAF8B /* LookupNameResponse.m in Sources */,
564C44641E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift in Sources */,
043999F71D1C2D9D00E99CD9 /* AppDelegate.swift in Sources */,
02B22DFC1DF755BB000358C9 /* AccountModel.swift in Sources */,
043866331D22CE8C00E06CE2 /* MeViewController.swift in Sources */,
56AC64DF1E804ECC00EA1AA9 /* SwitchCell.swift in Sources */,
56BBC9B91ED715FE00CDAF8B /* ContactModel.swift in Sources */,
56BBC9BA1ED715FE00CDAF8B /* ContactHelper.swift in Sources */,
04399AAE1D1C304300E99CD9 /* Utils.mm in Sources */,
56BBC9A31ED714DF00CDAF8B /* ConversationsService.swift in Sources */,
56BBC9B01ED7155700CDAF8B /* ConversationModel.swift in Sources */,
563AEC771EA664C0003A5641 /* RegistrationResponse.m in Sources */,
02B22DFD1DF755BB000358C9 /* CreateRingAccountViewModel.swift in Sources */,
043999FA1D1C2D9D00E99CD9 /* Ring.xcdatamodeld in Sources */,
564C445B1E8EA44E000F92B1 /* Durations.swift in Sources */,
0438663B1D2313B700E06CE2 /* AccountDetailsViewController.swift in Sources */,
02DD80CA1E1EAF1A009A3510 /* AccountCredentialsModel.swift in Sources */,
56559B171EEED50D00BF20E1 /* Colors.swift in Sources */,
0273C3081E0C68BF00CF00BA /* RoundedButton.swift in Sources */,
56BBC9BC1ED7161200CDAF8B /* Date+Helpers.swift in Sources */,
564C44621E943DE6000F92B1 /* NameService.swift in Sources */,
043866361D22D06500E06CE2 /* AccountTableViewCell.swift in Sources */,
04399AAD1D1C304300E99CD9 /* DRingAdapter.mm in Sources */,
0273C2FF1E0C438F00CF00BA /* AccountAdapterDelegate.swift in Sources */,
02B22DFF1DF755DB000358C9 /* AccountsService.swift in Sources */,
56BBC9A61ED7151500CDAF8B /* MessageModel.swift in Sources */,
56BBC9A21ED714DF00CDAF8B /* MessagesAdapterDelegate.swift in Sources */,
56BBC9B41ED7156500CDAF8B /* ConversationCell.swift in Sources */,
564C44601E943C37000F92B1 /* NameRegistrationAdapter.mm in Sources */,
564C44591E8D7F8F000F92B1 /* LocalizedStringTableNames.swift in Sources */,
56AC64D51E7C7F4000EA1AA9 /* WelcomeViewController.swift in Sources */,
......
......@@ -29,6 +29,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
static let daemonService = DaemonService(dRingAdaptor: DRingAdapter())
static let accountService = AccountsService(withAccountAdapter: AccountAdapter())
static let nameService = NameService(withNameRegistrationAdapter: NameRegistrationAdapter())
static let conversationsService = ConversationsService(withMessageAdapter: MessagesAdapter())
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
SystemAdapter().registerConfigurationHandler()
......
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_contact_picture.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
Ring/Ring/Assets.xcassets/ic_contact_picture.imageset/ic_contact_picture.png

4.49 KiB

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="qdG-Sd-QaE">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="qdG-Sd-QaE">
<device id="retina4_0" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
......@@ -22,7 +22,7 @@
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="PERSON PLACEHOLDER" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vcL-Nj-NcH">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="PERSON PLACEHOLDER" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vcL-Nj-NcH">
<rect key="frame" x="16" y="102" width="180" height="64"/>
<constraints>
<constraint firstAttribute="width" constant="180" id="CUM-z9-ubY"/>
......@@ -50,7 +50,7 @@
<rect key="frame" x="0.0" y="28" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="i1O-Yc-WGd" id="Bz1-A3-Z3f">
<rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bm0-lC-K2F">
......@@ -96,7 +96,7 @@
<rect key="frame" x="0.0" y="72" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Ok2-8L-eMm" id="m64-AI-t2h">
<rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Add Account" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kZv-uf-BsD" userLabel="Account Name Label">
......@@ -192,9 +192,11 @@
<objects>
<navigationController id="acv-jH-RCt" sceneMemberID="viewController">
<tabBarItem key="tabBarItem" title="Me" id="jo3-1i-bFH"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="tAT-cg-hut">
<navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="black" id="tAT-cg-hut">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="barTintColor" red="0.039215686270000001" green="0.4549019608" blue="0.53725490200000003" alpha="1" colorSpace="calibratedRGB"/>
</navigationBar>
<connections>
<segue destination="Adn-sB-m3h" kind="relationship" relationship="rootViewController" id="yoa-Sb-o2W"/>
......@@ -204,14 +206,16 @@
</objects>
<point key="canvasLocation" x="-954" y="-438"/>
</scene>
<!--Item-->
<!--Home-->
<scene sceneID="RrV-5t-V1t">
<objects>
<navigationController id="m3Y-hs-SzS" sceneMemberID="viewController">
<tabBarItem key="tabBarItem" title="Item" id="vc8-sv-IF0"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="G6y-tt-W3p">
<tabBarItem key="tabBarItem" title="Home" id="vc8-sv-IF0"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="black" id="G6y-tt-W3p">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="barTintColor" red="0.039215686270000001" green="0.4549019608" blue="0.53725490200000003" alpha="1" colorSpace="calibratedRGB"/>
</navigationBar>
<connections>
<segue destination="NIj-Cd-aWO" kind="relationship" relationship="rootViewController" id="GUx-m9-dbP"/>
......@@ -224,7 +228,7 @@
<!--Home-->
<scene sceneID="UuZ-iE-GB0">
<objects>
<viewController title="Home" id="NIj-Cd-aWO" sceneMemberID="viewController">
<viewController title="Home" id="NIj-Cd-aWO" customClass="SmartlistViewController" customModule="Ring" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="s1e-Lp-B2j"/>
<viewControllerLayoutGuide type="bottom" id="aoH-Yk-Qrn"/>
......@@ -241,8 +245,10 @@
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<tabBarItem key="tabBarItem" title="Home" id="1QA-0Y-BFL"/>
<navigationItem key="navigationItem" id="b8m-eG-Q9D"/>
<connections>
<outlet property="tableView" destination="B6Y-MZ-L7L" id="dXp-J4-x68"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="rzQ-ll-5bo" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
......@@ -256,6 +262,7 @@
<rect key="frame" x="0.0" y="0.0" width="320" height="49"/>
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<color key="tintColor" red="0.039215686270000001" green="0.4549019608" blue="0.53725490200000003" alpha="1" colorSpace="calibratedRGB"/>
</tabBar>
<connections>
<segue destination="m3Y-hs-SzS" kind="relationship" relationship="viewControllers" id="tnG-cB-lXh"/>
......
......@@ -29,3 +29,4 @@
#import "LookupNameResponse.h"
#import "RegistrationResponse.h"
#import "NameRegistrationResponse.h"
#import "MessagesAdapter.h"
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import UIKit
class Colors {
static let ringMainColor = UIColor(colorLiteralRed: 10.0/255.0,
green: 116.0/255.0,
blue: 137.0/255.0,
alpha: 1.0)
}
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import UIKit
import RxSwift
class ContactHelper {
fileprivate static var cache = [String : String]()
static func lookupUserName(forRingId ringId: String, nameService: NameService, disposeBag: DisposeBag) -> Variable<String> {
let userName = Variable("")
if ContactHelper.cache[ringId] == nil {
//Lookup the user name observer
nameService.usernameLookupStatus
.observeOn(MainScheduler.instance)
.filter({ lookupNameResponse in
return lookupNameResponse.address != nil && lookupNameResponse.address == ringId
}).subscribe(onNext: { lookupNameResponse in
if lookupNameResponse.state == .found {
self.cache[ringId] = lookupNameResponse.name
userName.value = lookupNameResponse.name
} else {
self.cache[ringId] = lookupNameResponse.address
userName.value = lookupNameResponse.address
}
}).addDisposableTo(disposeBag)
nameService.lookupAddress(withAccount: "", nameserver: "", address: ringId)
} else {
userName.value = self.cache[ringId]!
}
return userName
}
}
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import UIKit
class ContactModel {
var ringId: String
init(withRingId ringId: String) {
self.ringId = ringId
}
public static func ==(lhs: ContactModel, rhs: ContactModel) -> Bool {
return lhs.ringId == rhs.ringId
}
}
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import UIKit
import RxSwift
class ConversationCell: UITableViewCell {
@IBOutlet weak var profileImage: UIImageView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var newMessagesIndicator: UIView!
@IBOutlet weak var newMessagesLabel: UILabel!
@IBOutlet weak var lastMessageDateLabel: UILabel!
@IBOutlet weak var lastMessagePreviewLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
self.newMessagesIndicator.backgroundColor = UIColor.red
}
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
super.setHighlighted(highlighted, animated: animated)
self.newMessagesIndicator.backgroundColor = UIColor.red
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="ConversationCellId" rowHeight="76" id="KGk-i7-Jjw" customClass="ConversationCell" customModule="Ring" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="358" height="76"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
<rect key="frame" x="0.0" y="0.0" width="358" height="75.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_contact_picture" translatesAutoresizingMaskIntoConstraints="NO" id="pFB-Jn-TNP">
<rect key="frame" x="16" y="18" width="40" height="40"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="width" constant="40" id="Ptm-nU-6Xi"/>
<constraint firstAttribute="height" constant="40" id="eES-QW-paO"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="20"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="Yesterday" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7Yv-cC-LKx">
<rect key="frame" x="281" y="30.5" width="61" height="14.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="12"/>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2fJ-Wf-1e0">
<rect key="frame" x="60" y="4" width="217" height="41"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eug-ak-r49">
<rect key="frame" x="60" y="49" width="282" height="22.5"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view clipsSubviews="YES" contentMode="scaleToFill" horizontalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="JTE-eF-Y5s">
<rect key="frame" x="42" y="18" width="14" height="14"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="1" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="P5S-4k-0yx">
<rect key="frame" x="0.0" y="0.0" width="14" height="14"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="14" id="VEi-Hm-z85"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="10"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstItem="P5S-4k-0yx" firstAttribute="top" secondItem="JTE-eF-Y5s" secondAttribute="top" id="BH8-rD-0Oo"/>
<constraint firstAttribute="height" constant="14" id="Qxc-Mv-ssH"/>
<constraint firstItem="P5S-4k-0yx" firstAttribute="leading" secondItem="JTE-eF-Y5s" secondAttribute="leading" id="ZE1-mR-DoI"/>
<constraint firstAttribute="trailing" secondItem="P5S-4k-0yx" secondAttribute="trailing" id="a9D-mE-0qK"/>
<constraint firstAttribute="bottom" secondItem="P5S-4k-0yx" secondAttribute="bottom" id="qMW-uw-IoS"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="6"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
</subviews>
<constraints>
<constraint firstItem="2fJ-Wf-1e0" firstAttribute="leading" secondItem="pFB-Jn-TNP" secondAttribute="trailing" constant="4" id="2NV-6m-dri"/>
<constraint firstItem="eug-ak-r49" firstAttribute="leading" secondItem="pFB-Jn-TNP" secondAttribute="trailing" constant="4" id="9ah-Ed-RlY"/>
<constraint firstItem="pFB-Jn-TNP" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="9mO-5E-3lA"/>
<constraint firstItem="7Yv-cC-LKx" firstAttribute="leading" secondItem="2fJ-Wf-1e0" secondAttribute="trailing" constant="4" id="BzU-Ya-2ME"/>
<constraint firstAttribute="trailing" secondItem="eug-ak-r49" secondAttribute="trailing" constant="16" id="ITl-14-BeZ"/>
<constraint firstItem="JTE-eF-Y5s" firstAttribute="trailing" secondItem="pFB-Jn-TNP" secondAttribute="trailing" id="MgK-cd-QXM"/>
<constraint firstAttribute="trailing" secondItem="7Yv-cC-LKx" secondAttribute="trailing" constant="16" id="UOx-Og-IuZ"/>
<constraint firstItem="JTE-eF-Y5s" firstAttribute="top" secondItem="pFB-Jn-TNP" secondAttribute="top" id="W3A-IX-eXJ"/>
<constraint firstItem="2fJ-Wf-1e0" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="4" id="omS-kb-QbN"/>
<constraint firstItem="eug-ak-r49" firstAttribute="top" secondItem="7Yv-cC-LKx" secondAttribute="bottom" constant="4" id="oox-mY-e8b"/>
<constraint firstAttribute="bottom" secondItem="eug-ak-r49" secondAttribute="bottom" constant="4" id="rzH-w5-tpt"/>
<constraint firstItem="eug-ak-r49" firstAttribute="top" secondItem="2fJ-Wf-1e0" secondAttribute="bottom" constant="4" id="se0-Ur-K7G"/>
<constraint firstItem="pFB-Jn-TNP" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="suq-ak-BYg"/>
<constraint firstItem="7Yv-cC-LKx" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="xVO-gP-WdP"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="lastMessageDateLabel" destination="7Yv-cC-LKx" id="pFf-hW-zD8"/>
<outlet property="lastMessagePreviewLabel" destination="eug-ak-r49" id="3jj-Lx-jbU"/>
<outlet property="nameLabel" destination="2fJ-Wf-1e0" id="0Mb-yC-vh6"/>
<outlet property="newMessagesIndicator" destination="JTE-eF-Y5s" id="9kR-8x-Zpk"/>
<outlet property="newMessagesLabel" destination="P5S-4k-0yx" id="WlA-Z8-sNC"/>
<outlet property="profileImage" destination="pFB-Jn-TNP" id="zuf-CZ-9wL"/>
</connections>
<point key="canvasLocation" x="70" y="-92"/>
</tableViewCell>
</objects>
<resources>
<image name="ic_contact_picture" width="128" height="128"/>
</resources>
</document>
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
class ConversationModel {
var messages = [MessageModel]()
var recipient: ContactModel
var accountId: String
init(withRecipient recipient: ContactModel, accountId: String) {
self.recipient = recipient
self.accountId = accountId
}
}
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import UIKit
import RxSwift
class ConversationViewModel {
let conversation: ConversationModel
let userName: Observable<String>
//Displays the entire date ( for messages received before the current week )
private let dateFormatter = DateFormatter()
//Displays the hour of the message reception ( for messages received today )
private let hourFormatter = DateFormatter()
private let disposeBag = DisposeBag()
init(withConversation conversation: ConversationModel) {
self.conversation = conversation
dateFormatter.dateStyle = .medium
hourFormatter.dateFormat = "HH:mm"
self.userName = ContactHelper.lookupUserName(forRingId: self.conversation.recipient.ringId,
nameService: AppDelegate.nameService,
disposeBag: self.disposeBag).asObservable()
}
var unreadMessages: String {
return self.unreadMessagesCount.description
}
fileprivate var unreadMessagesCount: Int {
return self.conversation.messages.filter({ message in
return message.status != .read
}).count
}
var hasUnreadMessages: Bool {
return conversation.messages.count > 0
}
var lastMessage: String {
if let lastMessage = conversation.messages.last?.content {
return lastMessage
} else {
return ""
}
}
var lastMessageReceivedDate: String {
guard let lastMessageDate = self.conversation.messages.last?.receivedDate else {
return ""
}
let dateToday = Date()
//Get components from today date
let todayWeekOfYear = Calendar.current.component(.weekOfYear, from: dateToday)
let todayDay = Calendar.current.component(.day, from: dateToday)
let todayMonth = Calendar.current.component(.month, from: dateToday)
let todayYear = Calendar.current.component(.year, from: dateToday)
//Get components from last message date
let weekOfYear = Calendar.current.component(.weekOfYear, from: lastMessageDate)
let day = Calendar.current.component(.day, from: lastMessageDate)
let month = Calendar.current.component(.month, from: lastMessageDate)
let year = Calendar.current.component(.year, from: lastMessageDate)
if todayDay == day && todayMonth == month && todayYear == year {
return hourFormatter.string(from: lastMessageDate)
} else if day == todayDay - 1 {
return NSLocalizedString("Yesterday", tableName: "Smartlist", comment: "")
} else if todayYear == year && todayWeekOfYear == weekOfYear {
return lastMessageDate.dayOfWeek()
} else {
return dateFormatter.string(from: lastMessageDate)
}
}
}
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import UIKit
import RxSwift
class ConversationsService: MessagesAdapterDelegate {
fileprivate let messageAdapter :MessagesAdapter
fileprivate let disposeBag = DisposeBag()
fileprivate let textPlainMIMEType = "text/plain"
let conversations = Variable([ConversationModel]())
init(withMessageAdapter messageAdapter: MessagesAdapter) {
self.messageAdapter = messageAdapter
MessagesAdapter.delegate = self
}
func status(forMessageId messageId: UInt64) -> MessageStatus {
return self.messageAdapter.status(forMessageId: messageId)
}
//MARK: Message Adapter delegate
func didReceiveMessage(_ message: Dictionary<String, String>, from senderAccount: String,
to receiverAccountId: String) {
if let content = message[textPlainMIMEType] {
let message = MessageModel(withId: nil, receivedDate: Date(), content: content, author: senderAccount)
//Get conversations for this sender
var currentConversation = conversations.value.filter({ conversation in
return conversation.recipient.ringId == senderAccount
}).first
//Get the current array of conversations
var currentConversations = self.conversations.value
//Create a new conversation for this sender if not exists
if currentConversation == nil {
currentConversation = ConversationModel(withRecipient: ContactModel(withRingId: senderAccount), accountId: receiverAccountId)
currentConversations.append(currentConversation!)
}
//Add the received message into the conversation
currentConversation?.messages.append(message)
//Upate the value of the Variable
self.conversations.value = currentConversations
}
}
func messageStatusChanged(_ status: MessageStatus, for messageId: UInt64,
from senderAccountId: String, to receiverAccount: String) {
print("messageStatusChanged: \(status.rawValue) for: \(messageId) from: \(senderAccountId) to: \(receiverAccount)")
}
}
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
extension Date {
func dayNumberOfWeek() -> Int? {
return Calendar.current.dateComponents([.weekday], from: self).weekday
}
func dayOfWeek() -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE"
return dateFormatter.string(from: self)
}
}
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
"HomeTabBarTitle" = "Home";
......@@ -23,6 +23,12 @@ import UIKit
class MainTabBarViewController: UITabBarController {
fileprivate let accountService = AppDelegate.accountService
override func viewDidLoad() {
super.viewDidLoad()
UITabBarItem.appearance()
.setTitleTextAttributes( [NSForegroundColorAttributeName : Colors.ringMainColor], for: .selected)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !accountService.hasAccounts() {
......
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
class MessageModel {
var id: UInt64?
var receivedDate: Date
var content: String
var author: String
var status: MessageStatus
init(withId id: UInt64?, receivedDate: Date, content: String, author: String) {
self.id = id
self.receivedDate = receivedDate
self.content = content
self.author = author
self.status = .unknown
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment