Skip to content

Commit

Permalink
Merge pull request #6 from pexip/feature/live-captions-filters
Browse files Browse the repository at this point in the history
Add live captions and video filters
  • Loading branch information
vadymmarkov authored Aug 2, 2022
2 parents 9d7c942 + b129bc8 commit 248840e
Show file tree
Hide file tree
Showing 18 changed files with 627 additions and 275 deletions.
205 changes: 90 additions & 115 deletions Examples/SPM/Example.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@
value = "YES"
isEnabled = "YES">
</AdditionalOption>
<AdditionalOption
key = "MallocScribble"
value = ""
isEnabled = "YES">
</AdditionalOption>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
Expand Down
11 changes: 8 additions & 3 deletions Examples/SPM/SwiftUI/Shared/App/ViewFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ protocol ViewFactoryProtocol {
struct ViewFactory: ViewFactoryProtocol {
private let apiClientFactory = InfinityClientFactory()
private let conferenceFactory = ConferenceFactory()
private let settings = Settings()

func displayNameView(
onComplete: @escaping () -> Void
Expand Down Expand Up @@ -87,17 +88,17 @@ struct ViewFactory: ViewFactoryProtocol {
conference: conference,
mediaConnectionConfig: mediaConnectionConfig,
mediaConnectionFactory: mediaConnectionFactory,
settings: settings,
onComplete: onComplete
)
return ConferenceView(viewModel: viewModel)
}

func chatView(
chat: Chat,
roster: Roster,
store: ChatMessageStore,
onDismiss: @escaping () -> Void
) -> ChatView {
let viewModel = ChatViewModel(chat: chat, roster: roster)
let viewModel = ChatViewModel(store: store)
return ChatView(viewModel: viewModel, onDismiss: onDismiss)
}

Expand All @@ -121,6 +122,10 @@ struct ViewFactory: ViewFactoryProtocol {
return ScreenMediaSourcePicker(viewModel: viewModel)
}
#endif

func settingsView() -> SettingsView {
SettingsView(settings: settings)
}
}

// MARK: - Environment
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "background_image.jpg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 4 additions & 3 deletions Examples/SPM/SwiftUI/Shared/Components/CallButtons.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ struct ParticipantsButton: View {

var body: some View {
CircleButton(
icon: "person.2",
icon: "person.2.fill",
background: Color.clear,
font: .title2,
action: action
Expand All @@ -93,7 +93,7 @@ struct ChatButton: View {

var body: some View {
CircleButton(
icon: "text.bubble",
icon: "text.bubble.fill",
background: Color.clear,
font: .title2,
action: action
Expand All @@ -120,12 +120,13 @@ private struct CircleButton<Background: ShapeStyle>: View {
.background(background)
.clipShape(Circle())
}
.shadow(radius: 4)
.preferredColorScheme(.dark)
.buttonStyle(PlainButtonStyle())
}
}

private struct SystemIcon: View {
struct SystemIcon: View {
let name: String
let font: Font
var foregroundColor: Color = .white
Expand Down
15 changes: 15 additions & 0 deletions Examples/SPM/SwiftUI/Shared/Extensions/CGImage+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import SwiftUI

extension CGImage {
static func withName(_ name: String) -> CGImage? {
#if os(iOS)
return UIImage(named: "background_image")?.cgImage
#else
return NSImage(named: "background_image")?.cgImage(
forProposedRect: nil,
context: nil,
hints: nil
)
#endif
}
}
74 changes: 74 additions & 0 deletions Examples/SPM/SwiftUI/Shared/Screens/Chat/ChatMessageStore.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import Foundation
import PexipConference
import Combine

final class ChatMessageStore: ObservableObject {
@Published private(set) var messages = [Chat.Message]()
private let chat: Chat
private var cancellables = Set<AnyCancellable>()

// MARK: - Init

init(chat: Chat, roster: Roster, messages: [Chat.Message] = []) {
self.chat = chat

chat.publisher.sink(receiveValue: { [weak self] message in
self?.messages.append(.init(
title: message.senderName,
text: message.payload,
date: message.receivedAt
))
}).store(in: &cancellables)

roster.eventPublisher.sink(receiveValue: { [weak self] event in
guard let self = self else { return }

let senderName = "Chatbot"

switch event {
case .added(let participant):
self.messages.append(.init(
title: senderName,
text: "\(participant.displayName) joined"
))
case .deleted(let participant):
self.messages.append(.init(
title: senderName,
text: "\(participant.displayName) left"
))
case .updated, .reloaded:
break
}
}).store(in: &cancellables)
}

// MARK: - Internal

func addMessage(_ text: String) async throws -> Bool {
guard !text.isEmpty else {
return false
}

return try await !chat.sendMessage(text)
}
}

// MARK: - Message

extension Chat {
struct Message: Hashable {
static let dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm"
return dateFormatter
}()

let title: String
let text: String
var date = Date()

var timeString: String {
Self.dateFormatter.string(from: date)
}
}
}
50 changes: 27 additions & 23 deletions Examples/SPM/SwiftUI/Shared/Screens/Chat/ChatView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct ChatView: View {
// MARK: - Subviews

private struct ChatMessageCell: View {
let message: ChatViewModel.Message
let message: Chat.Message

var body: some View {
VStack(alignment: .leading, spacing: 5) {
Expand Down Expand Up @@ -136,29 +136,33 @@ struct ChatView_Previews: PreviewProvider {
}

static var chatView: ChatView {
let chat = Chat(
senderName: "User Name",
senderId: UUID(),
sendMessage: { _ in true }
)
let roster = Roster(
currentParticipantId: UUID(),
currentParticipantName: "User Name",
avatarURL: { _ in nil }
)
let viewModel = ChatViewModel(
chat: Chat(
senderName: "User Name",
senderId: UUID(),
sendMessage: { _ in true }
),
roster: Roster(
currentParticipantId: UUID(),
currentParticipantName: "User Name",
avatarURL: { _ in nil }
),
messages: [
.init(title: "Chatbot", text: "User Name joined"),
.init(title: "User Name", text: "Hello!"),
.init(
title: "Participant",
text: """
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo.
"""
)
]
store: ChatMessageStore(
chat: chat,
roster: roster,
messages: [
.init(title: "Chatbot", text: "User Name joined"),
.init(title: "User Name", text: "Hello!"),
.init(
title: "Participant",
text: """
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo.
"""
)
]
)
)
return ChatView(viewModel: viewModel, onDismiss: {})
}
Expand Down
72 changes: 9 additions & 63 deletions Examples/SPM/SwiftUI/Shared/Screens/Chat/ChatViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,28 @@ import Combine
import PexipConference

final class ChatViewModel: ObservableObject {
@Published private(set) var messages: [Message]
@Published private(set) var messages: [Chat.Message]
@Published var text = ""
@Published var showingErrorBadge = false
var canSend: Bool {
!text.isEmpty
}
private let chat: Chat
private let roster: Roster
private let store: ChatMessageStore
private var cancellables = Set<AnyCancellable>()

// MARK: - Init

init(chat: Chat, roster: Roster, messages: [Message] = []) {
self.chat = chat
self.roster = roster
self.messages = messages
init(store: ChatMessageStore) {
self.store = store
self.messages = store.messages
addEventListeners()
}

// MARK: - Actions

func send() {
guard canSend else {
return
}

showingErrorBadge = false

Task { @MainActor in
do {
showingErrorBadge = try await !chat.sendMessage(text)
showingErrorBadge = try await !store.addMessage(text)
} catch {
showingErrorBadge = true
debugPrint("Cannot send message, error: \(error)")
Expand All @@ -53,53 +44,8 @@ final class ChatViewModel: ObservableObject {
self?.showingErrorBadge = false
}.store(in: &cancellables)

chat.publisher.sink(receiveValue: { [weak self] message in
self?.messages.append(Message(
title: message.senderName,
text: message.payload,
date: message.receivedAt
))
}).store(in: &cancellables)

roster.eventPublisher.sink(receiveValue: { [weak self] event in
guard let self = self else { return }

let senderName = "Chatbot"

switch event {
case .added(let participant):
self.messages.append(Message(
title: senderName,
text: "\(participant.displayName) joined"
))
case .deleted(let participant):
self.messages.append(Message(
title: senderName,
text: "\(participant.displayName) left"
))
case .updated, .reloaded:
break
}
}).store(in: &cancellables)
}
}

// MARK: - Message

extension ChatViewModel {
struct Message: Hashable {
static let dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm"
return dateFormatter
}()

let title: String
let text: String
var date = Date()

var timeString: String {
Self.dateFormatter.string(from: date)
}
store.$messages.sink { [weak self] messages in
self?.messages = messages
}.store(in: &cancellables)
}
}
Loading

0 comments on commit 248840e

Please sign in to comment.