diff --git a/Ring/Ring.xcodeproj/project.pbxproj b/Ring/Ring.xcodeproj/project.pbxproj index 5fd4a265ad3c217cea541df42ea13a95e0b23e8f..0e0389be657c42853c664fb6d9ebfc4e9e4a0c56 100644 --- a/Ring/Ring.xcodeproj/project.pbxproj +++ b/Ring/Ring.xcodeproj/project.pbxproj @@ -83,6 +83,7 @@ 04399B131D1C341A00E99CD9 /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 04399AE11D1C341A00E99CD9 /* libvpx.a */; }; 04399B141D1C341A00E99CD9 /* libx264.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 04399AE21D1C341A00E99CD9 /* libx264.a */; }; 04399B151D1C341A00E99CD9 /* libyaml-cpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 04399AE31D1C341A00E99CD9 /* libyaml-cpp.a */; }; + 0586C94B1F684DF600613517 /* UIImage+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0586C94A1F684DF600613517 /* UIImage+Helpers.swift */; }; 1A0C4EDA1F1D4B1B00550433 /* WelcomeViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1A0C4ED91F1D4B1B00550433 /* WelcomeViewController.storyboard */; }; 1A0C4EDC1F1D4B7E00550433 /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0C4EDB1F1D4B7E00550433 /* WelcomeViewController.swift */; }; 1A0C4EE31F1D673600550433 /* InjectionBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0C4EE21F1D673600550433 /* InjectionBag.swift */; }; @@ -136,7 +137,6 @@ 1A2D18FD1F292DAD00B2C785 /* ConversationCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1A2D18FB1F292DAD00B2C785 /* ConversationCell.xib */; }; 1A2D18FF1F29352D00B2C785 /* MeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2D18FE1F29352D00B2C785 /* MeViewModel.swift */; }; 1A2D19011F29353A00B2C785 /* MeDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2D19001F29353A00B2C785 /* MeDetailViewModel.swift */; }; - 1A2D19041F2937DF00B2C785 /* AccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2D19031F2937DF00B2C785 /* AccountTableViewCell.swift */; }; 1A3CA32B1F102BB700283748 /* Chameleon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A3CA32A1F102BB700283748 /* Chameleon.framework */; }; 1A3CA32D1F13DA7200283748 /* Chameleon+Ring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A3CA32C1F13DA7200283748 /* Chameleon+Ring.swift */; }; 1A3D28A71F0EB9DB00B524EE /* Bool+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A3D28A61F0EB9DB00B524EE /* Bool+String.swift */; }; @@ -295,6 +295,7 @@ 04399AE11D1C341A00E99CD9 /* libvpx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvpx.a; path = ../fat/lib/libvpx.a; sourceTree = "<group>"; }; 04399AE21D1C341A00E99CD9 /* libx264.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libx264.a; path = ../fat/lib/libx264.a; sourceTree = "<group>"; }; 04399AE31D1C341A00E99CD9 /* libyaml-cpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libyaml-cpp.a"; path = "../fat/lib/libyaml-cpp.a"; sourceTree = "<group>"; }; + 0586C94A1F684DF600613517 /* UIImage+Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Helpers.swift"; sourceTree = "<group>"; }; 1A0C4ED91F1D4B1B00550433 /* WelcomeViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = WelcomeViewController.storyboard; path = Welcome/WelcomeViewController.storyboard; sourceTree = "<group>"; }; 1A0C4EDB1F1D4B7E00550433 /* WelcomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WelcomeViewController.swift; path = Welcome/WelcomeViewController.swift; sourceTree = "<group>"; }; 1A0C4EE21F1D673600550433 /* InjectionBag.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InjectionBag.swift; sourceTree = "<group>"; }; @@ -348,7 +349,6 @@ 1A2D18FB1F292DAD00B2C785 /* ConversationCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ConversationCell.xib; sourceTree = "<group>"; }; 1A2D18FE1F29352D00B2C785 /* MeViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeViewModel.swift; sourceTree = "<group>"; }; 1A2D19001F29353A00B2C785 /* MeDetailViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeDetailViewModel.swift; sourceTree = "<group>"; }; - 1A2D19031F2937DF00B2C785 /* AccountTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountTableViewCell.swift; sourceTree = "<group>"; }; 1A3CA32A1F102BB700283748 /* Chameleon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Chameleon.framework; path = Carthage/Build/iOS/Chameleon.framework; sourceTree = "<group>"; }; 1A3CA32C1F13DA7200283748 /* Chameleon+Ring.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Chameleon+Ring.swift"; sourceTree = "<group>"; }; 1A3D28A61F0EB9DB00B524EE /* Bool+String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Bool+String.swift"; sourceTree = "<group>"; }; @@ -610,6 +610,7 @@ 1A2D18991F2642C000B2C785 /* NotificationCenter+Ring.swift */, 1A2D189B1F264AD900B2C785 /* UIViewController+Ring.swift */, 1A2D18A51F27F7A400B2C785 /* UIViewController+Rx.swift */, + 0586C94A1F684DF600613517 /* UIImage+Helpers.swift */, ); path = Extensions; sourceTree = "<group>"; @@ -914,7 +915,6 @@ 1A2D18D91F2918F300B2C785 /* Me */ = { isa = PBXGroup; children = ( - 1A2D19021F2937BB00B2C785 /* Cells */, 1A2D18EC1F2919D800B2C785 /* MeViewController.storyboard */, 1A5DC02B1F3565250075E8EF /* MeViewController.swift */, 1A2D18FE1F29352D00B2C785 /* MeViewModel.swift */, @@ -943,14 +943,6 @@ path = ../SmartList/Cells; sourceTree = "<group>"; }; - 1A2D19021F2937BB00B2C785 /* Cells */ = { - isa = PBXGroup; - children = ( - 1A2D19031F2937DF00B2C785 /* AccountTableViewCell.swift */, - ); - path = Cells; - sourceTree = "<group>"; - }; 1A5DC0331F3567080075E8EF /* ContactRequests */ = { isa = PBXGroup; children = ( @@ -1248,6 +1240,7 @@ buildActionMask = 2147483647; files = ( 557086521E8ADB9D001A7CE4 /* SystemAdapter.mm in Sources */, + 0586C94B1F684DF600613517 /* UIImage+Helpers.swift in Sources */, 1A2D18AC1F29149D00B2C785 /* MeCoordinator.swift in Sources */, 1A2D18C51F29180700B2C785 /* ContactModel.swift in Sources */, 1A2D18F71F292D7200B2C785 /* MessageCellSent.swift in Sources */, @@ -1291,7 +1284,6 @@ 1A2041821F1E906B00C08435 /* CreateProfileViewModel.swift in Sources */, 1A0C4EE31F1D673600550433 /* InjectionBag.swift in Sources */, 564C44641E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift in Sources */, - 1A2D19041F2937DF00B2C785 /* AccountTableViewCell.swift in Sources */, 1A2D18AA1F29131900B2C785 /* ConversationsCoordinator.swift in Sources */, 043999F71D1C2D9D00E99CD9 /* AppDelegate.swift in Sources */, 1A2041861F1EA19600C08435 /* CreateAccountViewController.swift in Sources */, diff --git a/Ring/Ring/Extensions/UIImage+Helpers.swift b/Ring/Ring/Extensions/UIImage+Helpers.swift new file mode 100644 index 0000000000000000000000000000000000000000..3c5d367dffa8102be54eb485878baca5c3370b8c --- /dev/null +++ b/Ring/Ring/Extensions/UIImage+Helpers.swift @@ -0,0 +1,48 @@ +// +// UIImage+Helpers.swift +// Ring +// +// Created by Hadrien De Sousa on 17-07-19. +// Copyright © 2017 Savoir-faire Linux. All rights reserved. +// + +import Foundation +import UIKit + +extension UIImage { + var circleMasked: UIImage? { + let newSize = self.size + + let minEdge = min(newSize.height, newSize.width) + let size = CGSize(width: minEdge, height: minEdge) + + UIGraphicsBeginImageContextWithOptions(size, false, 0.0) + let context = UIGraphicsGetCurrentContext() + + self.draw(in: CGRect(origin: CGPoint.zero, size: size), blendMode: .copy, alpha: 1.0) + + context!.setBlendMode(.copy) + context!.setFillColor(UIColor.clear.cgColor) + + let rectPath = UIBezierPath(rect: CGRect(origin: CGPoint.zero, size: size)) + let circlePath = UIBezierPath(ovalIn: CGRect(origin: CGPoint.zero, size: size)) + rectPath.append(circlePath) + rectPath.usesEvenOddFillRule = true + rectPath.fill() + + let result = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + return result + } + // convenience function in UIImage extension to resize a given image + func convert(toSize size: CGSize, scale: CGFloat) -> UIImage { + let imgRect = CGRect(origin: CGPoint(x:0.0, y:0.0), size: size) + UIGraphicsBeginImageContextWithOptions(size, false, scale) + self.draw(in: imgRect) + let copied = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + return copied! + } +} diff --git a/Ring/Ring/Features/Me/Me/Cells/AccountTableViewCell.swift b/Ring/Ring/Features/Me/Me/Cells/AccountTableViewCell.swift deleted file mode 100644 index 866d74bf227cc910c0eb2043c5fbdceb4acf6c39..0000000000000000000000000000000000000000 --- a/Ring/Ring/Features/Me/Me/Cells/AccountTableViewCell.swift +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2016 Savoir-faire Linux Inc. - * - * Author: Edric Ladent-Milaret <edric.ladent-milaret@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 Reusable - -class AccountTableViewCell: UITableViewCell, NibReusable { - - // MARK: - Properties - @IBOutlet weak var activeSwitch: UISwitch! - @IBOutlet weak var accountNameLabel: UILabel! - @IBOutlet weak var accountTypeLabel: UILabel! - - var account: AccountModel! - - // MARK: - Actions - @IBAction func switchAccountState(_ sender: UISwitch) { -// account.isEnabled = sender.isOn - } -} diff --git a/Ring/Ring/Features/Me/Me/MeViewController.storyboard b/Ring/Ring/Features/Me/Me/MeViewController.storyboard index 80a1ae9582f8ab30291189042d6608f5777e8ab2..cc22d1cc7437135b1a3151d450d8786d6d9d91d3 100644 --- a/Ring/Ring/Features/Me/Me/MeViewController.storyboard +++ b/Ring/Ring/Features/Me/Me/MeViewController.storyboard @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="RuW-kz-iBP"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="RuW-kz-iBP"> <device id="retina4_7" orientation="portrait"> <adaptation id="fullscreen"/> </device> @@ -22,119 +22,61 @@ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> - <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="pZo-fN-8Fj"> - <rect key="frame" x="132.5" y="297" width="110" height="110"/> - <constraints> - <constraint firstAttribute="width" constant="110" id="Nps-H6-gl2"/> - <constraint firstAttribute="height" constant="110" id="yhs-CD-gXk"/> - </constraints> - </imageView> - <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="XF9-LL-io7"> - <rect key="frame" x="0.0" y="449" width="375" height="218"/> - <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> - <constraints> - <constraint firstAttribute="height" constant="218" id="VQN-HR-xT0"/> - </constraints> - <prototypes> - <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="AccountTableViewCell" id="HQc-Zx-7l9" customClass="AccountTableViewCell" customModule="Ring" customModuleProvider="target"> - <rect key="frame" x="0.0" y="28" width="375" height="44"/> - <autoresizingMask key="autoresizingMask"/> - <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="HQc-Zx-7l9" id="KOa-Yg-Sgf"> - <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/> - <autoresizingMask key="autoresizingMask"/> - <subviews> - <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ljw-sY-kbY"> - <rect key="frame" x="8" y="6" width="51" height="31"/> - <connections> - <action selector="switchAccountState:" destination="HQc-Zx-7l9" eventType="valueChanged" id="UD8-Qj-NgC"/> - </connections> - </switch> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="TYPE" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Zmt-fY-s9P"> - <rect key="frame" x="230" y="11" width="42" height="21"/> - <constraints> - <constraint firstAttribute="width" constant="42" id="kXz-v3-xRs"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="17"/> - <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> - <nil key="highlightedColor"/> - </label> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pEo-sN-P32" userLabel="Account Name Label"> - <rect key="frame" x="71" y="11" width="100" height="21"/> - <fontDescription key="fontDescription" type="system" pointSize="17"/> - <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> - <nil key="highlightedColor"/> - </label> - </subviews> - <constraints> - <constraint firstItem="Zmt-fY-s9P" firstAttribute="baseline" secondItem="pEo-sN-P32" secondAttribute="baseline" id="72G-HL-GXC"/> - <constraint firstItem="Zmt-fY-s9P" firstAttribute="leading" secondItem="pEo-sN-P32" secondAttribute="trailing" constant="59" id="Agl-eH-BKo"/> - <constraint firstItem="ljw-sY-kbY" firstAttribute="centerY" secondItem="KOa-Yg-Sgf" secondAttribute="centerY" id="Oda-Wx-tbm"/> - <constraint firstItem="ljw-sY-kbY" firstAttribute="leading" secondItem="KOa-Yg-Sgf" secondAttribute="leadingMargin" id="PUS-h8-tWK"/> - <constraint firstItem="pEo-sN-P32" firstAttribute="leading" secondItem="ljw-sY-kbY" secondAttribute="trailing" constant="14" id="gq5-lU-NOx"/> - <constraint firstAttribute="trailingMargin" secondItem="Zmt-fY-s9P" secondAttribute="trailing" constant="40" id="rVw-f7-Vax"/> - <constraint firstItem="ljw-sY-kbY" firstAttribute="centerY" secondItem="pEo-sN-P32" secondAttribute="centerY" id="xpx-TF-OmA"/> - </constraints> - </tableViewCellContentView> - <connections> - <outlet property="accountNameLabel" destination="pEo-sN-P32" id="GlP-6d-tWw"/> - <outlet property="accountTypeLabel" destination="Zmt-fY-s9P" id="14Z-88-8oU"/> - <outlet property="activeSwitch" destination="ljw-sY-kbY" id="Mqy-YL-aKK"/> - </connections> - </tableViewCell> - <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="addAccountTableCell" id="5Xh-6L-7id"> - <rect key="frame" x="0.0" y="72" width="375" height="44"/> - <autoresizingMask key="autoresizingMask"/> - <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="5Xh-6L-7id" id="NQl-GU-fNn"> - <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/> - <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="abD-8d-YV0" userLabel="Account Name Label"> - <rect key="frame" x="72" y="11" width="99" height="21"/> - <fontDescription key="fontDescription" type="system" pointSize="17"/> - <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> - <nil key="highlightedColor"/> - </label> - <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="contactAdd" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WqP-Hb-0XW"> - <rect key="frame" x="23" y="11" width="22" height="22"/> - <connections> - <action selector="addAccountClicked:" destination="RuW-kz-iBP" eventType="touchUpInside" id="hsq-5y-nrW"/> - </connections> - </button> - </subviews> - <constraints> - <constraint firstItem="WqP-Hb-0XW" firstAttribute="leading" secondItem="NQl-GU-fNn" secondAttribute="leadingMargin" constant="15" id="57r-PN-Cv9"/> - <constraint firstItem="abD-8d-YV0" firstAttribute="leading" secondItem="WqP-Hb-0XW" secondAttribute="trailing" constant="27" id="Y23-Qc-qx7"/> - <constraint firstItem="abD-8d-YV0" firstAttribute="top" secondItem="WqP-Hb-0XW" secondAttribute="top" id="Z57-DQ-a7x"/> - <constraint firstItem="WqP-Hb-0XW" firstAttribute="centerY" secondItem="NQl-GU-fNn" secondAttribute="centerY" id="r6D-Ma-YOX"/> - </constraints> - </tableViewCellContentView> - </tableViewCell> - </prototypes> - <connections> - <outlet property="dataSource" destination="RuW-kz-iBP" id="GfQ-Rx-J3H"/> - <outlet property="delegate" destination="RuW-kz-iBP" id="tH0-Pm-aAd"/> - </connections> - </tableView> - <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="w8x-Sv-T50"> - <rect key="frame" x="16" y="40" width="180" height="64"/> - <constraints> - <constraint firstAttribute="height" constant="64" id="j5c-ee-ima"/> - <constraint firstAttribute="width" constant="180" id="kVb-tA-4rc"/> - </constraints> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="PERSON PLACEHOLDER" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="w8x-Sv-T50"> + <rect key="frame" x="16" y="30" width="343" height="26.5"/> <fontDescription key="fontDescription" type="system" pointSize="22"/> - <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <color key="textColor" red="0.20000000300000001" green="0.20000000300000001" blue="0.20000000300000001" alpha="1" colorSpace="calibratedRGB"/> + <nil key="highlightedColor"/> + </label> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Ring id" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="11" translatesAutoresizingMaskIntoConstraints="NO" id="rC6-Ga-QjY" userLabel="RingId Label"> + <rect key="frame" x="16" y="66.5" width="343" height="18"/> + <fontDescription key="fontDescription" type="system" pointSize="15"/> + <color key="textColor" red="0.29803922770000002" green="0.29803922770000002" blue="0.29803922770000002" alpha="1" colorSpace="calibratedRGB"/> <nil key="highlightedColor"/> </label> + <stackView opaque="NO" contentMode="center" distribution="fillEqually" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="reK-Om-ReA"> + <rect key="frame" x="16" y="232.5" width="343" height="30"/> + <subviews> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rfv-Ak-7NM"> + <rect key="frame" x="0.0" y="0.0" width="171.5" height="30"/> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> + <color key="tintColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> + <state key="normal" title="Take a picture"> + <color key="titleColor" red="0.40000000600000002" green="0.40000000600000002" blue="0.40000000600000002" alpha="1" colorSpace="calibratedRGB"/> + </state> + <connections> + <action selector="takePicture:" destination="MXJ-Bb-hGu" eventType="touchDown" id="M3f-W6-cfc"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hq2-0j-DsW"> + <rect key="frame" x="171.5" y="0.0" width="171.5" height="30"/> + <state key="normal" title="Import a picture"> + <color key="titleColor" red="0.40000000600000002" green="0.40000000600000002" blue="0.40000000600000002" alpha="1" colorSpace="calibratedRGB"/> + </state> + <connections> + <action selector="importPicture:" destination="MXJ-Bb-hGu" eventType="touchDown" id="Cgc-Uj-vJE"/> + </connections> + </button> + </subviews> + </stackView> + <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_contact_picture" translatesAutoresizingMaskIntoConstraints="NO" id="8HY-Zl-94u"> + <rect key="frame" x="16" y="104.5" width="343" height="128"/> + </imageView> </subviews> <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <constraints> - <constraint firstAttribute="trailing" secondItem="XF9-LL-io7" secondAttribute="trailing" id="718-Oh-eiW"/> - <constraint firstItem="XF9-LL-io7" firstAttribute="top" secondItem="pZo-fN-8Fj" secondAttribute="bottom" constant="42" id="78P-ZG-RJW"/> - <constraint firstItem="XF9-LL-io7" firstAttribute="leading" secondItem="nkh-py-Uar" secondAttribute="leading" id="XgK-Iq-WPC"/> - <constraint firstItem="XF9-LL-io7" firstAttribute="centerX" secondItem="pZo-fN-8Fj" secondAttribute="centerX" id="aqn-W8-WhD"/> - <constraint firstItem="tam-QD-Xpf" firstAttribute="top" secondItem="XF9-LL-io7" secondAttribute="bottom" id="fVp-mz-u7B"/> - <constraint firstItem="w8x-Sv-T50" firstAttribute="leading" secondItem="nkh-py-Uar" secondAttribute="leadingMargin" id="gCm-aq-fb9"/> - <constraint firstItem="w8x-Sv-T50" firstAttribute="top" secondItem="SYf-gf-IKh" secondAttribute="bottom" constant="20" id="wHN-au-sTr"/> + <constraint firstAttribute="trailingMargin" secondItem="8HY-Zl-94u" secondAttribute="trailing" id="8Uy-Pp-lgo"/> + <constraint firstItem="rC6-Ga-QjY" firstAttribute="leading" secondItem="nkh-py-Uar" secondAttribute="leadingMargin" id="IQi-1b-isC"/> + <constraint firstItem="rC6-Ga-QjY" firstAttribute="trailing" secondItem="nkh-py-Uar" secondAttribute="trailingMargin" id="Rkf-1X-wgP"/> + <constraint firstItem="8HY-Zl-94u" firstAttribute="top" secondItem="rC6-Ga-QjY" secondAttribute="bottom" constant="20" id="ZZS-Wh-23Z"/> + <constraint firstItem="8HY-Zl-94u" firstAttribute="leading" secondItem="nkh-py-Uar" secondAttribute="leadingMargin" id="ceB-3O-BOQ"/> + <constraint firstItem="rC6-Ga-QjY" firstAttribute="top" secondItem="w8x-Sv-T50" secondAttribute="bottom" constant="10" id="lnm-Mq-ocY"/> + <constraint firstItem="w8x-Sv-T50" firstAttribute="leading" secondItem="nkh-py-Uar" secondAttribute="leadingMargin" id="nMK-tO-WU0"/> + <constraint firstItem="w8x-Sv-T50" firstAttribute="top" secondItem="SYf-gf-IKh" secondAttribute="bottom" constant="10" id="rUH-Jk-nMV"/> + <constraint firstAttribute="trailingMargin" secondItem="reK-Om-ReA" secondAttribute="trailing" id="tUZ-Io-Jbc"/> + <constraint firstItem="w8x-Sv-T50" firstAttribute="trailing" secondItem="nkh-py-Uar" secondAttribute="trailingMargin" id="uYH-if-S88"/> + <constraint firstItem="reK-Om-ReA" firstAttribute="leading" secondItem="nkh-py-Uar" secondAttribute="leadingMargin" id="w47-Gi-x8l"/> + <constraint firstItem="reK-Om-ReA" firstAttribute="top" secondItem="8HY-Zl-94u" secondAttribute="bottom" id="zEx-uZ-4SL"/> </constraints> </view> <extendedEdge key="edgesForExtendedLayout" bottom="YES"/> @@ -143,9 +85,11 @@ <barButtonItem key="rightBarButtonItem" systemItem="edit" id="NqP-iv-qav"/> </navigationItem> <connections> - <outlet property="accountTableView" destination="XF9-LL-io7" id="y6M-sn-b5R"/> + <outlet property="importButton" destination="hq2-0j-DsW" id="TJA-fa-k8g"/> <outlet property="nameLabel" destination="w8x-Sv-T50" id="OAT-b7-q3U"/> - <outlet property="qrImageView" destination="pZo-fN-8Fj" id="tjL-5d-Kvk"/> + <outlet property="photoButton" destination="Rfv-Ak-7NM" id="Hl5-bN-0CV"/> + <outlet property="profileImageView" destination="8HY-Zl-94u" id="RQx-NQ-Ezs"/> + <outlet property="ringIdLabel" destination="rC6-Ga-QjY" id="McC-Ah-cfF"/> </connections> </viewController> <placeholder placeholderIdentifier="IBFirstResponder" id="MXJ-Bb-hGu" userLabel="First Responder" sceneMemberID="firstResponder"/> @@ -153,4 +97,7 @@ <point key="canvasLocation" x="-94" y="-438"/> </scene> </scenes> + <resources> + <image name="ic_contact_picture" width="128" height="128"/> + </resources> </document> diff --git a/Ring/Ring/Features/Me/Me/MeViewController.swift b/Ring/Ring/Features/Me/Me/MeViewController.swift index 05de47f1a51faf2c3f86b3e50838dbc0e034bdba..c82b34e830a4f2d88a5043137fd4b8f6afc123fb 100644 --- a/Ring/Ring/Features/Me/Me/MeViewController.swift +++ b/Ring/Ring/Features/Me/Me/MeViewController.swift @@ -20,16 +20,20 @@ import UIKit import Reusable +import RxSwift -class MeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, StoryboardBased, ViewModelBased { +class MeViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, StoryboardBased, ViewModelBased { // MARK: - outlets - @IBOutlet weak var accountTableView: UITableView! @IBOutlet weak var nameLabel: UILabel! - @IBOutlet weak var qrImageView: UIImageView! + @IBOutlet weak var ringIdLabel: UILabel! + @IBOutlet weak var profileImageView: UIImageView! + @IBOutlet weak var importButton: UIButton! + @IBOutlet weak var photoButton: UIButton! // MARK: - members var viewModel: MeViewModel! + fileprivate let disposeBag = DisposeBag() // MARK: - functions override func viewDidLoad() { @@ -37,76 +41,88 @@ class MeViewController: UIViewController, UITableViewDelegate, UITableViewDataSo self.title = L10n.Global.meTabBarTitle self.navigationItem.title = L10n.Global.meTabBarTitle - + self.setupUI() } - // MARK: - QRCode - func createQRFromString(_ str: String) { + func setupUI() { - let data = str.data(using: String.Encoding.isoLatin1, allowLossyConversion: false) + self.viewModel.userName.asObservable() + .bind(to: self.nameLabel.rx.text) + .disposed(by: disposeBag) - let filter = CIFilter(name: "CIQRCodeGenerator") - filter!.setValue(data, forKey: "inputMessage") + self.viewModel.ringId.asObservable() + .bind(to: self.ringIdLabel.rx.text) + .disposed(by: disposeBag) - let qrImage: CIImage = filter!.outputImage! + let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:))) + profileImageView.isUserInteractionEnabled = true + profileImageView.addGestureRecognizer(tapGestureRecognizer) - let scaleX = qrImageView.frame.size.width / qrImage.extent.size.width - let scaleY = qrImageView.frame.size.height / qrImage.extent.size.height + photoButton.rx.tap.subscribe(onNext: { + self.takePicture() + }).disposed(by: self.disposeBag) + photoButton.backgroundColor = UIColor(white: 1, alpha: 0) - let resultQrImage = qrImage.applying(CGAffineTransform(scaleX: scaleX, y: scaleY)) - qrImageView.image = UIImage(ciImage: resultQrImage) + importButton.rx.tap.subscribe(onNext: { + self.importPicture() + }).disposed(by: self.disposeBag) + importButton.backgroundColor = UIColor(white: 1, alpha: 0) } - // MARK: - TableView - func numberOfSections(in tableView: UITableView) -> Int { - return 1 - } + func imageTapped(tapGestureRecognizer: UITapGestureRecognizer) { - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return self.viewModel.accountNumber + 1 } - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - - if indexPath.row < self.viewModel.accountNumber { - let cell = tableView.dequeueReusableCell(for: indexPath, cellType: AccountTableViewCell.self) - let account = self.viewModel.account(at: indexPath.row) - - cell.account = account - - return cell - - } else { - let cell = tableView.dequeueReusableCell(withIdentifier: "addAccountTableCell", for: indexPath) - return cell + func takePicture() { + if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) { + let imagePicker = UIImagePickerController() + imagePicker.delegate = self + imagePicker.sourceType = UIImagePickerControllerSourceType.camera + imagePicker.cameraDevice = UIImagePickerControllerCameraDevice.front + imagePicker.allowsEditing = true + self.present(imagePicker, animated: true, completion: nil) } - } - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if indexPath.row == self.viewModel.accountNumber { - accountTableView.reloadData() - } + func importPicture() { + let imagePicker = UIImagePickerController() + imagePicker.delegate = self + imagePicker.allowsEditing = true + imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary + self.present(imagePicker, animated: true, completion: nil) } - func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { - if indexPath.row == self.viewModel.accountNumber { - return false - } - return true - } + // MARK: - Delegates + func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { + var image: UIImage! + + if let img = info[UIImagePickerControllerEditedImage] as? UIImage { + image = img - func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { - if editingStyle == UITableViewCellEditingStyle.delete { - self.viewModel.deleteAccount(at: indexPath.row) - accountTableView.reloadData() + } else if let img = info[UIImagePickerControllerOriginalImage] as? UIImage { + image = img } - } - // MARK: - Actions - @IBAction func addAccountClicked(_ sender: AnyObject) { - let index = IndexPath(row: self.viewModel.accountNumber, section: 0) - accountTableView.selectRow(at: index, animated: false, scrollPosition: UITableViewScrollPosition.none) - tableView(accountTableView, didSelectRowAt: index) + profileImageView.contentMode = .scaleAspectFit + profileImageView.image = image.convert(toSize:CGSize(width:100.0, height:100.0), scale: UIScreen.main.scale).circleMasked + dismiss(animated:true, completion: nil) } + + // MARK: - QRCode +// func createQRFromString(_ str: String) { +// +// let data = str.data(using: String.Encoding.isoLatin1, allowLossyConversion: false) +// +// let filter = CIFilter(name: "CIQRCodeGenerator") +// filter!.setValue(data, forKey: "inputMessage") +// +// let qrImage: CIImage = filter!.outputImage! +// +// let scaleX = qrImageView.frame.size.width / qrImage.extent.size.width +// let scaleY = qrImageView.frame.size.height / qrImage.extent.size.height +// +// let resultQrImage = qrImage.applying(CGAffineTransform(scaleX: scaleX, y: scaleY)) +// qrImageView.image = UIImage(ciImage: resultQrImage) +// } + } diff --git a/Ring/Ring/Features/Me/Me/MeViewModel.swift b/Ring/Ring/Features/Me/Me/MeViewModel.swift index fa37bcbdebcb29c6a1aa19bc23e3f8870408cd20..d61bebf5803ba955271fea52ac63e32a297ce192 100644 --- a/Ring/Ring/Features/Me/Me/MeViewModel.swift +++ b/Ring/Ring/Features/Me/Me/MeViewModel.swift @@ -25,26 +25,19 @@ class MeViewModel: Stateable, ViewModel { // MARK: - Rx Stateable private let stateSubject = PublishSubject<State>() + + let accountService: AccountsService + var userName: Single<String?> + let ringId: Single<String?> + lazy var state: Observable<State> = { return self.stateSubject.asObservable() }() - var accountNumber: Int { - return self.accountService.accounts.count - } - - let accountService: AccountsService - required init(with injectionBag: InjectionBag) { self.accountService = injectionBag.accountService - } - - func account(at row: Int) -> AccountModel { - return self.accountService.accounts[row] - } - - func deleteAccount(at row: Int) { - self.accountService.removeAccount(row) + self.userName = Single.just(self.accountService.currentAccount?.volatileDetails?.get(withConfigKeyModel: ConfigKeyModel(withKey: ConfigKey.accountRegisteredName))) + self.ringId = Single.just(self.accountService.currentAccount?.details?.get(withConfigKeyModel: ConfigKeyModel(withKey: .accountUsername))) } } diff --git a/Ring/Ring/Info.plist b/Ring/Ring/Info.plist index f46a248c3694059f63064388c35876f05ead27b4..ff0eefcf5a203264abd643a655910694fced790f 100644 --- a/Ring/Ring/Info.plist +++ b/Ring/Ring/Info.plist @@ -2,6 +2,10 @@ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> + <key>NSPhotoLibraryUsageDescription</key> + <string>Used to let the user choose a profile picture</string> + <key>NSCameraUsageDescription</key> + <string>Used to take user profile picture</string> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundleExecutable</key>