[iOS] update bookmarks list

This commit is contained in:
Aleksey Belouosv 2018-11-21 16:46:23 +03:00 committed by Olesia Bolovintseva
parent 687c39a4ef
commit 38ede290ec
18 changed files with 184 additions and 44 deletions

View file

@ -27,7 +27,7 @@ class DownloadedBookmarksViewController: MWMViewController {
super.viewDidLoad()
tableView.backgroundColor = UIColor.pressBackground()
tableView.separatorColor = UIColor.blackDividers()
tableView.tableFooterView = bottomView
tableView.tableHeaderView = bottomView
tableView.registerNib(cell: CatalogCategoryCell.self)
tableView.registerNibForHeaderFooterView(BMCCategoriesHeader.self)
if #available(iOS 11, *) { return } // workaround for https://jira.mail.ru/browse/MAPSME-8101

View file

@ -38,11 +38,22 @@ class BMCCategory: BMCModel, Equatable {
}
}
init(identifier: MWMMarkGroupID = 0, title: String = L("core_my_places"), count: UInt64 = 0, isVisible: Bool = true) {
var accessStatus: MWMCategoryAccessStatus {
didSet {
notifyObservers()
}
}
init(identifier: MWMMarkGroupID = 0,
title: String = L("core_my_places"),
count: UInt64 = 0,
isVisible: Bool = true,
accessStatus: MWMCategoryAccessStatus = .local) {
self.identifier = identifier
self.title = title
self.count = count
self.isVisible = isVisible
self.accessStatus = accessStatus
}
private let observers = NSHashTable<BMCCategoryObserver>.weakObjects()

View file

@ -51,20 +51,14 @@ final class BMCViewController: MWMViewController {
viewModel.removeFromObserverList()
}
private func updateCategoryName(category: BMCCategory?) {
let isNewCategory = (category == nil)
private func createNewCategory() {
alertController.presentCreateBookmarkCategoryAlert(withMaxCharacterNum: viewModel.maxCategoryNameLength,
minCharacterNum: viewModel.minCategoryNameLength,
isNewCategory: isNewCategory)
isNewCategory: true)
{ [weak viewModel] (name: String!) -> Bool in
guard let model = viewModel else { return false }
if model.checkCategory(name: name) {
if isNewCategory {
model.addCategory(name: name)
} else {
model.renameCategory(category: category!, name: name)
}
model.addCategory(name: name)
return true
}
@ -72,9 +66,27 @@ final class BMCViewController: MWMViewController {
}
}
private func shareCategoryFile(category: BMCCategory, anchor: UIView) {
viewModel.shareCategory(category: category) {
switch $0 {
case let .success(url):
let shareController = MWMActivityViewController.share(for: url,
message: L("share_bookmarks_email_body"))
{ [weak self] _, _, _, _ in
self?.viewModel?.finishShareCategory()
}
shareController?.present(inParentViewController: self, anchorView: anchor)
case let .error(title, text):
MWMAlertViewController.activeAlert().presentInfoAlert(title, text: text)
}
}
}
private func shareCategory(category: BMCCategory, anchor: UIView) {
let storyboard = UIStoryboard.instance(.sharing)
let shareController = storyboard.instantiateInitialViewController() as! BookmarksSharingViewController
shareController.delegate = self
shareController.categoryId = category.identifier
MapViewController.topViewController().navigationController?.pushViewController(shareController,
@ -106,23 +118,23 @@ final class BMCViewController: MWMViewController {
ppc.sourceRect = anchor.bounds
}
let rename = L("rename").capitalized
actionSheet.addAction(UIAlertAction(title: rename, style: .default, handler: { _ in
self.updateCategoryName(category: category)
}))
let settings = L("settings").capitalized
let settings = L("list_settings").capitalized
actionSheet.addAction(UIAlertAction(title: settings, style: .default, handler: { _ in
self.openCategorySettings(category: category)
}))
let showHide = L(category.isVisible ? "hide" : "show").capitalized
let showHide = L(category.isVisible ? "hide_from_map" : "show_on_map").capitalized
actionSheet.addAction(UIAlertAction(title: showHide, style: .default, handler: { _ in
self.visibilityAction(category: category)
}))
let share = L("share").capitalized
let exportFile = L("export_file").capitalized
actionSheet.addAction(UIAlertAction(title: exportFile, style: .default, handler: { _ in
self.shareCategoryFile(category: category, anchor: anchor)
}))
let share = L("sharing_options").capitalized
actionSheet.addAction(UIAlertAction(title: share, style: .default, handler: { _ in
self.shareCategory(category: category, anchor: anchor)
}))
let delete = L("delete").capitalized
let delete = L("delete_list").capitalized
let deleteAction = UIAlertAction(title: delete, style: .destructive, handler: { [viewModel] _ in
viewModel!.deleteCategory(category: category)
})
@ -254,7 +266,7 @@ extension BMCViewController: UITableViewDelegate {
openCategory(category: category)
case let action as BMCAction:
switch action {
case .create: updateCategoryName(category: nil)
case .create: createNewCategory()
}
default:
assertionFailure()
@ -328,3 +340,9 @@ extension BMCViewController: CategorySettingsViewControllerDelegate {
viewModel?.reloadData()
}
}
extension BMCViewController: BookmarksSharingViewControllerDelegate {
func didShareCategory() {
viewModel?.reloadData()
}
}

View file

@ -52,7 +52,12 @@ final class BMCDefaultViewModel: NSObject {
let title = manager.getCategoryName(categoryId)
let count = manager.getCategoryMarksCount(categoryId) + manager.getCategoryTracksCount(categoryId)
let isVisible = manager.isCategoryVisible(categoryId)
return BMCCategory(identifier: categoryId, title: title, count: count, isVisible: isVisible)
let accessStatus = manager.getCategoryAccessStatus(categoryId)
return BMCCategory(identifier: categoryId,
title: title,
count: count,
isVisible: isVisible,
accessStatus: accessStatus)
}
}

View file

@ -4,18 +4,19 @@ protocol BMCCategoryCellDelegate {
}
final class BMCCategoryCell: MWMTableViewCell {
@IBOutlet private weak var accessImageView: UIImageView!
@IBOutlet private weak var visibility: UIButton!
@IBOutlet private weak var title: UILabel! {
@IBOutlet private weak var titleLabel: UILabel! {
didSet {
title.font = .regular16()
title.textColor = .blackPrimaryText()
titleLabel.font = .regular16()
titleLabel.textColor = .blackPrimaryText()
}
}
@IBOutlet private weak var count: UILabel! {
@IBOutlet private weak var subtitleLabel: UILabel! {
didSet {
count.font = .regular14()
count.textColor = .blackSecondaryText()
subtitleLabel.font = .regular14()
subtitleLabel.textColor = .blackSecondaryText()
}
}
@ -26,7 +27,7 @@ final class BMCCategoryCell: MWMTableViewCell {
}
}
private var category: BMCCategory! {
private var category: BMCCategory? {
willSet {
category?.removeObserver(self)
}
@ -36,7 +37,7 @@ final class BMCCategoryCell: MWMTableViewCell {
}
}
private var delegate: BMCCategoryCellDelegate!
private var delegate: BMCCategoryCellDelegate?
func config(category: BMCCategory, delegate: BMCCategoryCellDelegate) -> UITableViewCell {
self.category = category
@ -45,18 +46,40 @@ final class BMCCategoryCell: MWMTableViewCell {
}
@IBAction private func visibilityAction() {
delegate.visibilityAction(category: category)
guard let category = category else { return }
delegate?.visibilityAction(category: category)
}
@IBAction private func moreAction() {
delegate.moreAction(category: category, anchor: more)
guard let category = category else { return }
delegate?.moreAction(category: category, anchor: more)
}
}
extension BMCCategoryCell: BMCCategoryObserver {
func categoryUpdated() {
title.text = category.title
count.text = String(format: L("bookmarks_places"), category.count)
guard let category = category else { return }
titleLabel.text = category.title
let accessString: String
switch category.accessStatus {
case .local:
accessString = L("bookmarks_private_access")
accessImageView.image = UIImage(named: "ic_category_private")
case .public:
accessString = L("bookmarks_public_access")
accessImageView.image = UIImage(named: "ic_category_public")
case .private:
accessString = L("bookmarks_link_access")
accessImageView.image = UIImage(named: "ic_category_link")
case .other:
assert(false, "We don't expect category with .other status here")
accessImageView.image = nil
accessString = L("")
}
let placesString = String(format: L("bookmarks_places"), category.count)
subtitleLabel.text = "\(accessString)\(placesString)"
if category.isVisible {
visibility.tintColor = .linkBlue()

View file

@ -1,18 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<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="BMCCategoryCell" customModule="maps_me" customModuleProvider="target" propertyAccessControl="all">
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="KGk-i7-Jjw" customClass="BMCCategoryCell" customModule="maps_me" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="320" height="67"/>
<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">
@ -28,16 +28,16 @@
<action selector="visibilityAction" destination="KGk-i7-Jjw" eventType="touchUpInside" id="QeK-Un-BsO"/>
</connections>
</button>
<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="jut-eq-wia">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" verticalCompressionResistancePriority="751" text="My Places" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jut-eq-wia">
<rect key="frame" x="56" y="10" width="204" 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="jBd-Tj-RiW">
<rect key="frame" x="56" y="35" width="204" height="21.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public • 12 Bookmarks" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jBd-Tj-RiW">
<rect key="frame" x="71" y="35" width="189" height="21.5"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" white="0.0" alpha="0.5781785102739726" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2gi-fk-gR6">
@ -49,17 +49,26 @@
<action selector="moreAction" destination="KGk-i7-Jjw" eventType="touchUpInside" id="zmP-yn-CEM"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_category_public" translatesAutoresizingMaskIntoConstraints="NO" id="gJP-vc-RTA">
<rect key="frame" x="56" y="40" width="12" height="12"/>
<constraints>
<constraint firstAttribute="height" constant="12" id="1aT-fn-f8T"/>
<constraint firstAttribute="width" constant="12" id="vb2-sC-rLt"/>
</constraints>
</imageView>
</subviews>
<constraints>
<constraint firstItem="jBd-Tj-RiW" firstAttribute="leading" secondItem="gJP-vc-RTA" secondAttribute="trailing" constant="3" id="BBj-bB-xCt"/>
<constraint firstAttribute="trailing" secondItem="2gi-fk-gR6" secondAttribute="trailing" id="Ddb-qq-tEN"/>
<constraint firstAttribute="bottom" secondItem="Ci8-3V-BOL" secondAttribute="bottom" id="EEL-Or-h56"/>
<constraint firstAttribute="bottom" secondItem="jBd-Tj-RiW" secondAttribute="bottom" constant="10" id="ITj-Sq-UKz"/>
<constraint firstItem="jBd-Tj-RiW" firstAttribute="leading" secondItem="jut-eq-wia" secondAttribute="leading" id="TSL-ZU-baJ"/>
<constraint firstItem="jBd-Tj-RiW" firstAttribute="top" secondItem="jut-eq-wia" secondAttribute="bottom" constant="4" id="TT5-VN-D7j"/>
<constraint firstItem="Ci8-3V-BOL" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="UVe-rC-tFE"/>
<constraint firstItem="2gi-fk-gR6" firstAttribute="leading" secondItem="jut-eq-wia" secondAttribute="trailing" constant="4" id="Xx2-s7-Jt0"/>
<constraint firstItem="gJP-vc-RTA" firstAttribute="leading" secondItem="jut-eq-wia" secondAttribute="leading" id="Y5h-nV-1hQ"/>
<constraint firstItem="2gi-fk-gR6" firstAttribute="leading" secondItem="jBd-Tj-RiW" secondAttribute="trailing" constant="4" id="b4E-PQ-Lca"/>
<constraint firstItem="Ci8-3V-BOL" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="eGQ-WT-1u5"/>
<constraint firstItem="gJP-vc-RTA" firstAttribute="centerY" secondItem="jBd-Tj-RiW" secondAttribute="centerY" id="eff-V8-yEn"/>
<constraint firstAttribute="bottom" secondItem="2gi-fk-gR6" secondAttribute="bottom" id="maE-v3-UlZ"/>
<constraint firstItem="2gi-fk-gR6" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="nbD-ba-3tr"/>
<constraint firstItem="jut-eq-wia" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="10" id="omd-cs-RXb"/>
@ -68,11 +77,16 @@
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
<connections>
<outlet property="count" destination="jBd-Tj-RiW" id="tkS-p1-6gV"/>
<outlet property="accessImageView" destination="gJP-vc-RTA" id="LSs-ef-5cO"/>
<outlet property="more" destination="2gi-fk-gR6" id="t3r-XO-zDV"/>
<outlet property="title" destination="jut-eq-wia" id="clb-io-yVo"/>
<outlet property="subtitleLabel" destination="jBd-Tj-RiW" id="D3j-45-I9U"/>
<outlet property="titleLabel" destination="jut-eq-wia" id="pHy-5L-bhq"/>
<outlet property="visibility" destination="Ci8-3V-BOL" id="Om5-Ws-1au"/>
</connections>
<point key="canvasLocation" x="52.799999999999997" y="48.125937031484263"/>
</tableViewCell>
</objects>
<resources>
<image name="ic_category_public" width="10" height="10"/>
</resources>
</document>

View file

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_category_link.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ic_category_link@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ic_category_link@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_category_private.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ic_category_private@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ic_category_private@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 B

View file

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_category_public.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ic_category_public@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ic_category_public@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB