Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user profile view #105

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Core/Core/Data/Model/Data_UserProfile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Foundation
// MARK: - UserProfile
public extension DataLayer {
struct UserProfile: Codable {
public let id: Int
public let id: Int?
public let accountPrivacy: AccountPrivacy?
public let profileImage: ProfileImage?
public let username: String?
Expand Down Expand Up @@ -70,12 +70,13 @@ public extension DataLayer {
public enum AccountPrivacy: String, Codable {
case privateAccess = "private"
case allUsers = "all_users"
case allUsersBig = "ALL_USERS"

public var boolValue: Bool {
switch self {
case .privateAccess:
return false
case .allUsers:
case .allUsers, .allUsersBig:
return true
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public class DiscussionRepository: DiscussionRepositoryProtocol {
#if DEBUG
// swiftlint:disable all
public class DiscussionRepositoryMock: DiscussionRepositoryProtocol {

var comments = [
UserComment(authorName: "Bill",
authorAvatar: "",
Expand Down
11 changes: 11 additions & 0 deletions Discussion/Discussion/Presentation/Comments/Base/CommentCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public struct CommentCell: View {

private let comment: Post
private let addCommentAvailable: Bool
private var onAvatarTap: ((String) -> Void)
private var onLikeTap: (() -> Void)
private var onReportTap: (() -> Void)
private var onCommentsTap: (() -> Void)
Expand All @@ -25,6 +26,7 @@ public struct CommentCell: View {
comment: Post,
addCommentAvailable: Bool,
leftLineEnabled: Bool = false,
onAvatarTap: @escaping (String) -> Void,
onLikeTap: @escaping () -> Void,
onReportTap: @escaping () -> Void,
onCommentsTap: @escaping () -> Void,
Expand All @@ -33,6 +35,7 @@ public struct CommentCell: View {
self.comment = comment
self.addCommentAvailable = addCommentAvailable
self.leftLineEnabled = leftLineEnabled
self.onAvatarTap = onAvatarTap
self.onLikeTap = onLikeTap
self.onReportTap = onReportTap
self.onCommentsTap = onCommentsTap
Expand All @@ -42,11 +45,15 @@ public struct CommentCell: View {
public var body: some View {
VStack(alignment: .leading) {
HStack {
Button(action: {
onAvatarTap(comment.authorName)
}, label: {
KFImage(URL(string: comment.authorAvatar))
.onFailureImage(KFCrossPlatformImage(systemName: "person.circle"))
.resizable()
.frame(width: 32, height: 32)
.cornerRadius(16)
})

VStack(alignment: .leading) {
Text(comment.authorName)
Expand Down Expand Up @@ -170,6 +177,7 @@ struct CommentView_Previews: PreviewProvider {
comment: comment,
addCommentAvailable: true,
leftLineEnabled: false,
onAvatarTap: {_ in},
onLikeTap: {},
onReportTap: {},
onCommentsTap: {},
Expand All @@ -178,6 +186,7 @@ struct CommentView_Previews: PreviewProvider {
comment: comment,
addCommentAvailable: true,
leftLineEnabled: false,
onAvatarTap: {_ in},
onLikeTap: {},
onReportTap: {},
onCommentsTap: {},
Expand All @@ -192,6 +201,7 @@ struct CommentView_Previews: PreviewProvider {
comment: comment,
addCommentAvailable: true,
leftLineEnabled: false,
onAvatarTap: {_ in},
onLikeTap: {},
onReportTap: {},
onCommentsTap: {},
Expand All @@ -200,6 +210,7 @@ struct CommentView_Previews: PreviewProvider {
comment: comment,
addCommentAvailable: true,
leftLineEnabled: false,
onAvatarTap: {_ in},
onLikeTap: {},
onReportTap: {},
onCommentsTap: {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public struct ParentCommentView: View {

private let comments: Post
private var isThread: Bool
private var onAvatarTap: ((String) -> Void)
private var onLikeTap: (() -> Void)
private var onReportTap: (() -> Void)
private var onFollowTap: (() -> Void)
Expand All @@ -22,12 +23,14 @@ public struct ParentCommentView: View {
public init(
comments: Post,
isThread: Bool,
onAvatarTap: @escaping (String) -> Void,
onLikeTap: @escaping () -> Void,
onReportTap: @escaping () -> Void,
onFollowTap: @escaping () -> Void
) {
self.comments = comments
self.isThread = isThread
self.onAvatarTap = onAvatarTap
self.onLikeTap = onLikeTap
self.onReportTap = onReportTap
self.onFollowTap = onFollowTap
Expand All @@ -36,12 +39,16 @@ public struct ParentCommentView: View {
public var body: some View {
VStack(alignment: .leading) {
HStack {
Button(action: {
onAvatarTap(comments.authorName)
}, label: {
KFImage(URL(string: comments.authorAvatar))
.onFailureImage(KFCrossPlatformImage(systemName: "person"))
.resizable()
.background(Color.gray)
.frame(width: 48, height: 48)
.cornerRadius(isThread ? 8 : 24)
})
VStack(alignment: .leading) {
Text(comments.authorName)
.font(Theme.Fonts.titleMedium)
Expand Down Expand Up @@ -156,6 +163,7 @@ struct ParentCommentView_Previews: PreviewProvider {
ParentCommentView(
comments: comment,
isThread: true,
onAvatarTap: {_ in},
onLikeTap: {},
onReportTap: {},
onFollowTap: {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ public struct ResponsesView: View {
if let comments = viewModel.postComments {
ParentCommentView(
comments: comments,
isThread: false,
isThread: false, onAvatarTap: { username in
viewModel.router.showUserDetails(username: username)
},
onLikeTap: {
Task {
if await viewModel.vote(
Expand Down Expand Up @@ -93,7 +95,10 @@ public struct ResponsesView: View {
) { index, comment in
CommentCell(
comment: comment,
addCommentAvailable: false, leftLineEnabled: true,
addCommentAvailable: false, leftLineEnabled: true,
onAvatarTap: { username in
viewModel.router.showUserDetails(username: username)
},
onLikeTap: {
Task {
await viewModel.vote(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ public struct ThreadView: View {
if let comments = viewModel.postComments {
ParentCommentView(
comments: comments,
isThread: true,
isThread: true,
onAvatarTap: { username in
viewModel.router.showUserDetails(username: username)
},
onLikeTap: {
Task {
if await viewModel.vote(
Expand Down Expand Up @@ -91,7 +94,9 @@ public struct ThreadView: View {
CommentCell(
comment: comment,
addCommentAvailable: true,
onLikeTap: {
onAvatarTap: { username in
viewModel.router.showUserDetails(username: username)
}, onLikeTap: {
Task {
await viewModel.vote(
id: comment.commentID,
Expand Down
4 changes: 4 additions & 0 deletions Discussion/Discussion/Presentation/DiscussionRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import Combine
//sourcery: AutoMockable
public protocol DiscussionRouter: BaseRouter {

func showUserDetails(username: String)

func showThreads(courseID: String, topics: Topics, title: String, type: ThreadType)

func showThread(thread: UserThread, postStateSubject: CurrentValueSubject<PostState?, Never>)
Expand All @@ -33,6 +35,8 @@ public class DiscussionRouterMock: BaseRouterMock, DiscussionRouter {

public override init() {}

public func showUserDetails(username: String) {}

public func showThreads(courseID: String, topics: Topics, title: String, type: ThreadType) {}

public func showThread(thread: UserThread, postStateSubject: CurrentValueSubject<PostState?, Never>) {}
Expand Down
18 changes: 18 additions & 0 deletions Discussion/DiscussionTests/DiscussionMock.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1967,6 +1967,12 @@ open class DiscussionRouterMock: DiscussionRouter, Mock {



open func showUserDetails(username: String) {
addInvocation(.m_showUserDetails__username_username(Parameter<String>.value(`username`)))
let perform = methodPerformValue(.m_showUserDetails__username_username(Parameter<String>.value(`username`))) as? (String) -> Void
perform?(`username`)
}

open func showThreads(courseID: String, topics: Topics, title: String, type: ThreadType) {
addInvocation(.m_showThreads__courseID_courseIDtopics_topicstitle_titletype_type(Parameter<String>.value(`courseID`), Parameter<Topics>.value(`topics`), Parameter<String>.value(`title`), Parameter<ThreadType>.value(`type`)))
let perform = methodPerformValue(.m_showThreads__courseID_courseIDtopics_topicstitle_titletype_type(Parameter<String>.value(`courseID`), Parameter<Topics>.value(`topics`), Parameter<String>.value(`title`), Parameter<ThreadType>.value(`type`))) as? (String, Topics, String, ThreadType) -> Void
Expand Down Expand Up @@ -2077,6 +2083,7 @@ open class DiscussionRouterMock: DiscussionRouter, Mock {


fileprivate enum MethodType {
case m_showUserDetails__username_username(Parameter<String>)
case m_showThreads__courseID_courseIDtopics_topicstitle_titletype_type(Parameter<String>, Parameter<Topics>, Parameter<String>, Parameter<ThreadType>)
case m_showThread__thread_threadpostStateSubject_postStateSubject(Parameter<UserThread>, Parameter<CurrentValueSubject<PostState?, Never>>)
case m_showDiscussionsSearch__courseID_courseID(Parameter<String>)
Expand All @@ -2098,6 +2105,11 @@ open class DiscussionRouterMock: DiscussionRouter, Mock {

static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult {
switch (lhs, rhs) {
case (.m_showUserDetails__username_username(let lhsUsername), .m_showUserDetails__username_username(let rhsUsername)):
var results: [Matcher.ParameterComparisonResult] = []
results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsUsername, rhs: rhsUsername, with: matcher), lhsUsername, rhsUsername, "username"))
return Matcher.ComparisonResult(results)

case (.m_showThreads__courseID_courseIDtopics_topicstitle_titletype_type(let lhsCourseid, let lhsTopics, let lhsTitle, let lhsType), .m_showThreads__courseID_courseIDtopics_topicstitle_titletype_type(let rhsCourseid, let rhsTopics, let rhsTitle, let rhsType)):
var results: [Matcher.ParameterComparisonResult] = []
results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID"))
Expand Down Expand Up @@ -2200,6 +2212,7 @@ open class DiscussionRouterMock: DiscussionRouter, Mock {

func intValue() -> Int {
switch self {
case let .m_showUserDetails__username_username(p0): return p0.intValue
case let .m_showThreads__courseID_courseIDtopics_topicstitle_titletype_type(p0, p1, p2, p3): return p0.intValue + p1.intValue + p2.intValue + p3.intValue
case let .m_showThread__thread_threadpostStateSubject_postStateSubject(p0, p1): return p0.intValue + p1.intValue
case let .m_showDiscussionsSearch__courseID_courseID(p0): return p0.intValue
Expand All @@ -2222,6 +2235,7 @@ open class DiscussionRouterMock: DiscussionRouter, Mock {
}
func assertionName() -> String {
switch self {
case .m_showUserDetails__username_username: return ".showUserDetails(username:)"
case .m_showThreads__courseID_courseIDtopics_topicstitle_titletype_type: return ".showThreads(courseID:topics:title:type:)"
case .m_showThread__thread_threadpostStateSubject_postStateSubject: return ".showThread(thread:postStateSubject:)"
case .m_showDiscussionsSearch__courseID_courseID: return ".showDiscussionsSearch(courseID:)"
Expand Down Expand Up @@ -2258,6 +2272,7 @@ open class DiscussionRouterMock: DiscussionRouter, Mock {
public struct Verify {
fileprivate var method: MethodType

public static func showUserDetails(username: Parameter<String>) -> Verify { return Verify(method: .m_showUserDetails__username_username(`username`))}
public static func showThreads(courseID: Parameter<String>, topics: Parameter<Topics>, title: Parameter<String>, type: Parameter<ThreadType>) -> Verify { return Verify(method: .m_showThreads__courseID_courseIDtopics_topicstitle_titletype_type(`courseID`, `topics`, `title`, `type`))}
public static func showThread(thread: Parameter<UserThread>, postStateSubject: Parameter<CurrentValueSubject<PostState?, Never>>) -> Verify { return Verify(method: .m_showThread__thread_threadpostStateSubject_postStateSubject(`thread`, `postStateSubject`))}
public static func showDiscussionsSearch(courseID: Parameter<String>) -> Verify { return Verify(method: .m_showDiscussionsSearch__courseID_courseID(`courseID`))}
Expand All @@ -2282,6 +2297,9 @@ open class DiscussionRouterMock: DiscussionRouter, Mock {
fileprivate var method: MethodType
var performs: Any

public static func showUserDetails(username: Parameter<String>, perform: @escaping (String) -> Void) -> Perform {
return Perform(method: .m_showUserDetails__username_username(`username`), performs: perform)
}
public static func showThreads(courseID: Parameter<String>, topics: Parameter<Topics>, title: Parameter<String>, type: Parameter<ThreadType>, perform: @escaping (String, Topics, String, ThreadType) -> Void) -> Perform {
return Perform(method: .m_showThreads__courseID_courseIDtopics_topicstitle_titletype_type(`courseID`, `topics`, `title`, `type`), performs: perform)
}
Expand Down
10 changes: 5 additions & 5 deletions OpenEdX/DI/ScreenAssembly.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,14 @@ class ScreenAssembly: Assembly {
config: r.resolve(Config.self)!
)
}
container.register(ProfileInteractor.self) { r in
container.register(ProfileInteractorProtocol.self) { r in
ProfileInteractor(
repository: r.resolve(ProfileRepositoryProtocol.self)!
)
}
container.register(ProfileViewModel.self) { r in
ProfileViewModel(
interactor: r.resolve(ProfileInteractor.self)!,
interactor: r.resolve(ProfileInteractorProtocol.self)!,
router: r.resolve(ProfileRouter.self)!,
analytics: r.resolve(ProfileAnalytics.self)!,
config: r.resolve(Config.self)!,
Expand All @@ -151,7 +151,7 @@ class ScreenAssembly: Assembly {
container.register(EditProfileViewModel.self) { r, userModel in
EditProfileViewModel(
userModel: userModel,
interactor: r.resolve(ProfileInteractor.self)!,
interactor: r.resolve(ProfileInteractorProtocol.self)!,
router: r.resolve(ProfileRouter.self)!,
analytics: r.resolve(ProfileAnalytics.self)!

Expand All @@ -160,14 +160,14 @@ class ScreenAssembly: Assembly {

container.register(SettingsViewModel.self) { r in
SettingsViewModel(
interactor: r.resolve(ProfileInteractor.self)!,
interactor: r.resolve(ProfileInteractorProtocol.self)!,
router: r.resolve(ProfileRouter.self)!
)
}

container.register(DeleteAccountViewModel.self) { r in
DeleteAccountViewModel(
interactor: r.resolve(ProfileInteractor.self)!,
interactor: r.resolve(ProfileInteractorProtocol.self)!,
router: r.resolve(ProfileRouter.self)!,
connectivity: r.resolve(ConnectivityProtocol.self)!
)
Expand Down
10 changes: 10 additions & 0 deletions OpenEdX/Router.swift
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,16 @@ public class Router: AuthorizationRouter,
navigationController.pushViewController(controller, animated: true)
}

public func showUserDetails(username: String) {
let interactor = container.resolve(ProfileInteractorProtocol.self)!

let vm = UserProfileViewModel(interactor: interactor,
username: username)
let view = UserProfileView(viewModel: vm)
let controller = UIHostingController(rootView: view)
navigationController.pushViewController(controller, animated: true)
}

public func showEditProfile(
userModel: Core.UserProfile,
avatar: UIImage?,
Expand Down
Loading