Compare commits

...

15 Commits

Author SHA1 Message Date
Alex Bumbu
1893ced556 iOS: toggle audio mute & leave meeting lock screen widgets (#12581) 2022-11-18 13:25:48 +02:00
Calin-Teodor
7d9c13a618 feat(prejoin): updated styles 2022-11-18 11:02:05 +02:00
Hristo Terezov
48ed3b7dc6 fix(dialog): cancel hide timeout on openDialog
Since we unmount the dialog after a timeout because of an animation we
need to cancel the timeout in case we need to render new dialog.
Otherwise the actual hiding can be executed after we render the new
dialog.
2022-11-17 17:00:02 -06:00
Hristo Terezov
04abfe1a3b feat(dialog): add disableAutoHideOnSubmit prop
Needed for shared video dialog.
2022-11-17 17:00:02 -06:00
Alex Bumbu
d45decc393 Update JitsiMeet.h (#12574) 2022-11-17 16:31:37 +02:00
Saúl Ibarra Corretgé
88f8f48465 fix(participants) don't treat Jigasi like a fake participant
We only really want to know if a participant is Jigasi for displaying a
specific icon, for all other intents and purposes it's a normal
participant.
2022-11-17 15:13:54 +01:00
Saúl Ibarra Corretgé
8127ea2479 feat(redux) throw exception in case invalid listeners are registered
This allows catching mistakes early.
2022-11-17 11:07:57 +01:00
Saúl Ibarra Corretgé
b22915c169 fix(rn,filmstrip) fix invalid selector registered as state listener 2022-11-17 11:07:57 +01:00
Saúl Ibarra Corretgé
14fcd153e5 fix(rn,connection-indicator) align rendering with web
Use the same way for calculating que perceived quality and display it.
2022-11-17 11:07:57 +01:00
Robert Pintilii
48efe36cdf fix(dial-in) Fix warning (#12571)
Only show warning if the feature is enabled
2022-11-16 12:14:58 +02:00
Saúl Ibarra Corretgé
0c373e105b ref(StageFilmstrip) mark as experimental
THere are a bunch of unhandled corner cases involving virtual
screen-sharing participants.
2022-11-15 10:34:58 -06:00
Shawn
e57c7f92a8 refactor(end-conference): distinguish between component vs host module logic 2022-11-15 10:34:40 -06:00
Jaya Allamsetty
70fa44f85f chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1533.0.0+7b257686...v1535.0.0+e6263e7c
2022-11-15 11:08:37 -05:00
rinenweb
bcc5beb73d fix(lang) fixup main-el.json
Missing "{" in line 74 and name is not displayed at all when {name} is used in line 520.
2022-11-15 09:41:43 +01:00
Joseph Garrone
4ef4e45ee4 fix(styles) Remove Theme type annotation (#12544)
* tss-react doesn't need a type anotation for the Theme

* Update tss-react to 4.4.4
2022-11-15 09:50:22 +02:00
121 changed files with 1571 additions and 373 deletions

View File

@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,13 @@
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "end_call_button.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "microphone_off_button.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "microphone_on_button.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,101 @@
//
// DarwinNotificationsObserver.swift
// WidgetsExtension
//
// Created by Alex Bumbu on 17.10.2022.
//
import Foundation
enum DarwinNotification: String {
case meetingMutedChanged = "iOS_MeetingMutedChanged"
}
extension DarwinNotification {
var name: String { rawValue }
}
class DarwinNotificationsObserver {
private static var observers = Array<ProxyObserver>()
private let queue = DispatchQueue(label: "org.jitsi.meet.darwinNotificationObserver", qos: .default, autoreleaseFrequency: .workItem)
private var notificationCenter: CFNotificationCenter
init() {
notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
}
func observe(notification: DarwinNotification, handler: @escaping () -> Void) {
let proxyObserver = ProxyObserver(observer: self, notificationName: notification.name, handler: handler)
queue.async {
DarwinNotificationsObserver.observers.append(proxyObserver)
}
let callback: CFNotificationCallback = { _, observer, name, _, _ in
guard let observer = observer else {
return
}
// Extract pointer to `observer` from void pointer:
let proxyObserver = Unmanaged<ProxyObserver>.fromOpaque(observer).takeUnretainedValue()
var observers = DarwinNotificationsObserver.observers
if !proxyObserver.forwardNotification(), let index = observers.firstIndex(of: proxyObserver) {
// cleanup if `forwardNotification` fails
observers.remove(at: index)
}
}
CFNotificationCenterAddObserver(notificationCenter,
Unmanaged.passUnretained(proxyObserver).toOpaque(),
callback,
notification.name as CFString,
nil,
.deliverImmediately)
}
func stopObserving(notification: DarwinNotification) {
queue.sync {
DarwinNotificationsObserver.observers.removeAll { $0.observer == nil }
}
if let index = DarwinNotificationsObserver.observers.firstIndex(where: { $0.observer === self && $0.notificationName == notification.name }) {
let proxyObserver = DarwinNotificationsObserver.observers[index]
CFNotificationCenterRemoveObserver(notificationCenter,
Unmanaged.passUnretained(proxyObserver).toOpaque(),
CFNotificationName(notification.name as CFString),
nil)
queue.async {
DarwinNotificationsObserver.observers.remove(at: index)
}
}
}
}
private class ProxyObserver: Equatable {
let notificationName: String
weak var observer: AnyObject?
private let handler: () -> (Void)
static func == (lhs: ProxyObserver, rhs: ProxyObserver) -> Bool {
lhs.observer === rhs.observer && lhs.notificationName == rhs.notificationName
}
init(observer: AnyObject? = nil, notificationName: String, handler: @escaping () -> Void) {
self.notificationName = notificationName
self.handler = handler
self.observer = observer
}
func forwardNotification() -> Bool {
guard observer != nil else {
return false
}
handler()
return true
}
}

View File

@@ -0,0 +1,11 @@
<?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>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.widgetkit-extension</string>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,54 @@
//
// LockScreenLeaveMeetingWidget.swift
// WidgetsExtension
//
// Created by Alex Bumbu on 31.10.2022.
//
import SwiftUI
import WidgetKit
struct LockScreenLeaveMeetingWidget: Widget {
let kind: String = "LockScreenLeaveMeetingWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
WidgetsEntryView(entry: entry)
}
.configurationDisplayName("Leave Jitsi Meeting Widget")
.description("This is a lockscreen widget for leaving the ongoing Jitsi meeting.")
.supportedFamilies([.accessoryCircular])
}
}
//struct LockScreenLeaveMeetingWidget_Preview: PreviewProvider {
// static var previews: some View {
// let meetingState = MeetingState(audioMuted: true)
//
// WidgetsEntryView(entry: CurrentMeetingEntry(date: Date(), meetingState: meetingState))
// .previewContext(WidgetPreviewContext(family: .accessoryCircular))
// .previewDisplayName("Circular")
// }
//}
private struct WidgetsEntryView: View {
@Environment(\.widgetFamily) var widgetFamily
var entry: Provider.Entry
var body: some View {
if entry.meetingState != nil, widgetFamily == .accessoryCircular {
AccessoryCircularWidgetView()
} else {
EmptyView()
}
}
}
private struct AccessoryCircularWidgetView: View {
var body: some View {
Image("leave_meeting")
.resizable()
.aspectRatio(contentMode: .fit)
.widgetURL(URL(string: "meet/leaveMeeting")!)
}
}

View File

@@ -0,0 +1,89 @@
//
// LockScreenMuteAudioWidget.swift
// WidgetsExtension
//
// Created by Alex Bumbu on 31.10.2022.
//
import SwiftUI
import WidgetKit
struct LockScreenMuteAudioWidget: Widget {
let kind: String = "LockScreenMuteAudioWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
WidgetsEntryView(entry: entry)
}
.configurationDisplayName("Mute Jitsi Audio Widget")
.description("This is a lockscreen widget for muting or unmuting the audio for the ongoing Jitsi meeting.")
.supportedFamilies([.accessoryCircular])
}
}
//struct LockScreenMuteAudioWidget_Preview: PreviewProvider {
// static var previews: some View {
// let meetingState = MeetingState(audioMuted: true)
//
// WidgetsEntryView(entry: CurrentMeetingEntry(date: Date(), meetingState: meetingState))
// .previewContext(WidgetPreviewContext(family: .accessoryInline))
// .previewDisplayName("Inline")
//
// WidgetsEntryView(entry: CurrentMeetingEntry(date: Date(), meetingState: meetingState))
// .previewContext(WidgetPreviewContext(family: .accessoryCircular))
// .previewDisplayName("Circular")
//
// WidgetsEntryView(entry: CurrentMeetingEntry(date: Date(), meetingState: meetingState))
// .previewContext(WidgetPreviewContext(family: .accessoryRectangular))
// .previewDisplayName("Rectangular")
// }
//}
private struct WidgetsEntryView: View {
@Environment(\.widgetFamily) var widgetFamily
var entry: Provider.Entry
var body: some View {
if let meetingState = entry.meetingState {
switch widgetFamily {
case .accessoryInline:
Text("Some meeting name")
case .accessoryRectangular:
AccessoryCircularWidgetView(audioMuted: meetingState.audioMuted)
case .accessoryCircular:
AccessoryCircularWidgetView(audioMuted: meetingState.audioMuted)
default:
EmptyView()
}
} else {
EmptyView()
}
}
}
private struct AccessoryRectangularWidgetView: View {
var audioMuted: Bool
var body: some View {
let imageName: String = audioMuted ? "microphone_on" : "microphone_off"
let caption: String = audioMuted ? "Unmute \naudio" : "Mute \naudio"
HStack {
Image(imageName)
.resizable()
.aspectRatio(contentMode: .fit)
Text(caption)
}.widgetURL(URL(string: "meet/toggleAudioMute")!)
}
}
private struct AccessoryCircularWidgetView: View {
var audioMuted: Bool
var body: some View {
let imageName: String = audioMuted ? "microphone_on" : "microphone_off"
Image(imageName)
.resizable()
.aspectRatio(contentMode: .fit)
.widgetURL(URL(string: "meet/toggleAudioMute")!)
}
}

View File

@@ -0,0 +1,30 @@
//
// MeetingState.swift
// WidgetsExtension
//
// Created by Alex Bumbu on 28.10.2022.
//
import Foundation
struct MeetingState: Decodable {
var audioMuted: Bool
}
extension MeetingState {
private static var stateFileURL: URL? {
return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.org.jitsi.meet.appgroup")?.appending(component: "widgetState")
}
static func load() -> MeetingState? {
guard
let stateFileURL = stateFileURL,
let data = try? Data(contentsOf: stateFileURL)
else {
return nil
}
let decoder = PropertyListDecoder()
return try? decoder.decode(MeetingState.self, from: data)
}
}

View File

@@ -0,0 +1,44 @@
//
// Provider.swift
// WidgetsExtension
//
// Created by Alex Bumbu on 31.10.2022.
//
import WidgetKit
import SwiftUI
struct CurrentMeetingEntry: TimelineEntry {
let date: Date
var meetingState: MeetingState?
}
class Provider: TimelineProvider {
private var currentMeetingState: MeetingState? {
return MeetingState.load()
}
func placeholder(in context: Context) -> CurrentMeetingEntry {
CurrentMeetingEntry(date: Date(),
meetingState: MeetingState(audioMuted: false))
}
func getSnapshot(in context: Context, completion: @escaping (CurrentMeetingEntry) -> ()) {
var meetingState = currentMeetingState
if context.isPreview {
meetingState = MeetingState(audioMuted: false)
}
let entry = CurrentMeetingEntry(date: Date(), meetingState: meetingState)
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<CurrentMeetingEntry>) -> ()) {
var entries: [CurrentMeetingEntry] = []
let entry = CurrentMeetingEntry(date: Date(), meetingState: currentMeetingState)
entries.append(entry)
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
}

View File

@@ -0,0 +1,19 @@
//
// Widgets.swift
// Widgets
//
// Created by Alex Bumbu on 17.10.2022.
// Copyright © 2022 Facebook. All rights reserved.
//
import WidgetKit
import SwiftUI
@main
struct Widgets: WidgetBundle {
@WidgetBundleBuilder
var body: some Widget {
LockScreenMuteAudioWidget()
LockScreenLeaveMeetingWidget()
}
}

View File

@@ -0,0 +1,10 @@
<?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>com.apple.security.application-groups</key>
<array>
<string>group.org.jitsi.meet.appgroup</string>
</array>
</dict>
</plist>

View File

@@ -23,14 +23,26 @@
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
2681BB562C7A0B42CFBA6719 /* libPods-JitsiMeet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D6152FF9E9F7B0E86F70A21D /* libPods-JitsiMeet.a */; };
4E46D952290FF39E00761DEF /* LockScreenMuteAudioWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E46D951290FF39E00761DEF /* LockScreenMuteAudioWidget.swift */; };
4E46D954290FF55600761DEF /* LockScreenLeaveMeetingWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E46D953290FF55600761DEF /* LockScreenLeaveMeetingWidget.swift */; };
4E6920B828FD84D700645D9E /* DarwinNotificationsObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E6920B728FD84D700645D9E /* DarwinNotificationsObserver.swift */; };
4E6A3E17291024B900E6B0B5 /* Provider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E6A3E16291024B900E6B0B5 /* Provider.swift */; };
4E90F9402632D1AB001102D4 /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E90F93F2632D1AB001102D4 /* Atomic.swift */; };
4EA73DA3290C1D6C00A16FF8 /* MeetingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EA73DA2290C1D6C00A16FF8 /* MeetingState.swift */; };
4EB06024260E026600F524C5 /* ReplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EC49B8625BED71300E76218 /* ReplayKit.framework */; };
4EB06027260E026600F524C5 /* SampleHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB06026260E026600F524C5 /* SampleHandler.swift */; };
4EB0602B260E026600F524C5 /* JitsiMeetBroadcastExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 4EB06023260E026600F524C5 /* JitsiMeetBroadcastExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
4EB0603C260E09D000F524C5 /* SocketConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB06039260E09D000F524C5 /* SocketConnection.swift */; };
4EB0603D260E09D000F524C5 /* DarwinNotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB0603A260E09D000F524C5 /* DarwinNotificationCenter.swift */; };
4EB0603E260E09D000F524C5 /* SampleUploader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB0603B260E09D000F524C5 /* SampleUploader.swift */; };
4EBB458A28FFFD4100855769 /* RoutesHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBB458928FFFD4100855769 /* RoutesHandler.m */; };
4EBB458E2902E85B00855769 /* WidgetKitHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EBB458D2902E85B00855769 /* WidgetKitHelper.swift */; };
4ECA496628FD590000085365 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4ECA496528FD590000085365 /* WidgetKit.framework */; };
4ECA496828FD590000085365 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4ECA496728FD590000085365 /* SwiftUI.framework */; };
4ECA496B28FD590000085365 /* Widgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4ECA496A28FD590000085365 /* Widgets.swift */; };
4ECA496D28FD590000085365 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4ECA496C28FD590000085365 /* Assets.xcassets */; };
4ECA497128FD590000085365 /* WidgetsExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 4ECA496428FD590000085365 /* WidgetsExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
C2116A7673E01A1CCD5DC1F4 /* libPods-JitsiMeet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BF9FEBA4DEAB800AD735681 /* libPods-JitsiMeet.a */; };
DE4C456121DE1E4E00EA0709 /* FIRUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = DE4C455F21DE1E4E00EA0709 /* FIRUtilities.m */; };
DEA9F289258A6EA800D4CD74 /* JitsiMeetSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEA9F288258A6EA800D4CD74 /* JitsiMeetSDK.framework */; };
DEA9F28A258A6EA800D4CD74 /* JitsiMeetSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DEA9F288258A6EA800D4CD74 /* JitsiMeetSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@@ -64,6 +76,13 @@
remoteGlobalIDString = 4EB06022260E026600F524C5;
remoteInfo = "JitsiMeetBroadcast Extension";
};
4ECA496F28FD590000085365 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 4ECA496328FD590000085365;
remoteInfo = WidgetsExtension;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -108,6 +127,7 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
4ECA497128FD590000085365 /* WidgetsExtension.appex in Embed App Extensions */,
4EB0602B260E026600F524C5 /* JitsiMeetBroadcastExtension.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
@@ -134,6 +154,7 @@
0BEA5C3A1F7B8F73000D0AB4 /* ComplicationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComplicationController.swift; sourceTree = "<group>"; };
0BEA5C3C1F7B8F73000D0AB4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
0BEA5C3E1F7B8F73000D0AB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0BF9FEBA4DEAB800AD735681 /* libPods-JitsiMeet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-JitsiMeet.a"; sourceTree = BUILT_PRODUCTS_DIR; };
13B07F961A680F5B00A75B9A /* jitsi-meet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "jitsi-meet.app"; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@@ -141,8 +162,12 @@
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
3E0F4ED943C0B12BE77F6B45 /* Pods-JitsiMeet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.release.xcconfig"; path = "Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.release.xcconfig"; sourceTree = "<group>"; };
4E46D951290FF39E00761DEF /* LockScreenMuteAudioWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockScreenMuteAudioWidget.swift; sourceTree = "<group>"; };
4E46D953290FF55600761DEF /* LockScreenLeaveMeetingWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockScreenLeaveMeetingWidget.swift; sourceTree = "<group>"; };
4E6920B728FD84D700645D9E /* DarwinNotificationsObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DarwinNotificationsObserver.swift; sourceTree = "<group>"; };
4E6A3E16291024B900E6B0B5 /* Provider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Provider.swift; sourceTree = "<group>"; };
4E90F93F2632D1AB001102D4 /* Atomic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = "<group>"; };
4EA73DA2290C1D6C00A16FF8 /* MeetingState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingState.swift; sourceTree = "<group>"; };
4EB06023260E026600F524C5 /* JitsiMeetBroadcastExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = JitsiMeetBroadcastExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
4EB06026260E026600F524C5 /* SampleHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleHandler.swift; sourceTree = "<group>"; };
4EB06028260E026600F524C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -150,10 +175,21 @@
4EB06039260E09D000F524C5 /* SocketConnection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketConnection.swift; sourceTree = "<group>"; };
4EB0603A260E09D000F524C5 /* DarwinNotificationCenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DarwinNotificationCenter.swift; sourceTree = "<group>"; };
4EB0603B260E09D000F524C5 /* SampleUploader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SampleUploader.swift; sourceTree = "<group>"; };
4EBB458828FFFD4100855769 /* RoutesHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RoutesHandler.h; sourceTree = "<group>"; };
4EBB458928FFFD4100855769 /* RoutesHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoutesHandler.m; sourceTree = "<group>"; };
4EBB458B2902A94700855769 /* WidgetsExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WidgetsExtension.entitlements; sourceTree = "<group>"; };
4EBB458C2902E85B00855769 /* JitsiMeet-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiMeet-Bridging-Header.h"; sourceTree = "<group>"; };
4EBB458D2902E85B00855769 /* WidgetKitHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetKitHelper.swift; sourceTree = "<group>"; };
4EC49B8625BED71300E76218 /* ReplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ReplayKit.framework; path = System/Library/Frameworks/ReplayKit.framework; sourceTree = SDKROOT; };
756FCE06C08D9B947653C98A /* Pods-JitsiMeet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.debug.xcconfig"; path = "Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.debug.xcconfig"; sourceTree = "<group>"; };
4ECA496428FD590000085365 /* WidgetsExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = WidgetsExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
4ECA496528FD590000085365 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
4ECA496728FD590000085365 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
4ECA496A28FD590000085365 /* Widgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Widgets.swift; sourceTree = "<group>"; };
4ECA496C28FD590000085365 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
4ECA496E28FD590000085365 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
7052390E12D7319D36D8E4CA /* Pods-JitsiMeet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.debug.xcconfig"; path = "Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.debug.xcconfig"; sourceTree = "<group>"; };
8CAA3C5A38E868335D1C1EC1 /* Pods-JitsiMeet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.release.xcconfig"; path = "Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.release.xcconfig"; sourceTree = "<group>"; };
B3B083EB1D4955FF0069CEE7 /* app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = app.entitlements; sourceTree = "<group>"; };
D6152FF9E9F7B0E86F70A21D /* libPods-JitsiMeet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-JitsiMeet.a"; sourceTree = BUILT_PRODUCTS_DIR; };
DE050388256E904600DEE3A5 /* WebRTC.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = WebRTC.xcframework; path = "../../node_modules/react-native-webrtc/apple/WebRTC.xcframework"; sourceTree = "<group>"; };
DE4C455F21DE1E4E00EA0709 /* FIRUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIRUtilities.m; sourceTree = "<group>"; };
DE4C456021DE1E4E00EA0709 /* FIRUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIRUtilities.h; sourceTree = "<group>"; };
@@ -180,7 +216,7 @@
DED016F128ECBC9D009D5E8D /* WebRTC.xcframework in Frameworks */,
DEA9F289258A6EA800D4CD74 /* JitsiMeetSDK.framework in Frameworks */,
FD572B9827EDF32300A800FB /* GiphyUISDK.xcframework in Frameworks */,
2681BB562C7A0B42CFBA6719 /* libPods-JitsiMeet.a in Frameworks */,
C2116A7673E01A1CCD5DC1F4 /* libPods-JitsiMeet.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -199,6 +235,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
4ECA496128FD590000085365 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4ECA496828FD590000085365 /* SwiftUI.framework in Frameworks */,
4ECA496628FD590000085365 /* WidgetKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -213,7 +258,9 @@
DEFDBBDB25656E3B00344B23 /* WebRTC.xcframework */,
0BD6B4361EF82A6B00D1F4CD /* WebRTC.framework */,
4EC49B8625BED71300E76218 /* ReplayKit.framework */,
D6152FF9E9F7B0E86F70A21D /* libPods-JitsiMeet.a */,
4ECA496528FD590000085365 /* WidgetKit.framework */,
4ECA496728FD590000085365 /* SwiftUI.framework */,
0BF9FEBA4DEAB800AD735681 /* libPods-JitsiMeet.a */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -261,6 +308,10 @@
0BBD021F212EB69D00CCB19F /* Types.h */,
0B412F1D1EDEE6E800B1A0A6 /* ViewController.h */,
0B412F1E1EDEE6E800B1A0A6 /* ViewController.m */,
4EBB458828FFFD4100855769 /* RoutesHandler.h */,
4EBB458928FFFD4100855769 /* RoutesHandler.m */,
4EBB458D2902E85B00855769 /* WidgetKitHelper.swift */,
4EBB458C2902E85B00855769 /* JitsiMeet-Bridging-Header.h */,
);
path = src;
sourceTree = "<group>";
@@ -282,9 +333,25 @@
sourceTree = "<group>";
tabWidth = 4;
};
4ECA496928FD590000085365 /* Widgets Extension */ = {
isa = PBXGroup;
children = (
4ECA496A28FD590000085365 /* Widgets.swift */,
4E46D951290FF39E00761DEF /* LockScreenMuteAudioWidget.swift */,
4E46D953290FF55600761DEF /* LockScreenLeaveMeetingWidget.swift */,
4E6A3E16291024B900E6B0B5 /* Provider.swift */,
4EA73DA2290C1D6C00A16FF8 /* MeetingState.swift */,
4E6920B728FD84D700645D9E /* DarwinNotificationsObserver.swift */,
4ECA496C28FD590000085365 /* Assets.xcassets */,
4ECA496E28FD590000085365 /* Info.plist */,
);
path = "Widgets Extension";
sourceTree = "<group>";
};
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
4EBB458B2902A94700855769 /* WidgetsExtension.entitlements */,
B3B083EB1D4955FF0069CEE7 /* app.entitlements */,
0B26BE711EC5BC4D00EEFB41 /* Frameworks */,
83CBBA001A601CBA00E9B192 /* Products */,
@@ -292,11 +359,12 @@
0BEA5C261F7B8F73000D0AB4 /* Watch app */,
0BEA5C351F7B8F73000D0AB4 /* WatchKit extension */,
4EB06025260E026600F524C5 /* JitsiMeetBroadcast Extension */,
CDD71F5E1157E9F283DF92A8 /* Pods */,
4ECA496928FD590000085365 /* Widgets Extension */,
BD4E28FA984EA7018FD927DF /* Pods */,
);
indentWidth = 2;
indentWidth = 4;
sourceTree = "<group>";
tabWidth = 2;
tabWidth = 4;
};
83CBBA001A601CBA00E9B192 /* Products */ = {
isa = PBXGroup;
@@ -305,15 +373,16 @@
0BEA5C251F7B8F73000D0AB4 /* JitsiMeetCompanion.app */,
0BEA5C311F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex */,
4EB06023260E026600F524C5 /* JitsiMeetBroadcastExtension.appex */,
4ECA496428FD590000085365 /* WidgetsExtension.appex */,
);
name = Products;
sourceTree = "<group>";
};
CDD71F5E1157E9F283DF92A8 /* Pods */ = {
BD4E28FA984EA7018FD927DF /* Pods */ = {
isa = PBXGroup;
children = (
756FCE06C08D9B947653C98A /* Pods-JitsiMeet.debug.xcconfig */,
3E0F4ED943C0B12BE77F6B45 /* Pods-JitsiMeet.release.xcconfig */,
7052390E12D7319D36D8E4CA /* Pods-JitsiMeet.debug.xcconfig */,
8CAA3C5A38E868335D1C1EC1 /* Pods-JitsiMeet.release.xcconfig */,
);
name = Pods;
path = ../Pods;
@@ -361,7 +430,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "JitsiMeet" */;
buildPhases = (
69BC5020DBE393B56BD76636 /* [CP] Check Pods Manifest.lock */,
58E2CB346F2C2A873294F481 /* [CP] Check Pods Manifest.lock */,
0BBA83C41EC9F7600075A103 /* Run React packager */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
@@ -380,6 +449,7 @@
dependencies = (
0BEA5C401F7B8F73000D0AB4 /* PBXTargetDependency */,
4EB0602A260E026600F524C5 /* PBXTargetDependency */,
4ECA497028FD590000085365 /* PBXTargetDependency */,
);
name = JitsiMeet;
productName = "Jitsi Meet";
@@ -403,15 +473,32 @@
productReference = 4EB06023260E026600F524C5 /* JitsiMeetBroadcastExtension.appex */;
productType = "com.apple.product-type.app-extension";
};
4ECA496328FD590000085365 /* WidgetsExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4ECA497428FD590100085365 /* Build configuration list for PBXNativeTarget "WidgetsExtension" */;
buildPhases = (
4ECA496028FD590000085365 /* Sources */,
4ECA496128FD590000085365 /* Frameworks */,
4ECA496228FD590000085365 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = WidgetsExtension;
productName = WidgetsExtension;
productReference = 4ECA496428FD590000085365 /* WidgetsExtension.appex */;
productType = "com.apple.product-type.app-extension";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
83CBB9F71A601CBA00E9B192 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1240;
LastSwiftUpdateCheck = 1400;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = Facebook;
ORGANIZATIONNAME = "";
TargetAttributes = {
0BEA5C241F7B8F73000D0AB4 = {
CreatedOnToolsVersion = 9.0;
@@ -424,6 +511,7 @@
ProvisioningStyle = Automatic;
};
13B07F861A680F5B00A75B9A = {
LastSwiftMigration = 1400;
SystemCapabilities = {
com.apple.SafariKeychain = {
enabled = 1;
@@ -436,6 +524,9 @@
4EB06022260E026600F524C5 = {
CreatedOnToolsVersion = 12.4;
};
4ECA496328FD590000085365 = {
CreatedOnToolsVersion = 14.0.1;
};
};
};
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "app" */;
@@ -455,6 +546,7 @@
0BEA5C241F7B8F73000D0AB4 /* JitsiMeetCompanion */,
0BEA5C301F7B8F73000D0AB4 /* JitsiMeetCompanion Extension */,
4EB06022260E026600F524C5 /* JitsiMeetBroadcastExtension */,
4ECA496328FD590000085365 /* WidgetsExtension */,
);
};
/* End PBXProject section */
@@ -494,6 +586,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
4ECA496228FD590000085365 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4ECA496D28FD590000085365 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@@ -543,7 +643,7 @@
shellPath = /bin/sh;
shellScript = "if test \"$PRODUCT_BUNDLE_IDENTIFIER\" = \"com.atlassian.JitsiMeet.ios\"; then\n ENTITLEMENTS_PLIST=\"$PROJECT_DIR/app.entitlements\"\n \n /usr/libexec/PlistBuddy -c \"Add :com.apple.developer.avfoundation.multitasking-camera-access bool 1\" $ENTITLEMENTS_PLIST\nfi\n";
};
69BC5020DBE393B56BD76636 /* [CP] Check Pods Manifest.lock */ = {
58E2CB346F2C2A873294F481 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -642,8 +742,10 @@
files = (
0B412F1F1EDEE6E800B1A0A6 /* ViewController.m in Sources */,
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
4EBB458E2902E85B00855769 /* WidgetKitHelper.swift in Sources */,
DE4C456121DE1E4E00EA0709 /* FIRUtilities.m in Sources */,
13B07FC11A68108700A75B9A /* main.m in Sources */,
4EBB458A28FFFD4100855769 /* RoutesHandler.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -659,6 +761,19 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
4ECA496028FD590000085365 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4ECA496B28FD590000085365 /* Widgets.swift in Sources */,
4E6920B828FD84D700645D9E /* DarwinNotificationsObserver.swift in Sources */,
4E46D954290FF55600761DEF /* LockScreenLeaveMeetingWidget.swift in Sources */,
4EA73DA3290C1D6C00A16FF8 /* MeetingState.swift in Sources */,
4E6A3E17291024B900E6B0B5 /* Provider.swift in Sources */,
4E46D952290FF39E00761DEF /* LockScreenMuteAudioWidget.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
@@ -677,6 +792,11 @@
target = 4EB06022260E026600F524C5 /* JitsiMeetBroadcastExtension */;
targetProxy = 4EB06029260E026600F524C5 /* PBXContainerItemProxy */;
};
4ECA497028FD590000085365 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4ECA496328FD590000085365 /* WidgetsExtension */;
targetProxy = 4ECA496F28FD590000085365 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@@ -845,11 +965,12 @@
};
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 756FCE06C08D9B947653C98A /* Pods-JitsiMeet.debug.xcconfig */;
baseConfigurationReference = 7052390E12D7319D36D8E4CA /* Pods-JitsiMeet.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIconDebug;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = app.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
@@ -871,16 +992,20 @@
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet;
PRODUCT_NAME = "jitsi-meet";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "src/JitsiMeet-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3E0F4ED943C0B12BE77F6B45 /* Pods-JitsiMeet.release.xcconfig */;
baseConfigurationReference = 8CAA3C5A38E868335D1C1EC1 /* Pods-JitsiMeet.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIconRelease;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = app.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
@@ -901,6 +1026,8 @@
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet;
PRODUCT_NAME = "jitsi-meet";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "src/JitsiMeet-Bridging-Header.h";
SWIFT_VERSION = 5.0;
};
name = Release;
};
@@ -973,6 +1100,91 @@
};
name = Release;
};
4ECA497228FD590100085365 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = WidgetsExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = FC967L3QRG;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Widgets Extension/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = Widgets;
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 Facebook. All rights reserved.";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet.widgets.extension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
4ECA497328FD590100085365 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = WidgetsExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = FC967L3QRG;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Widgets Extension/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = Widgets;
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2022 Facebook. All rights reserved.";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet.widgets.extension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
83CBBA201A601CBA00E9B192 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -1126,6 +1338,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4ECA497428FD590100085365 /* Build configuration list for PBXNativeTarget "WidgetsExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4ECA497228FD590100085365 /* Debug */,
4ECA497328FD590100085365 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "app" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1400"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4ECA496328FD590000085365"
BuildableName = "WidgetsExtension.appex"
BlueprintName = "WidgetsExtension"
ReferencedContainer = "container:app.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "jitsi-meet.app"
BlueprintName = "JitsiMeet"
ReferencedContainer = "container:app.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
askForAppToLaunch = "Yes"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.springboard">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4ECA496328FD590000085365"
BuildableName = "WidgetsExtension.appex"
BlueprintName = "WidgetsExtension"
ReferencedContainer = "container:app.xcodeproj">
</BuildableReference>
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "jitsi-meet.app"
BlueprintName = "JitsiMeet"
ReferencedContainer = "container:app.xcodeproj">
</BuildableReference>
</MacroExpansion>
<EnvironmentVariables>
<EnvironmentVariable
key = "_XCWidgetKind"
value = "LockScreenLeaveMeetingWidget"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "_XCWidgetDefaultView"
value = "timeline"
isEnabled = "NO">
</EnvironmentVariable>
<EnvironmentVariable
key = "_XCWidgetFamily"
value = "medium"
isEnabled = "NO">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
askForAppToLaunch = "Yes"
launchAutomaticallySubstyle = "2">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "jitsi-meet.app"
BlueprintName = "JitsiMeet"
ReferencedContainer = "container:app.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -17,6 +17,7 @@
#import "AppDelegate.h"
#import "FIRUtilities.h"
#import "RoutesHandler.h"
#import "Types.h"
#import "ViewController.h"
@@ -69,7 +70,7 @@
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *restorableObjects))restorationHandler {
if ([FIRUtilities appContainsRealServiceInfoPlist]) {
// 1. Attempt to handle Universal Links through Firebase in order to support
// its Dynamic Links (which we utilize for the purposes of deferred deep
@@ -107,6 +108,10 @@
if ([[url absoluteString] containsString:@"google/link/?dismiss=1&is_weak_match=1"]) {
return NO;
}
if ([[RoutesHandler sharedInstance] routeURL:url]) {
return YES;
}
NSURL *openUrl = url;

View File

@@ -1,6 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}
}

View File

@@ -0,0 +1,4 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//

View File

@@ -0,0 +1,27 @@
//
// RoutesHandler.h
// JitsiMeet
//
// Created by Alex Bumbu on 19.10.2022.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol RouteObserving <NSObject>
@property (nonatomic, readonly) void (^didRouteCallback)(NSString *route);
@end
@interface RoutesHandler : NSObject
+ (instancetype)sharedInstance;
- (void)registerObserver:(id<RouteObserving>)observer forRoute:(NSString *)route;
- (void)unregisterObserver:(id<RouteObserving>)observer;
- (BOOL)routeURL:(NSURL *)url;
@end
NS_ASSUME_NONNULL_END

123
ios/app/src/RoutesHandler.m Normal file
View File

@@ -0,0 +1,123 @@
//
// RoutesHandler.m
// JitsiMeet
//
// Created by Alex Bumbu on 19.10.2022.
//
#import "RoutesHandler.h"
@protocol Routing <NSObject>
@property (nonatomic, readonly) NSString *route;
@property (nonatomic, readonly) id<RouteObserving> observer;
@end
@interface Route: NSObject <Routing>
@property (nonatomic, readonly) NSString *route;
@property (nonatomic, readonly, weak) id<RouteObserving> observer;
+ (instancetype)routeWithString:(nonnull NSString *)route observer:(id<RouteObserving>)observer;
@end
#pragma mark -
@implementation RoutesHandler {
NSMutableArray *routes;
}
+ (instancetype)sharedInstance {
static RoutesHandler *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (instancetype)init {
self = [super init];
if (self) {
routes = [[NSMutableArray alloc] init];
}
return self;
}
- (void)registerObserver:(id<RouteObserving>)observer forRoute:(NSString *)route {
[routes addObject:[Route routeWithString:route observer:observer]];
}
- (void)unregisterObserver:(id<RouteObserving>)observer {
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id<Routing> _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
return evaluatedObject.observer == nil || evaluatedObject.observer == observer;
}];
NSArray *routesToClear = [routes filteredArrayUsingPredicate:predicate];
[routes removeObjectsInArray:routesToClear];
}
- (BOOL)routeURL:(NSURL *)url {
[self clearRoutes];
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:false];
if (!components) {
return false;
}
NSString *route = components.path;
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id<Routing> _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
return [evaluatedObject.route isEqualToString:route];
}];
NSArray *routesToHandle = [routes filteredArrayUsingPredicate:predicate];
if ([routesToHandle count] == 0) {
return false;
}
for (id<Routing> route in routesToHandle) {
route.observer.didRouteCallback(route.route);
}
return true;
}
- (void)clearRoutes {
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id<Routing> _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
return evaluatedObject.observer == nil;
}];
NSArray *routesToClear = [routes filteredArrayUsingPredicate:predicate];
[routes removeObjectsInArray:routesToClear];
}
@end
#pragma mark -
@interface Route()
@property (nonatomic, nonnull, copy) NSString *route;
@property (nonatomic, weak) id<RouteObserving> observer;
@end
@implementation Route
+ (instancetype)routeWithString:(nonnull NSString *)route observer:(nonnull id<RouteObserving>)observer {
return [[Route alloc] initWithString:route observer:observer];
}
- (instancetype)initWithString:(nonnull NSString *)route observer:(nonnull id<RouteObserving>)observer {
self = [super init];
if (self) {
self.route = route;
self.observer = observer;
}
return self;
}
@end

View File

@@ -21,8 +21,16 @@
@import JitsiMeetSDK;
#import "Types.h"
#import "RoutesHandler.h"
#import "ViewController.h"
#import "jitsi_meet-Swift.h"
@interface ViewController() <RouteObserving>
@property (nonatomic, nonnull, copy) void (^didRouteCallback)(NSString *);
@property (nonatomic, assign) BOOL audioMuted;
@end
@implementation ViewController
@@ -33,6 +41,8 @@
view.delegate = self;
[view join:[[JitsiMeet sharedInstance] getInitialConferenceOptions]];
[self registerRouteObserver];
}
// JitsiMeetViewDelegate
@@ -53,6 +63,10 @@
- (void)conferenceJoined:(NSDictionary *)data {
[self _onJitsiMeetViewDelegateEvent:@"CONFERENCE_JOINED" withData:data];
self.audioMuted = [[data objectForKey:@"isAudioMuted"] boolValue];
[self refreshWidgetState:self.audioMuted];
// Register a NSUserActivity for this conference so it can be invoked as a
// Siri shortcut.
@@ -82,6 +96,12 @@
- (void)conferenceTerminated:(NSDictionary *)data {
[self _onJitsiMeetViewDelegateEvent:@"CONFERENCE_TERMINATED" withData:data];
NSURL *sharedContainer = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.org.jitsi.meet.appgroup"];
NSURL *widgetStateFileURL = [sharedContainer URLByAppendingPathComponent:@"widgetState"];
[[NSFileManager defaultManager] removeItemAtURL:widgetStateFileURL error:nil];
[WidgetKitHelper reloadAllWidgets];
}
- (void)conferenceWillJoin:(NSDictionary *)data {
@@ -107,7 +127,16 @@
}
- (void)audioMutedChanged:(NSDictionary *)data {
NSLog(@"%@%@", @"Audio muted changed: ", data[@"muted"]);
NSLog(@"%@%@", @"Audio muted changed: ", data[@"muted"]);
// CFNotificationCenterRef notificationCenter = CFNotificationCenterGetDarwinNotifyCenter();
// CFNotificationCenterPostNotification(notificationCenter,
// (__bridge CFStringRef)@"iOS_MeetingMutedChanged",
// NULL,
// NULL,
// true);
self.audioMuted = [[data objectForKey:@"muted"] boolValue];
[self refreshWidgetState:self.audioMuted];
}
- (void)endpointTextMessageReceived:(NSDictionary *)data {
@@ -132,9 +161,40 @@
#pragma mark - Helpers
- (void)registerRouteObserver {
__weak typeof(self) weakSelf = self;
__weak JitsiMeetView *view = (JitsiMeetView *)self.view;
self.didRouteCallback = ^(NSString *route) {
if ([route isEqual:@"meet/toggleAudioMute"]) {
weakSelf.audioMuted = !weakSelf.audioMuted;
[view setAudioMuted:weakSelf.audioMuted];
} else if ([route isEqualToString:@"meet/leaveMeeting"]) {
[weakSelf terminate];
}
};
[[RoutesHandler sharedInstance] registerObserver:self forRoute:@"meet/toggleAudioMute"];
[[RoutesHandler sharedInstance] registerObserver:self forRoute:@"meet/leaveMeeting"];
}
- (void)terminate {
JitsiMeetView *view = (JitsiMeetView *) self.view;
[view leave];
}
- (void)refreshWidgetState:(BOOL)audioMuted {
// let sharedContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Constants.appGroupIdentifier)
// return sharedContainer?.appendingPathComponent("rtc_SSFD").path ?? ""
NSURL *sharedContainer = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.org.jitsi.meet.appgroup"];
NSURL *widgetStateFileURL = [sharedContainer URLByAppendingPathComponent:@"widgetState"];
NSDictionary *meetingState = @{@"audioMuted": @(audioMuted)};
if (![meetingState writeToURL:widgetStateFileURL atomically:true]) {
NSLog(@"error saving state file");
}
[WidgetKitHelper reloadAllWidgets];
}
@end

View File

@@ -0,0 +1,20 @@
//
// WidgetKitHelper.swift
// JitsiMeet
//
// Created by Alex Bumbu on 21.10.2022.
//
import WidgetKit
@available(iOS 14.0, *)
@objcMembers final class WidgetKitHelper: NSObject {
class func reloadAllWidgets(){
#if arch(arm64) || arch(i386) || arch(x86_64)
WidgetCenter.shared.reloadAllTimelines()
#endif
}
}

View File

@@ -57,8 +57,8 @@
openURL:(NSURL *_Nonnull)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *_Nonnull)options;
- (UIInterfaceOrientationMask)application:(UIApplication *)application
supportedInterfaceOrientationsForWindow:(UIWindow *)window;
- (UIInterfaceOrientationMask)application:(UIApplication *_Nonnull)application
supportedInterfaceOrientationsForWindow:(UIWindow *_Nonnull)window;
#pragma mark - Utility methods

View File

@@ -71,7 +71,7 @@
"titleWithPolls": "Εισάγετε ένα ψευδώνυμο για τη χρήση της συνομιλίας"
},
"noMessagesMessage": "Δεν υπάρχουν μηνύματα στη συνάντηση ακόμα. Ξεκινήστε μια συζήτηση εδώ!",
"privateNotice": "Ιδιωτικό μηνύμα στον / στην {recipient}}",
"privateNotice": "Ιδιωτικό μηνύμα στον / στην {{recipient}}",
"sendButton": "Στείλτε",
"title": "Συνομιλία",
"titleWithPolls": "Συνομιλία",
@@ -517,7 +517,7 @@
"oldElectronClientDescription3": " τώρα!",
"passwordRemovedRemotely": "Το $t(lockRoomPasswordUppercase) αφαιρέθηκε από έναν άλλον συμμετέχοντα",
"passwordSetRemotely": "Το $t(lockRoomPasswordUppercase) ορίστηκε από άλλον συμμετέχοντα",
"raisedHand": "Ο/Η {{name}} θα ήθελε να μιλήσει.",
"raisedHand": "Ο/Η {{participantDisplayName}} θα ήθελε να μιλήσει.",
"somebody": "Κάποιος",
"startSilentDescription": "Ξαναμπείτε στη συνάντηση για να ενεργοποιήσετε τον ήχο",
"startSilentTitle": "Μπήκες χωρίς συσκευή εξόδου ήχου!",

View File

@@ -964,7 +964,7 @@
"incomingMessage": "Incoming message",
"language": "Language",
"loggedIn": "Logged in as {{name}}",
"maxStageParticipants": "Maximum number of participants who can be pinned to the main stage",
"maxStageParticipants": "Maximum number of participants who can be pinned to the main stage (EXPERIMENTAL)",
"microphones": "Microphones",
"moderator": "Moderator",
"more": "More",

24
package-lock.json generated
View File

@@ -74,7 +74,7 @@
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1533.0.0+7b257686/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1535.0.0+e6263e7c/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
@@ -127,7 +127,7 @@
"resemblejs": "4.0.0",
"seamless-scroll-polyfill": "2.1.8",
"styled-components": "3.4.9",
"tss-react": "4.0.0",
"tss-react": "4.4.4",
"util": "0.12.1",
"uuid": "8.3.2",
"wasm-check": "2.0.1",
@@ -13497,8 +13497,8 @@
},
"node_modules/lib-jitsi-meet": {
"version": "0.0.0",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1533.0.0+7b257686/lib-jitsi-meet.tgz",
"integrity": "sha512-AOsGOXwuZJrdaJPSBCkLtoDUrg/JKWZOdcR1Sw/ZGjlszcQ+gyfT8UbM9NI+b5hC3h39K9gmnGVcI8acNxpBrQ==",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1535.0.0+e6263e7c/lib-jitsi-meet.tgz",
"integrity": "sha512-RgMoesoWyscWi2fL9Hxp8PUwDlUtHbo+GhXosD3GeKR0zmihu/kxTONMUifGQnF8XdtcjaZfL2jCJynLwYKlkw==",
"license": "Apache-2.0",
"dependencies": {
"@jitsi/js-utils": "2.0.0",
@@ -19019,9 +19019,9 @@
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/tss-react": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/tss-react/-/tss-react-4.0.0.tgz",
"integrity": "sha512-pPkOKWiWWPbKdQFnGGeHEgRceUwkjrv0eldVCAdBll3j6Y3Ys/xwqsnlWYwWOU3SMJygVRE/S4CsIYx6KPpOkA==",
"version": "4.4.4",
"resolved": "https://registry.npmjs.org/tss-react/-/tss-react-4.4.4.tgz",
"integrity": "sha512-Bzyg99bIQq3Lk4Rwc5XMOps58c1biw1rghCkApIX5XkAB+/VjGCIFSl63PePhmiRNvKRxJRpawGPPxHytiw1TA==",
"dependencies": {
"@emotion/cache": "*",
"@emotion/serialize": "*",
@@ -30510,8 +30510,8 @@
}
},
"lib-jitsi-meet": {
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1533.0.0+7b257686/lib-jitsi-meet.tgz",
"integrity": "sha512-AOsGOXwuZJrdaJPSBCkLtoDUrg/JKWZOdcR1Sw/ZGjlszcQ+gyfT8UbM9NI+b5hC3h39K9gmnGVcI8acNxpBrQ==",
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1535.0.0+e6263e7c/lib-jitsi-meet.tgz",
"integrity": "sha512-RgMoesoWyscWi2fL9Hxp8PUwDlUtHbo+GhXosD3GeKR0zmihu/kxTONMUifGQnF8XdtcjaZfL2jCJynLwYKlkw==",
"requires": {
"@jitsi/js-utils": "2.0.0",
"@jitsi/logger": "2.0.0",
@@ -34738,9 +34738,9 @@
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"tss-react": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/tss-react/-/tss-react-4.0.0.tgz",
"integrity": "sha512-pPkOKWiWWPbKdQFnGGeHEgRceUwkjrv0eldVCAdBll3j6Y3Ys/xwqsnlWYwWOU3SMJygVRE/S4CsIYx6KPpOkA==",
"version": "4.4.4",
"resolved": "https://registry.npmjs.org/tss-react/-/tss-react-4.4.4.tgz",
"integrity": "sha512-Bzyg99bIQq3Lk4Rwc5XMOps58c1biw1rghCkApIX5XkAB+/VjGCIFSl63PePhmiRNvKRxJRpawGPPxHytiw1TA==",
"requires": {
"@emotion/cache": "*",
"@emotion/serialize": "*",

View File

@@ -79,7 +79,7 @@
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1533.0.0+7b257686/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1535.0.0+e6263e7c/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
@@ -132,7 +132,7 @@
"resemblejs": "4.0.0",
"seamless-scroll-polyfill": "2.1.8",
"styled-components": "3.4.9",
"tss-react": "4.0.0",
"tss-react": "4.4.4",
"util": "0.12.1",
"uuid": "8.3.2",
"wasm-check": "2.0.1",

View File

@@ -1,5 +1,4 @@
/* eslint-disable react/jsx-no-bind */
import { Theme } from '@mui/material';
import React, { useEffect, useState } from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -8,7 +7,7 @@ import { IconCheck, IconCopy } from '../icons/svg';
import { withPixelLineHeight } from '../styles/functions.web';
import { copyText } from '../util/copyText.web';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
copyButton: {
...withPixelLineHeight(theme.typography.bodyShortBold),

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { ReactNode } from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -76,7 +75,7 @@ interface IProps {
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
container: {
alignItems: 'center',

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -45,7 +44,7 @@ interface IProps {
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
label: {
...withPixelLineHeight(theme.typography.labelRegular),

View File

@@ -32,7 +32,7 @@ const AVATAR_CHECKED_URLS = new Map();
/* eslint-disable arrow-body-style, no-unused-vars */
const AVATAR_CHECKER_FUNCTIONS = [
(participant: IParticipant) => {
return isJigasiParticipant(participant) ? JIGASI_PARTICIPANT_ICON : null;
return participant?.isJigasi ? JIGASI_PARTICIPANT_ICON : null;
},
(participant: IParticipant) => {
return isWhiteboardParticipant(participant) ? WHITEBOARD_PARTICIPANT_ICON : null;
@@ -281,16 +281,6 @@ export function getFakeParticipants(stateful: IStateful) {
return toState(stateful)['features/base/participants'].fakeParticipants;
}
/**
* Returns whether the fake participant is Jigasi.
*
* @param {IParticipant|undefined} participant - The participant entity.
* @returns {boolean} - True if it's a Jigasi participant.
*/
function isJigasiParticipant(participant?: IParticipant): boolean {
return participant?.fakeParticipant === FakeParticipant.Jigasi;
}
/**
* Returns whether the fake participant is a local screenshare.
*

View File

@@ -80,7 +80,7 @@ import {
} from './functions';
import logger from './logger';
import { PARTICIPANT_JOINED_FILE, PARTICIPANT_LEFT_FILE } from './sounds';
import { FakeParticipant, IJitsiParticipant } from './types';
import { IJitsiParticipant } from './types';
import './subscriber';
@@ -438,7 +438,7 @@ StateListenerRegistry.register(
store.dispatch(participantUpdated({
conference,
id: participant.getId(),
fakeParticipant: value ? FakeParticipant.Jigasi : undefined
isJigasi: value
})),
// eslint-disable-next-line @typescript-eslint/no-unused-vars
'features_screen-sharing': (participant: IJitsiParticipant, value: string) =>

View File

@@ -1,5 +1,4 @@
export enum FakeParticipant {
Jigasi = 'Jigasi',
LocalScreenShare = 'LocalScreenShare',
RemoteScreenShare = 'RemoteScreenShare',
SharedVideo = 'SharedVideo',
@@ -21,6 +20,7 @@ export interface IParticipant {
};
getId?: Function;
id: string;
isJigasi?: boolean;
isReplaced?: boolean;
isReplacing?: number;
jwtId?: string;

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { ReactNode, useCallback } from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -80,7 +79,7 @@ interface IProps {
type: string;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
actionButton: {
...withPixelLineHeight(theme.typography.bodyLongBold),

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { useCallback, useState } from 'react';
import { WithTranslation } from 'react-i18next';
import { makeStyles } from 'tss-react/mui';
@@ -25,7 +24,7 @@ interface IProps extends WithTranslation {
connectionType?: string;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
connectionStatus: {
borderRadius: '6px',

View File

@@ -1,5 +1,4 @@
/* eslint-disable lines-around-comment */
import { Theme } from '@mui/material';
import React, { ReactNode } from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -85,7 +84,7 @@ interface IProps {
videoTrack?: Object;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
subtitle: {
...withPixelLineHeight(theme.typography.heading5),

View File

@@ -136,6 +136,10 @@ class StateListenerRegistry {
* @returns {void}
*/
register(selector: Selector, listener: Listener, options?: RegistrationOptions) {
if (typeof selector !== 'function' || typeof listener !== 'function') {
throw new Error('Invalid selector or listener!');
}
this._selectorListeners.add({
listener,
selector,

View File

@@ -1,3 +1,8 @@
/**
* IMPORTANT: this file is deprecated. All of these colors should be moved to
* the theme instead.
*/
/**
* The application's definition of the default color black.
*/
@@ -18,29 +23,12 @@ export const ColorPalette = {
* the sake of consistency.
*/
black: BLACK,
blackBlue: 'rgb(0, 3, 6)',
blue: '#17A0DB',
blueHighlight: '#1081b2',
buttonUnderlay: '#495258',
darkGrey: '#555555',
darkBackground: 'rgb(19,21,25)',
green: '#40b183',
lightGrey: '#AAAAAA',
overflowMenuItemUnderlay: '#EEEEEE',
red: '#D00000',
transparent: 'rgba(0, 0, 0, 0)',
toggled: 'rgba(255,255,255,.15)',
warning: 'rgb(215, 121, 118)',
white: '#FFFFFF',
/**
* These are colors from the atlaskit to be used on mobile, when needed.
*
* FIXME: Maybe a better solution would be good, or a native packaging of
* the respective atlaskit components.
*/
G400: '#00875A', // Slime
N500: '#42526E', // McFanning
R400: '#DE350B', // Red dirt
Y200: '#FFC400' // Pub mix
white: '#FFFFFF'
};

View File

@@ -2,7 +2,7 @@
import React, { Component, Fragment } from 'react';
import { statsEmitter } from '../../../connection-indicator';
import statsEmitter from '../../../connection-indicator/statsEmitter';
import { getLocalParticipant } from '../../participants';
import { connect } from '../../redux';
import { isTestModeEnabled } from '../functions';

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { makeStyles } from 'tss-react/mui';
@@ -47,7 +46,7 @@ interface IProps extends IButtonProps {
testId?: string;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
button: {
backgroundColor: theme.palette.action01,

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -40,7 +39,7 @@ interface ICheckboxProps {
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
formControl: {
...withPixelLineHeight(theme.typography.bodyLongRegular),

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -12,7 +11,7 @@ interface IProps {
onClick: () => void;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
button: {
padding: '2px',

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { ReactNode, useEffect, useLayoutEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
@@ -104,7 +103,7 @@ interface IProps {
const MAX_HEIGHT = 400;
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
contextMenu: {
backgroundColor: theme.palette.ui01,

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { ReactNode } from 'react';
import { useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
@@ -71,7 +70,7 @@ export interface IProps {
textClassName?: string;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
contextMenuItem: {
alignItems: 'center',

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { ReactNode } from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -18,7 +17,7 @@ interface IProps {
children?: ReactNode;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
contextMenuItemGroup: {
'&:not(:empty)': {

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { useCallback, useContext, useEffect } from 'react';
import FocusLock from 'react-focus-lock';
import { useTranslation } from 'react-i18next';
@@ -15,7 +14,7 @@ import ClickableIcon from './ClickableIcon';
import { DialogTransitionContext } from './DialogTransition';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
container: {
width: '100%',
@@ -191,6 +190,7 @@ interface IDialogProps {
children?: React.ReactNode;
className?: string;
description?: string;
disableAutoHideOnSubmit?: boolean;
disableBackdropClose?: boolean;
disableEnter?: boolean;
hideCloseButton?: boolean;
@@ -212,6 +212,7 @@ const Dialog = ({
children,
className,
description,
disableAutoHideOnSubmit = false,
disableBackdropClose,
hideCloseButton,
disableEnter,
@@ -233,7 +234,7 @@ const Dialog = ({
}, [ onCancel ]);
const submit = useCallback(() => {
dispatch(hideDialog());
!disableAutoHideOnSubmit && dispatch(hideDialog());
onSubmit?.();
}, [ onSubmit ]);

View File

@@ -2,18 +2,29 @@ import React, { ReactElement, useEffect, useState } from 'react';
export const DialogTransitionContext = React.createContext({ isUnmounting: false });
type TimeoutType = ReturnType<typeof setTimeout>;
const DialogTransition = ({ children }: { children: ReactElement | null; }) => {
const [ childrenToRender, setChildrenToRender ] = useState(children);
const [ isUnmounting, setIsUnmounting ] = useState(false);
const [ timeoutID, setTimeoutID ] = useState<TimeoutType | undefined>(undefined);
useEffect(() => {
if (children === null) {
setIsUnmounting(true);
setTimeout(() => {
setChildrenToRender(children);
setIsUnmounting(false);
}, 150);
if (typeof timeoutID === 'undefined') {
setTimeoutID(setTimeout(() => {
setChildrenToRender(children);
setIsUnmounting(false);
setTimeoutID(undefined);
}, 150));
}
} else {
if (typeof timeoutID !== 'undefined') {
clearTimeout(timeoutID);
setTimeoutID(undefined);
setIsUnmounting(false);
}
setChildrenToRender(children);
}
}, [ children ]);

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { useCallback } from 'react';
import TextareaAutosize from 'react-textarea-autosize';
import { makeStyles } from 'tss-react/mui';
@@ -26,7 +25,7 @@ interface IProps extends IInputProps {
type?: 'text' | 'email' | 'number' | 'password';
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
inputContainer: {
display: 'flex',

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { ChangeEvent } from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -53,7 +52,7 @@ interface ISelectProps {
value: number | string;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
container: {
display: 'flex',

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { useCallback } from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -15,7 +14,7 @@ interface IProps extends ISwitchProps {
id?: string;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
container: {
position: 'relative',

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { useCallback } from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -18,7 +17,7 @@ interface ITabProps {
}>;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
container: {
display: 'flex'

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React from 'react';
import { WithTranslation } from 'react-i18next';
import { makeStyles } from 'tss-react/mui';
@@ -17,7 +16,7 @@ export interface INewMessagesButtonProps extends WithTranslation {
onGoToFirstUnreadMessage: () => void;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
container: {
position: 'absolute',

View File

@@ -1,4 +1,5 @@
/* eslint-disable lines-around-comment */
import React from 'react';
import { StyleProp, Text, View, ViewStyle } from 'react-native';
import { useSelector } from 'react-redux';
@@ -57,7 +58,9 @@ const TitleBar = (props: IProps): JSX.Element => {
<VideoQualityLabel />
</View>
<ConnectionIndicator
// @ts-ignore
iconStyle = { styles.connectionIndicatorIcon }
// @ts-ignore
participantId = { localParticipantId } />
<View style = { styles.headerLabels as StyleProp<ViewStyle> }>
<RecordingLabel mode = { JitsiRecordingConstants.mode.FILE } />

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
@@ -12,7 +11,7 @@ import Label from '../../../base/label/components/web/Label';
import { Tooltip } from '../../../base/tooltip';
import { open as openParticipantsPane } from '../../../participants-pane/actions';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
label: {
backgroundColor: theme.palette.warning02,

View File

@@ -209,7 +209,7 @@ class AbstractConnectionIndicator<P: Props, S: State> extends Component<P, S> {
*/
export function mapStateToProps(state: Object) {
return {
_autoHideTimeout: state['features/base/config'].connectionIndicators.autoHideTimeout ?? defaultAutoHideTimeout
_autoHideTimeout: state['features/base/config'].connectionIndicators?.autoHideTimeout ?? defaultAutoHideTimeout
};
}

View File

@@ -1,3 +0,0 @@
// @flow
export * from './native';

View File

@@ -1,3 +0,0 @@
// @flow
export * from './web';

View File

@@ -1,68 +0,0 @@
// @flow
import React from 'react';
import { View } from 'react-native';
import { IconConnection } from '../../../base/icons';
import { BaseIndicator } from '../../../base/react';
import { connect } from '../../../base/redux';
import indicatorStyles from '../../../filmstrip/components/native/styles';
import AbstractConnectionIndicator, {
type Props,
type State
} from '../AbstractConnectionIndicator';
import { CONNECTOR_INDICATOR_COLORS, iconStyle } from './styles';
/**
* Implements an indicator to show the quality of the connection of a participant.
*/
class ConnectionIndicator extends AbstractConnectionIndicator<Props, State> {
/**
* Initializes a new {@code ConnectionIndicator} instance.
*
* @inheritdoc
*/
constructor(props: Props) {
super(props);
this.state = {
autoHideTimeout: undefined,
showIndicator: false,
stats: {}
};
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
const { showIndicator, stats } = this.state;
const { percent } = stats;
if (!showIndicator || typeof percent === 'undefined') {
return null;
}
// Signal level on a scale 0..2
const signalLevel = Math.floor(percent / 33.4);
return (
<View
style = {{
...indicatorStyles.indicatorContainer,
backgroundColor: CONNECTOR_INDICATOR_COLORS[signalLevel]
}}>
<BaseIndicator
icon = { IconConnection }
iconStyle = { this.props.iconStyle || iconStyle } />
</View>
);
}
}
export default connect()(ConnectionIndicator);

View File

@@ -0,0 +1,216 @@
/* eslint-disable lines-around-comment */
import React from 'react';
import { View } from 'react-native';
import { IReduxState } from '../../../app/types';
import { IconConnection } from '../../../base/icons/svg';
import { MEDIA_TYPE } from '../../../base/media/constants';
import {
getLocalParticipant,
getParticipantById,
isScreenShareParticipant
} from '../../../base/participants/functions';
// @ts-ignore
import BaseIndicator from '../../../base/react/components/native/BaseIndicator';
import { connect } from '../../../base/redux/functions';
import {
getTrackByMediaTypeAndParticipant
} from '../../../base/tracks/functions.native';
// @ts-ignore
import indicatorStyles from '../../../filmstrip/components/native/styles';
import {
isTrackStreamingStatusInactive,
isTrackStreamingStatusInterrupted
} from '../../functions';
import AbstractConnectionIndicator, {
type Props as AbstractProps,
mapStateToProps as _abstractMapStateToProps
// @ts-ignore
} from '../AbstractConnectionIndicator';
import {
CONNECTOR_INDICATOR_COLORS,
CONNECTOR_INDICATOR_LOST,
CONNECTOR_INDICATOR_OTHER,
iconStyle
} from './styles';
type IProps = AbstractProps & {
/**
* Whether connection indicators are disabled or not.
*/
_connectionIndicatorDisabled: boolean;
/**
* Whether the inactive connection indicator is disabled or not.
*/
_connectionIndicatorInactiveDisabled: boolean;
/**
* Whether the connection is inactive or not.
*/
_isConnectionStatusInactive: boolean;
/**
* Whether the connection is interrupted or not.
*/
_isConnectionStatusInterrupted: boolean;
/**
* Whether the current participant is a virtual screenshare.
*/
_isVirtualScreenshareParticipant: boolean;
/**
* Redux dispatch function.
*/
dispatch: Function;
/**
* Icon style override.
*/
iconStyle: any;
};
type IState = {
autoHideTimeout: number | undefined;
showIndicator: boolean;
stats: any;
};
/**
* Implements an indicator to show the quality of the connection of a participant.
*/
class ConnectionIndicator extends AbstractConnectionIndicator<IProps, IState> {
/**
* Initializes a new {@code ConnectionIndicator} instance.
*
* @inheritdoc
*/
constructor(props: IProps) {
super(props);
// @ts-ignore
this.state = {
autoHideTimeout: undefined,
showIndicator: false,
stats: {}
};
}
/**
* Get the icon configuration from CONNECTOR_INDICATOR_COLORS which has a percentage
* that matches or exceeds the passed in percentage. The implementation
* assumes CONNECTOR_INDICATOR_COLORS is already sorted by highest to lowest
* percentage.
*
* @param {number} percent - The connection percentage, out of 100, to find
* the closest matching configuration for.
* @private
* @returns {Object}
*/
_getDisplayConfiguration(percent: number): any {
return CONNECTOR_INDICATOR_COLORS.find(x => percent >= x.percent) || {};
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
const {
_connectionIndicatorInactiveDisabled,
_connectionIndicatorDisabled,
_isVirtualScreenshareParticipant,
_isConnectionStatusInactive,
_isConnectionStatusInterrupted
// @ts-ignore
} = this.props;
const {
showIndicator,
stats
// @ts-ignore
} = this.state;
const { percent } = stats;
if (!showIndicator || typeof percent === 'undefined'
|| _connectionIndicatorDisabled || _isVirtualScreenshareParticipant) {
return null;
}
let indicatorColor;
if (_isConnectionStatusInactive) {
if (_connectionIndicatorInactiveDisabled) {
return null;
}
indicatorColor = CONNECTOR_INDICATOR_OTHER;
} else if (_isConnectionStatusInterrupted) {
indicatorColor = CONNECTOR_INDICATOR_LOST;
} else {
const displayConfig = this._getDisplayConfiguration(percent);
if (!displayConfig) {
return null;
}
indicatorColor = displayConfig.color;
}
return (
<View
style = {{
...indicatorStyles.indicatorContainer,
backgroundColor: indicatorColor
}}>
<BaseIndicator
icon = { IconConnection }
// @ts-ignore
iconStyle = { this.props.iconStyle || iconStyle } />
</View>
);
}
}
/**
* Maps part of the Redux state to the props of this component.
*
* @param {Object} state - The Redux state.
* @param {IProps} ownProps - The own props of the component.
* @returns {IProps}
*/
export function _mapStateToProps(state: IReduxState, ownProps: IProps) {
const { participantId } = ownProps;
const tracks = state['features/base/tracks'];
const participant = participantId ? getParticipantById(state, participantId) : getLocalParticipant(state);
const _isVirtualScreenshareParticipant = isScreenShareParticipant(participant);
let _isConnectionStatusInactive;
let _isConnectionStatusInterrupted;
if (!_isVirtualScreenshareParticipant) {
const _videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, participantId);
_isConnectionStatusInactive = isTrackStreamingStatusInactive(_videoTrack);
_isConnectionStatusInterrupted = isTrackStreamingStatusInterrupted(_videoTrack);
}
return {
..._abstractMapStateToProps(state),
_connectionIndicatorInactiveDisabled:
Boolean(state['features/base/config'].connectionIndicators?.inactiveDisabled),
_connectionIndicatorDisabled:
Boolean(state['features/base/config'].connectionIndicators?.disabled),
_isVirtualScreenshareParticipant,
_isConnectionStatusInactive,
_isConnectionStatusInterrupted
};
}
// @ts-ignore
export default connect(_mapStateToProps)(ConnectionIndicator);

View File

@@ -1,3 +0,0 @@
// @flow
export { default as ConnectionIndicator } from './ConnectionIndicator';

View File

@@ -1,13 +0,0 @@
// @flow
import { ColorPalette } from '../../../base/styles';
export const CONNECTOR_INDICATOR_COLORS = [
ColorPalette.red,
ColorPalette.Y200,
ColorPalette.green
];
export const iconStyle = {
fontSize: 14
};

View File

@@ -0,0 +1,32 @@
/* eslint-disable lines-around-comment */
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
// @ts-ignore
import { INDICATOR_DISPLAY_THRESHOLD } from '../AbstractConnectionIndicator';
export const CONNECTOR_INDICATOR_LOST = BaseTheme.palette.ui05;
export const CONNECTOR_INDICATOR_OTHER = BaseTheme.palette.action01;
export const CONNECTOR_INDICATOR_COLORS = [
// Full (3 bars)
{
color: BaseTheme.palette.success01,
percent: INDICATOR_DISPLAY_THRESHOLD
},
// 2 bars.
{
color: BaseTheme.palette.warning01,
percent: 10
},
// 1 bar.
{
color: BaseTheme.palette.iconError,
percent: 0
}
];
export const iconStyle = {
fontSize: 14
};

View File

@@ -27,7 +27,8 @@ import {
import AbstractConnectionIndicator, {
type Props as AbstractProps,
type State as AbstractState,
INDICATOR_DISPLAY_THRESHOLD
INDICATOR_DISPLAY_THRESHOLD,
mapStateToProps as _abstractMapStateToProps
// @ts-ignore
} from '../AbstractConnectionIndicator';
@@ -386,6 +387,7 @@ export function _mapStateToProps(state: IReduxState, ownProps: Props) {
const _isConnectionStatusInterrupted = isTrackStreamingStatusInterrupted(_videoTrack);
return {
..._abstractMapStateToProps(state),
_connectionIndicatorInactiveDisabled:
Boolean(state['features/base/config'].connectionIndicators?.inactiveDisabled),
_isVirtualScreenshareParticipant: isScreenShareParticipant(participant),

View File

@@ -1,5 +0,0 @@
// @flow
export * from './components';
export { default as statsEmitter } from './statsEmitter';

View File

@@ -1,5 +1,4 @@
/* eslint-disable lines-around-comment */
import { Theme } from '@mui/material';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
@@ -50,7 +49,7 @@ interface IProps {
thumbnailType: string;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
displayName: {
...withPixelLineHeight(theme.typography.labelBold),

View File

@@ -1,8 +1,7 @@
import { Theme } from '@mui/material';
import React from 'react';
import { makeStyles } from 'tss-react/mui';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
const { text01 } = theme.palette;
return {

View File

@@ -1,6 +1,5 @@
/* eslint-disable lines-around-comment */
import { Theme } from '@mui/material';
import React from 'react';
import { useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
@@ -22,7 +21,7 @@ import { isLayoutTileView } from '../../../video-layout';
import DisplayNameBadge from './DisplayNameBadge';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
badgeContainer: {
...withPixelLineHeight(theme.typography.bodyShortRegularLarge),

View File

@@ -25,7 +25,7 @@ import {
getVideoTrackByParticipant,
trackStreamingStatusChanged
} from '../../../base/tracks';
import { ConnectionIndicator } from '../../../connection-indicator';
import ConnectionIndicator from '../../../connection-indicator/components/native/ConnectionIndicator';
import { DisplayNameLabel } from '../../../display-name';
import { getGifDisplayMode, getGifForParticipant } from '../../../gifs/functions';
import {
@@ -191,6 +191,8 @@ class Thumbnail extends PureComponent<Props> {
dispatch(showSharedVideoMenu(_participantId));
}
// TODO: add support for getting info about the virtual screen shares.
if (!_fakeParticipant) {
dispatch(showContextMenuDetails(_participantId, _local));
}

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React from 'react';
import { useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
@@ -31,7 +30,7 @@ interface IProps {
tooltipPosition: string;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
raisedHandIndicator: {
backgroundColor: theme.palette.warning02,

View File

@@ -85,6 +85,16 @@ export function getActiveParticipantsIds(_state: any) {
return [];
}
/**
* Not implemented on mobile.
*
* @param {any} _state - Redux state.
* @returns {Array<Object>}
*/
export function getPinnedActiveParticipants(_state: any) {
return [];
}
/**
* Returns the number of participants displayed in tile view.
*

View File

@@ -1,7 +1,6 @@
/* eslint-disable lines-around-comment */
import { GiphyFetch, TrendingOptions } from '@giphy/js-fetch-api';
import { Grid } from '@giphy/react-components';
import { Theme } from '@mui/material';
import React, { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { batch, useDispatch, useSelector } from 'react-redux';
@@ -29,7 +28,7 @@ import {
const OVERFLOW_DRAWER_PADDING = 16;
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
gifsMenu: {
width: '100%',

View File

@@ -183,7 +183,7 @@ function AddPeopleDialog({
&& <DialInSection phoneNumber = { _phoneNumber } />
}
{
!_dialInVisible && _isVpaasMeeting && <DialInLimit />
!_phoneNumber && _dialInVisible && _isVpaasMeeting && <DialInLimit />
}
</div>
</Dialog>

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { makeStyles } from 'tss-react/mui';
@@ -15,7 +14,7 @@ interface IProps {
url: string;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
label: {
display: 'block',

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React from 'react';
import { WithTranslation } from 'react-i18next';
import { makeStyles } from 'tss-react/mui';
@@ -7,7 +6,7 @@ import { translate } from '../../../../base/i18n/functions';
import { withPixelLineHeight } from '../../../../base/styles/functions.web';
import { UPGRADE_OPTIONS_LINK, UPGRADE_OPTIONS_TEXT } from '../../../constants';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
limitContainer: {
backgroundColor: theme.palette.warning01,

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
@@ -21,7 +20,7 @@ interface IProps {
phoneNumber: string;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
container: {
'& .info-label': {

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { makeStyles } from 'tss-react/mui';
@@ -35,7 +34,7 @@ interface IProps {
inviteTextiOS: string;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
container: {
marginTop: theme.spacing(4)

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { makeStyles } from 'tss-react/mui';
@@ -25,7 +24,7 @@ interface IProps {
*
* @returns {Object}
*/
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
list: {
listStyleType: 'none',

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { useCallback } from 'react';
import { WithTranslation } from 'react-i18next';
import { useStore } from 'react-redux';
@@ -9,7 +8,7 @@ import { translate } from '../../base/i18n/functions';
// @ts-ignore
import { setSeeWhatIsBeingShared } from '../actions.web';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
overlayContainer: {
width: '100%',

View File

@@ -1,6 +1,6 @@
import { FlagGroupContext } from '@atlaskit/flag/flag-group';
import { AtlasKitThemeProvider } from '@atlaskit/theme';
import { Theme } from '@mui/material';
import { Theme } from '@mui/material/styles';
import { withStyles } from '@mui/styles';
import clsx from 'clsx';
import React, { Component } from 'react';

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { ReactElement, useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
@@ -80,7 +79,7 @@ interface IProps {
toggleParticipantMenu: Function;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
container: {
boxShadow: 'none'

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
@@ -20,7 +19,7 @@ interface IProps {
};
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
button: {
marginRight: theme.spacing(2)

View File

@@ -1,5 +1,4 @@
/* eslint-disable lines-around-comment */
import { Theme } from '@mui/material';
import React, { useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
@@ -49,7 +48,7 @@ interface IProps {
onSelect: (force?: any) => void;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
text: {
color: theme.palette.text02,

View File

@@ -1,5 +1,4 @@
/* eslint-disable lines-around-comment */
import { Theme } from '@mui/material';
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
@@ -39,7 +38,7 @@ import { SETTINGS_TABS } from '../../../settings/constants';
// @ts-ignore
import { MuteEveryonesVideoDialog } from '../../../video-menu/components';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
contextMenu: {
bottom: 'auto',

View File

@@ -1,6 +1,5 @@
// eslint-disable-next-line lines-around-comment
import { Theme } from '@mui/material';
import React, { useCallback, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
@@ -39,7 +38,7 @@ interface IProps {
participant: IParticipant;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
button: {
marginRight: theme.spacing(2)

View File

@@ -1,5 +1,4 @@
/* eslint-disable lines-around-comment */
import { Theme } from '@mui/material';
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
@@ -22,7 +21,7 @@ import { useLobbyActions, useParticipantDrawer } from '../../hooks';
// @ts-ignore
import LobbyParticipantItems from './LobbyParticipantItems';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
drawerActions: {
listStyleType: 'none',

View File

@@ -1,6 +1,5 @@
/* eslint-disable lines-around-comment */
import { Theme } from '@mui/material';
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
@@ -30,7 +29,7 @@ import MeetingParticipantContextMenu from './MeetingParticipantContextMenu';
// @ts-ignore
import MeetingParticipantItems from './MeetingParticipantItems';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
heading: {
color: theme.palette.text02,

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { ReactElement, useCallback } from 'react';
import { WithTranslation } from 'react-i18next';
import { makeStyles } from 'tss-react/mui';
@@ -97,7 +96,7 @@ interface IProps extends WithTranslation {
youText?: string;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
nameContainer: {
display: 'flex',

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
@@ -46,7 +45,7 @@ interface IProps {
participantName: string;
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
button: {
marginRight: theme.spacing(2)

View File

@@ -1,5 +1,4 @@
/* eslint-disable lines-around-comment */
import { Theme } from '@mui/material';
import React, { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
@@ -32,7 +31,7 @@ import LobbyParticipants from './LobbyParticipants';
import MeetingParticipants from './MeetingParticipants';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
container: {
boxSizing: 'border-box' as const,

View File

@@ -1,11 +1,10 @@
import { Theme } from '@mui/material';
import React from 'react';
import { makeStyles } from 'tss-react/mui';
import Icon from '../../../base/icons/components/Icon';
import { IconRaiseHand } from '../../../base/icons/svg';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
indicator: {
backgroundColor: theme.palette.warning02,

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -9,7 +8,7 @@ import { BUTTON_TYPES } from '../../../base/ui/constants.web';
import { isSubmitAnswerDisabled } from '../../functions';
import AbstractPollAnswer, { AbstractProps } from '../AbstractPollAnswer';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
buttonMargin: {
marginRight: theme.spacing(2)

View File

@@ -1,5 +1,4 @@
/* eslint-disable lines-around-comment */
import { Theme } from '@mui/material';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -15,7 +14,7 @@ import AbstractPollCreate from '../AbstractPollCreate';
// @ts-ignore
import type { AbstractProps } from '../AbstractPollCreate';
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
buttonMargin: {
marginRight: theme.spacing(2)

View File

@@ -143,7 +143,7 @@ const Prejoin: React.FC<IPrejoinProps> = ({ navigation }: IPrejoinProps) => {
return (
<JitsiScreen
addBottomPadding = { false }
safeAreaInsets = { [ 'left' ] }
safeAreaInsets = { [ 'left', 'right' ] }
style = { contentWrapperStyles }>
<BrandingImageBackground />
{

View File

@@ -3,11 +3,12 @@ import BaseTheme from '../../base/ui/components/BaseTheme.native';
export default {
joinButton: {
marginVertical: BaseTheme.spacing[3]
marginTop: BaseTheme.spacing[3]
},
joinLowBandwidthLabel: {
color: BaseTheme.palette.text01,
marginTop: BaseTheme.spacing[3],
textAlign: 'center'
},
@@ -76,7 +77,7 @@ export default {
flexDirection: 'row',
height: 60,
justifyContent: 'space-between',
marginVertical: BaseTheme.spacing[3],
marginBottom: BaseTheme.spacing[3],
paddingHorizontal: BaseTheme.spacing[2],
width: 148
},

View File

@@ -1,4 +1,3 @@
import { Theme } from '@mui/material';
import React from 'react';
import { makeStyles } from 'tss-react/mui';
@@ -33,7 +32,7 @@ interface IProps {
}
const useStyles = makeStyles()((theme: Theme) => {
const useStyles = makeStyles()(theme => {
return {
prejoinPreviewDropdownBtn: {
alignItems: 'center',

Some files were not shown because too many files have changed in this diff Show More