Skip to content

Commit

Permalink
Discussions refactoring (#491)
Browse files Browse the repository at this point in the history
* Format code

* Use Reusable & NibLoadable

* Remove unused DiscussionWebTableViewCell

* Remove Label group

* Update DiscussionTableViewCell

* Refactor rename DiscussionTableViewCells -> DiscussionTableViewCell

* Remove unused DiscussionCellDelegate

* Create Views group

* Remove unused DiscussionUpdateDelegate

* Sort Discussions group files by name

* Update WriteCommentViewController

* Format DiscussionAlertConstructor's code

* Update LoadMoreTableViewCell

* Update DiscussionAlertConstructor

* Tmp for DiscussionsViewController

* Init Discussions only with DiscussionsLegacyAssembly

* Initial commit for DiscussionsPresenter

* Sort Services group by name

* Create DiscussionProxiesNetworkService

* Create CommentsNetworkService

* Add Error for DiscussionProxiesNetworkService

* tmp

* Use ProfileAssembly

* Use Comment.IdType

* Remove unused

* Create VotesNetworkService

* Inject VotesNetworkService

* Set DiscussionsViewController

* Update VoteValue comparison

* Initial commit for DiscussionsView

* Fetch & like & abuse comments

* Make DiscussionsViewData immutable

* Show more text for loading cells

* Refactor rename DiscussionsViewData's vars

* Update loading cells

* Increment step discussions sount on create

* Set Swift language version to 4.2

* Run swiftlint autocorrect

* Refactor rename discussionsFetchingRepliesIds

* Use StepsPersistenceService

* Create DiscussionsTableViewDataSource

* Display alert on error

* Move SeparatorType to DiscussionsViewData

* Refresh on appear
  • Loading branch information
ivan-magda authored Jul 9, 2019
1 parent d071d1c commit 254139f
Show file tree
Hide file tree
Showing 27 changed files with 1,006 additions and 1,382 deletions.
2 changes: 1 addition & 1 deletion .swift-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.0
4.2
188 changes: 66 additions & 122 deletions Stepic.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions Stepic/CardsStepsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,11 @@ class CardsStepsViewController: UIViewController, CardsStepsView, ControllerWith
}

func presentDiscussions(stepId: Int, discussionProxyId: String) {
let vc = DiscussionsViewController(nibName: "DiscussionsViewController", bundle: nil)
vc.discussionProxyId = discussionProxyId
vc.target = stepId
navigationController?.pushViewController(vc, animated: true)
let assembly = DiscussionsLegacyAssembly(
discussionProxyID: discussionProxyId,
stepID: stepId
)
self.push(module: assembly.makeModule())
}

func updateProgress(rating: Int, prevMaxRating: Int, maxRating: Int, level: Int) {
Expand Down
20 changes: 10 additions & 10 deletions Stepic/DeepLinkRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,11 @@ final class DeepLinkRouter {
}

if let discussionProxyId = step.discussionProxyId {
let vc = DiscussionsViewController(nibName: "DiscussionsViewController", bundle: nil)
vc.discussionProxyId = discussionProxyId
vc.target = step.id
vc.step = step
completion(viewControllers + [vc])
let assembly = DiscussionsLegacyAssembly(
discussionProxyID: discussionProxyId,
stepID: step.id
)
completion(viewControllers + [assembly.makeModule()])
} else {
completion([])
}
Expand Down Expand Up @@ -317,11 +317,11 @@ final class DeepLinkRouter {
}

if let discussionProxyId = step.discussionProxyId {
let vc = DiscussionsViewController(nibName: "DiscussionsViewController", bundle: nil)
vc.discussionProxyId = discussionProxyId
vc.target = step.id
vc.step = step
completion(viewControllers + [vc])
let assembly = DiscussionsLegacyAssembly(
discussionProxyID: discussionProxyId,
stepID: step.id
)
completion(viewControllers + [assembly.makeModule()])
} else {
completion([])
}
Expand Down
12 changes: 5 additions & 7 deletions Stepic/DiscussionAlertConstructor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation

final class DiscussionAlertConstructor {
static func getCommentAlert(
_ comment: Comment,
comment: Comment,
replyBlock: @escaping (() -> Void),
likeBlock: @escaping (() -> Void),
abuseBlock: @escaping (() -> Void),
Expand Down Expand Up @@ -39,19 +39,17 @@ final class DiscussionAlertConstructor {
}))

if comment.userId != AuthInfo.shared.userId {
let likeTitle: String = (comment.vote.value == VoteValue.Epic)
let likeTitle: String = (comment.vote.value == .epic)
? NSLocalizedString("Unlike", comment: "")
: NSLocalizedString("Like", comment: "")
alert.addAction(UIAlertAction(title: likeTitle, style: .default, handler: {
_ in
alert.addAction(UIAlertAction(title: likeTitle, style: .default, handler: { _ in
likeBlock()
}))

let abuseTitle: String = (comment.vote.value == VoteValue.Abuse)
let abuseTitle: String = (comment.vote.value == .abuse)
? NSLocalizedString("Unabuse", comment: "")
: NSLocalizedString("Abuse", comment: "")
alert.addAction(UIAlertAction(title: abuseTitle, style: .destructive, handler: {
_ in
alert.addAction(UIAlertAction(title: abuseTitle, style: .destructive, handler: { _ in
abuseBlock()
}))
}
Expand Down
13 changes: 0 additions & 13 deletions Stepic/DiscussionCellDelegate.swift

This file was deleted.

197 changes: 92 additions & 105 deletions Stepic/DiscussionTableViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,156 +10,143 @@ import UIKit
import SDWebImage
import SnapKit

protocol DiscussionTableViewCellDelegate: class {
func didOpenProfile(for userWithId: Int)
}

class DiscussionTableViewCell: UITableViewCell {
weak var delegate: DiscussionTableViewCellDelegate?

final class DiscussionTableViewCell: UITableViewCell, Reusable, NibLoadable {
@IBOutlet weak var userAvatarImageView: AvatarImageView!
@IBOutlet weak var nameLabel: StepikLabel!
@IBOutlet weak var userAvatarImageViewLeadingConstraint: NSLayoutConstraint!

@IBOutlet weak var badgeLabel: WiderLabel!
@IBOutlet weak var commentLabel: StepikLabel!
@IBOutlet weak var commentLabelLeadingConstraint: NSLayoutConstraint!

@IBOutlet weak var separatorView: UIView!
@IBOutlet weak var timeLabel: StepikLabel!

@IBOutlet weak var labelLeadingConstraint: NSLayoutConstraint!

@IBOutlet weak var ImageLeadingConstraint: NSLayoutConstraint!

@IBOutlet weak var separatorHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var separatorLeadingConstraint: NSLayoutConstraint!
@IBOutlet weak var separatorViewHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var separatorViewLeadingConstraint: NSLayoutConstraint!

@IBOutlet weak var nameLabel: StepikLabel!
@IBOutlet weak var badgeLabel: WiderLabel!
@IBOutlet weak var timeLabel: StepikLabel!
@IBOutlet weak var likesLabel: StepikLabel!
@IBOutlet weak var likesImageView: UIImageView!

@IBOutlet weak var commentLabel: StepikLabel!
var comment: Comment?

var onProfileButtonClick: ((Int) -> Void)?

var hasSeparator: Bool = false {
private var hasSeparator: Bool = false {
didSet {
separatorView?.isHidden = !hasSeparator
self.separatorView.isHidden = !self.hasSeparator
}
}

var separatorType: SeparatorType = .none {
private var separatorType: DiscussionsViewData.SeparatorType = .none {
didSet {
switch separatorType {
switch self.separatorType {
case .none:
hasSeparator = false
separatorHeightConstraint.constant = 0
break
self.hasSeparator = false
self.separatorViewHeightConstraint.constant = 0
case .small:
hasSeparator = true
separatorHeightConstraint.constant = 0.5
separatorLeadingConstraint.constant = 8
break
self.hasSeparator = true
self.separatorViewHeightConstraint.constant = 0.5
self.separatorViewLeadingConstraint.constant = 8
case .big:
hasSeparator = true
separatorHeightConstraint.constant = 10
separatorLeadingConstraint.constant = -8
break
self.hasSeparator = true
self.separatorViewHeightConstraint.constant = 10
self.separatorViewLeadingConstraint.constant = -8
}
updateConstraints()
self.updateConstraints()
}
}

var comment: Comment?
var heightUpdateBlock : (() -> Void)?
override func awakeFromNib() {
super.awakeFromNib()

self.badgeLabel.setRoundedCorners(cornerRadius: 10)

self.nameLabel?.isUserInteractionEnabled = true
self.nameLabel?.addGestureRecognizer(
UITapGestureRecognizer(target: self, action: #selector(self.actionUserTapped))
)

self.userAvatarImageView?.isUserInteractionEnabled = true
self.userAvatarImageView?.addGestureRecognizer(
UITapGestureRecognizer(target: self, action: #selector(self.actionUserTapped))
)
}

override func prepareForReuse() {
super.prepareForReuse()

self.comment = nil
self.updateConstraints()
}

override func updateConstraints() {
super.updateConstraints()
self.setLeadingConstraints(self.comment?.parentId == nil ? 0 : -40)
}

func configure(viewData: DiscussionsViewData) {
guard let comment = viewData.comment else {
return
}

func initWithComment(_ comment: Comment, separatorType: SeparatorType) {
if let url = URL(string: comment.userInfo.avatarURL) {
userAvatarImageView.set(with: url)
self.userAvatarImageView.set(with: url)
}

nameLabel.text = "\(comment.userInfo.firstName) \(comment.userInfo.lastName)"
self.nameLabel.text = "\(comment.userInfo.firstName) \(comment.userInfo.lastName)"
self.comment = comment
self.separatorType = separatorType
timeLabel.text = comment.time.getStepicFormatString(withTime: true)
setLiked(comment.vote.value == .Epic, likesCount: comment.epicCount)
loadLabel(comment.text)
self.separatorType = viewData.separatorType
self.timeLabel.text = comment.time.getStepicFormatString(withTime: true)
self.setLiked(comment.vote.value == .epic, likesCount: comment.epicCount)
self.commentLabel.setTextWithHTMLString(comment.text)

if comment.isDeleted {
self.contentView.backgroundColor = UIColor.wrongQuizBackground
self.contentView.backgroundColor = .wrongQuizBackground
if comment.text == "" {
loadLabel(NSLocalizedString("DeletedComment", comment: ""))
self.commentLabel.text = NSLocalizedString("DeletedComment", comment: "")
}
} else {
self.contentView.backgroundColor = UIColor.white
self.contentView.backgroundColor = .white
}

switch comment.userRole {
case .Student:
badgeLabel.text = ""
badgeLabel.backgroundColor = UIColor.clear
case .Teacher:
badgeLabel.text = NSLocalizedString("CourseStaff", comment: "")
badgeLabel.backgroundColor = UIColor.lightGray
case .Staff:
badgeLabel.text = NSLocalizedString("Staff", comment: "")
badgeLabel.backgroundColor = UIColor.lightGray
case .student:
self.badgeLabel.text = ""
self.badgeLabel.backgroundColor = .clear
case .teacher:
self.badgeLabel.text = NSLocalizedString("CourseStaff", comment: "")
self.badgeLabel.backgroundColor = .lightGray
case .staff:
self.badgeLabel.text = NSLocalizedString("Staff", comment: "")
self.badgeLabel.backgroundColor = .lightGray
}
}

fileprivate func loadLabel(_ htmlString: String) {
commentLabel.setTextWithHTMLString(htmlString)
private func setLiked(_ liked: Bool, likesCount: Int) {
self.likesLabel.text = "\(likesCount)"
if liked {
self.likesImageView.image = Images.thumbsUp.filled
} else {
self.likesImageView.image = Images.thumbsUp.normal
}
}

fileprivate func setLeadingConstraints(_ constant: CGFloat) {
ImageLeadingConstraint.constant = constant
labelLeadingConstraint.constant = -constant
private func setLeadingConstraints(_ constant: CGFloat) {
self.userAvatarImageViewLeadingConstraint.constant = constant
self.commentLabelLeadingConstraint.constant = -constant

switch self.separatorType {
case .small:
separatorLeadingConstraint.constant = -constant
break
self.separatorViewLeadingConstraint.constant = -constant
default:
break
}
}

func setLiked(_ liked: Bool, likesCount: Int) {
likesLabel.text = "\(likesCount)"
if liked {
likesImageView.image = Images.thumbsUp.filled
} else {
likesImageView.image = Images.thumbsUp.normal
}
}

override func awakeFromNib() {
super.awakeFromNib()
badgeLabel.setRoundedCorners(cornerRadius: 10)

let tapActionNameLabel = UITapGestureRecognizer(target: self, action: #selector(self.actionUserTapped))
nameLabel?.isUserInteractionEnabled = true
nameLabel?.addGestureRecognizer(tapActionNameLabel)

let tapActionAvatarView = UITapGestureRecognizer(target: self, action: #selector(self.actionUserTapped))
userAvatarImageView?.isUserInteractionEnabled = true
userAvatarImageView?.addGestureRecognizer(tapActionAvatarView)
}

@objc func actionUserTapped() {
guard let userId = comment?.userInfo.id else {
return
@objc
private func actionUserTapped() {
if let userId = self.comment?.userInfo.id {
self.onProfileButtonClick?(userId)
}

delegate?.didOpenProfile(for: userId)
}

override func prepareForReuse() {
super.prepareForReuse()
comment = nil
updateConstraints()
}

override func updateConstraints() {
super.updateConstraints()
setLeadingConstraints(comment?.parentId == nil ? 0 : -40)
}

override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}

}
15 changes: 7 additions & 8 deletions Stepic/DiscussionTableViewCell.xib
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
Expand Down Expand Up @@ -63,7 +62,7 @@
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="753" text="0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0qt-gd-xNy" customClass="StepikLabel" customModule="Adaptive_1838" customModuleProvider="target">
<rect key="frame" x="380" y="13" width="9" height="16"/>
<rect key="frame" x="380" y="12.5" width="9" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
Expand Down Expand Up @@ -114,18 +113,18 @@
<viewLayoutGuide key="safeArea" id="A0U-wb-SKO"/>
<inset key="separatorInset" minX="15" minY="0.0" maxX="0.0" maxY="0.0"/>
<connections>
<outlet property="ImageLeadingConstraint" destination="zeC-Ii-ThB" id="ZcW-0g-gNI"/>
<outlet property="badgeLabel" destination="JBD-B0-dRF" id="xD5-za-CIg"/>
<outlet property="commentLabel" destination="qtJ-hP-Joz" id="sc7-SB-dp1"/>
<outlet property="labelLeadingConstraint" destination="eal-E1-aBI" id="15O-Re-2oa"/>
<outlet property="commentLabelLeadingConstraint" destination="eal-E1-aBI" id="15O-Re-2oa"/>
<outlet property="likesImageView" destination="eQf-K2-Thw" id="7Hh-xy-3WI"/>
<outlet property="likesLabel" destination="0qt-gd-xNy" id="UQw-MR-Wd0"/>
<outlet property="nameLabel" destination="6YZ-wn-n05" id="OxI-1P-viA"/>
<outlet property="separatorHeightConstraint" destination="wgI-Pg-Mbo" id="epW-KA-daK"/>
<outlet property="separatorLeadingConstraint" destination="EJ0-8Z-U7Z" id="X2X-wB-q8E"/>
<outlet property="separatorView" destination="pV4-ue-5er" id="ZQA-fC-Y3W"/>
<outlet property="separatorViewHeightConstraint" destination="wgI-Pg-Mbo" id="1BA-fY-gfC"/>
<outlet property="separatorViewLeadingConstraint" destination="EJ0-8Z-U7Z" id="X2X-wB-q8E"/>
<outlet property="timeLabel" destination="RmE-el-xJX" id="aU3-Xg-wIJ"/>
<outlet property="userAvatarImageView" destination="IO2-jl-qQ3" id="FXP-ux-Uch"/>
<outlet property="userAvatarImageViewLeadingConstraint" destination="zeC-Ii-ThB" id="ZcW-0g-gNI"/>
</connections>
<point key="canvasLocation" x="184.5" y="443"/>
</tableViewCell>
Expand Down
Loading

0 comments on commit 254139f

Please sign in to comment.