Commit 81dac45a authored by Kateryna Kostiuk's avatar Kateryna Kostiuk

account: save profile

Save account profile in database instead of file.

Change-Id: Ief021b2e7206d03388fb353a562e466ea90675c0
parent 198f7b23
......@@ -97,6 +97,38 @@ final class ProfileDataHelper {
}
}
func updateURI(newURI: String, for profileId: Int64) throws {
guard let dataBase = RingDB.instance.ringDB else {
throw DataAccessError.datastoreConnectionError
}
let selectQuery = table.filter(id == profileId)
try dataBase.run(selectQuery.update(uri <- newURI))
}
func updateImageAndName(newName: String, newImage: String, for profileId: Int64) throws {
guard let dataBase = RingDB.instance.ringDB else {
throw DataAccessError.datastoreConnectionError
}
let selectQuery = table.filter(id == profileId)
try dataBase.run(selectQuery.update(alias <- newName, photo <- newImage))
}
func updateName(newName: String, for profileId: Int64) throws {
guard let dataBase = RingDB.instance.ringDB else {
throw DataAccessError.datastoreConnectionError
}
let selectQuery = table.filter(id == profileId)
try dataBase.run(selectQuery.update(alias <- newName))
}
func updateImage(newImage: String, for profileId: Int64) throws {
guard let dataBase = RingDB.instance.ringDB else {
throw DataAccessError.datastoreConnectionError
}
let selectQuery = table.filter(id == profileId)
try dataBase.run(selectQuery.update(photo <- newImage))
}
func selectProfile(profileId: Int64) throws -> Profile? {
guard let dataBase = RingDB.instance.ringDB else {
throw DataAccessError.datastoreConnectionError
......
......@@ -125,6 +125,8 @@ class DBManager {
// used to create object to save to db. When inserting in table defaultID will be replaced by autoincrementedID
let defaultID: Int64 = 1
let disposeBag = DisposeBag()
init(profileHepler: ProfileDataHelper, conversationHelper: ConversationDataHelper,
interactionHepler: InteractionDataHelper, accountProfileHelper: AccountProfileHelper) {
self.profileHepler = profileHepler
......@@ -179,8 +181,41 @@ class DBManager {
guard let jamiId = AccountModelHelper(withAccount: account).ringId else {
return false
}
guard let profile = try self.getRingProfile(for: jamiId) else {return false}
var accountProfile: Profile?
if let profile = try self.getRingProfile(for: jamiId) {
accountProfile = profile
} else if let profile = try self.getRingProfile(for: account.id) {
accountProfile = profile
// if profile was saved with account id update row
try profileHepler.updateURI(newURI: jamiId, for: profile.id)
}
guard let profile = accountProfile else {return false}
_ = accountProfileHelper.insert(item: ProfileAccount(profile.id, account.id, true))
//update profile image and alias
VCardUtils.loadVCard(named: VCardFiles.myProfile.rawValue,
inFolder: VCardFolders.profile.rawValue)
.subscribe(onSuccess: { [unowned self] card in
let name = card.familyName
do {
if let data = card.imageData {
let dataString = data.base64EncodedString()
if !name.isEmpty {
try self.profileHepler
.updateImageAndName(newName: name,
newImage: dataString,
for: profile.id)
} else {
try self.profileHepler
.updateImage(newImage: dataString,
for: profile.id)
}
} else if !name.isEmpty {
try self.profileHepler
.updateName(newName: name,
for: profile.id)
}
} catch {}
}).disposed(by: self.disposeBag)
let contacts = delegate.injectionBag.contactsService.contacts.value
for contact in contacts {
if let profile = try self.getRingProfile(for: contact.ringId) {
......@@ -595,7 +630,10 @@ class DBManager {
if let profile = try self.profileHepler.selectProfile(accountURI: profileUri) {
return profile
}
let profile = self.createTemplateRingProfile(account: profileUri)
var profile = self.createTemplateRingProfile(account: profileUri)
if isAccount {
profile.status = ProfileStatus.trusted.rawValue
}
if self.profileHepler.insert(item: profile) {
if let profile = try self.profileHepler.selectProfile(accountURI: profileUri) {
accountProfileHelper.insert(item: ProfileAccount(profile.id, accountId, isAccount))
......
......@@ -41,7 +41,7 @@ class EditProfileViewController: UIViewController, UITextFieldDelegate, UIImageP
override func viewDidLoad() {
super.viewDidLoad()
self.model = EditProfileViewModel()
//self.model = EditProfileViewModel()
}
override func viewWillAppear(_ animated: Bool) {
......@@ -54,11 +54,11 @@ class EditProfileViewController: UIViewController, UITextFieldDelegate, UIImageP
profileName.returnKeyType = .done
profileName.autocorrectionType = .no
self.model.image.asObservable()
self.model.profileImage
.bind(to: self.profileImageView.rx.image)
.disposed(by: disposeBag)
self.model.profileName.asObservable()
self.model.profileName
.bind(to: self.profileName.rx.text)
.disposed(by: disposeBag)
......@@ -73,7 +73,7 @@ class EditProfileViewController: UIViewController, UITextFieldDelegate, UIImageP
}
func resetProfileName() {
self.profileName.text = self.model.profileName.value
self.profileName.text = self.model.name
}
@objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer) {
......
......@@ -26,39 +26,73 @@ class EditProfileViewModel {
let disposeBag = DisposeBag()
let defaultImage = UIImage(named: "add_avatar")
var image = Variable<UIImage?>(nil)
var profileName = Variable<String>("")
var image: UIImage?
var name: String = ""
let profileService: ProfilesService
let accountService: AccountsService
init() {
lazy var profileImage: Observable<UIImage?> = { [unowned self] in
guard let account = self.accountService.currentAccount,
let jamiId = AccountModelHelper
.init(withAccount: account)
.ringId else {
return Observable.just(defaultImage)
}
return self.profileService.getProfile(ringId: jamiId)
.map({ profile in
if let photo = profile.photo,
let data = NSData(base64Encoded: photo,
options: NSData.Base64DecodingOptions.ignoreUnknownCharacters) as Data? {
self.image = UIImage(data: data)
return UIImage(data: data)
}
return self.defaultImage
})
}()
self.image.value = defaultImage
lazy var profileName: Observable<String?> = { [unowned self] in
guard let account = self.accountService.currentAccount,
let jamiId = AccountModelHelper
.init(withAccount: account)
.ringId else {
return Observable.just("")
}
return self.profileService.getProfile(ringId: jamiId)
.map({ profile in
if let alias = profile.alias, !alias.isEmpty {
self.name = alias
return alias
}
return ""
})
}()
VCardUtils.loadVCard(named: VCardFiles.myProfile.rawValue, inFolder: VCardFolders.profile.rawValue) .subscribe(onSuccess: { [unowned self]card in
self.profileName.value = card.familyName
if let data = card.imageData {
self.image.value = UIImage(data: data)?.convert(toSize: CGSize(width: 100.0, height: 100.0), scale: UIScreen.main.scale).circleMasked
}
}).disposed(by: disposeBag)
init(profileService: ProfilesService, accountService: AccountsService) {
self.profileService = profileService
self.accountService = accountService
}
func saveProfile() {
guard let account = self.accountService.currentAccount,
let jamiId = AccountModelHelper.init(withAccount: account).ringId else {return}
let vcard = CNMutableContact()
if let image = self.image.value, !image.isEqual(defaultImage) {
if let image = self.image, !image.isEqual(defaultImage) {
vcard.imageData = UIImagePNGRepresentation(image)
}
vcard.familyName = self.profileName.value
_ = VCardUtils.saveVCard(vCard: vcard, withName: VCardFiles.myProfile.rawValue, inFolder: VCardFolders.profile.rawValue).subscribe()
vcard.familyName = self.name
self.profileService.updateProfile(accountId: account.id,
profileUri: jamiId,
isAccount: true,
vCard: vcard)
}
func updateImage(_ image: UIImage) {
self.image.value = image
self.image = image
self.saveProfile()
}
func updateName(_ name: String) {
self.profileName.value = name
self.name = name
self.saveProfile()
}
}
......@@ -67,6 +67,8 @@ class MeCoordinator: Coordinator, StateableResponsive {
func start () {
let meViewController = MeViewController.instantiate(with: self.injectionBag)
meViewController.model = EditProfileViewModel(profileService: self.injectionBag.profileService,
accountService: self.injectionBag.accountService)
self.present(viewController: meViewController, withStyle: .show, withAnimation: true, withStateable: meViewController.viewModel)
}
......
......@@ -82,6 +82,8 @@ class WalkthroughCoordinator: Coordinator, StateableResponsive {
private func showCreateProfile () {
let createProfileViewController = CreateProfileViewController.instantiate(with: self.injectionBag)
createProfileViewController.model = EditProfileViewModel(profileService: self.injectionBag.profileService,
accountService: self.injectionBag.accountService)
self.present(viewController: createProfileViewController, withStyle: .show, withAnimation: true, withStateable: createProfileViewController.viewModel)
}
......
......@@ -146,27 +146,36 @@ class ProfilesService {
vCardData.append(currentData)
}
}
//Create the vCard, save and db and emit a new event
if let vCard = CNContactVCardSerialization.parseToVCard(data: vCardData) {
let name = VCardUtils.getName(from: vCard)
var stringImage: String?
if let image = vCard.imageData {
stringImage = image.base64EncodedString()
}
let uri = ringID.replacingOccurrences(of: "@ring.dht", with: "")
_ = self.dbManager
.createOrUpdateRingProfile(profileUri: uri,
alias: name,
image: stringImage,
status: ProfileStatus.untrasted,
accountId: accountId,
isAccount: false)
self.updateProfileFor(ringId: uri)
self.updateProfile(accountId: accountId,
profileUri: uri,
isAccount: false,
vCard: vCard)
}
}
func updateProfile(accountId: String,
profileUri: String,
isAccount: Bool,
vCard: CNContact) {
let name = VCardUtils.getName(from: vCard)
var stringImage: String?
if let image = vCard.imageData {
stringImage = image.base64EncodedString()
}
_ = self.dbManager
.createOrUpdateRingProfile(profileUri: profileUri,
alias: name,
image: stringImage,
status: ProfileStatus.untrasted,
accountId: accountId,
isAccount: isAccount)
self.updateProfileFor(ringId: profileUri)
}
private func addOrUpdatePrifileFor(ringId: String, accountId: String, isAccount: Bool) {
private func addAndGetPrifileFor(ringId: String, accountId: String, isAccount: Bool) {
guard let profileObservable = self.profiles[ringId] else {
return
}
......@@ -197,7 +206,7 @@ class ProfilesService {
let profileObservable = ReplaySubject<Profile>.create(bufferSize: 1)
self.profiles[ringId] = profileObservable
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.addOrUpdatePrifileFor(ringId: ringId, accountId: accountId, isAccount: isAccount)
self.addAndGetPrifileFor(ringId: ringId, accountId: accountId, isAccount: isAccount)
}
return profileObservable.share()
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment