117 lines
4.3 KiB
Swift
117 lines
4.3 KiB
Swift
import Messages
|
|
import SwiftUI
|
|
import UIKit
|
|
|
|
class MessagesViewController: MSMessagesAppViewController {
|
|
private let gameController = GameController()
|
|
private var hostingController: UIHostingController<RootView>?
|
|
private var currentSession: MSSession?
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
gameController.onRequestExpand = { [weak self] in
|
|
self?.requestPresentationStyle(.expanded)
|
|
}
|
|
gameController.onRequestCollapse = { [weak self] in
|
|
self?.requestPresentationStyle(.compact)
|
|
}
|
|
gameController.onShareGame = { [weak self] gameID, password, caption, newSession in
|
|
self?.insertGameMessage(
|
|
gameID: gameID,
|
|
password: password,
|
|
caption: caption,
|
|
newSession: newSession
|
|
)
|
|
}
|
|
embedRootIfNeeded()
|
|
}
|
|
|
|
override func willBecomeActive(with conversation: MSConversation) {
|
|
apply(conversation: conversation, style: presentationStyle)
|
|
embedRootIfNeeded()
|
|
}
|
|
|
|
override func didResignActive(with conversation: MSConversation) {
|
|
gameController.stopPolling()
|
|
}
|
|
|
|
override func didReceive(_ message: MSMessage, conversation: MSConversation) {
|
|
apply(conversation: conversation, style: presentationStyle)
|
|
}
|
|
|
|
override func didCancelSending(_ message: MSMessage, conversation: MSConversation) {
|
|
apply(conversation: conversation, style: presentationStyle)
|
|
}
|
|
|
|
override func willTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
|
|
gameController.presentationStyle = chrome(for: presentationStyle)
|
|
}
|
|
|
|
override func didTransition(to presentationStyle: MSMessagesAppPresentationStyle) {
|
|
gameController.presentationStyle = chrome(for: presentationStyle)
|
|
}
|
|
|
|
private func apply(conversation: MSConversation, style: MSMessagesAppPresentationStyle) {
|
|
if let selected = conversation.selectedMessage {
|
|
currentSession = selected.session
|
|
}
|
|
gameController.configureMessages(
|
|
style: chrome(for: style),
|
|
remoteParticipantCount: conversation.remoteParticipantIdentifiers.count,
|
|
gameURL: conversation.selectedMessage?.url
|
|
)
|
|
}
|
|
|
|
private func chrome(for style: MSMessagesAppPresentationStyle) -> PresentationChrome {
|
|
style == .expanded ? .expanded : .compact
|
|
}
|
|
|
|
private func insertGameMessage(
|
|
gameID: Int,
|
|
password: String?,
|
|
caption: String,
|
|
newSession: Bool
|
|
) {
|
|
guard let conversation = activeConversation else {
|
|
gameController.errorMessage = "No active conversation to send into."
|
|
return
|
|
}
|
|
let session = newSession ? nil : (conversation.selectedMessage?.session ?? currentSession)
|
|
let message = MSMessage(session: session ?? MSSession())
|
|
message.url = MessageGameID.url(gameID: gameID, password: password)
|
|
message.summaryText = caption
|
|
|
|
let layout = MSMessageTemplateLayout()
|
|
layout.caption = "Six Card Golf"
|
|
layout.subcaption = caption
|
|
layout.trailingCaption = "#\(gameID)"
|
|
message.layout = layout
|
|
|
|
currentSession = message.session
|
|
// `send` delivers immediately (no compose-field Send tap), like Game Pigeon.
|
|
conversation.send(message) { [weak self] error in
|
|
DispatchQueue.main.async {
|
|
if let error {
|
|
self?.gameController.errorMessage = error.localizedDescription
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private func embedRootIfNeeded() {
|
|
guard hostingController == nil else { return }
|
|
let hosting = UIHostingController(rootView: RootView(controller: gameController))
|
|
hostingController = hosting
|
|
addChild(hosting)
|
|
hosting.view.translatesAutoresizingMaskIntoConstraints = false
|
|
hosting.view.backgroundColor = .clear
|
|
view.addSubview(hosting.view)
|
|
NSLayoutConstraint.activate([
|
|
hosting.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
hosting.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
|
hosting.view.topAnchor.constraint(equalTo: view.topAnchor),
|
|
hosting.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
|
])
|
|
hosting.didMove(toParent: self)
|
|
}
|
|
}
|