Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:58:55 +01:00
parent 4af19165ec
commit 68073add76
12458 changed files with 12350765 additions and 2 deletions

View file

@ -0,0 +1,40 @@
final class BookmarksListCell: UITableViewCell {
private static let extendedImageViewTappableMargin: CGFloat = -15
private var trackColorDidTapAction: (() -> Void)?
override func awakeFromNib() {
super.awakeFromNib()
setupCell()
}
private func setupCell() {
accessoryType = .detailButton
if let imageView {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(colorDidTapAction(_:)))
imageView.addGestureRecognizer(tapGesture)
imageView.isUserInteractionEnabled = true
}
}
func config(_ bookmark: IBookmarksListItemViewModel) {
imageView?.image = bookmark.image
textLabel?.text = bookmark.name
detailTextLabel?.text = bookmark.subtitle
trackColorDidTapAction = bookmark.colorDidTapAction
}
@objc private func colorDidTapAction(_ sender: UITapGestureRecognizer) {
trackColorDidTapAction?()
}
// Extends the imageView tappable area.
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if let imageView, imageView.convert(imageView.bounds, to: self).insetBy(dx: Self.extendedImageViewTappableMargin, dy: Self.extendedImageViewTappableMargin).contains(point) {
return imageView
} else {
return super.hitTest(point, with: event)
}
}
}

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/>
<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" textLabel="QgU-jK-sWK" detailTextLabel="zC9-YD-CfS" rowHeight="64" style="IBUITableViewCellStyleSubtitle" id="KGk-i7-Jjw" customClass="BookmarksListCell" customModule="CoMaps" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="320" height="64"/>
<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="64"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="QgU-jK-sWK">
<rect key="frame" x="16" y="16" width="25" height="14.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="0.0"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular16:blackPrimaryText"/>
</userDefinedRuntimeAttributes>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Subtitle" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="zC9-YD-CfS">
<rect key="frame" x="16" y="32.5" width="44" height="14.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="0.0"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular14:blackSecondaryText"/>
</userDefinedRuntimeAttributes>
</label>
</subviews>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
<point key="canvasLocation" x="137.68115942028987" y="104.12946428571428"/>
</tableViewCell>
</objects>
</document>

View file

@ -0,0 +1,58 @@
final class BookmarksListCellStrategy {
private enum CellId {
static let listItem = "BookmarksListCell"
static let subgroup = "SubgroupCell"
static let sectionHeader = "SectionHeader"
}
typealias CheckHandlerClosure = (IBookmarksListSectionViewModel, Int, Bool) -> Void
var cellCheckHandler: CheckHandlerClosure?
typealias VisibilityHandlerClosure = (IBookmarksListSectionViewModel) -> Void
var cellVisibilityHandler: VisibilityHandlerClosure?
func registerCells(_ tableView: UITableView) {
tableView.register(UINib(nibName: "BookmarksListCell", bundle: nil), forCellReuseIdentifier: CellId.listItem)
tableView.register(UINib(nibName: "SubgroupCell", bundle: nil), forCellReuseIdentifier: CellId.subgroup)
tableView.register(UINib(nibName: "BookmarksListSectionHeader", bundle: nil),
forHeaderFooterViewReuseIdentifier: CellId.sectionHeader)
}
func tableCell(_ tableView: UITableView,
for viewModel: IBookmarksListSectionViewModel,
at indexPath: IndexPath) -> UITableViewCell {
switch viewModel {
case let bookmarksSection as IBookmarksSectionViewModel:
let bookmark = bookmarksSection.bookmarks[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: CellId.listItem, for: indexPath) as! BookmarksListCell
cell.config(bookmark)
return cell
case let tracksSection as ITracksSectionViewModel:
let track = tracksSection.tracks[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: CellId.listItem, for: indexPath) as! BookmarksListCell
cell.config(track)
return cell
case let subgroupsSection as ISubgroupsSectionViewModel:
let subgroup = subgroupsSection.subgroups[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: CellId.subgroup, for: indexPath) as! SubgroupCell
cell.config(subgroup)
cell.checkHandler = { [weak self] checked in
self?.cellCheckHandler?(viewModel, indexPath.row, checked)
}
return cell
default:
fatalError("Unexpected item")
}
}
func headerView(_ tableView: UITableView,
for viewModel: IBookmarksListSectionViewModel) -> UITableViewHeaderFooterView {
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: CellId.sectionHeader)
as! BookmarksListSectionHeader
headerView.config(viewModel)
headerView.visibilityHandler = { [weak self] in
self?.cellVisibilityHandler?(viewModel)
}
return headerView
}
}

View file

@ -0,0 +1,25 @@
final class BookmarksListSectionHeader: UITableViewHeaderFooterView {
@IBOutlet private var titleLabel: UILabel!
@IBOutlet private var visibilityButton: UIButton!
typealias VisibilityHandlerClosure = () -> Void
var visibilityHandler: VisibilityHandlerClosure?
@IBAction private func onVisibilityButton(_ sender: UIButton) {
visibilityHandler?()
}
func config(_ section: IBookmarksListSectionViewModel) {
titleLabel.text = section.sectionTitle
switch section.visibilityButtonState {
case .hidden:
visibilityButton.isHidden = true
case .hideAll:
visibilityButton.isHidden = false
visibilityButton.setTitle(L("bookmark_lists_hide_all"), for: .normal)
case .showAll:
visibilityButton.isHidden = false
visibilityButton.setTitle(L("bookmark_lists_show_all"), for: .normal)
}
}
}

View file

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17125"/>
<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"/>
<view contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="iN0-l3-epB" customClass="BookmarksListSectionHeader" customModule="CoMaps" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="375" height="60"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xCm-Dh-8mT">
<rect key="frame" x="16" y="12" width="343" height="48"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="Bookmarks" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yNv-Yr-Hkr">
<rect key="frame" x="0.0" y="0.0" width="287" height="48"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="20"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="bold20:blackPrimaryText"/>
</userDefinedRuntimeAttributes>
</label>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" horizontalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zdf-Q0-3xO">
<rect key="frame" x="287" y="0.0" width="56" height="48"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<state key="normal" title="Hide All"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="linkBlueText"/>
</userDefinedRuntimeAttributes>
<connections>
<action selector="onVisibilityButton:" destination="iN0-l3-epB" eventType="touchUpInside" id="w2u-1a-M9u"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="xCm-Dh-8mT" secondAttribute="bottom" id="3MG-Ep-gMo"/>
<constraint firstItem="xCm-Dh-8mT" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="16" id="9XD-d8-7vk"/>
<constraint firstAttribute="trailing" secondItem="xCm-Dh-8mT" secondAttribute="trailing" constant="16" id="OGF-TS-kyi"/>
<constraint firstItem="xCm-Dh-8mT" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="12" id="OLp-AI-xo9"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outlet property="titleLabel" destination="yNv-Yr-Hkr" id="2D1-wr-wFj"/>
<outlet property="visibilityButton" destination="zdf-Q0-3xO" id="Z64-hc-gnc"/>
</connections>
<point key="canvasLocation" x="138.40000000000001" y="201.94902548725639"/>
</view>
</objects>
</document>

View file

@ -0,0 +1,18 @@
final class SubgroupCell: UITableViewCell {
@IBOutlet private var subgroupTitleLabel: UILabel!
@IBOutlet private var subgroupSubtitleLabel: UILabel!
@IBOutlet private var subgroupVisibleMark: Checkmark!
typealias CheckHandlerClosure = (Bool) -> Void
var checkHandler: CheckHandlerClosure?
func config(_ subgroup: ISubgroupViewModel) {
subgroupTitleLabel.text = subgroup.subgroupName
subgroupSubtitleLabel.text = subgroup.subtitle
subgroupVisibleMark.isChecked = subgroup.isVisible
}
@IBAction private func onCheck(_ sender: Checkmark) {
checkHandler?(sender.isChecked)
}
}

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17125"/>
<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" rowHeight="64" id="KGk-i7-Jjw" customClass="SubgroupCell" customModule="CoMaps" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="320" height="64"/>
<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="64"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" horizontalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="mAZ-hb-J9T" customClass="Checkmark" customModule="CoMaps" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="56" height="64"/>
<constraints>
<constraint firstAttribute="width" constant="56" id="aar-GM-DaJ"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="image" keyPath="offImage" value="ic_eye_off"/>
<userDefinedRuntimeAttribute type="image" keyPath="onImage" value="ic_eye_on"/>
</userDefinedRuntimeAttributes>
<connections>
<action selector="onCheck:" destination="KGk-i7-Jjw" eventType="valueChanged" id="xp2-kL-Hgu"/>
</connections>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="L2V-JY-eeP">
<rect key="frame" x="56" y="11" width="224" height="20"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular16:blackPrimaryText"/>
</userDefinedRuntimeAttributes>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mcK-1H-ZBS">
<rect key="frame" x="56" y="35" width="224" height="16.5"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="regular14:blackSecondaryText"/>
</userDefinedRuntimeAttributes>
</label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_disclosure" translatesAutoresizingMaskIntoConstraints="NO" id="UOn-k5-sEA">
<rect key="frame" x="288" y="20" width="24" height="24"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="styleName" value="MWMGray"/>
</userDefinedRuntimeAttributes>
</imageView>
</subviews>
<constraints>
<constraint firstItem="L2V-JY-eeP" firstAttribute="leading" secondItem="mAZ-hb-J9T" secondAttribute="trailing" id="3fE-vM-7lQ"/>
<constraint firstAttribute="bottom" secondItem="mcK-1H-ZBS" secondAttribute="bottom" constant="12.5" id="Ca4-dk-CyT"/>
<constraint firstAttribute="bottom" secondItem="mAZ-hb-J9T" secondAttribute="bottom" id="EEL-tz-cXw"/>
<constraint firstItem="UOn-k5-sEA" firstAttribute="leading" secondItem="mcK-1H-ZBS" secondAttribute="trailing" constant="8" id="GMX-F4-EWk"/>
<constraint firstAttribute="trailing" secondItem="UOn-k5-sEA" secondAttribute="trailing" constant="8" id="Pdg-cN-1Py"/>
<constraint firstItem="mAZ-hb-J9T" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="SzN-rJ-pMf"/>
<constraint firstItem="L2V-JY-eeP" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="11" id="ayo-1v-WC2"/>
<constraint firstItem="mcK-1H-ZBS" firstAttribute="leading" secondItem="mAZ-hb-J9T" secondAttribute="trailing" id="bsr-4x-bfr"/>
<constraint firstItem="mAZ-hb-J9T" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="gws-UG-2oB"/>
<constraint firstItem="UOn-k5-sEA" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="hTX-sY-kSJ"/>
<constraint firstItem="UOn-k5-sEA" firstAttribute="leading" secondItem="L2V-JY-eeP" secondAttribute="trailing" constant="8" id="pua-Zn-zVM"/>
<constraint firstItem="mcK-1H-ZBS" firstAttribute="top" secondItem="L2V-JY-eeP" secondAttribute="bottom" constant="4" id="ycS-hQ-Y91"/>
</constraints>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
<connections>
<outlet property="subgroupSubtitleLabel" destination="mcK-1H-ZBS" id="x96-KI-R0D"/>
<outlet property="subgroupTitleLabel" destination="L2V-JY-eeP" id="ZUX-Yy-zHY"/>
<outlet property="subgroupVisibleMark" destination="mAZ-hb-J9T" id="zrV-cz-C1i"/>
</connections>
<point key="canvasLocation" x="127.53623188405798" y="60.267857142857139"/>
</tableViewCell>
</objects>
<resources>
<image name="ic_disclosure" width="24" height="24"/>
<image name="ic_eye_off" width="24" height="24"/>
<image name="ic_eye_on" width="24" height="24"/>
</resources>
</document>