mirror of
https://codeberg.org/comaps/comaps
synced 2026-01-03 03:13:48 +00:00
Organic Maps sources as of 02.04.2025 (fad26bbf22ac3da75e01e62aa01e5c8e11861005)
To expand with full Organic Maps and Maps.ME commits history run: git remote add om-historic [om-historic.git repo url] git fetch --tags om-historic git replace squashed-history historic-commits
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
final class ButtonsStackView: UIView {
|
||||
|
||||
private let stackView = UIStackView()
|
||||
private var didTapHandlers = [UIButton: (() -> Void)?]()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setupViews()
|
||||
arrangeViews()
|
||||
layoutViews()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
setupViews()
|
||||
arrangeViews()
|
||||
layoutViews()
|
||||
}
|
||||
|
||||
private func setupViews() {
|
||||
stackView.distribution = .fillEqually
|
||||
stackView.axis = .vertical
|
||||
stackView.spacing = 20
|
||||
}
|
||||
|
||||
private func arrangeViews() {
|
||||
addSubview(stackView)
|
||||
}
|
||||
|
||||
private func layoutViews() {
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
let offset = CGFloat(20)
|
||||
NSLayoutConstraint.activate([
|
||||
stackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: offset),
|
||||
stackView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -offset),
|
||||
stackView.topAnchor.constraint(equalTo: topAnchor),
|
||||
stackView.bottomAnchor.constraint(equalTo: bottomAnchor)
|
||||
])
|
||||
}
|
||||
|
||||
@objc private func buttonTapped(_ sender: UIButton) {
|
||||
guard let didTapHandler = didTapHandlers[sender] else { return }
|
||||
didTapHandler?()
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
func addButton(title: String, font: UIFont = .regular14(), didTapHandler: @escaping () -> Void) {
|
||||
let button = UIButton()
|
||||
button.setStyleAndApply(.flatPrimaryTransButton)
|
||||
button.setTitle(title, for: .normal)
|
||||
button.titleLabel?.font = font
|
||||
button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
|
||||
stackView.addArrangedSubview(button)
|
||||
didTapHandlers[button] = didTapHandler
|
||||
}
|
||||
}
|
||||
67
iphone/Maps/UI/Help/AboutController/Views/DonationView.swift
Normal file
67
iphone/Maps/UI/Help/AboutController/Views/DonationView.swift
Normal file
@@ -0,0 +1,67 @@
|
||||
final class DonationView: UIView {
|
||||
|
||||
private let donateTextLabel = UILabel()
|
||||
private let donateButton = UIButton()
|
||||
|
||||
var donateButtonDidTapHandler: (() -> Void)?
|
||||
|
||||
init() {
|
||||
super.init(frame: .zero)
|
||||
setupViews()
|
||||
arrangeViews()
|
||||
layoutViews()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
setupViews()
|
||||
arrangeViews()
|
||||
layoutViews()
|
||||
}
|
||||
|
||||
private func setupViews() {
|
||||
donateTextLabel.setFontStyle(.regular14, color: .blackPrimary)
|
||||
donateTextLabel.text = L("donate_description")
|
||||
donateTextLabel.textAlignment = .center
|
||||
donateTextLabel.lineBreakMode = .byWordWrapping
|
||||
donateTextLabel.numberOfLines = 0
|
||||
|
||||
donateButton.setStyle(.flatNormalButton)
|
||||
donateButton.setTitle(L("donate").localizedUppercase, for: .normal)
|
||||
donateButton.addTarget(self, action: #selector(donateButtonDidTap), for: .touchUpInside)
|
||||
}
|
||||
|
||||
private func arrangeViews() {
|
||||
addSubview(donateTextLabel)
|
||||
addSubview(donateButton)
|
||||
}
|
||||
|
||||
private func layoutViews() {
|
||||
donateTextLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
donateButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
donateTextLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
donateTextLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
donateTextLabel.topAnchor.constraint(equalTo: topAnchor),
|
||||
|
||||
donateButton.topAnchor.constraint(equalTo: donateTextLabel.bottomAnchor, constant: 10),
|
||||
donateButton.widthAnchor.constraint(equalTo: widthAnchor, constant: -40).withPriority(.defaultHigh),
|
||||
donateButton.widthAnchor.constraint(lessThanOrEqualToConstant: 400).withPriority(.defaultHigh),
|
||||
donateButton.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
donateButton.heightAnchor.constraint(equalToConstant: 40),
|
||||
donateButton.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
])
|
||||
}
|
||||
|
||||
@objc private func donateButtonDidTap() {
|
||||
donateButtonDidTapHandler?()
|
||||
}
|
||||
}
|
||||
|
||||
private extension NSLayoutConstraint {
|
||||
func withPriority(_ priority: UILayoutPriority) -> NSLayoutConstraint {
|
||||
self.priority = priority
|
||||
return self
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
final class InfoTableViewCell: UITableViewCell {
|
||||
|
||||
private let infoView = InfoView()
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: .default, reuseIdentifier: reuseIdentifier)
|
||||
setupView()
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
setupView()
|
||||
}
|
||||
|
||||
private func setupView() {
|
||||
backgroundView = UIView() // Set background color to clear
|
||||
setStyle(.clearBackground)
|
||||
contentView.addSubview(infoView)
|
||||
infoView.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
infoView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
|
||||
infoView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
|
||||
infoView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
infoView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||
])
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
func set(image: UIImage?, title: String) {
|
||||
infoView.set(image: image, title: title)
|
||||
}
|
||||
}
|
||||
81
iphone/Maps/UI/Help/AboutController/Views/InfoView.swift
Normal file
81
iphone/Maps/UI/Help/AboutController/Views/InfoView.swift
Normal file
@@ -0,0 +1,81 @@
|
||||
final class InfoView: UIView {
|
||||
|
||||
private let stackView = UIStackView()
|
||||
private let imageView = UIImageView()
|
||||
private let titleLabel = UILabel()
|
||||
private lazy var imageViewWidthConstrain = imageView.widthAnchor.constraint(equalToConstant: 0)
|
||||
|
||||
init() {
|
||||
super.init(frame: .zero)
|
||||
self.setupView()
|
||||
self.arrangeViews()
|
||||
self.layoutViews()
|
||||
}
|
||||
|
||||
convenience init(image: UIImage?, title: String) {
|
||||
self.init()
|
||||
self.set(image: image, title: title)
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
if #available(iOS 13.0, *), traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
|
||||
imageView.applyTheme()
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
private func setupView() {
|
||||
stackView.axis = .horizontal
|
||||
stackView.distribution = .fill
|
||||
stackView.alignment = .center
|
||||
stackView.spacing = 16
|
||||
|
||||
titleLabel.setFontStyle(.regular16, color: .blackPrimary)
|
||||
titleLabel.lineBreakMode = .byWordWrapping
|
||||
titleLabel.numberOfLines = .zero
|
||||
|
||||
imageView.setStyle(.black)
|
||||
imageView.contentMode = .scaleAspectFit
|
||||
}
|
||||
|
||||
private func arrangeViews() {
|
||||
addSubview(stackView)
|
||||
stackView.addArrangedSubview(imageView)
|
||||
stackView.addArrangedSubview(titleLabel)
|
||||
}
|
||||
|
||||
private func layoutViews() {
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
titleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.setContentHuggingPriority(.defaultHigh, for: .vertical)
|
||||
imageView.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
||||
titleLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
||||
NSLayoutConstraint.activate([
|
||||
stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
stackView.topAnchor.constraint(equalTo: topAnchor),
|
||||
stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
imageView.heightAnchor.constraint(equalToConstant: 24),
|
||||
imageViewWidthConstrain
|
||||
])
|
||||
updateImageWidth()
|
||||
}
|
||||
|
||||
private func updateImageWidth() {
|
||||
imageViewWidthConstrain.constant = imageView.image == nil ? 0 : 24
|
||||
imageView.isHidden = imageView.image == nil
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
func set(image: UIImage?, title: String) {
|
||||
imageView.image = image
|
||||
titleLabel.text = title
|
||||
updateImageWidth()
|
||||
}
|
||||
}
|
||||
87
iphone/Maps/UI/Help/AboutController/Views/OSMView.swift
Normal file
87
iphone/Maps/UI/Help/AboutController/Views/OSMView.swift
Normal file
@@ -0,0 +1,87 @@
|
||||
final class OSMView: UIView {
|
||||
|
||||
private let OSMImageView = UIImageView()
|
||||
private let OSMTextLabel = UILabel()
|
||||
private var mapDate: String?
|
||||
|
||||
var didTapHandler: (() -> Void)?
|
||||
|
||||
init() {
|
||||
super.init(frame: .zero)
|
||||
setupViews()
|
||||
arrangeViews()
|
||||
layoutViews()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
setupViews()
|
||||
arrangeViews()
|
||||
layoutViews()
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
guard let mapDate, traitCollection.userInterfaceStyle != previousTraitCollection?.userInterfaceStyle else { return }
|
||||
OSMTextLabel.attributedText = attributedString(for: mapDate)
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
func setMapDate(_ mapDate: String) {
|
||||
self.mapDate = mapDate
|
||||
OSMTextLabel.attributedText = attributedString(for: mapDate)
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
private func setupViews() {
|
||||
OSMImageView.image = UIImage(named: "osm_logo")
|
||||
|
||||
OSMTextLabel.setFontStyle(.regular14, color: .blackPrimary)
|
||||
OSMTextLabel.lineBreakMode = .byWordWrapping
|
||||
OSMTextLabel.numberOfLines = 0
|
||||
OSMTextLabel.isUserInteractionEnabled = true
|
||||
|
||||
let osmDidTapGesture = UITapGestureRecognizer(target: self, action: #selector(osmDidTap))
|
||||
OSMTextLabel.addGestureRecognizer(osmDidTapGesture)
|
||||
}
|
||||
|
||||
private func arrangeViews() {
|
||||
addSubview(OSMImageView)
|
||||
addSubview(OSMTextLabel)
|
||||
}
|
||||
|
||||
private func layoutViews() {
|
||||
OSMImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
OSMTextLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
OSMImageView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
OSMImageView.heightAnchor.constraint(equalToConstant: 40),
|
||||
OSMImageView.widthAnchor.constraint(equalTo: OSMImageView.heightAnchor),
|
||||
OSMImageView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor),
|
||||
OSMImageView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor),
|
||||
|
||||
OSMTextLabel.leadingAnchor.constraint(equalTo: OSMImageView.trailingAnchor, constant: 8),
|
||||
OSMTextLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
OSMTextLabel.topAnchor.constraint(greaterThanOrEqualTo: topAnchor),
|
||||
OSMTextLabel.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor),
|
||||
OSMTextLabel.centerYAnchor.constraint(equalTo: OSMImageView.centerYAnchor)
|
||||
])
|
||||
}
|
||||
|
||||
@objc private func osmDidTap() {
|
||||
didTapHandler?()
|
||||
}
|
||||
|
||||
private func attributedString(for date: String) -> NSAttributedString {
|
||||
let osmLink = "OpenStreetMap.org"
|
||||
let attributedString = NSMutableAttributedString(string: String(format: L("osm_presentation"), date.trimmingCharacters(in: .punctuationCharacters)),
|
||||
attributes: [.font: UIFont.regular14(),
|
||||
.foregroundColor: StyleManager.shared.theme!.colors.blackPrimaryText]
|
||||
)
|
||||
let linkRange = attributedString.mutableString.range(of: osmLink)
|
||||
attributedString.addAttribute(.link, value: "https://www.openstreetmap.org/", range: linkRange)
|
||||
|
||||
return attributedString
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
final class SocialMediaCollectionViewCell: UICollectionViewCell {
|
||||
|
||||
private let imageView = UIImageView()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setupView()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
setupView()
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
guard traitCollection.userInterfaceStyle != previousTraitCollection?.userInterfaceStyle else { return }
|
||||
updateImageColor()
|
||||
}
|
||||
|
||||
private func setupView() {
|
||||
setStyle(.clearBackground)
|
||||
|
||||
imageView.contentMode = .scaleAspectFit
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
contentView.addSubview(imageView)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
imageView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
||||
imageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
|
||||
imageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
|
||||
imageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
|
||||
])
|
||||
}
|
||||
|
||||
private func updateImageColor() {
|
||||
imageView.tintColor = StyleManager.shared.theme?.colors.blackPrimaryText
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
func setImage(_ image: UIImage) {
|
||||
imageView.image = image
|
||||
updateImageColor()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
final class SocialMediaCollectionViewHeader: UICollectionReusableView {
|
||||
|
||||
static let reuseIdentifier = String(describing: SocialMediaCollectionViewHeader.self)
|
||||
|
||||
private let titleLabel = UILabel()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setupView()
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
private func setupView() {
|
||||
addSubview(titleLabel)
|
||||
titleLabel.setFontStyleAndApply(.regular16, color: .blackPrimary)
|
||||
titleLabel.numberOfLines = 1
|
||||
titleLabel.allowsDefaultTighteningForTruncation = true
|
||||
titleLabel.adjustsFontSizeToFitWidth = true
|
||||
titleLabel.minimumScaleFactor = 0.5
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
func setTitle(_ title: String) {
|
||||
titleLabel.text = title
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user