Skip to content

Conversation

@caitlynjin
Copy link
Contributor

@caitlynjin caitlynjin commented Nov 26, 2023

Overview

Implemented settings and blocked users pages. Updated profile page according to new design. Created custom classes for settings' cells and pop up views. Adjusted some views and other minor changes.

Changes Made

Settings Cell View

  • Created custom SettingsCellView, which contains the setting name label and icon. Created for the settings page.

Settings Page

  • Created SettingsViewController, which contains SettingCellViews for blocked users, reporting a problem, and signing out.
  • Each cell has a UITapGestureRecognizer attached to it, which performs their respective actions when tapping on the cell.
    • Tapping "Blocked users" pushes an instance of the BlockedUsersViewController.
    • Tapping "Report a problem" contains a temporary TODO; needs to be implemented.
    • Tapping "Sign out" takes the user back to the login screen by pushing an instance of the LoginViewController.

Pop Up View Controller

  • Created custom PopUpViewController to be used to initialize and display a pop up, which contains a title, subtitle, cancel button, and action button, on top of a blurred background.
  • Used a UIStackView to display these elements so that the spacing is correct with or without a subtitle.
  • Created the PopUpViewDelegate, so that any view can conform to the protocol and implement the action for when the "confirm/action" button of the pop up is clicked.

Empty State View

  • Removed the main UIView and replaced with a UIStackView.
  • Created a if statement in the setup function to make setting up a title conditional on having a title.
    • This change allows the spacing to be correct even when it is initialized with a blank title (parts of design only display the small text in the empty state).

Blocked Users Page

  • Created BlockedUsersTableViewCell, which contains the blocked user's profile image, name, and an unblock/block button.
  • Clicking the unblock button will display a pop up view using delegation to BlockedUserViewController, which asks the user to confirm unblocking.
    • If confirmed, the unblock button will change to the block state and updates the blocked users. Otherwise, the pop up view is dismissed.
  • Created BlockedUsersViewController, which displays a list of all the users blocked using a table view. When there are no blocked users, an empty state is displayed instead.
  • Temporarily, a blocked users dummy data array is used to test the functionality. Created TODOs to replace hard-coded data with network calls to fetch blocked users, block a user, and unblock a user.
    • blockedUsersDummyData is stored in the Users.swift file as an extension to the BaseUser class. This should be removed after implementing networking.

Profile Page

  • Changed header image to updated image and created gradient to fade into the background of the whole view.
  • Set navigation controller property in viewWillAppear and viewWillDisappear, so that the buttons near the top of the screen are interactable.
  • Removed actions and edit profile buttons from the containerView and added them to the view. Updated images and constraints to align with design.
  • Created settings button that pushes an instance of the SettingsViewController when tapped. This button is only displayed when the user is viewing their own profile.
  • Removed snack, song, and stop images from the Roadtrip Favorites section. Changed from ImageLabelViews to UILabels. Adjusted spacing and other code to adopt the change.

Edit Profile Page

  • Adjusted gradient for the background of the view in EditProfileViewController.
  • When the delete account button is clicked, a pop up view is displayed.
    • If confirmed, a delete user network request is made and an instance of the LoginViewController is pushed. Otherwise, the pop up view is dismissed.
  • Fixed uploading profile image. After clicking the save button, the profile image url is now included in the updateAuthenticatedUserRequest. Corrected prof_pic argument in the updateAuthenticatedUser and deleteUser network request.

Other Changes

  • Created getBlockedUsers network call that returns an array of the currently blocked users.
  • Fixed the slider thumb, slider track, and slider tick images in PreferencesViewController and EditProfileViewController.
  • Removed User class from User.swift due to being unused code.
  • Modified gradients in Extension+UIImage.swift.
  • Added fonts and colors in Extension+UIFont.swift and Extension+UIColor.swift.

Test Coverage

  • Manually tested the button actions and updated blocked users list on BlockedUserViewController for when a user is unblocked, unblocked then blocked again, leaving the page and returning back to the page, no users are blocked, etc.
  • Manually tested pop up views to ensure that pressing the cancel button only dismisses the pop up and pressing the action/confirm button does the corresponding action.
  • Tested upload profile image in EditProfileViewController to ensure profile image is being saved for my user.

Next Steps

  • Implement blocking and unblocking user network requests and replace temporary code in the appropriate places.
  • Update allBlockedUsers network request if necessary once the backend issue is resolved.
  • Push the "Report a problem" view controller in SettingsViewController once implemented.

Screenshots

Before: Profile Page
Before: Edit Profile Page
After
profile-settings.mp4

- Moved edit profile button
- Shifted details stack view
- Changed slider track to correct UIImage
- Changed slider thumb to smaller slider thumb
- Set navigation bar to hidden when view appears / set to false when view disapp
ears in ProfileVC - allows button to be pressed
- Created settings button in ProfileVC
- Changed edit profile button in ProfileVC
- Shifted settingsButton, editButton, and profileImageView
- Removed image from Roadtrip Favorites details, replaced with UILabel's
- Created SettingsViewController, able to push to SettingsVC from ProfileVC
- Created custom class SettingsCellView for settings cells
- Added properties to UI extension files
…rofile image

- Created `BlockedUsersViewController` that displays all the blocked users or an empty state if there's no blocked users (TODO: networking calls)
- Created `BlockedUserTableViewCell` that contains the user profile image and name, as well as a button to block/unblock the user
- Updates the list of blocked users after leaving the blocked users page and returning back to the page
- Modified `EditProfileViewController` to present a pop up once tapping the delete account button, which provides the option to either delete account or cancel
- Modified `EditProfileViewController` to save the uploaded profile photo (fixed)
- Added lines in between cells in `SettingsViewController`, and added functionality to pushing the blockedUsersVC and signing out of the app
- Deleted unused code in `User` model
- Created `getBlockedUsers` to get all the blocked users in `NetworkManager`
- Added necessary fonts and images to extension files
- Removed main UIView in `EmptyStateView` and replaced with UIStackView so that if there is no title, only the subtitle will appear on screen with the proper constraints
- Created `PopUpViewController` as a custom class that can be initialized as a pop up that contains a title, subtitle, and two buttons for either performing an action or canceling; includes blur effect in background
- Once clicking the unblock button, displays pop up to choose whether to
  unblock the user or to cancel
- User will still be displayed on block users page, but the button
  changed to block; this button only changes after confirming
- If the user decides to block some other user again, the button will
  change to the unblock state again
- When leaving the page and re-entering, the proper list of blocked
  users will display
- `PopUpViewController` title parameter updated to take in an attributed
  string instead of a string, so that specific styling can be specified
- Dummy data for the blocked users is included in the `User` model
Copy link
Collaborator

@vinnie4k vinnie4k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Next time, please break up your PRs. All of these features should be broken down into ~4 different PRs. I briefly skimmed your code, but please keep this in mind next time.

Request me again once you have addressed my comments.

Comment on lines -115 to -116
2C6BE1AD29EF8106007EA3AA /* Keys.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Keys.plist; path = ../../../../../../Keys.plist; sourceTree = "<group>"; };
2C6BE1AE29EF8106007EA3AA /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "../../../../../../GoogleService-Info.plist"; sourceTree = "<group>"; };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure you don't have dependency issues when removing these from the project.

Comment on lines -283 to -284
2C6BE1AE29EF8106007EA3AA /* GoogleService-Info.plist */,
2C6BE1AD29EF8106007EA3AA /* Keys.plist */,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

Comment on lines +15 to +16
private let userLabel = UILabel()
private let unblockButton = UIButton()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put these in order.

private let unblockButton = UIButton()

static let reuse = "BlockedUserCellReuse"
weak var delegate: BlockedUsersDelegate?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is being used anywhere. Mark it as private.

Comment on lines +41 to +44
self.user = user
profileImageView.sd_setImage(with: URL(string: user.profilePicUrl ?? ""), placeholderImage: UIImage.scooped.emptyImage)
userLabel.text = "\(user.firstName) \(user.lastName)"
self.delegate = delegate
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.user = user and self.delegate = delegate should be right on top of one another.

Comment on lines +106 to +111
popUpVC.configure(
title: attributedTitle,
subtitle: "",
actionButtonText: "Unblock",
delegate: self
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can do this directly through the initializer if you define it like such. See my message at the very bottom.

Comment on lines +70 to +81
private func setupEmptyStateView() {
emptyStateView.setup(
image: UIImage(),
title: "",
subtitle: "No blocked users"
)
view.addSubview(emptyStateView)

emptyStateView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice use of the EmptyStateView class to make things reusable.


@objc private func doAction() {
dismiss(animated: true)
delegate?.acceptPopUp()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why we use a weak reference for delegates. If you didn't use a weak reference, this right here would cause a retain cycle. You would be dismissing this instance and then still having a strong reference to the delegate.

Comment on lines +183 to +192
do {
let blockedUsers = try jsonDecoder.decode([BaseUser].self, from: data)
completion(.success(blockedUsers))
} catch {
completion(.failure(error))
}
case .failure(let error):
completion(.failure(error))
print("Request getBlockedUsers Failed: \(error.localizedDescription)")
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of how Scooped does networking. There are too many unnecessary print statements as well as inconsistencies with them. Logging is a powerful tool and should not be abused. I would note this in the handoff doc.

"scale" : "2x"
},
{
"filename" : "SliderThumb.png",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, in the video you sent, the circle looks a bit transparent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants