Files
comaps/iphone/Maps/UI/LocationSharing/LocationSharingViewController.swift
2025-10-20 04:32:30 -07:00

226 lines
8.6 KiB
Swift

import UIKit
/// View controller for managing live location sharing
@objc class LocationSharingViewController: UIViewController {
private let service = LocationSharingService.shared
// UI Components
private let scrollView = UIScrollView()
private let contentView = UIView()
private let statusLabel = UILabel()
private let descriptionLabel = UILabel()
private let urlTextView = UITextView()
private let startStopButton = UIButton(type: .system)
private let copyButton = UIButton(type: .system)
private let shareButton = UIButton(type: .system)
override func viewDidLoad() {
super.viewDidLoad()
title = NSLocalizedString("location_sharing_title", comment: "")
view.backgroundColor = .systemBackground
setupUI()
updateUI()
}
// MARK: - UI Setup
private func setupUI() {
// Setup scroll view
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
contentView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(contentView)
// Status label
statusLabel.font = .systemFont(ofSize: 16, weight: .medium)
statusLabel.textColor = .label
statusLabel.numberOfLines = 0
statusLabel.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(statusLabel)
// Description label
descriptionLabel.font = .systemFont(ofSize: 14)
descriptionLabel.textColor = .secondaryLabel
descriptionLabel.numberOfLines = 0
descriptionLabel.text = NSLocalizedString("location_sharing_description", comment: "")
descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(descriptionLabel)
// URL text view
urlTextView.font = .monospacedSystemFont(ofSize: 12, weight: .regular)
urlTextView.textColor = .label
urlTextView.backgroundColor = .secondarySystemBackground
urlTextView.layer.cornerRadius = 8
urlTextView.isEditable = false
urlTextView.isScrollEnabled = false
urlTextView.textContainerInset = UIEdgeInsets(top: 12, left: 12, bottom: 12, right: 12)
urlTextView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(urlTextView)
// Buttons
setupButtons()
// Constraints
setupConstraints()
}
private func setupButtons() {
// Start/Stop button
startStopButton.titleLabel?.font = .systemFont(ofSize: 17, weight: .semibold)
startStopButton.addTarget(self, action: #selector(startStopTapped), for: .touchUpInside)
startStopButton.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(startStopButton)
// Copy button
copyButton.setTitle(NSLocalizedString("location_sharing_copy_url", comment: ""), for: .normal)
copyButton.addTarget(self, action: #selector(copyTapped), for: .touchUpInside)
copyButton.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(copyButton)
// Share button
shareButton.setTitle(NSLocalizedString("location_sharing_share_url", comment: ""), for: .normal)
shareButton.addTarget(self, action: #selector(shareTapped), for: .touchUpInside)
shareButton.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(shareButton)
}
private func setupConstraints() {
NSLayoutConstraint.activate([
// Scroll view
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
// Content view
contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
// Status label
statusLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16),
statusLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
statusLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
// Description label
descriptionLabel.topAnchor.constraint(equalTo: statusLabel.bottomAnchor, constant: 8),
descriptionLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
descriptionLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
// URL text view
urlTextView.topAnchor.constraint(equalTo: descriptionLabel.bottomAnchor, constant: 16),
urlTextView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
urlTextView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
// Start/Stop button
startStopButton.topAnchor.constraint(equalTo: urlTextView.bottomAnchor, constant: 24),
startStopButton.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
startStopButton.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
startStopButton.heightAnchor.constraint(equalToConstant: 50),
// Copy button
copyButton.topAnchor.constraint(equalTo: startStopButton.bottomAnchor, constant: 12),
copyButton.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
copyButton.heightAnchor.constraint(equalToConstant: 44),
// Share button
shareButton.topAnchor.constraint(equalTo: startStopButton.bottomAnchor, constant: 12),
shareButton.leadingAnchor.constraint(equalTo: copyButton.trailingAnchor, constant: 12),
shareButton.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
shareButton.widthAnchor.constraint(equalTo: copyButton.widthAnchor),
shareButton.heightAnchor.constraint(equalToConstant: 44),
shareButton.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -16),
])
}
// MARK: - Update UI
private func updateUI() {
let isSharing = service.isSharing
// Update status
statusLabel.text = isSharing
? NSLocalizedString("location_sharing_status_active", comment: "")
: NSLocalizedString("location_sharing_status_inactive", comment: "")
// Update URL
if let shareUrl = service.shareUrl, isSharing {
urlTextView.text = shareUrl
urlTextView.isHidden = false
} else {
urlTextView.isHidden = true
}
// Update buttons
let startStopTitle = isSharing
? NSLocalizedString("location_sharing_stop", comment: "")
: NSLocalizedString("location_sharing_start", comment: "")
startStopButton.setTitle(startStopTitle, for: .normal)
startStopButton.backgroundColor = isSharing ? .systemRed : .systemBlue
startStopButton.setTitleColor(.white, for: .normal)
startStopButton.layer.cornerRadius = 8
copyButton.isHidden = !isSharing
shareButton.isHidden = !isSharing
}
// MARK: - Actions
@objc private func startStopTapped() {
if service.isSharing {
stopSharing()
} else {
startSharing()
}
}
private func startSharing() {
guard let shareUrl = service.startSharing() else {
showAlert(message: NSLocalizedString("location_sharing_failed_to_start", comment: ""))
return
}
// Auto-copy URL to clipboard
UIPasteboard.general.string = shareUrl
showAlert(message: NSLocalizedString("location_sharing_started", comment: ""))
updateUI()
}
private func stopSharing() {
service.stopSharing()
showAlert(message: NSLocalizedString("location_sharing_stopped", comment: ""))
updateUI()
}
@objc private func copyTapped() {
guard let shareUrl = service.shareUrl else { return }
UIPasteboard.general.string = shareUrl
showAlert(message: NSLocalizedString("location_sharing_url_copied", comment: ""))
}
@objc private func shareTapped() {
guard let shareUrl = service.shareUrl else { return }
let message = String(format: NSLocalizedString("location_sharing_share_message", comment: ""), shareUrl)
let activityVC = UIActivityViewController(activityItems: [message], applicationActivities: nil)
activityVC.popoverPresentationController?.sourceView = shareButton
present(activityVC, animated: true)
}
// MARK: - Helpers
private func showAlert(message: String) {
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("close", comment: ""), style: .default))
present(alert, animated: true)
}
}