| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- // Copyright 2023 Google LLC
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- import UIKit
- class FeedbackViewController: UIViewController, UITextViewDelegate {
- // TODO: Consider the situations where this instance is initiated once, and used
- // multiple times.
- var viewDidDisappearCallback: () -> Void = {}
- // (TODO) Can we make feedbackName and additionalFormText non-null?
- var releaseName: String?
- var additionalFormText: String?
- var image: UIImage?
- @IBOutlet var screenshotUIImageView: UIImageView!
- @IBOutlet var additionalFormTextLabel: UILabel!
- @IBOutlet var feedbackTextView: UITextView!
- @IBOutlet var navigationBar: UINavigationBar!
- @IBOutlet var scrollView: UIScrollView!
- // MARK: - UIViewController
- override func viewDidLoad() {
- super.viewDidLoad()
- // Do any additional setup after loading the view.
- feedbackTextView.isScrollEnabled = false
- setScrollViewConstraints()
- setAdditionalFormTextConstraints()
- setFeedbackInputConstraints()
- setScreenshotImageConstrains()
- let additionalFormText = additionalFormText
- if additionalFormText != nil {
- additionalFormTextLabel.text = additionalFormText
- }
- feedbackTextView.delegate = self
- resetFeedbackTextViewWithPlaceholderText()
- if let image = image {
- screenshotUIImageView.image = image
- self.image = nil
- }
- }
- override func viewDidDisappear(_ animated: Bool) {
- viewDidDisappearCallback()
- }
- // MARK: - Actions
- @IBAction func tappedSend(_ sender: Any) {
- guard let releaseName = releaseName else {
- // TODO(tundeagboola) throw error or
- return
- }
- ApiService
- .createFeedback(releaseName: releaseName,
- feedbackText: feedbackTextView.text) { feedbackName, error in
- if error != nil {
- // TODO(tundeaboola) handle error if create feedback fails
- return
- }
- guard let feedbackName = feedbackName else {
- // TODO(tundeaboola) handle error if create feedback fails
- return
- }
- guard let image = self.screenshotUIImageView.image else {
- return self.commitFeedback(feedbackName: feedbackName)
- }
- ApiService.uploadImage(feedbackName: feedbackName, image: image) { error in
- if error != nil {
- // TODO(tundeaboola) handle error if upload image fails
- return
- }
- self.commitFeedback(feedbackName: feedbackName)
- }
- }
- }
- @IBAction func tappedCancel(_ sender: Any) {
- dismiss(animated: true)
- }
- // MARK: - Utilties
- private func commitFeedback(feedbackName: String) {
- ApiService.commitFeedback(feedbackName: feedbackName) { error in
- if error != nil {
- // TODO(tundeaboola) handle error if commit feedback fails
- }
- self.feedbackSubmitted()
- }
- }
- func feedbackSubmitted() {
- // TODO(tundeagboola) show success toast
- dismiss(animated: true)
- }
- // MARK: - UI Constraints
- func setScrollViewConstraints() {
- scrollView.translatesAutoresizingMaskIntoConstraints = false
- scrollView.alwaysBounceVertical = true
- let bottomConstraint = NSLayoutConstraint(
- item: scrollView!,
- attribute: .bottom,
- relatedBy: .equal,
- toItem: view,
- attribute: .bottom,
- multiplier: 1,
- constant: 0
- )
- let leftConstraint = NSLayoutConstraint(
- item: scrollView!,
- attribute: .left,
- relatedBy: .equal,
- toItem: navigationBar,
- attribute: .left,
- multiplier: 1,
- constant: 0
- )
- let rightConstraint = NSLayoutConstraint(
- item: scrollView!,
- attribute: .right,
- relatedBy: .equal,
- toItem: navigationBar,
- attribute: .right,
- multiplier: 1,
- constant: 0
- )
- view.addConstraints([bottomConstraint, leftConstraint, rightConstraint])
- }
- func setAdditionalFormTextConstraints() {
- additionalFormTextLabel.translatesAutoresizingMaskIntoConstraints = false
- additionalFormTextLabel.numberOfLines = 0
- let topConstraint = NSLayoutConstraint(
- item: additionalFormTextLabel!,
- attribute: .top,
- relatedBy: .equal,
- toItem: scrollView,
- attribute: .top,
- multiplier: 1,
- constant: 0
- )
- let bottomConstraint = NSLayoutConstraint(
- item: additionalFormTextLabel!,
- attribute: .bottom,
- relatedBy: .greaterThanOrEqual,
- toItem: scrollView,
- attribute: .top,
- multiplier: 1,
- constant: 40
- )
- let leftConstraint = NSLayoutConstraint(
- item: additionalFormTextLabel!,
- attribute: .left,
- relatedBy: .equal,
- toItem: scrollView,
- attribute: .left,
- multiplier: 1,
- constant: 0
- )
- let rightConstraint = NSLayoutConstraint(
- item: additionalFormTextLabel!,
- attribute: .right,
- relatedBy: .equal,
- toItem: scrollView,
- attribute: .right,
- multiplier: 1,
- constant: 0
- )
- scrollView.addConstraints([topConstraint, bottomConstraint, leftConstraint, rightConstraint])
- let widthConstraint = NSLayoutConstraint(
- item: additionalFormTextLabel!,
- attribute: .width,
- relatedBy: .equal,
- toItem: navigationBar,
- attribute: .width,
- multiplier: 1,
- constant: 0
- )
- view
- .addConstraints([topConstraint, bottomConstraint, leftConstraint, rightConstraint,
- widthConstraint])
- // TODO: Better color
- additionalFormTextLabel.backgroundColor = .lightGray
- }
- func setFeedbackInputConstraints() {
- feedbackTextView.translatesAutoresizingMaskIntoConstraints = false
- let topConstraint = NSLayoutConstraint(
- item: feedbackTextView!,
- attribute: .top,
- relatedBy: .equal,
- toItem: additionalFormTextLabel,
- attribute: .bottom,
- multiplier: 1,
- constant: 0
- )
- let bottomConstraint = NSLayoutConstraint(
- item: feedbackTextView!,
- attribute: .bottom,
- relatedBy: .greaterThanOrEqual,
- toItem: additionalFormTextLabel,
- attribute: .top,
- multiplier: 1,
- constant: 100
- )
- let leftConstraint = NSLayoutConstraint(
- item: feedbackTextView!,
- attribute: .left,
- relatedBy: .equal,
- toItem: scrollView,
- attribute: .left,
- multiplier: 1,
- constant: 0
- )
- let rightConstraint = NSLayoutConstraint(
- item: feedbackTextView!,
- attribute: .right,
- relatedBy: .equal,
- toItem: scrollView,
- attribute: .right,
- multiplier: 1,
- constant: 0
- )
- let widthConstraint = NSLayoutConstraint(
- item: feedbackTextView!,
- attribute: .width,
- relatedBy: .equal,
- toItem: navigationBar,
- attribute: .width,
- multiplier: 1,
- constant: 0
- )
- view
- .addConstraints([topConstraint, bottomConstraint, leftConstraint, rightConstraint,
- widthConstraint])
- feedbackTextView.textContainerInset = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
- }
- func setScreenshotImageConstrains() {
- screenshotUIImageView.translatesAutoresizingMaskIntoConstraints = false
- let topConstraint = NSLayoutConstraint(
- item: screenshotUIImageView!,
- attribute: .top,
- relatedBy: .equal,
- toItem: feedbackTextView,
- attribute: .bottom,
- multiplier: 1,
- constant: 0
- )
- let bottomConstraint = NSLayoutConstraint(
- item: screenshotUIImageView!,
- attribute: .bottom,
- relatedBy: .greaterThanOrEqual,
- toItem: scrollView,
- attribute: .bottom,
- multiplier: 1,
- constant: 10
- )
- let leftConstraint = NSLayoutConstraint(
- item: screenshotUIImageView!,
- attribute: .left,
- relatedBy: .equal,
- toItem: scrollView,
- attribute: .left,
- multiplier: 1,
- constant: 0
- )
- let rightConstraint = NSLayoutConstraint(
- item: screenshotUIImageView!,
- attribute: .right,
- relatedBy: .equal,
- toItem: scrollView,
- attribute: .right,
- multiplier: 1,
- constant: 0
- )
- let widthConstraint = NSLayoutConstraint(
- item: screenshotUIImageView!,
- attribute: .width,
- relatedBy: .equal,
- toItem: feedbackTextView,
- attribute: .width,
- multiplier: 1,
- constant: 0
- )
- scrollView
- .addConstraints([topConstraint, bottomConstraint, leftConstraint, rightConstraint,
- widthConstraint])
- }
- // MARK: - UITextViewDelegate
- func textViewDidBeginEditing(_ textView: UITextView) {
- textView.text = nil
- textView.textColor = .black
- }
- func textViewDidEndEditing(_ textView: UITextView) {
- if textView.text.isEmpty {
- resetFeedbackTextViewWithPlaceholderText()
- }
- }
- func resetFeedbackTextViewWithPlaceholderText() {
- feedbackTextView.text = "Do you have any feedback?"
- feedbackTextView.textColor = .lightGray
- }
- }
|