|
|
@@ -947,9 +947,55 @@ private extension ViewController {
|
|
947
|
947
|
return
|
|
948
|
948
|
}
|
|
949
|
949
|
|
|
950
|
|
- guard let url = URL(string: "https://meet.google.com/new") else { return }
|
|
951
|
|
- openInDefaultBrowser(url: url)
|
|
952
|
|
- consumeNonPremiumJoinTrialIfNeeded()
|
|
|
950
|
+ // Meet blocks WKWebView. To support instant-stop recording we must create a real Meet space (with meeting code)
|
|
|
951
|
+ // before launching the user's browser.
|
|
|
952
|
+ guard hasGoogleSessionAvailable() else {
|
|
|
953
|
+ showSimpleAlert(
|
|
|
954
|
+ title: "Connect Google to start Instant Meeting",
|
|
|
955
|
+ message: "To auto-stop recording when the meeting ends, connect your Google account first."
|
|
|
956
|
+ )
|
|
|
957
|
+ guard let fallbackURL = URL(string: "https://meet.google.com/new") else { return }
|
|
|
958
|
+ openInDefaultBrowser(url: fallbackURL)
|
|
|
959
|
+ consumeNonPremiumJoinTrialIfNeeded()
|
|
|
960
|
+ return
|
|
|
961
|
+ }
|
|
|
962
|
+
|
|
|
963
|
+ let title = "Instant Meeting"
|
|
|
964
|
+ let consentChoice = requestMeetingRecordingConsent(title: title)
|
|
|
965
|
+ if consentChoice == .dismissed { return }
|
|
|
966
|
+
|
|
|
967
|
+ meetingRecordingMonitorTask?.cancel()
|
|
|
968
|
+ meetingRecordingMonitorTask = nil
|
|
|
969
|
+ if activeMeetingRecordingSession != nil { finishActiveMeetingRecording(cancelMonitoring: false) }
|
|
|
970
|
+
|
|
|
971
|
+ Task { [weak self] in
|
|
|
972
|
+ guard let self else { return }
|
|
|
973
|
+ do {
|
|
|
974
|
+ let now = Date()
|
|
|
975
|
+ let end = now.addingTimeInterval(60 * 60) // 1h placeholder; Meet lifecycle monitor will stop recording when call ends.
|
|
|
976
|
+ let token = try await self.googleOAuth.validAccessToken(presentingWindow: self.view.window)
|
|
|
977
|
+ let meeting = try await self.calendarClient.createEvent(
|
|
|
978
|
+ accessToken: token,
|
|
|
979
|
+ title: title,
|
|
|
980
|
+ description: nil,
|
|
|
981
|
+ start: now,
|
|
|
982
|
+ end: end
|
|
|
983
|
+ )
|
|
|
984
|
+
|
|
|
985
|
+ DispatchQueue.main.async {
|
|
|
986
|
+ if consentChoice == .allowAndContinue {
|
|
|
987
|
+ // Start Meet API-based recording lifecycle monitoring using the real meeting URL (has code).
|
|
|
988
|
+ self.startAutomaticRecordingFlow(meetingTitle: title, meetingURL: meeting.meetURL)
|
|
|
989
|
+ }
|
|
|
990
|
+ self.openInDefaultBrowser(url: meeting.meetURL)
|
|
|
991
|
+ self.consumeNonPremiumJoinTrialIfNeeded()
|
|
|
992
|
+ }
|
|
|
993
|
+ } catch {
|
|
|
994
|
+ DispatchQueue.main.async {
|
|
|
995
|
+ self.showSimpleAlert(title: "Could not create Instant Meeting", message: error.localizedDescription)
|
|
|
996
|
+ }
|
|
|
997
|
+ }
|
|
|
998
|
+ }
|
|
953
|
999
|
}
|
|
954
|
1000
|
|
|
955
|
1001
|
private func consumeNonPremiumJoinTrialIfNeeded() {
|