Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
signalapp
GitHub Repository: signalapp/Signal-iOS
Path: blob/main/Signal/Calls/UserInterface/Survey/CallQualitySurveyRatingViewController.swift
1 views
//
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//

import SignalServiceKit
import SignalUI

final class CallQualitySurveyRatingViewController: CallQualitySurveySheetViewController {
    private let stackView = UIStackView()

    override func viewDidLoad() {
        super.viewDidLoad()

        title = OWSLocalizedString(
            "CALL_QUALITY_SURVEY_RATING_TITLE",
            comment: "Title for the initial rating screen in the call quality survey",
        )

        view.addSubview(stackView)
        // Don't pin the bottom edge because we need to use this view to
        // calculate the height to pass to the sheet presentation controller
        // via customSheetHeight(context:)
        stackView.autoPinEdges(toSuperviewEdgesExcludingEdge: .bottom)
        stackView.isLayoutMarginsRelativeArrangement = true
        stackView.axis = .vertical
        stackView.spacing = 32

        let headerLabel = UILabel()
        headerLabel.text = OWSLocalizedString(
            "CALL_QUALITY_SURVEY_RATING_HEADER",
            comment: "Header text explaining the purpose of the call quality survey",
        )
        headerLabel.font = .dynamicTypeSubheadline
        headerLabel.textColor = .Signal.secondaryLabel
        headerLabel.numberOfLines = 0
        headerLabel.textAlignment = .center
        let header = UIView()
        header.addSubview(headerLabel)
        headerLabel.autoPinEdgesToSuperviewEdges(with: .init(hMargin: 32, vMargin: 0))
        stackView.addArrangedSubview(header)

        let thumbsDown = makeButton(
            image: .thumbsDown,
            tintColor: .Signal.red,
            label: OWSLocalizedString(
                "CALL_QUALITY_SURVEY_HAD_ISSUES_BUTTON",
                comment: "Button label for indicating the call had issues in the call quality survey",
            ),
        ) { [weak sheetNav] in
            sheetNav?.didTapHadIssues()
        }
        let thumbsUp = makeButton(
            image: .thumbsUp,
            tintColor: .Signal.ultramarine,
            label: OWSLocalizedString(
                "CALL_QUALITY_SURVEY_GREAT_BUTTON",
                comment: "Button label for indicating the call did not have issues in the call quality survey",
            ),
        ) { [weak sheetNav] in
            sheetNav?.doneSelectingIssues(rating: .satisfied)
        }

        // Zero-width spacer views with .equalSpacing distribution makes the
        // space between the buttons the same as that on the outer edges.
        let hStack = UIStackView(arrangedSubviews: [
            UIView(),
            thumbsDown,
            thumbsUp,
            UIView(),
        ])
        hStack.axis = .horizontal
        hStack.distribution = .equalSpacing
        hStack.alignment = .top

        stackView.addArrangedSubview(hStack)
    }

    private func makeButton(
        image: ImageResource,
        tintColor: UIColor,
        label text: String,
        action: @escaping () -> Void,
    ) -> UIView {
        var config = UIButton.Configuration.gray()
        config.cornerStyle = .capsule
        config.baseBackgroundColor = .Signal.secondaryGroupedBackground

        let button = UIButton(
            configuration: config,
            primaryAction: .init { _ in action() },
        )
        button.autoSetDimensions(to: .square(72))

        let imageView = UIImageView(image: UIImage(resource: image))
        button.addSubview(imageView)
        imageView.autoCenterInSuperview()
        imageView.autoSetDimensions(to: .square(36))
        imageView.contentMode = .scaleAspectFit
        imageView.tintColor = tintColor
        imageView.isUserInteractionEnabled = false

        let label = UILabel()
        label.text = text
        label.font = .dynamicTypeSubheadline
        label.textColor = .Signal.label
        label.numberOfLines = 2
        label.textAlignment = .center
        label.autoSetDimension(.width, toSize: 144)

        let stackView = UIStackView(arrangedSubviews: [button, label])
        stackView.axis = .vertical
        stackView.spacing = 12
        stackView.alignment = .center
        return stackView
    }

    @available(iOS 16.0, *)
    override func customSheetHeight() -> CGFloat? {
        stackView.bounds.height
    }
}