Skip to content

Commit

Permalink
Merge pull request #317 from WalletConnect/feature/chat-sample-homesc…
Browse files Browse the repository at this point in the history
…reen-#293

[Chat] Showcase app UI #293
  • Loading branch information
André Vants authored Jul 8, 2022
2 parents 2d900a2 + cd83c7f commit 14d204b
Show file tree
Hide file tree
Showing 39 changed files with 467 additions and 56 deletions.
24 changes: 24 additions & 0 deletions Example/ExampleApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
A5629AE02876CC6E00094373 /* InviteListRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629ADB2876CC6E00094373 /* InviteListRouter.swift */; };
A5629AE12876CC6E00094373 /* InviteListInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629ADC2876CC6E00094373 /* InviteListInteractor.swift */; };
A5629AE22876CC6E00094373 /* InviteListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629ADD2876CC6E00094373 /* InviteListView.swift */; };
A5629AE42876E6D200094373 /* ThreadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AE32876E6D200094373 /* ThreadViewModel.swift */; };
A5629AE828772A0100094373 /* InviteViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AE728772A0100094373 /* InviteViewModel.swift */; };
A578FA322873036400AA7720 /* InputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A578FA312873036400AA7720 /* InputView.swift */; };
A578FA35287304A300AA7720 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = A578FA34287304A300AA7720 /* Color.swift */; };
A578FA372873D8EE00AA7720 /* UIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A578FA362873D8EE00AA7720 /* UIColor.swift */; };
Expand Down Expand Up @@ -197,6 +199,8 @@
A5629ADB2876CC6E00094373 /* InviteListRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteListRouter.swift; sourceTree = "<group>"; };
A5629ADC2876CC6E00094373 /* InviteListInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteListInteractor.swift; sourceTree = "<group>"; };
A5629ADD2876CC6E00094373 /* InviteListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteListView.swift; sourceTree = "<group>"; };
A5629AE32876E6D200094373 /* ThreadViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadViewModel.swift; sourceTree = "<group>"; };
A5629AE728772A0100094373 /* InviteViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteViewModel.swift; sourceTree = "<group>"; };
A578FA312873036400AA7720 /* InputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputView.swift; sourceTree = "<group>"; };
A578FA34287304A300AA7720 /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = "<group>"; };
A578FA362873D8EE00AA7720 /* UIColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColor.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -476,6 +480,7 @@
A5629AB72876CBA700094373 /* ChatList */ = {
isa = PBXGroup;
children = (
A5629AE5287729EF00094373 /* Models */,
A5629AB82876CBC000094373 /* ChatListModule.swift */,
A5629AB92876CBC000094373 /* ChatListPresenter.swift */,
A5629ABA2876CBC000094373 /* ChatListRouter.swift */,
Expand All @@ -500,6 +505,7 @@
A5629AD82876CC5B00094373 /* InviteList */ = {
isa = PBXGroup;
children = (
A5629AE6287729F800094373 /* Models */,
A5629AD92876CC6E00094373 /* InviteListModule.swift */,
A5629ADA2876CC6E00094373 /* InviteListPresenter.swift */,
A5629ADB2876CC6E00094373 /* InviteListRouter.swift */,
Expand All @@ -509,6 +515,22 @@
path = InviteList;
sourceTree = "<group>";
};
A5629AE5287729EF00094373 /* Models */ = {
isa = PBXGroup;
children = (
A5629AE32876E6D200094373 /* ThreadViewModel.swift */,
);
path = Models;
sourceTree = "<group>";
};
A5629AE6287729F800094373 /* Models */ = {
isa = PBXGroup;
children = (
A5629AE728772A0100094373 /* InviteViewModel.swift */,
);
path = Models;
sourceTree = "<group>";
};
A578FA332873049400AA7720 /* Style */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -1045,12 +1067,14 @@
A578FA35287304A300AA7720 /* Color.swift in Sources */,
A5629ADE2876CC6E00094373 /* InviteListModule.swift in Sources */,
A578FA322873036400AA7720 /* InputView.swift in Sources */,
A5629AE42876E6D200094373 /* ThreadViewModel.swift in Sources */,
A58E7D0C2872A45B0082D443 /* MainModule.swift in Sources */,
A58E7D0D2872A45B0082D443 /* MainPresenter.swift in Sources */,
A5629AD62876CC5700094373 /* InviteInteractor.swift in Sources */,
A5629AE12876CC6E00094373 /* InviteListInteractor.swift in Sources */,
A58E7CED28729F550082D443 /* SceneDelegate.swift in Sources */,
A578FA372873D8EE00AA7720 /* UIColor.swift in Sources */,
A5629AE828772A0100094373 /* InviteViewModel.swift in Sources */,
A5629AA92876A23100094373 /* ChatService.swift in Sources */,
A5629AC02876CBC000094373 /* ChatListInteractor.swift in Sources */,
A5629AE22876CC6E00094373 /* InviteListView.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ import UIKit
struct AppearanceConfigurator: Configurator {

func configure() {
let appearance = UINavigationBarAppearance()
appearance.titleTextAttributes = [
.foregroundColor: UIColor.w_foreground
]

UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance
UINavigationBar.appearance().compactAppearance = appearance

}
}
42 changes: 36 additions & 6 deletions Example/Showcase/Classes/DomainLayer/ChatService.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import Foundation
import Combine

typealias MessageStream = AsyncPublisher<AnyPublisher<[Message], Never>>
typealias Stream<T> = AsyncPublisher<AnyPublisher<T, Never>>

final class ChatService {

static let authorAccount: String = "TODO"

private let messagesSubject: CurrentValueSubject<[Message], Never> = {
return CurrentValueSubject([
Message(message: "✨gm", authorAccount: "2", timestamp: 0),
Expand All @@ -19,21 +21,49 @@ final class ChatService {
])
}()

func getMessages(topic: String) -> MessageStream {
private let threadsSubject: CurrentValueSubject<[Thread], Never> = {
return CurrentValueSubject([
Thread(topic: "topic1"),
Thread(topic: "topic2")
])
}()

private let invitesSubject: CurrentValueSubject<[Invite], Never> = {
return CurrentValueSubject([
Invite(message: "In a few minutes, bitch.", pubKey: "slava.eth")
])
}()

func getMessages(topic: String) -> Stream<[Message]> {
return messagesSubject.eraseToAnyPublisher().values
}

func getAuthorAccount() async -> String {
return "1"
func getThreads() -> Stream<[Thread]> {
return threadsSubject.eraseToAnyPublisher().values
}

func getInvites() -> Stream<[Invite]> {
return invitesSubject.eraseToAnyPublisher().values
}

func sendMessage(text: String) async throws {
let authorAccount = await getAuthorAccount()
let message = Message(
message: text,
authorAccount: authorAccount,
authorAccount: ChatService.authorAccount,
timestamp: Int64(Date().timeIntervalSince1970)
)
messagesSubject.send(messagesSubject.value + [message])
}

func accept(invite: Invite) async throws {

}

func reject(invite: Invite) async throws {

}

func invite(account: String) async throws {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ final class ChatInteractor {
self.chatService = chatService
}

func getCurrentAccount() async -> String {
return await chatService.getAuthorAccount()
}

func getMessages(topic: String) -> MessageStream {
func getMessages(topic: String) -> Stream<[Message]> {
return chatService.getMessages(topic: topic)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import SwiftUI
final class ChatModule {

@discardableResult
static func create(app: Application) -> UIViewController {
static func create(topic: String, app: Application) -> UIViewController {
let router = ChatRouter(app: app)
let interactor = ChatInteractor(chatService: app.chatService)
let presenter = ChatPresenter(topic: "", interactor: interactor, router: router)
let presenter = ChatPresenter(topic: topic, interactor: interactor, router: router)
let view = ChatView().environmentObject(presenter)
let viewController = SceneViewController(viewModel: presenter, content: view)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ final class ChatPresenter: ObservableObject {

@MainActor
func setupInitialState() async {
let account = await interactor.getCurrentAccount()

for await messages in interactor.getMessages(topic: topic) {
self.messages = messages
.sorted(by: { $0.timestamp < $1.timestamp })
.map { MessageViewModel(message: $0, currentAccount: account) }
.map { MessageViewModel(message: $0, currentAccount: "TODO") }
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

// TODO: After Chat SDK integration
// TODO: Delete after Chat SDK integration
struct Message: Codable, Equatable {
let message: String
let authorAccount: String
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
final class ChatListInteractor {

private let chatService: ChatService

init(chatService: ChatService) {
self.chatService = chatService
}

func getThreads() -> Stream<[Thread]> {
return chatService.getThreads()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ final class ChatListModule {
@discardableResult
static func create(app: Application) -> UIViewController {
let router = ChatListRouter(app: app)
let interactor = ChatListInteractor()
let interactor = ChatListInteractor(chatService: app.chatService)
let presenter = ChatListPresenter(interactor: interactor, router: router)
let view = ChatListView().environmentObject(presenter)
let viewController = SceneViewController(viewModel: presenter, content: view)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,24 @@ final class ChatListPresenter: ObservableObject {
private let router: ChatListRouter
private var disposeBag = Set<AnyCancellable>()

@Published var threads: [ThreadViewModel] = []

init(interactor: ChatListInteractor, router: ChatListRouter) {
self.interactor = interactor
self.router = router
}

@MainActor
func setupInitialState() async {
for await threads in interactor.getThreads() {
self.threads = threads
.sorted(by: { $0.topic < $1.topic })
.map { ThreadViewModel(thread: $0) }
}
}

func didPressThread(_ thread: ThreadViewModel) {
router.presentChat(topic: thread.topic)
}

func didPressChatRequests() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@ final class ChatListRouter {
}

func presentInvite() {
InviteModule.create(app: app).push(from: viewController)
InviteModule.create(app: app)
.wrapToNavigationController()
.present(from: viewController)
}

func presentInviteList() {
InviteListModule.create(app: app).push(from: viewController)
}

func presentChat(topic: String) {
ChatModule.create(topic: topic, app: app).push(from: viewController)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,55 @@ struct ChatListView: View {
@EnvironmentObject var presenter: ChatListPresenter

var body: some View {
VStack {
Spacer()
ScrollView {
VStack {
Button(action: {
presenter.didPressChatRequests()
}) {
HStack(spacing: 8.0) {
Text("1")
.frame(width: 24.0, height: 24.0)
.background(Color.w_greenForground)
.foregroundColor(.w_greenBackground)
.font(.system(size: 17.0, weight: .bold))
.clipShape(Circle())

Button("Chat Requests") {
presenter.didPressChatRequests()
Text("Chat Requests")
.foregroundColor(.w_greenForground)
.font(.system(size: 17.0, weight: .bold))
}
}
.frame(height: 44.0)
.frame(maxWidth: .infinity)
.background(Color.w_greenBackground)
.clipShape(Capsule())
.padding(16.0)

ForEach(presenter.threads) { thread in
Button(action: {
presenter.didPressThread(thread)
}) {
HStack(spacing: 16.0) {
Image("avatar")
.resizable()
.frame(width: 64.0, height: 64.0)

VStack(alignment: .leading) {
Text(thread.title)
.font(.title3)
.foregroundColor(.w_foreground)
.lineLimit(1)

Text(thread.subtitle)
.font(.subheadline)
.foregroundColor(.w_secondaryForeground)
.multilineTextAlignment(.leading)
}
}
.frame(height: 64.0)
}
}
.padding(16.0)
}
}
.task {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Foundation

// TODO: Delete after Chat SDK integration
struct Thread: Codable {
let topic: String
}

struct ThreadViewModel: Identifiable {
private let thread: Thread

init(thread: Thread) {
self.thread = thread
}

var topic: String {
return thread.topic
}

var id: String {
return thread.topic
}

var title: String {
return thread.topic
}

var subtitle: String {
return "Chicken, Peter, you’re just a little chicken. Cheep, cheep, cheep, cheep…"
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
final class InviteInteractor {
private let chatService: ChatService

init(chatService: ChatService) {
self.chatService = chatService
}

func invite(account: String) async {
try! await chatService.invite(account: account)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ final class InviteModule {
@discardableResult
static func create(app: Application) -> UIViewController {
let router = InviteRouter(app: app)
let interactor = InviteInteractor()
let interactor = InviteInteractor(chatService: app.chatService)
let presenter = InvitePresenter(interactor: interactor, router: router)
let view = InviteView().environmentObject(presenter)
let viewController = SceneViewController(viewModel: presenter, content: view)
Expand Down
Loading

0 comments on commit 14d204b

Please sign in to comment.