oficina / meet Public

Restore recent accounts and return from native browser sign-in

Reviewed by GPT-6 Astra. Add saved account switching, app URL handlers, and domain-based Store bundle identifiers. Both Mac and iOS signed build 4 archives and exports verified under Team Tito.
Paul Campbell pushed by codex agent, operated by paul@keymail.dev 4f85f6eeed232a1a0e7566be16eb2de6ac27bcfc parent b3fd624
13 files changed, +308 −73
  • native/apple/Package.resolved +19 −19
  • native/apple/Package.swift +3 −3
  • native/apple/Sources/MeetKit/Call.swift +8 −0
  • native/apple/Sources/MeetKit/MeetAccountRoot.swift +23 −0
  • native/apple/Sources/MeetKit/MeetLobby.swift +6 −0
  • native/apple/Sources/MeetKit/MeetModel.swift +105 −6
  • native/apple/Sources/MeetMac/MeetMac.swift +11 −1
  • native/ios/Info.plist +35 −0
  • native/ios/Sources/MeetPhone.swift +15 −1
  • native/ios/project.yml +44 −26
  • native/macos/Info.plist +13 −0
  • native/macos/MeetMacStore.xcodeproj/project.pbxproj +4 −2
  • native/macos/project.yml +22 −15

CI passed — run details

diff --git a/native/apple/Package.resolved b/native/apple/Package.resolved
index dfd04e9..616b048 100644
--- a/native/apple/Package.resolved
+++ b/native/apple/Package.resolved
@@ -1,31 +1,31 @@
{
- "pins": [
+ "pins" : [
{
- "identity": "native",
- "kind": "remoteSourceControl",
- "location": "https://amadan.net/rastrillo/native",
- "state": {
- "revision": "4c61d6283a188c95647e1d0e609e69d29c2e7fa1"
+ "identity" : "native",
+ "kind" : "remoteSourceControl",
+ "location" : "https://amadan.net/rastrillo/native",
+ "state" : {
+ "revision" : "229525909e1d6ac3b6a353d1c4d022798b0e9a24"
}
},
{
- "identity": "sparkle",
- "kind": "remoteSourceControl",
- "location": "https://github.com/sparkle-project/Sparkle",
- "state": {
- "revision": "ac2def288cbff5cfc7df3ffef6abdf45b72bcb0a",
- "version": "2.9.6"
+ "identity" : "sparkle",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/sparkle-project/Sparkle",
+ "state" : {
+ "revision" : "ac2def288cbff5cfc7df3ffef6abdf45b72bcb0a",
+ "version" : "2.9.6"
}
},
{
- "identity": "webrtc",
- "kind": "remoteSourceControl",
- "location": "https://github.com/stasel/WebRTC.git",
- "state": {
- "revision": "1d04692697cb642bfebf6ad2dd99fe52649c3d6d",
- "version": "152.0.0"
+ "identity" : "webrtc",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/stasel/WebRTC.git",
+ "state" : {
+ "revision" : "1d04692697cb642bfebf6ad2dd99fe52649c3d6d",
+ "version" : "152.0.0"
}
}
],
- "version": 2
+ "version" : 2
}
diff --git a/native/apple/Package.swift b/native/apple/Package.swift
index 9328049..c9d2082 100644
--- a/native/apple/Package.swift
+++ b/native/apple/Package.swift
@@ -2,8 +2,8 @@
import PackageDescription
import Foundation
-let sharedNative: Package.Dependency = ProcessInfo.processInfo.environment["OFICINA_NATIVE_PACKAGE_PATH"].map { .package(path: $0) }
- ?? .package(url: "https://amadan.net/rastrillo/native", revision: "4c61d6283a188c95647e1d0e609e69d29c2e7fa1")
+let sharedNative: Package.Dependency = ProcessInfo.processInfo.environment["OFICINA_NATIVE_PACKAGE_PATH"].map { .package(name: "native", path: $0) }
+ ?? .package(url: "https://amadan.net/rastrillo/native", revision: "229525909e1d6ac3b6a353d1c4d022798b0e9a24")
let package = Package(
@@ -21,7 +21,7 @@ let package = Package(
targets: [
.binaryTarget(name: "MeetBridge", path: "../build/MeetBridge.xcframework"),
.target(
- name: "MeetKit", dependencies: ["MeetBridge", .product(name: "WebRTC", package: "WebRTC")]),
+ name: "MeetKit", dependencies: [.product(name: "RastrilloApple", package: "native"), "MeetBridge", .product(name: "WebRTC", package: "WebRTC")]),
.executableTarget(name: "MeetMac", dependencies: [.product(name: "RastrilloMacUpdates", package: "native", condition: .when(platforms: [.macOS])), "MeetKit"], resources: [.copy("Resources/AppIcon.png"), .copy("Resources/MacIcon.png")]),
.executableTarget(name: "MeetInterop", dependencies: ["MeetKit"]),
.testTarget(name: "MeetKitTests", dependencies: ["MeetKit"]),
diff --git a/native/apple/Sources/MeetKit/Call.swift b/native/apple/Sources/MeetKit/Call.swift
index a1fdfe9..5064464 100644
--- a/native/apple/Sources/MeetKit/Call.swift
+++ b/native/apple/Sources/MeetKit/Call.swift
@@ -86,6 +86,14 @@ private final class Events: NSObject, BridgeListenerProtocol {
localTrack = media.localVideo
try client.start()
}
+ public func clearAccount() {
+ close()
+ chat = []
+ receivedChatCount = 0
+ title = "Meet"
+ standing = ""
+ status = "Ready to join"
+ }
public func close() {
epoch = UUID()
let old = bridge
diff --git a/native/apple/Sources/MeetKit/MeetAccountRoot.swift b/native/apple/Sources/MeetKit/MeetAccountRoot.swift
new file mode 100644
index 0000000..8913007
--- /dev/null
+++ b/native/apple/Sources/MeetKit/MeetAccountRoot.swift
@@ -0,0 +1,23 @@
+import RastrilloApple
+import SwiftUI
+
+@MainActor public struct MeetAccountRoot<Content: View>: View {
+ @ObservedObject private var model: MeetModel
+ @ObservedObject private var connection: NativeConnection
+ private let content: Content
+ public init(model: MeetModel, @ViewBuilder content: () -> Content) {
+ self.model = model
+ self.connection = model.connection
+ self.content = content()
+ }
+ public var body: some View {
+ Group {
+ if connection.client == nil && !model.addingAccount {
+ NativeAccountsView("Oficina Meet", systemImage: "video", connection: connection,
+ addAccount: model.addAccount)
+ } else {
+ content
+ }
+ }.onOpenURL(perform: model.handleOpenURL)
+ }
+}
diff --git a/native/apple/Sources/MeetKit/MeetLobby.swift b/native/apple/Sources/MeetKit/MeetLobby.swift
index d824e8c..6d98602 100644
--- a/native/apple/Sources/MeetKit/MeetLobby.swift
+++ b/native/apple/Sources/MeetKit/MeetLobby.swift
@@ -61,6 +61,12 @@ import SwiftUI
#endif
.onSubmit(model.connect)
}
+ if model.addingAccount {
+ TextField("Account name (optional)", text: Binding(
+ get: { model.connection.accountName },
+ set: { model.connection.accountName = $0 }))
+ .textFieldStyle(.roundedBorder)
+ }
Button("Continue", systemImage: "arrow.right", action: model.connect)
.buttonStyle(.borderedProminent).keyboardShortcut(.defaultAction)
.disabled(model.address.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
diff --git a/native/apple/Sources/MeetKit/MeetModel.swift b/native/apple/Sources/MeetKit/MeetModel.swift
index 86af864..e403a4c 100644
--- a/native/apple/Sources/MeetKit/MeetModel.swift
+++ b/native/apple/Sources/MeetKit/MeetModel.swift
@@ -1,5 +1,6 @@
import Combine
import Foundation
+import RastrilloApple
@preconcurrency import MeetBridge
#if os(iOS)
@@ -23,9 +24,49 @@ import Foundation
@Published public var origin = ""
public let call = Call()
private var cookies = ""
- public init() {}
+ public let connection = NativeConnection(defaultServer: "https://meet.oficina.works")
+ @Published public var addingAccount = false
+ private let browser = NativeBrowserSignIn()
+ private var accountChanges: AnyCancellable?
+ public init() {
+ accountChanges = connection.objectWillChange.sink { [weak self] _ in self?.objectWillChange.send() }
+ }
+ public func showAccounts() {
+ guard !joining else { return }
+ cancelSignIn()
+ call.clearAccount()
+ connection.showAccounts()
+ signedIn = false
+ addingAccount = false
+ address = ""
+ room = ""
+ origin = ""
+ cookies = ""
+ }
+ public func signOut() {
+ guard !joining else { return }
+ connection.signOut()
+ showAccounts()
+ }
+ public func addAccount() {
+ showAccounts()
+ connection.accountName = ""
+ addingAccount = true
+ }
+ public func handleOpenURL(_ url: URL) {
+ guard let signin, let start = URLComponents(url: signin, resolvingAgainstBaseURL: false),
+ let id = start.queryItems?.first(where: { $0.name == "id" })?.value,
+ url.scheme == "works.oficina.meet", url.host == "signin", url.path.isEmpty,
+ URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems == [URLQueryItem(name: "state", value: id)] else { return }
+ browser.cancel()
+ }
+
public func connect() {
+ if let client = connection.client, !addingAccount {
+ connectSavedAccount(client)
+ return
+ }
cancelSignIn()
authenticating = true
error = ""
@@ -66,6 +107,11 @@ import Foundation
guard epoch == authEpoch else { return }
let data = Data(result.utf8)
let response = try JSONDecoder().decode(SignInResult.self, from: data)
+ guard response.cookies.count == 1, let approved = response.cookies.first,
+ let server = URL(string: response.origin) else { throw NativeClientError.message("Invalid sign-in response.") }
+ try connection.rememberSession(NativeSession(name: approved.name, value: approved.value), origin: server, name: connection.accountName)
+ addingAccount = false
+ browser.cancel()
cookies = String(data: try JSONEncoder().encode(response.cookies), encoding: .utf8)!
origin = response.origin
room = response.room
@@ -84,14 +130,16 @@ import Foundation
}
}
public func openBrowser(_ url: URL) async -> Bool {
- #if os(iOS)
- return await UIApplication.shared.open(url)
- #else
- return NSWorkspace.shared.open(url)
- #endif
+ let epoch = authEpoch
+ return browser.start(url: url, scheme: "works.oficina.meet") { [weak self] callback in
+ guard let self, self.authEpoch == epoch else { return }
+ if let callback { self.handleOpenURL(callback) } else { self.cancelSignIn() }
+ }
}
+
public func cancelSignIn() {
authEpoch = UUID()
+ browser.cancel()
authentication?.cancel()
authentication = nil
authenticating = false
@@ -107,6 +155,57 @@ import Foundation
let value: String
}
}
+ private func connectSavedAccount(_ client: NativeHTTP) {
+ cancelSignIn()
+ let epoch = authEpoch
+ error = ""
+ authenticating = true
+ let link = address.trimmingCharacters(in: .whitespacesAndNewlines)
+ Task {
+ do {
+ guard var components = URLComponents(string: link), components.user == nil,
+ components.password == nil, components.query == nil, components.fragment == nil else {
+ throw NativeClientError.message("Enter a full meeting or invitation link.")
+ }
+ var target = components.path
+ components.path = ""
+ guard components.url == client.origin else {
+ throw NativeClientError.message("Choose an account for this meeting’s server.")
+ }
+ if target.hasSuffix("/join") { target = String(target.dropLast(5)) }
+ func roomID(_ path: String, prefix: String) -> String? {
+ guard path.hasPrefix(prefix) else { return nil }
+ let id = String(path.dropFirst(prefix.count))
+ guard !id.isEmpty, id.count <= 128,
+ id.utf8.allSatisfy({ (65...90).contains($0) || (97...122).contains($0) || (48...57).contains($0) || $0 == 45 || $0 == 95 }) else { return nil }
+ return id
+ }
+ if roomID(target, prefix: "/j/") != nil {
+ let result = try await client.responseDetails(target)
+ guard result.status == 303, let location = result.headers["Location"] ?? result.headers["location"],
+ let redirected = URL(string: location), redirected.scheme == nil, redirected.host == nil,
+ redirected.query == nil, redirected.fragment == nil, redirected.path.hasSuffix("/join") else {
+ throw NativeClientError.message("This invitation is unavailable. Sign in again if your session has expired.")
+ }
+ target = String(redirected.path.dropLast(5))
+ }
+ guard let room = roomID(target, prefix: "/m/"), let credential = client.credential else {
+ throw NativeClientError.message("Enter a full meeting or invitation link.")
+ }
+ guard self.authEpoch == epoch else { return }
+ self.cookies = String(decoding: try JSONEncoder().encode([credential]), as: UTF8.self)
+ self.room = room
+ self.origin = client.origin.absoluteString
+ self.signedIn = true
+ self.authenticating = false
+ } catch {
+ guard self.authEpoch == epoch else { return }
+ self.error = error.localizedDescription
+ self.authenticating = false
+ }
+ }
+ }
+
public func join() {
callEpoch = UUID()
let operation = callEpoch
diff --git a/native/apple/Sources/MeetMac/MeetMac.swift b/native/apple/Sources/MeetMac/MeetMac.swift
index c76862a..673f580 100644
--- a/native/apple/Sources/MeetMac/MeetMac.swift
+++ b/native/apple/Sources/MeetMac/MeetMac.swift
@@ -15,7 +15,17 @@ import WebRTC
@StateObject private var model = MeetModel()
var body: some Scene {
Window("Meet", id: "main") {
- ContentView(model: model).frame(minWidth: 760, minHeight: 540).onDisappear { model.leave() }
+ MeetAccountRoot(model: model) {
+ NavigationStack {
+ ContentView(model: model)
+ .toolbar {
+ if !model.joining {
+ ToolbarItem(placement: .navigation) { Button("Accounts", systemImage: "chevron.backward", action: model.showAccounts) }
+ ToolbarItem { Button("Sign out", action: model.signOut).disabled(model.connection.client == nil) }
+ }
+ }
+ }
+ }.frame(minWidth: 760, minHeight: 540).onDisappear { model.leave() }
}
.defaultSize(width: 1000, height: 760)
.commands {
diff --git a/native/ios/Info.plist b/native/ios/Info.plist
new file mode 100644
index 0000000..8d035b4
--- /dev/null
+++ b/native/ios/Info.plist
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>$(MARKETING_VERSION)</string>
+ <key>CFBundleURLTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>CFBundleURLName</key>
+ <string>works.oficina.meet.signin</string>
+ <key>CFBundleURLSchemes</key>
+ <array>
+ <string>works.oficina.meet</string>
+ </array>
+ </dict>
+ </array>
+ <key>CFBundleVersion</key>
+ <string>$(CURRENT_PROJECT_VERSION)</string>
+</dict>
+</plist>
diff --git a/native/ios/Sources/MeetPhone.swift b/native/ios/Sources/MeetPhone.swift
index adf6cdb..b30e551 100644
--- a/native/ios/Sources/MeetPhone.swift
+++ b/native/ios/Sources/MeetPhone.swift
@@ -7,7 +7,7 @@ import WebRTC
@Environment(\.scenePhase) private var scenePhase
var body: some Scene {
WindowGroup {
- PhoneHome(model: model)
+ MeetAccountRoot(model: model) { PhoneHome(model: model) }
.onChange(of: scenePhase) { _, phase in
// This milestone is foreground-only. Browser sign-in is kept alive;
// an active call leaves cleanly instead of silently sending audio.
@@ -32,6 +32,20 @@ struct PhoneHome: View {
MeetLobby(model: model)
}
}.tint(MeetAppearance.accent).navigationTitle("Meet").navigationBarTitleDisplayMode(.inline)
+ .toolbar {
+ if !model.joining {
+ ToolbarItem(placement: .topBarLeading) {
+ Button("Accounts", systemImage: "chevron.backward", action: model.showAccounts)
+ }
+ ToolbarItem(placement: .topBarTrailing) {
+ if model.connection.client != nil {
+ Menu("More", systemImage: "ellipsis") {
+ Button("Sign out", role: .destructive, action: model.signOut)
+ }
+ }
+ }
+ }
+ }
}
}
}
diff --git a/native/ios/project.yml b/native/ios/project.yml
index b3d8629..271439b 100644
--- a/native/ios/project.yml
+++ b/native/ios/project.yml
@@ -10,55 +10,71 @@ settings:
base:
SWIFT_VERSION: '5.0'
CODE_SIGN_STYLE: Automatic
- MARKETING_VERSION: '0.2.0'
+ MARKETING_VERSION: 0.2.0
CURRENT_PROJECT_VERSION: '1'
targets:
MeetPhone:
type: application
platform: iOS
sources:
- - Sources
- - Assets.xcassets
- - path: ../LICENSE.lucide
- buildPhase: resources
- - path: ../PrivacyInfo.xcprivacy
- buildPhase: resources
+ - Sources
+ - Assets.xcassets
+ - path: ../LICENSE.lucide
+ buildPhase: resources
+ - path: ../PrivacyInfo.xcprivacy
+ buildPhase: resources
dependencies:
- - package: MeetNative
- product: MeetKit
+ - package: MeetNative
+ product: MeetKit
settings:
base:
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
- PRODUCT_BUNDLE_IDENTIFIER: net.amadan.oficina.meet.ios
- TARGETED_DEVICE_FAMILY: '1,2'
- GENERATE_INFOPLIST_FILE: YES
+ PROVISIONING_PROFILE_SPECIFIER: $(OFICINA_PROVISIONING_PROFILE)
+ PRODUCT_BUNDLE_IDENTIFIER: works.oficina.meet
+ TARGETED_DEVICE_FAMILY: 1,2
+ GENERATE_INFOPLIST_FILE: true
INFOPLIST_KEY_CFBundleDisplayName: Meet
- INFOPLIST_KEY_NSCameraUsageDescription: Meet uses your camera so people in your meeting can see you.
- INFOPLIST_KEY_NSMicrophoneUsageDescription: Meet uses your microphone so people in your meeting can hear you.
- INFOPLIST_KEY_UILaunchScreen_Generation: YES
- INFOPLIST_KEY_UISupportedInterfaceOrientations: UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortraitUpsideDown
+ INFOPLIST_KEY_NSCameraUsageDescription: Meet uses your camera so people in
+ your meeting can see you.
+ INFOPLIST_KEY_NSMicrophoneUsageDescription: Meet uses your microphone so people
+ in your meeting can hear you.
+ INFOPLIST_KEY_UILaunchScreen_Generation: true
+ INFOPLIST_KEY_UISupportedInterfaceOrientations: UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight
+ UIInterfaceOrientationPortraitUpsideDown
+ info:
+ path: Info.plist
+ properties:
+ CFBundleURLTypes:
+ - CFBundleURLName: works.oficina.meet.signin
+ CFBundleURLSchemes:
+ - works.oficina.meet
+ CFBundleTypeRole: Editor
+ CFBundleShortVersionString: $(MARKETING_VERSION)
+ CFBundleVersion: $(CURRENT_PROJECT_VERSION)
MeetPhoneTests:
type: bundle.unit-test
platform: iOS
sources:
- - Tests
- - ../apple/Sources/MeetInterop/SyntheticVideo.swift
+ - Tests
+ - ../apple/Sources/MeetInterop/SyntheticVideo.swift
dependencies:
- - target: MeetPhone
- - package: MeetNative
- product: MeetKit
+ - target: MeetPhone
+ - package: MeetNative
+ product: MeetKit
settings:
base:
- GENERATE_INFOPLIST_FILE: YES
+ GENERATE_INFOPLIST_FILE: true
MeetPhoneUITests:
type: bundle.ui-testing
platform: iOS
- sources: [UITests]
+ sources:
+ - UITests
dependencies:
- - target: MeetPhone
+ - target: MeetPhone
settings:
base:
- GENERATE_INFOPLIST_FILE: YES
+ GENERATE_INFOPLIST_FILE: true
TEST_TARGET_NAME: MeetPhone
info:
path: ../build/ios-test-info.plist
@@ -71,4 +87,6 @@ schemes:
targets:
MeetPhone: all
test:
- targets: [MeetPhoneUITests, MeetPhoneTests]
+ targets:
+ - MeetPhoneUITests
+ - MeetPhoneTests
diff --git a/native/macos/Info.plist b/native/macos/Info.plist
index 9a21cb5..3a2bb38 100644
--- a/native/macos/Info.plist
+++ b/native/macos/Info.plist
@@ -20,6 +20,19 @@
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
+ <key>CFBundleURLTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>CFBundleURLName</key>
+ <string>works.oficina.meet.signin</string>
+ <key>CFBundleURLSchemes</key>
+ <array>
+ <string>works.oficina.meet</string>
+ </array>
+ </dict>
+ </array>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSApplicationCategoryType</key>
diff --git a/native/macos/MeetMacStore.xcodeproj/project.pbxproj b/native/macos/MeetMacStore.xcodeproj/project.pbxproj
index e1788bc..41f21c2 100644
--- a/native/macos/MeetMacStore.xcodeproj/project.pbxproj
+++ b/native/macos/MeetMacStore.xcodeproj/project.pbxproj
@@ -196,7 +196,8 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = net.amadan.oficina.meet;
+ PRODUCT_BUNDLE_IDENTIFIER = works.oficina.meet;
+ PROVISIONING_PROFILE_SPECIFIER = "$(OFICINA_PROVISIONING_PROFILE)";
SDKROOT = macosx;
};
name = Release;
@@ -339,7 +340,8 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = net.amadan.oficina.meet;
+ PRODUCT_BUNDLE_IDENTIFIER = works.oficina.meet;
+ PROVISIONING_PROFILE_SPECIFIER = "$(OFICINA_PROVISIONING_PROFILE)";
SDKROOT = macosx;
};
name = Debug;
diff --git a/native/macos/project.yml b/native/macos/project.yml
index 30444fc..f231f7c 100644
--- a/native/macos/project.yml
+++ b/native/macos/project.yml
@@ -12,26 +12,26 @@ settings:
base:
SWIFT_VERSION: '5.0'
CODE_SIGN_STYLE: Automatic
- MARKETING_VERSION: '0.1.0'
+ MARKETING_VERSION: 0.1.0
CURRENT_PROJECT_VERSION: '3'
- ENABLE_HARDENED_RUNTIME: YES
+ ENABLE_HARDENED_RUNTIME: true
targets:
MeetMacStore:
type: application
platform: macOS
sources:
- - ../apple/Sources/MeetMac
- - path: AppIcon.icns
- buildPhase: resources
- - path: ../LICENSE.lucide
- buildPhase: resources
- - path: ../PrivacyInfo.xcprivacy
- buildPhase: resources
+ - ../apple/Sources/MeetMac
+ - path: AppIcon.icns
+ buildPhase: resources
+ - path: ../LICENSE.lucide
+ buildPhase: resources
+ - path: ../PrivacyInfo.xcprivacy
+ buildPhase: resources
dependencies:
- - package: MeetNative
- product: MeetKit
- - package: WebRTC
- product: WebRTC
+ - package: MeetNative
+ product: MeetKit
+ - package: WebRTC
+ product: WebRTC
info:
path: Info.plist
properties:
@@ -43,8 +43,15 @@ targets:
LSApplicationCategoryType: public.app-category.productivity
NSHighResolutionCapable: true
NSCameraUsageDescription: Meet uses your camera to share video in a meeting.
- NSMicrophoneUsageDescription: Meet uses your microphone so people in the meeting can hear you.
+ NSMicrophoneUsageDescription: Meet uses your microphone so people in the meeting
+ can hear you.
+ CFBundleURLTypes:
+ - CFBundleURLName: works.oficina.meet.signin
+ CFBundleURLSchemes:
+ - works.oficina.meet
+ CFBundleTypeRole: Editor
settings:
base:
- PRODUCT_BUNDLE_IDENTIFIER: net.amadan.oficina.meet
+ PROVISIONING_PROFILE_SPECIFIER: $(OFICINA_PROVISIONING_PROFILE)
+ PRODUCT_BUNDLE_IDENTIFIER: works.oficina.meet
CODE_SIGN_ENTITLEMENTS: AppStore.entitlements