Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Grechuhin <i.grechuhin@gmail.com>2017-10-06 20:23:43 +0300
committerRoman Kuznetsov <r.kuznetsow@gmail.com>2017-10-16 17:17:33 +0300
commit18874322a2f8c59ffcf0f127e91a32cd468d7f9c (patch)
treefe970898f273efc6c933aae44765f8894f029509 /iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC
parent5c6bdc3841c1d4ce22d7f8f3da83b798c587aa0e (diff)
[ugc] stash
Diffstat (limited to 'iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC')
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewController.swift86
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewController.xib28
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewRatingCell.swift33
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewRatingCell.xib55
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewTextCell.swift18
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewTextCell.xib47
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCReviewModel.swift19
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReviewCell.swift98
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReviewCell.xib338
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCRating.swift24
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCReview.swift14
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCReviewCell.swift50
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCReviewCell.xib92
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingCell.swift101
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingCell.xib132
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingStarsCell.swift19
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingStarsCell.xib43
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCYourReview.swift12
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCYourReviewCell.swift103
-rw-r--r--iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCYourReviewCell.xib119
20 files changed, 1431 insertions, 0 deletions
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewController.swift b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewController.swift
new file mode 100644
index 0000000000..5f6c96ce51
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewController.swift
@@ -0,0 +1,86 @@
+@objc(MWMUGCAddReviewController)
+final class UGCAddReviewController: MWMTableViewController {
+ typealias Model = UGCReviewModel
+
+ enum Sections {
+ case ratings
+ case text
+ }
+
+ @objc static func instance(model: Model, onSave: @escaping (Model) -> Void) -> UGCAddReviewController {
+ let vc = UGCAddReviewController(nibName: toString(self), bundle: nil)
+ vc.model = model
+ vc.onSave = onSave
+ return vc
+ }
+
+ private var model: Model! {
+ didSet {
+ sections = []
+ if !model.ratings.isEmpty {
+ sections.append(.ratings)
+ }
+ if model.canAddTextToReview {
+ sections.append(.text)
+ }
+ }
+ }
+
+ private var onSave: ((Model) -> Void)!
+ private var sections: [Sections] = []
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ configNavBar()
+ configTableView()
+ }
+
+ private func configNavBar() {
+ title = model.title
+ navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(onDone))
+ }
+
+ private func configTableView() {
+ tableView.register(cellClass: UGCAddReviewRatingCell.self)
+ tableView.register(cellClass: UGCAddReviewTextCell.self)
+
+ tableView.estimatedRowHeight = 48
+ tableView.rowHeight = UITableViewAutomaticDimension
+ }
+
+ @objc private func onDone() {
+ onSave(model)
+ guard let nc = navigationController else { return }
+ if MWMAuthorizationViewModel.isAuthenticated() {
+ nc.popViewController(animated: true)
+ } else {
+ let authVC = AuthorizationViewController(barButtonItem: navigationItem.rightBarButtonItem!,
+ completion: { nc.popViewController(animated: true) })
+ nc.show(authVC, sender: self)
+ }
+ }
+
+ override func numberOfSections(in _: UITableView) -> Int {
+ return sections.count
+ }
+
+ override func tableView(_: UITableView, numberOfRowsInSection section: Int) -> Int {
+ switch sections[section] {
+ case .ratings: return model.ratings.count
+ case .text: return 1
+ }
+ }
+
+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ switch sections[indexPath.section] {
+ case .ratings:
+ let cell = tableView.dequeueReusableCell(withCellClass: UGCAddReviewRatingCell.self, indexPath: indexPath) as! UGCAddReviewRatingCell
+ cell.model = model.ratings[indexPath.row]
+ return cell
+ case .text:
+ let cell = tableView.dequeueReusableCell(withCellClass: UGCAddReviewTextCell.self, indexPath: indexPath) as! UGCAddReviewTextCell
+ cell.reviewText = model.text
+ return cell
+ }
+ }
+}
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewController.xib b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewController.xib
new file mode 100644
index 0000000000..67e2e12e41
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewController.xib
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" 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="12089"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <objects>
+ <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UGCAddReviewController" customModule="cm_beta" customModuleProvider="target">
+ <connections>
+ <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
+ </connections>
+ </placeholder>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+ <tableView opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" bouncesZoom="NO" style="grouped" separatorStyle="none" allowsSelection="NO" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="i5M-Pr-FkT">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
+ <connections>
+ <outlet property="dataSource" destination="-1" id="Tng-2m-Rnh"/>
+ <outlet property="delegate" destination="-1" id="9aC-8N-iBw"/>
+ </connections>
+ </tableView>
+ </objects>
+</document>
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewRatingCell.swift b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewRatingCell.swift
new file mode 100644
index 0000000000..4b07eca444
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewRatingCell.swift
@@ -0,0 +1,33 @@
+final class UGCAddReviewRatingCell: MWMTableViewCell {
+ @IBOutlet weak var titleLabel: UILabel! {
+ didSet {
+ titleLabel.font = UIFont.regular16()
+ titleLabel.textColor = UIColor.blackPrimaryText()
+ }
+ }
+
+ @IBOutlet weak var ratingView: RatingView! {
+ didSet {
+ ratingView.filledColor = UIColor.ratingYellow()
+ ratingView.emptyColor = UIColor.blackDividers()
+ ratingView.borderWidth = 0
+ ratingView.delegate = self
+ }
+ }
+
+ var model: UGCRatingStars! {
+ didSet {
+ titleLabel.text = model.title
+ ratingView.value = model.value
+ ratingView.starsCount = 5
+ }
+ }
+}
+
+extension UGCAddReviewRatingCell: RatingViewDelegate {
+ func didTouchRatingView(_ view: RatingView) {
+ model.value = view.value
+ }
+
+ func didFinishTouchingRatingView(_: RatingView) {}
+}
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewRatingCell.xib b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewRatingCell.xib
new file mode 100644
index 0000000000..941c206d15
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewRatingCell.xib
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" 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="12089"/>
+ <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" id="KGk-i7-Jjw" customClass="UGCAddReviewRatingCell" customModule="cm_beta" customModuleProvider="target">
+ <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
+ <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="320" height="43.5"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZYO-sw-mr0">
+ <rect key="frame" x="8" y="14" width="42" height="15.5"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <nil key="textColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FRG-q1-pKr" customClass="RatingView" customModule="cm_beta" customModuleProvider="target">
+ <rect key="frame" x="172" y="10" width="132" height="24"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="height" constant="24" placeholder="YES" id="7mb-r1-zTa"/>
+ <constraint firstAttribute="width" constant="132" placeholder="YES" id="UYe-7Z-Dby"/>
+ </constraints>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="number" keyPath="minTouchRating">
+ <real key="value" value="0.0"/>
+ </userDefinedRuntimeAttribute>
+ </userDefinedRuntimeAttributes>
+ </view>
+ </subviews>
+ <constraints>
+ <constraint firstAttribute="bottom" secondItem="ZYO-sw-mr0" secondAttribute="bottom" constant="14" id="JGH-iW-T5A"/>
+ <constraint firstAttribute="trailing" secondItem="FRG-q1-pKr" secondAttribute="trailing" constant="16" id="RsB-As-Tpo"/>
+ <constraint firstItem="ZYO-sw-mr0" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="8" id="UzX-2P-uVU"/>
+ <constraint firstItem="FRG-q1-pKr" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="Yo0-tP-fqk"/>
+ <constraint firstItem="ZYO-sw-mr0" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="14" id="mps-PB-xMQ"/>
+ </constraints>
+ </tableViewCellContentView>
+ <connections>
+ <outlet property="ratingView" destination="FRG-q1-pKr" id="JeO-LW-1So"/>
+ <outlet property="titleLabel" destination="ZYO-sw-mr0" id="HPm-he-K6V"/>
+ </connections>
+ </tableViewCell>
+ </objects>
+</document>
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewTextCell.swift b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewTextCell.swift
new file mode 100644
index 0000000000..49994841e0
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewTextCell.swift
@@ -0,0 +1,18 @@
+final class UGCAddReviewTextCell: MWMTableViewCell {
+ @IBOutlet private weak var textView: MWMTextView! {
+ didSet {
+ textView.placeholder = L("review_placeholder")
+ textView.font = UIFont.regular16()
+ textView.textColor = UIColor.blackPrimaryText()
+ textView.placeholderView.textColor = UIColor.blackSecondaryText()
+ }
+ }
+
+ var reviewText: String! {
+ get { return textView.text }
+ set { textView.text = newValue }
+ }
+}
+
+extension UGCAddReviewTextCell: UITextViewDelegate {
+}
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewTextCell.xib b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewTextCell.xib
new file mode 100644
index 0000000000..485ce5df2a
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewTextCell.xib
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" 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="12089"/>
+ <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" id="KGk-i7-Jjw" customClass="UGCAddReviewTextCell" customModule="cm_beta" customModuleProvider="target">
+ <rect key="frame" x="0.0" y="0.0" width="320" height="224"/>
+ <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="320" height="224"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="jOG-IN-cox" customClass="MWMTextView">
+ <rect key="frame" x="16" y="12" width="288" height="200"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="height" constant="200" id="HNl-UQ-bTU"/>
+ </constraints>
+ <string key="text">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.</string>
+ <fontDescription key="fontDescription" type="system" pointSize="14"/>
+ <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
+ <connections>
+ <outlet property="delegate" destination="KGk-i7-Jjw" id="LaU-0e-7bb"/>
+ </connections>
+ </textView>
+ </subviews>
+ <constraints>
+ <constraint firstAttribute="bottom" secondItem="jOG-IN-cox" secondAttribute="bottom" constant="12" id="Cz0-CW-4Uw"/>
+ <constraint firstItem="jOG-IN-cox" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="12" id="D07-74-g8h"/>
+ <constraint firstItem="jOG-IN-cox" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="jeY-W5-z6V"/>
+ <constraint firstAttribute="trailing" secondItem="jOG-IN-cox" secondAttribute="trailing" constant="16" id="vS5-1E-gwo"/>
+ </constraints>
+ </tableViewCellContentView>
+ <connections>
+ <outlet property="textView" destination="jOG-IN-cox" id="0ES-Xl-PPh"/>
+ </connections>
+ </tableViewCell>
+ </objects>
+</document>
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCReviewModel.swift b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCReviewModel.swift
new file mode 100644
index 0000000000..abc5aa0195
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCReviewModel.swift
@@ -0,0 +1,19 @@
+@objc(MWMUGCReviewModel)
+final class UGCReviewModel: NSObject {
+ let reviewValue: MWMRatingSummaryViewValueType
+
+ let ratings: [UGCRatingStars]
+
+ let canAddTextToReview: Bool
+
+ let title: String
+ let text: String
+
+ @objc init(reviewValue: MWMRatingSummaryViewValueType, ratings: [UGCRatingStars], canAddTextToReview: Bool, title: String, text: String) {
+ self.reviewValue = reviewValue
+ self.ratings = ratings
+ self.canAddTextToReview = canAddTextToReview
+ self.title = title
+ self.text = text
+ }
+}
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReviewCell.swift b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReviewCell.swift
new file mode 100644
index 0000000000..0d1634c2a1
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReviewCell.swift
@@ -0,0 +1,98 @@
+@objc(MWMUGCAddReviewCell)
+final class UGCAddReviewCell: MWMTableViewCell {
+ @IBOutlet private weak var titleLabel: UILabel! {
+ didSet {
+ titleLabel.text = L("placepage_rate_comment")
+ titleLabel.textColor = UIColor.blackPrimaryText()
+ titleLabel.font = UIFont.medium14()
+ }
+ }
+
+ @IBOutlet private weak var horribleButton: UIButton! {
+ didSet {
+ horribleButton.setImage(#imageLiteral(resourceName: "ic_24px_rating_horrible"), for: .normal)
+ horribleButton.tintColor = UIColor.ratingRed()
+ }
+ }
+
+ @IBOutlet private weak var badButton: UIButton! {
+ didSet {
+ badButton.setImage(#imageLiteral(resourceName: "ic_24px_rating_bad"), for: .normal)
+ badButton.tintColor = UIColor.ratingOrange()
+ }
+ }
+
+ @IBOutlet private weak var normalButton: UIButton! {
+ didSet {
+ normalButton.setImage(#imageLiteral(resourceName: "ic_24px_rating_normal"), for: .normal)
+ normalButton.tintColor = UIColor.ratingYellow()
+ }
+ }
+
+ @IBOutlet private weak var goodButton: UIButton! {
+ didSet {
+ goodButton.setImage(#imageLiteral(resourceName: "ic_24px_rating_good"), for: .normal)
+ goodButton.tintColor = UIColor.ratingLightGreen()
+ }
+ }
+
+ @IBOutlet private weak var excellentButton: UIButton! {
+ didSet {
+ excellentButton.setImage(#imageLiteral(resourceName: "ic_24px_rating_excellent"), for: .normal)
+ excellentButton.tintColor = UIColor.ratingGreen()
+ }
+ }
+
+ @IBOutlet private weak var horribleLabel: UILabel! {
+ didSet {
+ horribleLabel.text = L("placepage_rate_horrible")
+ horribleLabel.textColor = UIColor.blackSecondaryText()
+ horribleLabel.font = UIFont.medium10()
+ }
+ }
+
+ @IBOutlet private weak var badLabel: UILabel! {
+ didSet {
+ badLabel.text = L("placepage_rate_bad")
+ badLabel.textColor = UIColor.blackSecondaryText()
+ badLabel.font = UIFont.medium10()
+ }
+ }
+
+ @IBOutlet private weak var normalLabel: UILabel! {
+ didSet {
+ normalLabel.text = L("placepage_rate_normal")
+ normalLabel.textColor = UIColor.blackSecondaryText()
+ normalLabel.font = UIFont.medium10()
+ }
+ }
+
+ @IBOutlet private weak var goodLabel: UILabel! {
+ didSet {
+ goodLabel.text = L("placepage_rate_good")
+ goodLabel.textColor = UIColor.blackSecondaryText()
+ goodLabel.font = UIFont.medium10()
+ }
+ }
+
+ @IBOutlet private weak var excellentLabel: UILabel! {
+ didSet {
+ excellentLabel.text = L("placepage_rate_excellent")
+ excellentLabel.textColor = UIColor.blackSecondaryText()
+ excellentLabel.font = UIFont.medium10()
+ }
+ }
+
+ @objc var onRateTap: ((MWMRatingSummaryViewValueType) -> Void)!
+
+ @IBAction private func rate(_ button: UIButton) {
+ switch button {
+ case horribleButton: onRateTap(.horrible)
+ case badButton: onRateTap(.bad)
+ case normalButton: onRateTap(.normal)
+ case goodButton: onRateTap(.good)
+ case excellentButton: onRateTap(.excellent)
+ default: assert(false)
+ }
+ }
+}
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReviewCell.xib b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReviewCell.xib
new file mode 100644
index 0000000000..308997bf35
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReviewCell.xib
@@ -0,0 +1,338 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13196" 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="13173"/>
+ <capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
+ <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="none" indentationWidth="10" reuseIdentifier="UGCAddReviewCell" id="KGk-i7-Jjw" customClass="MWMUGCAddReviewCell">
+ <rect key="frame" x="0.0" y="0.0" width="320" height="128"/>
+ <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="320" height="127.5"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="O6m-tq-AL7">
+ <rect key="frame" x="16" y="16" width="288" height="20"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <nil key="textColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OWZ-cu-RdT">
+ <rect key="frame" x="16" y="52" width="288" height="59.5"/>
+ <subviews>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="stA-xC-5jb">
+ <rect key="frame" x="0.0" y="0.0" width="40" height="59.5"/>
+ <subviews>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="D4Q-0A-Efb">
+ <rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="width" secondItem="D4Q-0A-Efb" secondAttribute="height" multiplier="1:1" id="bUS-re-59E"/>
+ </constraints>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="blackDividers"/>
+ <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
+ <integer key="value" value="20"/>
+ </userDefinedRuntimeAttribute>
+ </userDefinedRuntimeAttributes>
+ </view>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Horrible" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7eh-cZ-bQ2">
+ <rect key="frame" x="0.0" y="47.5" width="40" height="12"/>
+ <fontDescription key="fontDescription" type="system" weight="medium" pointSize="10"/>
+ <nil key="textColor"/>
+ <nil key="highlightedColor"/>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="localizedText" value="horrible"/>
+ <userDefinedRuntimeAttribute type="string" keyPath="fontName" value="medium10"/>
+ </userDefinedRuntimeAttributes>
+ </label>
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="JsA-OK-Evh">
+ <rect key="frame" x="0.0" y="0.0" width="40" height="59.5"/>
+ <inset key="imageEdgeInsets" minX="0.0" minY="-19" maxX="0.0" maxY="0.0"/>
+ <state key="normal" image="ic_24px_rating_horrible"/>
+ <connections>
+ <action selector="rate:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="krI-QW-xfD"/>
+ </connections>
+ </button>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstItem="D4Q-0A-Efb" firstAttribute="leading" secondItem="stA-xC-5jb" secondAttribute="leading" id="3yG-qO-g25"/>
+ <constraint firstAttribute="trailing" secondItem="JsA-OK-Evh" secondAttribute="trailing" id="Eby-Ii-Go1"/>
+ <constraint firstAttribute="trailing" secondItem="D4Q-0A-Efb" secondAttribute="trailing" id="IX8-Ia-ENd"/>
+ <constraint firstItem="JsA-OK-Evh" firstAttribute="leading" secondItem="stA-xC-5jb" secondAttribute="leading" id="P63-PR-2cU"/>
+ <constraint firstItem="7eh-cZ-bQ2" firstAttribute="centerX" secondItem="D4Q-0A-Efb" secondAttribute="centerX" id="cVh-li-Kcf"/>
+ <constraint firstAttribute="bottom" secondItem="7eh-cZ-bQ2" secondAttribute="bottom" id="iXQ-cn-K7Q"/>
+ <constraint firstItem="JsA-OK-Evh" firstAttribute="top" secondItem="stA-xC-5jb" secondAttribute="top" id="ig5-nk-iNe"/>
+ <constraint firstItem="D4Q-0A-Efb" firstAttribute="top" secondItem="stA-xC-5jb" secondAttribute="top" id="nts-K9-6KA"/>
+ <constraint firstAttribute="bottom" secondItem="JsA-OK-Evh" secondAttribute="bottom" id="pTF-5e-F8K"/>
+ <constraint firstAttribute="width" constant="40" id="tjR-Li-tu4"/>
+ </constraints>
+ </view>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="02P-Ht-B8E">
+ <rect key="frame" x="40" y="0.0" width="84" height="59.5"/>
+ <subviews>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FR5-Ym-AgZ">
+ <rect key="frame" x="22" y="0.0" width="40" height="59.5"/>
+ <subviews>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZfD-kJ-Q3m">
+ <rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="width" secondItem="ZfD-kJ-Q3m" secondAttribute="height" multiplier="1:1" id="z0R-9P-1b6"/>
+ </constraints>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="blackDividers"/>
+ <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
+ <integer key="value" value="20"/>
+ </userDefinedRuntimeAttribute>
+ </userDefinedRuntimeAttributes>
+ </view>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Bad" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HDt-VE-NRp">
+ <rect key="frame" x="10.5" y="47.5" width="19" height="12"/>
+ <fontDescription key="fontDescription" type="system" weight="medium" pointSize="10"/>
+ <nil key="textColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ep2-Ms-SEh">
+ <rect key="frame" x="0.0" y="0.0" width="40" height="59.5"/>
+ <inset key="imageEdgeInsets" minX="0.0" minY="-19" maxX="0.0" maxY="0.0"/>
+ <state key="normal" image="ic_24px_rating_bad"/>
+ <connections>
+ <action selector="rate:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="Inx-9h-O5J"/>
+ </connections>
+ </button>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="bottom" secondItem="ep2-Ms-SEh" secondAttribute="bottom" id="3MG-IU-KpZ"/>
+ <constraint firstItem="HDt-VE-NRp" firstAttribute="centerX" secondItem="ZfD-kJ-Q3m" secondAttribute="centerX" id="5iD-rm-WBO"/>
+ <constraint firstItem="ep2-Ms-SEh" firstAttribute="leading" secondItem="FR5-Ym-AgZ" secondAttribute="leading" id="G2d-ea-yyg"/>
+ <constraint firstAttribute="width" constant="40" id="VbC-Ku-HIE"/>
+ <constraint firstItem="ZfD-kJ-Q3m" firstAttribute="top" secondItem="FR5-Ym-AgZ" secondAttribute="top" id="WnY-aQ-tSv"/>
+ <constraint firstItem="ZfD-kJ-Q3m" firstAttribute="leading" secondItem="FR5-Ym-AgZ" secondAttribute="leading" id="aq5-bV-5e5"/>
+ <constraint firstItem="ep2-Ms-SEh" firstAttribute="top" secondItem="FR5-Ym-AgZ" secondAttribute="top" id="mob-uK-Nee"/>
+ <constraint firstAttribute="trailing" secondItem="ep2-Ms-SEh" secondAttribute="trailing" id="n7A-Jl-VNr"/>
+ <constraint firstAttribute="bottom" secondItem="HDt-VE-NRp" secondAttribute="bottom" id="nfj-Za-38k"/>
+ <constraint firstAttribute="trailing" secondItem="ZfD-kJ-Q3m" secondAttribute="trailing" id="slF-sW-NwT"/>
+ </constraints>
+ </view>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstItem="FR5-Ym-AgZ" firstAttribute="centerX" secondItem="02P-Ht-B8E" secondAttribute="centerX" id="8Z3-ig-9bW"/>
+ <constraint firstItem="FR5-Ym-AgZ" firstAttribute="top" secondItem="02P-Ht-B8E" secondAttribute="top" id="DU6-me-Vzd"/>
+ <constraint firstAttribute="bottom" secondItem="FR5-Ym-AgZ" secondAttribute="bottom" id="a2R-BK-HPC"/>
+ </constraints>
+ </view>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IvZ-jc-I5F">
+ <rect key="frame" x="124" y="0.0" width="40" height="59.5"/>
+ <subviews>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3W8-Mg-bTw">
+ <rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="width" secondItem="3W8-Mg-bTw" secondAttribute="height" multiplier="1:1" id="qaN-7W-Yvj"/>
+ </constraints>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="blackDividers"/>
+ <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
+ <integer key="value" value="20"/>
+ </userDefinedRuntimeAttribute>
+ </userDefinedRuntimeAttributes>
+ </view>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Normal" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vds-hI-dsi">
+ <rect key="frame" x="2" y="47.5" width="36" height="12"/>
+ <fontDescription key="fontDescription" type="system" weight="medium" pointSize="10"/>
+ <nil key="textColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1kJ-GS-ar5">
+ <rect key="frame" x="0.0" y="0.0" width="40" height="59.5"/>
+ <inset key="imageEdgeInsets" minX="0.0" minY="-19" maxX="0.0" maxY="0.0"/>
+ <state key="normal" image="ic_24px_rating_normal"/>
+ <connections>
+ <action selector="rate:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="SO7-j5-JDT"/>
+ </connections>
+ </button>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="bottom" secondItem="1kJ-GS-ar5" secondAttribute="bottom" id="3Pl-E1-sWV"/>
+ <constraint firstAttribute="bottom" secondItem="vds-hI-dsi" secondAttribute="bottom" id="ALl-qa-Etd"/>
+ <constraint firstItem="1kJ-GS-ar5" firstAttribute="top" secondItem="IvZ-jc-I5F" secondAttribute="top" id="GWK-GX-Qd7"/>
+ <constraint firstAttribute="trailing" secondItem="1kJ-GS-ar5" secondAttribute="trailing" id="Jdk-in-qWM"/>
+ <constraint firstItem="3W8-Mg-bTw" firstAttribute="top" secondItem="IvZ-jc-I5F" secondAttribute="top" id="OmH-Kk-ABG"/>
+ <constraint firstItem="3W8-Mg-bTw" firstAttribute="leading" secondItem="IvZ-jc-I5F" secondAttribute="leading" id="cWt-zd-YhL"/>
+ <constraint firstItem="vds-hI-dsi" firstAttribute="centerX" secondItem="3W8-Mg-bTw" secondAttribute="centerX" id="fcE-RB-6XV"/>
+ <constraint firstAttribute="trailing" secondItem="3W8-Mg-bTw" secondAttribute="trailing" id="iID-d3-iZ0"/>
+ <constraint firstAttribute="width" constant="40" id="ihb-jJ-Qmc"/>
+ <constraint firstItem="1kJ-GS-ar5" firstAttribute="leading" secondItem="IvZ-jc-I5F" secondAttribute="leading" id="sYl-rH-zsf"/>
+ </constraints>
+ </view>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="H26-KC-z3X">
+ <rect key="frame" x="164" y="0.0" width="84" height="59.5"/>
+ <subviews>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ADD-eW-XeA">
+ <rect key="frame" x="22" y="0.0" width="40" height="59.5"/>
+ <subviews>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lPm-nd-4qs">
+ <rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="width" secondItem="lPm-nd-4qs" secondAttribute="height" multiplier="1:1" id="ROk-bX-OdS"/>
+ </constraints>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="blackDividers"/>
+ <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
+ <integer key="value" value="20"/>
+ </userDefinedRuntimeAttribute>
+ </userDefinedRuntimeAttributes>
+ </view>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Good" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ST3-Um-4dH">
+ <rect key="frame" x="7" y="47.5" width="26.5" height="12"/>
+ <fontDescription key="fontDescription" type="system" weight="medium" pointSize="10"/>
+ <nil key="textColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TJy-zt-WQZ">
+ <rect key="frame" x="0.0" y="0.0" width="40" height="59.5"/>
+ <inset key="imageEdgeInsets" minX="0.0" minY="-19" maxX="0.0" maxY="0.0"/>
+ <state key="normal" image="ic_24px_rating_good"/>
+ <connections>
+ <action selector="rate:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="bj2-A7-l54"/>
+ </connections>
+ </button>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstItem="lPm-nd-4qs" firstAttribute="leading" secondItem="ADD-eW-XeA" secondAttribute="leading" id="0k6-DG-8Ik"/>
+ <constraint firstAttribute="bottom" secondItem="ST3-Um-4dH" secondAttribute="bottom" id="AaD-yc-kBx"/>
+ <constraint firstAttribute="trailing" secondItem="TJy-zt-WQZ" secondAttribute="trailing" id="AyO-5j-vbG"/>
+ <constraint firstItem="TJy-zt-WQZ" firstAttribute="leading" secondItem="ADD-eW-XeA" secondAttribute="leading" id="CUZ-ia-X2S"/>
+ <constraint firstAttribute="bottom" secondItem="TJy-zt-WQZ" secondAttribute="bottom" id="Cfs-cN-Ky1"/>
+ <constraint firstItem="lPm-nd-4qs" firstAttribute="top" secondItem="ADD-eW-XeA" secondAttribute="top" id="Fjp-vK-B7c"/>
+ <constraint firstAttribute="width" constant="40" id="Lcy-vk-DWu"/>
+ <constraint firstAttribute="trailing" secondItem="lPm-nd-4qs" secondAttribute="trailing" id="Pw5-sQ-9gG"/>
+ <constraint firstItem="ST3-Um-4dH" firstAttribute="centerX" secondItem="lPm-nd-4qs" secondAttribute="centerX" id="jId-h7-uhO"/>
+ <constraint firstItem="TJy-zt-WQZ" firstAttribute="top" secondItem="ADD-eW-XeA" secondAttribute="top" id="vk0-tY-py0"/>
+ </constraints>
+ </view>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="bottom" secondItem="ADD-eW-XeA" secondAttribute="bottom" id="9ca-9z-eKs"/>
+ <constraint firstItem="ADD-eW-XeA" firstAttribute="centerX" secondItem="H26-KC-z3X" secondAttribute="centerX" id="BM4-4g-yIH"/>
+ <constraint firstItem="ADD-eW-XeA" firstAttribute="top" secondItem="H26-KC-z3X" secondAttribute="top" id="YOo-6t-MUW"/>
+ </constraints>
+ </view>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gRX-L4-fra">
+ <rect key="frame" x="248" y="0.0" width="40" height="59.5"/>
+ <subviews>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="U5X-iD-KyI">
+ <rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="width" secondItem="U5X-iD-KyI" secondAttribute="height" multiplier="1:1" id="XZ1-91-XOt"/>
+ </constraints>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="blackDividers"/>
+ <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
+ <integer key="value" value="20"/>
+ </userDefinedRuntimeAttribute>
+ </userDefinedRuntimeAttributes>
+ </view>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Excellent" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jqs-rm-LpL">
+ <rect key="frame" x="-2.5" y="47.5" width="45" height="12"/>
+ <fontDescription key="fontDescription" type="system" weight="medium" pointSize="10"/>
+ <nil key="textColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OEs-63-qBj">
+ <rect key="frame" x="0.0" y="0.0" width="40" height="59.5"/>
+ <inset key="imageEdgeInsets" minX="0.0" minY="-19" maxX="0.0" maxY="0.0"/>
+ <state key="normal" image="ic_24px_rating_excellent"/>
+ <connections>
+ <action selector="rate:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="nZY-v3-ef7"/>
+ </connections>
+ </button>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstItem="U5X-iD-KyI" firstAttribute="top" secondItem="gRX-L4-fra" secondAttribute="top" id="3bl-37-M73"/>
+ <constraint firstItem="OEs-63-qBj" firstAttribute="top" secondItem="gRX-L4-fra" secondAttribute="top" id="DMK-7d-sZ3"/>
+ <constraint firstItem="jqs-rm-LpL" firstAttribute="centerX" secondItem="U5X-iD-KyI" secondAttribute="centerX" id="MwL-Cs-dcG"/>
+ <constraint firstItem="U5X-iD-KyI" firstAttribute="leading" secondItem="gRX-L4-fra" secondAttribute="leading" id="SPN-s1-gov"/>
+ <constraint firstAttribute="trailing" secondItem="OEs-63-qBj" secondAttribute="trailing" id="VYR-Ob-gOi"/>
+ <constraint firstAttribute="bottom" secondItem="jqs-rm-LpL" secondAttribute="bottom" id="Vrm-Ux-vVo"/>
+ <constraint firstAttribute="width" constant="40" id="cqB-mU-Z52"/>
+ <constraint firstItem="OEs-63-qBj" firstAttribute="leading" secondItem="gRX-L4-fra" secondAttribute="leading" id="jQM-c4-JUP"/>
+ <constraint firstAttribute="bottom" secondItem="OEs-63-qBj" secondAttribute="bottom" id="lBB-QK-bYB"/>
+ <constraint firstAttribute="trailing" secondItem="U5X-iD-KyI" secondAttribute="trailing" id="lye-pu-aqc"/>
+ </constraints>
+ </view>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstItem="02P-Ht-B8E" firstAttribute="leading" secondItem="stA-xC-5jb" secondAttribute="trailing" id="0Le-I4-1VY"/>
+ <constraint firstAttribute="bottom" secondItem="H26-KC-z3X" secondAttribute="bottom" id="5cn-Q5-qyf"/>
+ <constraint firstItem="02P-Ht-B8E" firstAttribute="top" secondItem="OWZ-cu-RdT" secondAttribute="top" id="9c4-sD-M5d"/>
+ <constraint firstAttribute="bottom" secondItem="gRX-L4-fra" secondAttribute="bottom" id="CC5-Gv-7iu"/>
+ <constraint firstItem="IvZ-jc-I5F" firstAttribute="centerX" secondItem="OWZ-cu-RdT" secondAttribute="centerX" id="JKc-jA-cgO"/>
+ <constraint firstAttribute="trailing" secondItem="gRX-L4-fra" secondAttribute="trailing" id="Jmy-6j-AdI"/>
+ <constraint firstItem="gRX-L4-fra" firstAttribute="top" secondItem="OWZ-cu-RdT" secondAttribute="top" id="NHb-z1-UET"/>
+ <constraint firstItem="stA-xC-5jb" firstAttribute="leading" secondItem="OWZ-cu-RdT" secondAttribute="leading" id="Odq-9w-jOd"/>
+ <constraint firstItem="stA-xC-5jb" firstAttribute="top" secondItem="OWZ-cu-RdT" secondAttribute="top" id="PWT-HJ-lT0"/>
+ <constraint firstAttribute="bottom" secondItem="02P-Ht-B8E" secondAttribute="bottom" id="RZn-7m-TGp"/>
+ <constraint firstItem="H26-KC-z3X" firstAttribute="top" secondItem="OWZ-cu-RdT" secondAttribute="top" id="aMV-5H-dSg"/>
+ <constraint firstItem="gRX-L4-fra" firstAttribute="leading" secondItem="H26-KC-z3X" secondAttribute="trailing" id="bh2-HU-EV3"/>
+ <constraint firstAttribute="bottom" secondItem="stA-xC-5jb" secondAttribute="bottom" id="cRq-QN-KDQ"/>
+ <constraint firstItem="H26-KC-z3X" firstAttribute="leading" secondItem="IvZ-jc-I5F" secondAttribute="trailing" id="dzP-s9-xBU"/>
+ <constraint firstAttribute="bottom" secondItem="IvZ-jc-I5F" secondAttribute="bottom" id="igo-WR-EER"/>
+ <constraint firstAttribute="height" priority="999" constant="60" id="jwR-jn-n5F"/>
+ <constraint firstItem="IvZ-jc-I5F" firstAttribute="leading" secondItem="02P-Ht-B8E" secondAttribute="trailing" id="uQh-yo-BLa"/>
+ <constraint firstItem="IvZ-jc-I5F" firstAttribute="top" secondItem="OWZ-cu-RdT" secondAttribute="top" id="vCX-MW-9Cl"/>
+ </constraints>
+ </view>
+ </subviews>
+ <constraints>
+ <constraint firstItem="O6m-tq-AL7" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="16" id="4t9-ae-kJg"/>
+ <constraint firstItem="OWZ-cu-RdT" firstAttribute="top" secondItem="O6m-tq-AL7" secondAttribute="bottom" priority="999" constant="16" id="8gl-1p-y2D"/>
+ <constraint firstItem="OWZ-cu-RdT" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="Abu-mW-1qn"/>
+ <constraint firstItem="O6m-tq-AL7" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="Grj-Cg-L89"/>
+ <constraint firstAttribute="bottom" secondItem="OWZ-cu-RdT" secondAttribute="bottom" constant="16" id="Mde-4A-DXt"/>
+ <constraint firstAttribute="trailing" secondItem="O6m-tq-AL7" secondAttribute="trailing" constant="16" id="nX7-dp-jUf"/>
+ <constraint firstAttribute="trailing" secondItem="OWZ-cu-RdT" secondAttribute="trailing" constant="16" id="xOk-9V-JMZ"/>
+ </constraints>
+ </tableViewCellContentView>
+ <connections>
+ <outlet property="badButton" destination="ep2-Ms-SEh" id="yj2-al-f7z"/>
+ <outlet property="badLabel" destination="HDt-VE-NRp" id="qef-nM-3Of"/>
+ <outlet property="excellentButton" destination="OEs-63-qBj" id="wbK-O3-tjI"/>
+ <outlet property="excellentLabel" destination="jqs-rm-LpL" id="ROF-dd-q1f"/>
+ <outlet property="goodButton" destination="TJy-zt-WQZ" id="xhs-8j-5La"/>
+ <outlet property="goodLabel" destination="ST3-Um-4dH" id="UP3-WM-VPg"/>
+ <outlet property="horribleButton" destination="JsA-OK-Evh" id="aYI-JD-BLU"/>
+ <outlet property="horribleLabel" destination="7eh-cZ-bQ2" id="tm7-IX-IKA"/>
+ <outlet property="normalButton" destination="1kJ-GS-ar5" id="uVy-98-Arz"/>
+ <outlet property="normalLabel" destination="vds-hI-dsi" id="gEX-i3-cw4"/>
+ <outlet property="titleLabel" destination="O6m-tq-AL7" id="VZ0-JQ-m6d"/>
+ </connections>
+ </tableViewCell>
+ </objects>
+ <resources>
+ <image name="ic_24px_rating_bad" width="24" height="24"/>
+ <image name="ic_24px_rating_excellent" width="24" height="24"/>
+ <image name="ic_24px_rating_good" width="24" height="24"/>
+ <image name="ic_24px_rating_horrible" width="24" height="24"/>
+ <image name="ic_24px_rating_normal" width="24" height="24"/>
+ </resources>
+</document>
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCRating.swift b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCRating.swift
new file mode 100644
index 0000000000..01c50b3582
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCRating.swift
@@ -0,0 +1,24 @@
+@objc(MWMUGCRatingValueType)
+class UGCRatingValueType: NSObject {
+ let value: String
+ let type: MWMRatingSummaryViewValueType
+
+ @objc init(value: String, type: MWMRatingSummaryViewValueType) {
+ self.value = value
+ self.type = type
+ super.init()
+ }
+}
+
+@objc(MWMUGCRatingStars)
+final class UGCRatingStars: NSObject {
+ let title: String
+ var value: CGFloat
+ let maxValue: CGFloat
+
+ @objc init(title: String, value: CGFloat, maxValue: CGFloat) {
+ self.title = title
+ self.value = value
+ self.maxValue = maxValue
+ }
+}
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCReview.swift b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCReview.swift
new file mode 100644
index 0000000000..bb11c9e958
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCReview.swift
@@ -0,0 +1,14 @@
+@objc(MWMUGCReview)
+final class UGCReview: NSObject, MWMReviewProtocol {
+ let title: String
+ let date: Date
+ let text: String
+ let rating: UGCRatingValueType
+
+ @objc init(title: String, date: Date, text: String, rating: UGCRatingValueType) {
+ self.title = title
+ self.date = date
+ self.text = text
+ self.rating = rating
+ }
+}
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCReviewCell.swift b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCReviewCell.swift
new file mode 100644
index 0000000000..cc95f4cddb
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCReviewCell.swift
@@ -0,0 +1,50 @@
+@objc(MWMUGCReviewCell)
+final class UGCReviewCell: MWMTableViewCell {
+ @IBOutlet private weak var titleLabel: UILabel! {
+ didSet {
+ titleLabel.font = UIFont.bold14()
+ titleLabel.textColor = UIColor.blackPrimaryText()
+ }
+ }
+
+ @IBOutlet private weak var dateLabel: UILabel! {
+ didSet {
+ dateLabel.font = UIFont.regular12()
+ dateLabel.textColor = UIColor.blackSecondaryText()
+ }
+ }
+
+ @IBOutlet private weak var ratingView: RatingSummaryView! {
+ didSet {
+ ratingView.horribleColor = UIColor.ratingRed()
+ ratingView.badColor = UIColor.ratingOrange()
+ ratingView.normalColor = UIColor.ratingYellow()
+ ratingView.goodColor = UIColor.ratingLightGreen()
+ ratingView.excellentColor = UIColor.ratingGreen()
+ ratingView.textFont = UIFont.bold16()
+ ratingView.textSize = 16
+ }
+ }
+
+ @IBOutlet private weak var reviewLabel: ExpandableTextView! {
+ didSet {
+ reviewLabel.textFont = UIFont.regular14()
+ reviewLabel.textColor = UIColor.blackPrimaryText()
+ reviewLabel.expandText = L("placepage_more_button")
+ reviewLabel.expandTextColor = UIColor.linkBlue()
+ }
+ }
+
+ @objc func config(review: UGCReview, onUpdate: @escaping () -> Void) {
+ titleLabel.text = review.title
+ let dateFormatter = DateFormatter()
+ dateFormatter.dateStyle = .medium
+ dateFormatter.timeStyle = .none
+ dateLabel.text = dateFormatter.string(from: review.date)
+ reviewLabel.text = review.text
+ reviewLabel.onUpdate = onUpdate
+ ratingView.value = review.rating.value
+ ratingView.type = review.rating.type
+ isSeparatorHidden = true
+ }
+}
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCReviewCell.xib b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCReviewCell.xib
new file mode 100644
index 0000000000..14f4c944be
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCReviewCell.xib
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13196" 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="13173"/>
+ <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="none" indentationWidth="10" reuseIdentifier="UGCReviewCell" id="KGk-i7-Jjw" customClass="MWMUGCReviewCell">
+ <rect key="frame" x="0.0" y="0.0" width="320" height="135"/>
+ <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="320" height="134.5"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sVT-L4-Mlw">
+ <rect key="frame" x="0.0" y="-1" width="320" height="135"/>
+ <subviews>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" verticalCompressionResistancePriority="751" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3PE-rI-3N0">
+ <rect key="frame" x="16" y="16" width="42" height="20.5"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <nil key="textColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" verticalCompressionResistancePriority="751" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CfZ-eF-OFu">
+ <rect key="frame" x="16" y="40.5" width="42" height="21"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <nil key="textColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="yfk-2d-jIs" customClass="RatingSummaryView" customModule="cm_beta" customModuleProvider="target">
+ <rect key="frame" x="256" y="16" width="48" height="20"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="height" constant="20" placeholder="YES" id="GCB-u9-ND9"/>
+ <constraint firstAttribute="width" constant="48" placeholder="YES" id="TVO-Dx-h45"/>
+ </constraints>
+ </view>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="762-NT-BKz" customClass="ExpandableTextView" customModule="cm_beta" customModuleProvider="target">
+ <rect key="frame" x="16" y="78" width="288" height="40"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ </view>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="d1v-ce-wSZ">
+ <rect key="frame" x="0.0" y="134" width="320" height="1"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="height" constant="1" id="juL-ad-Qhb"/>
+ </constraints>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="blackDividers"/>
+ </userDefinedRuntimeAttributes>
+ </view>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstItem="762-NT-BKz" firstAttribute="top" secondItem="CfZ-eF-OFu" secondAttribute="bottom" constant="16" id="1lo-ik-7Zm"/>
+ <constraint firstItem="CfZ-eF-OFu" firstAttribute="leading" secondItem="3PE-rI-3N0" secondAttribute="leading" id="51g-rF-VAQ"/>
+ <constraint firstItem="3PE-rI-3N0" firstAttribute="top" secondItem="sVT-L4-Mlw" secondAttribute="top" constant="16" id="Dsv-rC-mN3"/>
+ <constraint firstItem="3PE-rI-3N0" firstAttribute="leading" secondItem="sVT-L4-Mlw" secondAttribute="leading" constant="16" id="I43-QS-Z3Y"/>
+ <constraint firstItem="yfk-2d-jIs" firstAttribute="top" secondItem="sVT-L4-Mlw" secondAttribute="top" constant="16" id="IN6-Pr-eGH"/>
+ <constraint firstAttribute="trailing" secondItem="yfk-2d-jIs" secondAttribute="trailing" constant="16" id="Laz-IW-nlM"/>
+ <constraint firstAttribute="bottom" secondItem="d1v-ce-wSZ" secondAttribute="bottom" id="V6X-dF-duR"/>
+ <constraint firstItem="762-NT-BKz" firstAttribute="leading" secondItem="CfZ-eF-OFu" secondAttribute="leading" id="c4z-oJ-icf"/>
+ <constraint firstItem="d1v-ce-wSZ" firstAttribute="top" secondItem="762-NT-BKz" secondAttribute="bottom" priority="999" constant="16" id="cXY-MK-bsx"/>
+ <constraint firstItem="CfZ-eF-OFu" firstAttribute="top" secondItem="3PE-rI-3N0" secondAttribute="bottom" constant="4" id="dib-vK-VkM"/>
+ <constraint firstAttribute="trailing" secondItem="762-NT-BKz" secondAttribute="trailing" constant="16" id="eWs-tf-gnY"/>
+ <constraint firstItem="d1v-ce-wSZ" firstAttribute="leading" secondItem="sVT-L4-Mlw" secondAttribute="leading" id="fJH-u0-p1T"/>
+ <constraint firstAttribute="trailing" secondItem="d1v-ce-wSZ" secondAttribute="trailing" id="ix8-vC-6x9"/>
+ </constraints>
+ </view>
+ </subviews>
+ <constraints>
+ <constraint firstItem="sVT-L4-Mlw" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="NDg-Sq-JR5"/>
+ <constraint firstAttribute="bottom" secondItem="sVT-L4-Mlw" secondAttribute="bottom" constant="0.5" id="UOg-pG-9oV"/>
+ <constraint firstAttribute="trailing" secondItem="sVT-L4-Mlw" secondAttribute="trailing" id="lk8-vT-q6l"/>
+ <constraint firstItem="sVT-L4-Mlw" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="-1" id="oeh-CG-l1D"/>
+ </constraints>
+ </tableViewCellContentView>
+ <connections>
+ <outlet property="dateLabel" destination="CfZ-eF-OFu" id="RLX-Xu-oVJ"/>
+ <outlet property="ratingView" destination="yfk-2d-jIs" id="wyh-94-tVB"/>
+ <outlet property="reviewLabel" destination="762-NT-BKz" id="sqO-tb-UuV"/>
+ <outlet property="titleLabel" destination="3PE-rI-3N0" id="YqB-6N-buv"/>
+ </connections>
+ </tableViewCell>
+ </objects>
+</document>
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingCell.swift b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingCell.swift
new file mode 100644
index 0000000000..0b6e3bb9e7
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingCell.swift
@@ -0,0 +1,101 @@
+@objc(MWMUGCSummaryRatingCell)
+final class UGCSummaryRatingCell: MWMTableViewCell {
+ private enum Config {
+ static let minimumInteritemSpacing: CGFloat = 16
+ static let minItemsPerRow: CGFloat = 3
+ static let estimatedItemSize = CGSize(width: 96, height: 32)
+ }
+
+ @IBOutlet private weak var titleLabel: UILabel! {
+ didSet {
+ titleLabel.font = UIFont.bold22()
+ titleLabel.textColor = UIColor.blackPrimaryText()
+ titleLabel.text = L("placepage_summary_rating")
+ }
+ }
+
+ @IBOutlet private weak var countLabel: UILabel! {
+ didSet {
+ countLabel.font = UIFont.regular12()
+ countLabel.textColor = UIColor.blackSecondaryText()
+ }
+ }
+
+ @IBOutlet private weak var ratingSummaryView: RatingSummaryView! {
+ didSet {
+ ratingSummaryView.horribleColor = UIColor.ratingRed()
+ ratingSummaryView.badColor = UIColor.ratingOrange()
+ ratingSummaryView.normalColor = UIColor.ratingYellow()
+ ratingSummaryView.goodColor = UIColor.ratingLightGreen()
+ ratingSummaryView.excellentColor = UIColor.ratingGreen()
+ ratingSummaryView.textFont = UIFont.bold28()
+ ratingSummaryView.textSize = 28
+ }
+ }
+
+ @IBOutlet private weak var ratingCollectionViewHeight: NSLayoutConstraint!
+ @IBOutlet private weak var ratingCollectionView: UICollectionView! {
+ didSet {
+ ratingCollectionView.register(cellClass: UGCSummaryRatingStarsCell.self)
+ let layout = ratingCollectionView.collectionViewLayout as! UICollectionViewFlowLayout
+ layout.estimatedItemSize = Config.estimatedItemSize
+ }
+ }
+
+ fileprivate var ratings: [UGCRatingStars]!
+
+ override var frame: CGRect {
+ didSet {
+ if frame.size != oldValue.size {
+ updateCollectionView(nil)
+ }
+ }
+ }
+
+ @objc func config(reviewsCount: UInt, summaryRating: UGCRatingValueType, ratings: [UGCRatingStars]) {
+ countLabel.text = String(coreFormat: L("place_page_summary_rating_description"), arguments: [reviewsCount])
+ ratingSummaryView.value = summaryRating.value
+ ratingSummaryView.type = summaryRating.type
+ self.ratings = ratings
+ updateCollectionView { [weak self] in
+ self?.ratingCollectionView.reloadSections(IndexSet(integer: 0))
+ }
+ isSeparatorHidden = true
+ }
+
+ override func didMoveToSuperview() {
+ super.didMoveToSuperview()
+ updateCollectionView(nil)
+ }
+
+ private func updateCollectionView(_ updates: (() -> Void)?) {
+ guard let sv = superview else { return }
+ let layout = ratingCollectionView.collectionViewLayout as! UICollectionViewFlowLayout
+ let inset = layout.sectionInset
+ let viewWidth = sv.size.width - inset.left - inset.right
+ let maxItemWidth = layout.estimatedItemSize.width
+
+ let ratingsCount = CGFloat(ratings?.count ?? 0)
+ let itemsPerRow = floor(min(max(viewWidth / maxItemWidth, Config.minItemsPerRow), ratingsCount))
+ let itemWidth = floor(min((viewWidth - (itemsPerRow - 1) * Config.minimumInteritemSpacing) / itemsPerRow, maxItemWidth))
+ let interitemSpacing = floor((viewWidth - itemWidth * itemsPerRow) / (itemsPerRow - 1))
+ layout.minimumInteritemSpacing = interitemSpacing
+ layout.itemSize = CGSize(width: itemWidth, height: Config.estimatedItemSize.height)
+
+ let rowsCount = ceil(ratingsCount / itemsPerRow)
+ ratingCollectionViewHeight.constant = rowsCount * Config.estimatedItemSize.height + (rowsCount - 1) * layout.minimumLineSpacing + inset.top + inset.bottom
+ ratingCollectionView.performBatchUpdates(updates, completion: nil)
+ }
+}
+
+extension UGCSummaryRatingCell: UICollectionViewDataSource {
+ func collectionView(_: UICollectionView, numberOfItemsInSection _: Int) -> Int {
+ return ratings?.count ?? 0
+ }
+
+ func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+ let cell = collectionView.dequeueReusableCell(withCellClass: UGCSummaryRatingStarsCell.self, indexPath: indexPath) as! UGCSummaryRatingStarsCell
+ cell.config(rating: ratings[indexPath.item])
+ return cell
+ }
+}
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingCell.xib b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingCell.xib
new file mode 100644
index 0000000000..61b03d5e50
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingCell.xib
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13196" 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="13173"/>
+ <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="none" indentationWidth="0.0" reuseIdentifier="UGCSummaryRatingCell" id="KGk-i7-Jjw" customClass="MWMUGCSummaryRatingCell">
+ <rect key="frame" x="0.0" y="0.0" width="320" height="135"/>
+ <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="320" height="134.5"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="MSt-Fx-y5y">
+ <rect key="frame" x="0.0" y="0.0" width="320" height="78"/>
+ <subviews>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vuk-Pr-u1F">
+ <rect key="frame" x="16" y="16" width="42" height="21"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <nil key="textColor"/>
+ <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="dL4-7I-zUJ">
+ <rect key="frame" x="16" y="41" width="42" height="21"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <nil key="textColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1wF-gY-Wza" customClass="RatingSummaryView" customModule="cm_beta" customModuleProvider="target">
+ <rect key="frame" x="200" y="19" width="104" height="40"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="width" constant="104" placeholder="YES" id="K7d-bD-t4a"/>
+ <constraint firstAttribute="height" constant="40" placeholder="YES" id="XNy-10-mxa"/>
+ </constraints>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="image" keyPath="horribleImage" value="ic_24px_rating_horrible"/>
+ <userDefinedRuntimeAttribute type="image" keyPath="badImage" value="ic_24px_rating_bad"/>
+ <userDefinedRuntimeAttribute type="image" keyPath="normalImage" value="ic_24px_rating_normal"/>
+ <userDefinedRuntimeAttribute type="image" keyPath="goodImage" value="ic_24px_rating_good"/>
+ <userDefinedRuntimeAttribute type="image" keyPath="excellentImage" value="ic_24px_rating_excellent"/>
+ </userDefinedRuntimeAttributes>
+ </view>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ks7-ZL-gaO">
+ <rect key="frame" x="16" y="77" width="304" height="1"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="height" constant="1" id="0Ow-i9-Mmd"/>
+ </constraints>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="blackDividers"/>
+ </userDefinedRuntimeAttributes>
+ </view>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="bottom" secondItem="Ks7-ZL-gaO" secondAttribute="bottom" id="EQg-NU-aaE"/>
+ <constraint firstItem="Ks7-ZL-gaO" firstAttribute="leading" secondItem="vuk-Pr-u1F" secondAttribute="leading" id="EzT-6G-Aaz"/>
+ <constraint firstAttribute="trailing" secondItem="1wF-gY-Wza" secondAttribute="trailing" constant="16" id="TmZ-A7-jSz"/>
+ <constraint firstAttribute="bottom" secondItem="dL4-7I-zUJ" secondAttribute="bottom" constant="16" id="Y4t-mx-i4U"/>
+ <constraint firstItem="dL4-7I-zUJ" firstAttribute="top" secondItem="vuk-Pr-u1F" secondAttribute="bottom" constant="4" id="gwC-3A-Cn6"/>
+ <constraint firstAttribute="trailing" secondItem="Ks7-ZL-gaO" secondAttribute="trailing" id="rqS-JS-29d"/>
+ <constraint firstItem="vuk-Pr-u1F" firstAttribute="top" secondItem="MSt-Fx-y5y" secondAttribute="top" constant="16" id="sW5-pu-RyS"/>
+ <constraint firstItem="dL4-7I-zUJ" firstAttribute="leading" secondItem="vuk-Pr-u1F" secondAttribute="leading" id="t1x-yk-QNA"/>
+ <constraint firstItem="1wF-gY-Wza" firstAttribute="centerY" secondItem="MSt-Fx-y5y" secondAttribute="centerY" id="x7o-2J-PIT"/>
+ <constraint firstItem="vuk-Pr-u1F" firstAttribute="leading" secondItem="MSt-Fx-y5y" secondAttribute="leading" constant="16" id="ykf-u3-iXH"/>
+ </constraints>
+ </view>
+ <collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="none" prefetchingEnabled="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ek3-Zj-cfu">
+ <rect key="frame" x="0.0" y="78" width="320" height="55.5"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="height" priority="999" constant="56" id="NOt-1H-Ou6"/>
+ </constraints>
+ <collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="12" minimumInteritemSpacing="16" id="liK-AI-Noj">
+ <size key="itemSize" width="120" height="32"/>
+ <size key="headerReferenceSize" width="0.0" height="0.0"/>
+ <size key="footerReferenceSize" width="0.0" height="0.0"/>
+ <inset key="sectionInset" minX="16" minY="12" maxX="16" maxY="12"/>
+ </collectionViewFlowLayout>
+ <connections>
+ <outlet property="dataSource" destination="KGk-i7-Jjw" id="dDO-Dn-baT"/>
+ </connections>
+ </collectionView>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="deV-cR-pmt">
+ <rect key="frame" x="0.0" y="133.5" width="320" height="1"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="height" constant="1" id="xWy-nC-DYA"/>
+ </constraints>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="blackDividers"/>
+ </userDefinedRuntimeAttributes>
+ </view>
+ </subviews>
+ <constraints>
+ <constraint firstAttribute="trailing" secondItem="ek3-Zj-cfu" secondAttribute="trailing" id="Bqn-Ho-oHK"/>
+ <constraint firstItem="MSt-Fx-y5y" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="E6a-WS-t4d"/>
+ <constraint firstItem="deV-cR-pmt" firstAttribute="top" secondItem="ek3-Zj-cfu" secondAttribute="bottom" id="LVT-d5-pQ9"/>
+ <constraint firstItem="ek3-Zj-cfu" firstAttribute="top" secondItem="MSt-Fx-y5y" secondAttribute="bottom" id="Nof-jo-qQX"/>
+ <constraint firstItem="ek3-Zj-cfu" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="O1E-QI-WCE"/>
+ <constraint firstItem="deV-cR-pmt" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="ZMV-M7-CZf"/>
+ <constraint firstAttribute="trailing" secondItem="deV-cR-pmt" secondAttribute="trailing" id="cGS-Z6-Jhu"/>
+ <constraint firstAttribute="bottom" secondItem="deV-cR-pmt" secondAttribute="bottom" id="hYI-fo-9ZF"/>
+ <constraint firstAttribute="trailing" secondItem="MSt-Fx-y5y" secondAttribute="trailing" id="lrY-p6-nWm"/>
+ <constraint firstItem="MSt-Fx-y5y" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="vuv-N8-45j"/>
+ </constraints>
+ </tableViewCellContentView>
+ <connections>
+ <outlet property="countLabel" destination="dL4-7I-zUJ" id="Tff-bs-ZJ1"/>
+ <outlet property="ratingCollectionView" destination="ek3-Zj-cfu" id="yaA-5U-Hkd"/>
+ <outlet property="ratingCollectionViewHeight" destination="NOt-1H-Ou6" id="OAa-93-CP3"/>
+ <outlet property="ratingSummaryView" destination="1wF-gY-Wza" id="Cik-Nz-9lb"/>
+ <outlet property="titleLabel" destination="vuk-Pr-u1F" id="BS6-tI-lXe"/>
+ </connections>
+ </tableViewCell>
+ </objects>
+ <resources>
+ <image name="ic_24px_rating_bad" width="24" height="24"/>
+ <image name="ic_24px_rating_excellent" width="24" height="24"/>
+ <image name="ic_24px_rating_good" width="24" height="24"/>
+ <image name="ic_24px_rating_horrible" width="24" height="24"/>
+ <image name="ic_24px_rating_normal" width="24" height="24"/>
+ </resources>
+</document>
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingStarsCell.swift b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingStarsCell.swift
new file mode 100644
index 0000000000..722ecad58a
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingStarsCell.swift
@@ -0,0 +1,19 @@
+import UIKit
+
+final class UGCSummaryRatingStarsCell: UICollectionViewCell {
+ @IBOutlet private weak var ratingView: RatingView! {
+ didSet {
+ ratingView.topTextFont = UIFont.regular10()
+ ratingView.topTextColor = UIColor.blackSecondaryText()
+ ratingView.filledColor = UIColor.ratingYellow()
+ ratingView.emptyColor = UIColor.blackDividers()
+ ratingView.borderWidth = 0
+ }
+ }
+
+ func config(rating: UGCRatingStars) {
+ ratingView.topText = rating.title
+ ratingView.value = rating.value
+ ratingView.starsCount = Int(rating.maxValue)
+ }
+}
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingStarsCell.xib b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingStarsCell.xib
new file mode 100644
index 0000000000..921a287f60
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCSummaryRatingStarsCell.xib
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" 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="12089"/>
+ <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"/>
+ <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="UGCSummaryRatingStarsCell" customModule="cm_beta" customModuleProvider="target">
+ <rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
+ <rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <subviews>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="BLZ-qJ-zka" customClass="RatingView" customModule="cm_beta" customModuleProvider="target">
+ <rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="number" keyPath="starSize">
+ <real key="value" value="12"/>
+ </userDefinedRuntimeAttribute>
+ </userDefinedRuntimeAttributes>
+ </view>
+ </subviews>
+ </view>
+ <constraints>
+ <constraint firstAttribute="bottom" secondItem="BLZ-qJ-zka" secondAttribute="bottom" id="M7R-Mt-lBd"/>
+ <constraint firstItem="BLZ-qJ-zka" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="YpT-Vp-9OA"/>
+ <constraint firstAttribute="trailing" secondItem="BLZ-qJ-zka" secondAttribute="trailing" id="ZjF-5Y-apH"/>
+ <constraint firstItem="BLZ-qJ-zka" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="w5m-wz-I5t"/>
+ </constraints>
+ <connections>
+ <outlet property="ratingView" destination="BLZ-qJ-zka" id="BH2-xM-9PK"/>
+ </connections>
+ </collectionViewCell>
+ </objects>
+</document>
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCYourReview.swift b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCYourReview.swift
new file mode 100644
index 0000000000..9391193ae0
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCYourReview.swift
@@ -0,0 +1,12 @@
+@objc(MWMUGCYourReview)
+final class UGCYourReview: NSObject, MWMReviewProtocol {
+ let date: Date
+ let text: String
+ let ratings: [UGCRatingStars]
+
+ @objc init(date: Date, text: String, ratings: [UGCRatingStars]) {
+ self.date = date
+ self.text = text
+ self.ratings = ratings
+ }
+}
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCYourReviewCell.swift b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCYourReviewCell.swift
new file mode 100644
index 0000000000..4f823db004
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCYourReviewCell.swift
@@ -0,0 +1,103 @@
+@objc(MWMUGCYourReviewCell)
+final class UGCYourReviewCell: MWMTableViewCell {
+ private enum Config {
+ static let minimumInteritemSpacing: CGFloat = 16
+ static let minItemsPerRow: CGFloat = 3
+ static let estimatedItemSize = CGSize(width: 96, height: 32)
+ }
+
+ @IBOutlet private weak var titleLabel: UILabel! {
+ didSet {
+ titleLabel.font = UIFont.bold14()
+ titleLabel.textColor = UIColor.blackPrimaryText()
+ titleLabel.text = L("placepage_reviews_your_comment")
+ }
+ }
+
+ @IBOutlet private weak var dateLabel: UILabel! {
+ didSet {
+ dateLabel.font = UIFont.regular12()
+ dateLabel.textColor = UIColor.blackSecondaryText()
+ }
+ }
+
+ @IBOutlet private weak var reviewLabel: ExpandableTextView! {
+ didSet {
+ reviewLabel.textFont = UIFont.regular14()
+ reviewLabel.textColor = UIColor.blackPrimaryText()
+ reviewLabel.expandText = L("placepage_more_button")
+ reviewLabel.expandTextColor = UIColor.linkBlue()
+ }
+ }
+
+ @IBOutlet private weak var ratingCollectionViewHeight: NSLayoutConstraint!
+ @IBOutlet private weak var ratingCollectionView: UICollectionView! {
+ didSet {
+ ratingCollectionView.register(cellClass: UGCSummaryRatingStarsCell.self)
+ let layout = ratingCollectionView.collectionViewLayout as! UICollectionViewFlowLayout
+ layout.estimatedItemSize = Config.estimatedItemSize
+ }
+ }
+
+ private var yourReview: UGCYourReview!
+
+ override var frame: CGRect {
+ didSet {
+ if frame.size != oldValue.size {
+ updateCollectionView(nil)
+ }
+ }
+ }
+
+ @objc func config(yourReview: UGCYourReview, onUpdate: @escaping () -> Void) {
+ let dateFormatter = DateFormatter()
+ dateFormatter.dateStyle = .medium
+ dateFormatter.timeStyle = .none
+ dateLabel.text = dateFormatter.string(from: yourReview.date)
+ self.yourReview = yourReview
+ reviewLabel.text = yourReview.text
+ reviewLabel.onUpdate = onUpdate
+ updateCollectionView { [weak self] in
+ self?.ratingCollectionView.reloadSections(IndexSet(integer: 0))
+ }
+ isSeparatorHidden = true
+ }
+
+ override func didMoveToSuperview() {
+ super.didMoveToSuperview()
+ updateCollectionView(nil)
+ }
+
+ private func updateCollectionView(_ updates: (() -> Void)?) {
+ guard let sv = superview else { return }
+ DispatchQueue.main.async {
+ let layout = self.ratingCollectionView.collectionViewLayout as! UICollectionViewFlowLayout
+ let inset = layout.sectionInset
+ let viewWidth = sv.size.width - inset.left - inset.right
+ let maxItemWidth = layout.estimatedItemSize.width
+
+ let ratingsCount = CGFloat(self.yourReview?.ratings.count ?? 0)
+ let itemsPerRow = floor(min(max(viewWidth / maxItemWidth, Config.minItemsPerRow), ratingsCount))
+ let itemWidth = floor(min((viewWidth - (itemsPerRow - 1) * Config.minimumInteritemSpacing) / itemsPerRow, maxItemWidth))
+ let interitemSpacing = floor((viewWidth - itemWidth * itemsPerRow) / (itemsPerRow - 1))
+ layout.minimumInteritemSpacing = interitemSpacing
+ layout.itemSize = CGSize(width: itemWidth, height: Config.estimatedItemSize.height)
+
+ let rowsCount = ceil(ratingsCount / itemsPerRow)
+ self.ratingCollectionViewHeight.constant = rowsCount * Config.estimatedItemSize.height + (rowsCount - 1) * layout.minimumLineSpacing + inset.top + inset.bottom
+ self.ratingCollectionView.performBatchUpdates(updates, completion: nil)
+ }
+ }
+}
+
+extension UGCYourReviewCell: UICollectionViewDataSource {
+ func collectionView(_: UICollectionView, numberOfItemsInSection _: Int) -> Int {
+ return yourReview?.ratings.count ?? 0
+ }
+
+ func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+ let cell = collectionView.dequeueReusableCell(withCellClass: UGCSummaryRatingStarsCell.self, indexPath: indexPath) as! UGCSummaryRatingStarsCell
+ cell.config(rating: yourReview!.ratings[indexPath.item])
+ return cell
+ }
+}
diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCYourReviewCell.xib b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCYourReviewCell.xib
new file mode 100644
index 0000000000..5ea2a7cb5b
--- /dev/null
+++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCYourReviewCell.xib
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13196" 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="13173"/>
+ <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="none" indentationWidth="10" reuseIdentifier="UGCYourReviewCell" id="KGk-i7-Jjw" customClass="MWMUGCYourReviewCell">
+ <rect key="frame" x="0.0" y="0.0" width="320" height="192"/>
+ <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="320" height="191.5"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="M3q-L0-4Y7">
+ <rect key="frame" x="0.0" y="0.0" width="320" height="135"/>
+ <subviews>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" verticalCompressionResistancePriority="751" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nht-6C-S3i">
+ <rect key="frame" x="16" y="16" width="42" height="20.5"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <nil key="textColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" verticalCompressionResistancePriority="751" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qZ5-I9-7dJ">
+ <rect key="frame" x="16" y="40.5" width="42" height="21"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <nil key="textColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="G4x-pj-fmv" customClass="ExpandableTextView" customModule="cm_beta" customModuleProvider="target">
+ <rect key="frame" x="16" y="78" width="288" height="40"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ </view>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aOE-yo-hUQ">
+ <rect key="frame" x="16" y="134" width="304" height="1"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="height" constant="1" id="E6L-PS-9ij"/>
+ </constraints>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="blackDividers"/>
+ </userDefinedRuntimeAttributes>
+ </view>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstItem="G4x-pj-fmv" firstAttribute="leading" secondItem="qZ5-I9-7dJ" secondAttribute="leading" id="0tv-ab-Ino"/>
+ <constraint firstItem="aOE-yo-hUQ" firstAttribute="leading" secondItem="nht-6C-S3i" secondAttribute="leading" id="5zo-5x-C5V"/>
+ <constraint firstItem="qZ5-I9-7dJ" firstAttribute="leading" secondItem="nht-6C-S3i" secondAttribute="leading" id="Gau-1M-wwW"/>
+ <constraint firstItem="aOE-yo-hUQ" firstAttribute="top" secondItem="G4x-pj-fmv" secondAttribute="bottom" priority="999" constant="16" id="NW0-Eu-IsI"/>
+ <constraint firstItem="G4x-pj-fmv" firstAttribute="top" secondItem="qZ5-I9-7dJ" secondAttribute="bottom" constant="16" id="OH9-Mm-dbX"/>
+ <constraint firstAttribute="trailing" secondItem="G4x-pj-fmv" secondAttribute="trailing" constant="16" id="PNg-SO-p6V"/>
+ <constraint firstItem="nht-6C-S3i" firstAttribute="leading" secondItem="M3q-L0-4Y7" secondAttribute="leading" constant="16" id="PY2-qj-nDO"/>
+ <constraint firstItem="qZ5-I9-7dJ" firstAttribute="top" secondItem="nht-6C-S3i" secondAttribute="bottom" constant="4" id="S3o-tR-arb"/>
+ <constraint firstAttribute="trailing" secondItem="aOE-yo-hUQ" secondAttribute="trailing" id="cx3-dh-2bm"/>
+ <constraint firstAttribute="bottom" secondItem="aOE-yo-hUQ" secondAttribute="bottom" id="hbw-cC-TVb"/>
+ <constraint firstItem="nht-6C-S3i" firstAttribute="top" secondItem="M3q-L0-4Y7" secondAttribute="top" constant="16" id="v5J-lZ-cdA"/>
+ </constraints>
+ </view>
+ <collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="none" prefetchingEnabled="NO" translatesAutoresizingMaskIntoConstraints="NO" id="w6j-GC-6Bv">
+ <rect key="frame" x="0.0" y="135" width="320" height="55.5"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="height" priority="999" constant="56" id="2hn-mr-UAw"/>
+ </constraints>
+ <collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="12" minimumInteritemSpacing="16" id="MWR-PM-MMO">
+ <size key="itemSize" width="120" height="32"/>
+ <size key="headerReferenceSize" width="0.0" height="0.0"/>
+ <size key="footerReferenceSize" width="0.0" height="0.0"/>
+ <inset key="sectionInset" minX="16" minY="12" maxX="16" maxY="12"/>
+ </collectionViewFlowLayout>
+ <connections>
+ <outlet property="dataSource" destination="KGk-i7-Jjw" id="XNi-U1-zp7"/>
+ </connections>
+ </collectionView>
+ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="l8v-v7-2Xf">
+ <rect key="frame" x="0.0" y="190.5" width="320" height="1"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+ <constraints>
+ <constraint firstAttribute="height" constant="1" id="FbW-ej-brB"/>
+ </constraints>
+ <userDefinedRuntimeAttributes>
+ <userDefinedRuntimeAttribute type="string" keyPath="backgroundColorName" value="blackDividers"/>
+ </userDefinedRuntimeAttributes>
+ </view>
+ </subviews>
+ <constraints>
+ <constraint firstItem="w6j-GC-6Bv" firstAttribute="top" secondItem="M3q-L0-4Y7" secondAttribute="bottom" id="14p-0F-Of5"/>
+ <constraint firstItem="l8v-v7-2Xf" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="77N-Z4-HEp"/>
+ <constraint firstItem="w6j-GC-6Bv" firstAttribute="top" secondItem="M3q-L0-4Y7" secondAttribute="bottom" id="L8X-HU-Nlw"/>
+ <constraint firstItem="M3q-L0-4Y7" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="T9p-nW-wRb"/>
+ <constraint firstItem="M3q-L0-4Y7" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="WVZ-X8-ZDo"/>
+ <constraint firstAttribute="trailing" secondItem="w6j-GC-6Bv" secondAttribute="trailing" id="XBx-IK-uxK"/>
+ <constraint firstAttribute="trailing" secondItem="M3q-L0-4Y7" secondAttribute="trailing" id="azy-n1-1rx"/>
+ <constraint firstAttribute="trailing" secondItem="M3q-L0-4Y7" secondAttribute="trailing" id="cLA-Dj-Ldj"/>
+ <constraint firstAttribute="bottom" secondItem="l8v-v7-2Xf" secondAttribute="bottom" id="l0O-cH-aHC"/>
+ <constraint firstItem="l8v-v7-2Xf" firstAttribute="top" secondItem="w6j-GC-6Bv" secondAttribute="bottom" id="nHN-wy-OWN"/>
+ <constraint firstItem="w6j-GC-6Bv" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="nP1-Z3-mNg"/>
+ <constraint firstItem="M3q-L0-4Y7" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="pqg-Sh-Khw"/>
+ <constraint firstAttribute="trailing" secondItem="l8v-v7-2Xf" secondAttribute="trailing" id="tjg-JB-UYP"/>
+ <constraint firstItem="M3q-L0-4Y7" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="xIs-eU-Xzv"/>
+ </constraints>
+ </tableViewCellContentView>
+ <connections>
+ <outlet property="dateLabel" destination="qZ5-I9-7dJ" id="Hkf-h6-ybf"/>
+ <outlet property="ratingCollectionView" destination="w6j-GC-6Bv" id="SbY-HY-zXO"/>
+ <outlet property="ratingCollectionViewHeight" destination="2hn-mr-UAw" id="xbR-Dl-OR3"/>
+ <outlet property="reviewLabel" destination="G4x-pj-fmv" id="pWq-RG-xv0"/>
+ <outlet property="titleLabel" destination="nht-6C-S3i" id="1lQ-nA-n7z"/>
+ </connections>
+ </tableViewCell>
+ </objects>
+</document>