Merge remote-tracking branch 'upstream/master' into merge-webrtc-screenshare-2

Conflicts:
	bigbluebutton-html5/imports/ui/components/media/container.jsx
	bigbluebutton-html5/server/main.js
This commit is contained in:
perroned 2017-03-06 19:21:40 +00:00
commit dab5adb5be
166 changed files with 3119 additions and 3615 deletions

View File

@ -1,181 +1,184 @@
** NOTE: **
Taken from https://github.com/bytedeco/javacpp-presets/wiki/Build-Environments
Introduction
------------
This page contains a description of the environments that are used to build the JavaCPP Presets for [Android (ARM and x86)](#android-arm-and-x86), [Linux (x86 and x86_64)](#linux-x86-and-x86_64), [Linux (ARM)](#linux-arm), [Mac OS X (x86_64)](#mac-os-x-x86_64), and [Windows (x86 and x86_64)](#windows-x86-and-x86_64). We also explain our choices given the requirements and provide some recommendations. Furthermore, JavaCPP is by no means limited to these platforms, so if you happen to know how to set up an environment for other platforms, by all means, please do add that information to this page to share with others. Thank you!
Prerequisites for all platforms
-------------------------------
The build process for the modules of `javacpp-presets` usually depends on the same version of the `javacpp` module. To insure that you have the latest matching version of both, please execute the following before starting the build in the `javacpp-presets` directory:
```bash
$ git clone https://github.com/bytedeco/javacpp.git --branch <tag>
$ git clone https://github.com/bytedeco/javacpp-presets.git --branch <tag>
$ cd javacpp
$ mvn clean install
```
For the latest tag please check
https://github.com/bytedeco/javacpp-presets/tags
Android (ARM and x86)
---------------------
To produce native libraries for Android, we basically only need to install the JDK and the NDK, which is available for Linux, Mac OS X, and Windows. However, the build scripts of some libraries only run correctly under Linux, so we recommend using a recent distribution of Linux (such as Fedora or Ubuntu) as build environment for Android.
### Preparations
1. Download the latest version of the [NDK](https://developer.android.com/ndk/downloads/), which is r10e at the time of this writing and contains important fixes for OpenMP, among other things
2. Install the NDK under `~/Android/android-ndk`, where the build scripts will look for it by default
3. Finally, make sure to have installed at least OpenJDK and Maven as per the instructions of your distribution
After which the following commands can be used to start the build inside the `javacpp-presets` directory:
```bash
$ ANDROID_NDK=/path/to/android-ndk/ bash cppbuild.sh -platform android-xxx install
$ mvn clean install -Djavacpp.platform=android-xxx -Djavacpp.platform.root=/path/to/android-ndk/ -Djavacpp.platform.compiler=/path/to/target-g++
```
where `android-xxx` is either `android-arm` or `android-x86`, and where `target-g++` is either `arm-linux-androideabi-g++` or `i686-linux-android-g++`.
Linux (x86 and x86_64)
----------------------
To produce native libraries that can run on the largest possible number of Linux installations out there, it is recommended to build under CentOS 7. This is because it relies on an old enough version of glibc, which nevertheless works for all the libraries found in the JavaCPP Presets, and since newer versions of glibc are backward compatible, all recent distributions of Linux should support the binaries generated. We do not actually need to install CentOS 7 though. Pretty much any recent distribution of Linux comes with a package for [Docker](https://www.docker.com/). It is also possible to map existing directories, for example `/usr/local/lib/bazel` and `/usr/local/cuda` as shown in the steps below, to reuse an existing [Bazel](http://bazel.io/docs/install.html) or [CUDA](https://developer.nvidia.com/cuda-downloads) installation as well as any other set of files for the purpose of the build.
### Preparations
1. Install Docker under, for example, Fedora and Ubuntu, respectively:
```bash
$ sudo yum install docker
$ sudo apt-get install docker.io
```
2. When using SELinux, it might also be necessary to disable temporarily the firewall, for example:
```
$ sudo systemctl stop firewalld
$ sudo systemctl start docker
```
3. Start the container for CentOS 7 (the command might be `docker.io` instead of `docker`):
```bash
$ sudo docker run --privileged -it -v /usr/local/lib/bazel:/usr/local/lib/bazel -v /usr/local/cuda:/usr/local/cuda centos:7 /bin/bash
```
4. Finally, inside the container, we need to install a bunch of things:
```bash
$ ln -s /usr/local/lib/bazel/bin/bazel /usr/local/bin/bazel
$ yum install epel-release
$ yum install clang gcc-c++ gcc-gfortran java-devel maven python numpy swig git file which wget unzip tar bzip2 gzip xz patch make cmake3 perl nasm yasm alsa-lib-devel freeglut-devel gtk2-devel libusb-devel libusb1-devel zlib-devel
$ yum install `rpm -qa | sed s/.x86_64$/.i686/`
```
After which the following commands can be used to start the build inside the `javacpp-presets` directory:
```bash
$ bash cppbuild.sh -platform linux-xxx install
$ mvn clean install -Djavacpp.platform=linux-xxx
```
where `linux-xxx` is either `linux-x86` or `linux-x86_64`.
Linux (ARM)
-----------
There are a growing number of arm platforms running Linux, though testing of this build has mainly focussed on the Pi family of products. Compiling natively on these platforms can be quite time consuming, and as well to automate the build process, the build setup here relies on cross-compiling for the target arm platform. This has been tested using Ubuntu x64 15.10, but it should be reasonably similar approach for other host OS's.
You'll need to have setup a build environment with the usual packages (pkgconfig, build-essentials, yasm, nasm, maven3, etc). The major addition you'll need is a set of cross compilers: arm-linux-gnueabihf-gcc, arm-linux-gnueabihf-g++ and arm-linux-gnueabihf-cpp. It's best to get these via your OS's package manager, as there are other dependencies for these.
Originally a 5.x compiler was used, but this seems to caused problems in creating a dependency on newer glibc functionality which might not be present on your target arm device. The 4.8 or 4.9 version of the compiler seems to work fine, but, in targetting support for the Pi1 and well as Pi2-Pi3 (i.e. arm6 as well as arm7) it seems some compiler flag combinations might not be support by the standard gnueabihf compiler toolchain.
There are pi specific compilers available, so these have been used in the current setup.
1. Get the Pi tools: git clone https://github.com/raspberrypi/tools.git
2. From this folder, move out a specific compiler version to a more generic location: sudo cp -r ./tools/arm-bcm2708/arm-bcm2708-linux-gnueabi /opt
3. Setup alternatives of the generic compiler names in /usr/bin to point to this new compiler
```bash
$ update-alternatives --install /usr/bin/arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc /opt/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-gcc 46
$ update-alternatives --install /usr/bin/arm-linux-gnueabihf-g++ arm-linux-gnueabihf-g++ /opt/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-g++ 46
$ update-alternatives --install /usr/bin/arm-linux-gnueabihf-cpp arm-linux-gnueabihf-cpp /opt/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-cpp 46
```
(This way if you want to explore using other newer compilers, just add them to alternatives and the same build setup should work fine)
This should now have you setup ready to build for arm. It could be an idea to test at this stage with building a simple hello world executable (save your hello world test code as hello.cpp):
$ arm-linux-gnueabihf-g++ -O3 -g3 -Wall -fPIC -march=armv6 -mfpu=vfp -mfloat-abi=hard hello.cpp -c -o hello.o
$ arm-linux-gnueabihf-g++ -o hello hello.o
$ file hello
And you should see in the returned info that hello is built for ARM
With the build environment setup, now its on to building JavaCV. Not all components have been setup with the linux-armhf build configurations, so rather than building the entire project only a subset are built here, but enough to have core functionality (OpenCV, FFmpeg) working with some additional parts (artoolkitplus, flycapture, flandmark, libfreenect, libdc1394) built but not tested. For flycapture, you need to download the arm SDK (currently flycapture.2.9.3.13_armhf) and make these .so libs available, either in your path, or setting up a /usr/include/flycapture directory and moving them there.
Now all the dependencies are setup, the build can be started (assuming you've done a git clone of javacv, javacpp and javacpp-presets all to the same folder)
$ cd javacpp
$ mvn install
$ cd ..
$ cd javacpp-presets
$ ./cppbuild.sh -platform linux-armhf install
$ mvn install -Djavacpp.platform=linux-armhf -Djavacpp.platform.compiler=arm-linux-gnueabihf-g++
$ cd platform
$ mvn install -Djavacpp.platform=linux-armhf
Hopefully that all runs OK, and then in ./javacpp-presets/platform/target/ you should find there are platform specific (opencv-linux-armhf.jar, ffmpeg-linux-armhf.jar, etc) files built.
If you want to try alternative flags, you need to modify in javacpp, ./src/main/resources/org/bytedeco/javacpp/properties/linux-armhf.properties and then in javacpp-presets any project cppbuild.sh file where you want to update too (e.g. ./opencv/cppbuild.sh linux-armhf section). For newer Pis on arm7 it does look like there are potential performance gains in armv7 and neon flags, and using a newer compiler rather than the bcm2708 build used here may further improve things (some earlier builds specific for armv7 did look faster). Also if you are using onboard picam devices, make sure you load the module with "modprobe bcm2835-v4l2 max_video_width=2592 max_video_height=1944" - this way if you test just using OpenCV or FFMPEG grabber you should get at least 30fps as a start point. The more computation you then do on each frame, the more this will drop.
Mac OS X (x86_64)
-----------------
OS X Mavericks (10.9) is the first version of Mac OS X to support C++11 fully and properly, so to preserve your sanity, we do not recommend trying to build or use the JavaCPP Presets on any older versions of Mac OS X.
### Preparations
1. Install [Xcode](https://developer.apple.com/xcode/) and [Homebrew](http://brew.sh/)
2. Ensure the command line tools for Xcode are installed
```bash
$ xcode-select --install
```
3. Run the following commands to install the JDK, among other things Apple left out of Xcode:
```bash
$ brew install caskroom/cask/brew-cask
$ brew cask install cuda java
$ brew install gcc5 swig bazel cmake libusb maven nasm yasm xz pkg-config
```
After which the following commands can be used to start the build inside the `javacpp-presets` directory:
```bash
$ bash cppbuild.sh install
$ mvn clean install
```
Windows (x86 and x86_64)
------------------------
Visual Studio Community 2013 is the first free version to have been decently bundled with support for C++11, OpenMP, the Windows SDK, and everything else from Microsoft, so we recommend installing that version of Visual Studio, which consequently requires Windows 7. Still, to run the bash scripts and compile some things that the Microsoft C/C++ Compiler does not support, we need to install manually a few other things.
### Preparations
1. Install the [Java SE Development Kit](http://www.oracle.com/technetwork/java/javase/downloads/), [Maven](https://maven.apache.org/download.cgi), [MSYS2](https://msys2.github.io/), [Visual Studio Community 2013](https://www.visualstudio.com/en-us/news/vs2013-community-vs.aspx), and [CUDA](https://developer.nvidia.com/cuda-downloads)
2. Under an "MSYS2 Shell", run:
```bash
$ pacman -S base-devel tar patch make git unzip zip nasm yasm pkg-config mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc mingw-w64-i686-gcc mingw-w64-x86_64-gcc-fortran mingw-w64-i686-gcc-fortran mingw-w64-x86_64-libwinpthread-git mingw-w64-i686-libwinpthread-git
```
3. From the "Visual Studio Tools" found inside the Start menu, open:
- "VS2013 x86 Native Tools Command Prompt" and run `c:\msys64\mingw32_shell.bat` inside
- "VS2013 x64 Native Tools Command Prompt" and run `c:\msys64\mingw64_shell.bat` inside
- Making sure the `set MSYS2_PATH_TYPE=inherit` line is *not* commented out in either of those batch files.
4. Run the "Prerequisites for all platforms" tasks inside the shell
Afterwards the following commands can be used to start the build inside the `javacpp-presets` directory:
```bash
$ bash cppbuild.sh -platform windows-xxx install
$ mvn clean install -Djavacpp.platform=windows-xxx
```
where `windows-xxx` is either `windows-x86` or `windows-x86_64`. Run the builds for `windows-x86` inside the "MINGW32" window, and the ones for `windows-x86_64` in the "MINGW64" one.
These are instructions taken from JavaCV website to write the instructions above. We keep a copy here to make sure the instructions we have are compatible with out version of javacpp-presets.
** NOTE: **
Taken from https://github.com/bytedeco/javacpp-presets/wiki/Build-Environments
Introduction
------------
This page contains a description of the environments that are used to build the JavaCPP Presets for [Android (ARM and x86)](#android-arm-and-x86), [Linux (x86 and x86_64)](#linux-x86-and-x86_64), [Linux (ARM)](#linux-arm), [Mac OS X (x86_64)](#mac-os-x-x86_64), and [Windows (x86 and x86_64)](#windows-x86-and-x86_64). We also explain our choices given the requirements and provide some recommendations. Furthermore, JavaCPP is by no means limited to these platforms, so if you happen to know how to set up an environment for other platforms, by all means, please do add that information to this page to share with others. Thank you!
Prerequisites for all platforms
-------------------------------
The build process for the modules of `javacpp-presets` usually depends on the same version of the `javacpp` module. To insure that you have the latest matching version of both, please execute the following before starting the build in the `javacpp-presets` directory:
```bash
$ git clone https://github.com/bytedeco/javacpp.git --branch <tag>
$ git clone https://github.com/bytedeco/javacpp-presets.git --branch <tag>
$ cd javacpp
$ mvn clean install
```
For the latest tag please check
https://github.com/bytedeco/javacpp-presets/tags
Android (ARM and x86)
---------------------
To produce native libraries for Android, we basically only need to install the JDK and the NDK, which is available for Linux, Mac OS X, and Windows. However, the build scripts of some libraries only run correctly under Linux, so we recommend using a recent distribution of Linux (such as Fedora or Ubuntu) as build environment for Android.
### Preparations
1. Download the latest version of the [NDK](https://developer.android.com/ndk/downloads/), which is r10e at the time of this writing and contains important fixes for OpenMP, among other things
2. Install the NDK under `~/Android/android-ndk`, where the build scripts will look for it by default
3. Finally, make sure to have installed at least OpenJDK and Maven as per the instructions of your distribution
After which the following commands can be used to start the build inside the `javacpp-presets` directory:
```bash
$ ANDROID_NDK=/path/to/android-ndk/ bash cppbuild.sh -platform android-xxx install
$ mvn clean install -Djavacpp.platform=android-xxx -Djavacpp.platform.root=/path/to/android-ndk/ -Djavacpp.platform.compiler=/path/to/target-g++
```
where `android-xxx` is either `android-arm` or `android-x86`, and where `target-g++` is either `arm-linux-androideabi-g++` or `i686-linux-android-g++`.
Linux (x86 and x86_64)
----------------------
To produce native libraries that can run on the largest possible number of Linux installations out there, it is recommended to build under CentOS 7. This is because it relies on an old enough version of glibc, which nevertheless works for all the libraries found in the JavaCPP Presets, and since newer versions of glibc are backward compatible, all recent distributions of Linux should support the binaries generated. We do not actually need to install CentOS 7 though. Pretty much any recent distribution of Linux comes with a package for [Docker](https://www.docker.com/). It is also possible to map existing directories, for example `/usr/local/lib/bazel` and `/usr/local/cuda` as shown in the steps below, to reuse an existing [Bazel](http://bazel.io/docs/install.html) or [CUDA](https://developer.nvidia.com/cuda-downloads) installation as well as any other set of files for the purpose of the build.
### Preparations
1. Install Docker under, for example, Fedora and Ubuntu, respectively:
```bash
$ sudo yum install docker
$ sudo apt-get install docker.io
```
2. When using SELinux, it might also be necessary to disable temporarily the firewall, for example:
```
$ sudo systemctl stop firewalld
$ sudo systemctl start docker
```
3. Start the container for CentOS 7 (the command might be `docker.io` instead of `docker`):
```bash
$ sudo docker run --privileged -it -v /usr/local/lib/bazel:/usr/local/lib/bazel -v /usr/local/cuda:/usr/local/cuda centos:7 /bin/bash
```
4. Finally, inside the container, we need to install a bunch of things:
```bash
$ ln -s /usr/local/lib/bazel/bin/bazel /usr/local/bin/bazel
$ yum install epel-release
$ yum install clang gcc-c++ gcc-gfortran java-devel maven python numpy swig git file which wget unzip tar bzip2 gzip xz patch make cmake3 perl nasm yasm alsa-lib-devel freeglut-devel gtk2-devel libusb-devel libusb1-devel zlib-devel
$ yum install `rpm -qa | sed s/.x86_64$/.i686/`
```
After which the following commands can be used to start the build inside the `javacpp-presets` directory:
```bash
$ bash cppbuild.sh -platform linux-xxx install
$ mvn clean install -Djavacpp.platform=linux-xxx
```
where `linux-xxx` is either `linux-x86` or `linux-x86_64`.
Linux (ARM)
-----------
There are a growing number of arm platforms running Linux, though testing of this build has mainly focussed on the Pi family of products. Compiling natively on these platforms can be quite time consuming, and as well to automate the build process, the build setup here relies on cross-compiling for the target arm platform. This has been tested using Ubuntu x64 15.10, but it should be reasonably similar approach for other host OS's.
You'll need to have setup a build environment with the usual packages (pkgconfig, build-essentials, yasm, nasm, maven3, etc). The major addition you'll need is a set of cross compilers: arm-linux-gnueabihf-gcc, arm-linux-gnueabihf-g++ and arm-linux-gnueabihf-cpp. It's best to get these via your OS's package manager, as there are other dependencies for these.
Originally a 5.x compiler was used, but this seems to caused problems in creating a dependency on newer glibc functionality which might not be present on your target arm device. The 4.8 or 4.9 version of the compiler seems to work fine, but, in targetting support for the Pi1 and well as Pi2-Pi3 (i.e. arm6 as well as arm7) it seems some compiler flag combinations might not be support by the standard gnueabihf compiler toolchain.
There are pi specific compilers available, so these have been used in the current setup.
1. Get the Pi tools: git clone https://github.com/raspberrypi/tools.git
2. From this folder, move out a specific compiler version to a more generic location: sudo cp -r ./tools/arm-bcm2708/arm-bcm2708-linux-gnueabi /opt
3. Setup alternatives of the generic compiler names in /usr/bin to point to this new compiler
```bash
$ update-alternatives --install /usr/bin/arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc /opt/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-gcc 46
$ update-alternatives --install /usr/bin/arm-linux-gnueabihf-g++ arm-linux-gnueabihf-g++ /opt/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-g++ 46
$ update-alternatives --install /usr/bin/arm-linux-gnueabihf-cpp arm-linux-gnueabihf-cpp /opt/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-cpp 46
```
(This way if you want to explore using other newer compilers, just add them to alternatives and the same build setup should work fine)
This should now have you setup ready to build for arm. It could be an idea to test at this stage with building a simple hello world executable (save your hello world test code as hello.cpp):
$ arm-linux-gnueabihf-g++ -O3 -g3 -Wall -fPIC -march=armv6 -mfpu=vfp -mfloat-abi=hard hello.cpp -c -o hello.o
$ arm-linux-gnueabihf-g++ -o hello hello.o
$ file hello
And you should see in the returned info that hello is built for ARM
With the build environment setup, now its on to building JavaCV. Not all components have been setup with the linux-armhf build configurations, so rather than building the entire project only a subset are built here, but enough to have core functionality (OpenCV, FFmpeg) working with some additional parts (artoolkitplus, flycapture, flandmark, libfreenect, libdc1394) built but not tested. For flycapture, you need to download the arm SDK (currently flycapture.2.9.3.13_armhf) and make these .so libs available, either in your path, or setting up a /usr/include/flycapture directory and moving them there.
Now all the dependencies are setup, the build can be started (assuming you've done a git clone of javacv, javacpp and javacpp-presets all to the same folder)
$ cd javacpp
$ mvn install
$ cd ..
$ cd javacpp-presets
$ ./cppbuild.sh -platform linux-armhf install
$ mvn install -Djavacpp.platform=linux-armhf -Djavacpp.platform.compiler=arm-linux-gnueabihf-g++
$ cd platform
$ mvn install -Djavacpp.platform=linux-armhf
Hopefully that all runs OK, and then in ./javacpp-presets/platform/target/ you should find there are platform specific (opencv-linux-armhf.jar, ffmpeg-linux-armhf.jar, etc) files built.
If you want to try alternative flags, you need to modify in javacpp, ./src/main/resources/org/bytedeco/javacpp/properties/linux-armhf.properties and then in javacpp-presets any project cppbuild.sh file where you want to update too (e.g. ./opencv/cppbuild.sh linux-armhf section). For newer Pis on arm7 it does look like there are potential performance gains in armv7 and neon flags, and using a newer compiler rather than the bcm2708 build used here may further improve things (some earlier builds specific for armv7 did look faster). Also if you are using onboard picam devices, make sure you load the module with "modprobe bcm2835-v4l2 max_video_width=2592 max_video_height=1944" - this way if you test just using OpenCV or FFMPEG grabber you should get at least 30fps as a start point. The more computation you then do on each frame, the more this will drop.
Mac OS X (x86_64)
-----------------
OS X Mavericks (10.9) is the first version of Mac OS X to support C++11 fully and properly, so to preserve your sanity, we do not recommend trying to build or use the JavaCPP Presets on any older versions of Mac OS X.
### Preparations
1. Install [Xcode](https://developer.apple.com/xcode/) and [Homebrew](http://brew.sh/)
2. Ensure the command line tools for Xcode are installed
```bash
$ xcode-select --install
```
3. Run the following commands to install the JDK, among other things Apple left out of Xcode:
```bash
$ brew install caskroom/cask/brew-cask
$ brew cask install cuda java
$ brew install gcc5 swig bazel cmake libusb maven nasm yasm xz pkg-config
```
After which the following commands can be used to start the build inside the `javacpp-presets` directory:
```bash
$ bash cppbuild.sh install
$ mvn clean install
```
Windows (x86 and x86_64)
------------------------
Visual Studio Community 2013 is the first free version to have been decently bundled with support for C++11, OpenMP, the Windows SDK, and everything else from Microsoft, so we recommend installing that version of Visual Studio, which consequently requires Windows 7. Still, to run the bash scripts and compile some things that the Microsoft C/C++ Compiler does not support, we need to install manually a few other things.
### Preparations
1. Install the [Java SE Development Kit](http://www.oracle.com/technetwork/java/javase/downloads/), [Maven](https://maven.apache.org/download.cgi), [MSYS2](https://msys2.github.io/), [Visual Studio Community 2013](https://www.visualstudio.com/en-us/news/vs2013-community-vs.aspx), and [CUDA](https://developer.nvidia.com/cuda-downloads)
2. Under an "MSYS2 Shell", run:
```bash
$ pacman -S base-devel tar patch make git unzip zip nasm yasm pkg-config mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc mingw-w64-i686-gcc mingw-w64-x86_64-gcc-fortran mingw-w64-i686-gcc-fortran mingw-w64-x86_64-libwinpthread-git mingw-w64-i686-libwinpthread-git
```
3. From the "Visual Studio Tools" found inside the Start menu, open:
- "VS2013 x86 Native Tools Command Prompt" and run `c:\msys64\mingw32_shell.bat` inside
- "VS2013 x64 Native Tools Command Prompt" and run `c:\msys64\mingw64_shell.bat` inside
- Making sure the `set MSYS2_PATH_TYPE=inherit` line is *not* commented out in either of those batch files.
4. Run the "Prerequisites for all platforms" tasks inside the shell
Afterwards the following commands can be used to start the build inside the `javacpp-presets` directory:
```bash
$ bash cppbuild.sh -platform windows-xxx install
$ mvn clean install -Djavacpp.platform=windows-xxx
```
where `windows-xxx` is either `windows-x86` or `windows-x86_64`. Run the builds for `windows-x86` inside the "MINGW32" window, and the ones for `windows-x86_64` in the "MINGW64" one.

176
bbb-screenshare/README.md Executable file
View File

@ -0,0 +1,176 @@
This document contains instructions on how to build your own native libraries, screenshare webstart app, and how to deploy screenshare application.
Building your own native libraries
----------------------------------
Linux (x86 and x86_64)
----------------------
To produce native libraries that can run on the largest possible number of Linux installations out there, it is recommended to build under CentOS 7. This is because it relies on an old enough version of glibc, which nevertheless works for all the libraries found in the JavaCPP Presets, and since newer versions of glibc are backward compatible, all recent distributions of Linux should support the binaries generated. We do not actually need to install CentOS 7 though. Pretty much any recent distribution of Linux comes with a package for [Docker](https://www.docker.com/). It is also possible to map existing directories, for example `/usr/local/lib/bazel` and `/usr/local/cuda` as shown in the steps below, to reuse an existing [Bazel](http://bazel.io/docs/install.html) or [CUDA](https://developer.nvidia.com/cuda-downloads) installation as well as any other set of files for the purpose of the build.
### Preparations
1. Install Docker under, for example, Fedora and Ubuntu, respectively:
```bash
$ sudo yum install docker
$ sudo apt-get install docker.io
```
2. When using SELinux, it might also be necessary to disable temporarily the firewall, for example:
```
$ sudo systemctl stop firewalld
$ sudo systemctl start docker
```
3. Start the container for CentOS 7 (the command might be `docker.io` instead of `docker`):
```bash
$ sudo docker run --privileged -it -v /usr/local/lib/bazel:/usr/local/lib/bazel -v /usr/local/cuda:/usr/local/cuda centos:7 /bin/bash
```
4. Finally, inside the container, we need to install a bunch of things:
```bash
$ ln -s /usr/local/lib/bazel/bin/bazel /usr/local/bin/bazel
$ yum install epel-release
$ yum install clang gcc-c++ gcc-gfortran java-devel maven python numpy swig git file which wget unzip tar bzip2 gzip xz patch make cmake3 perl nasm yasm alsa-lib-devel freeglut-devel gtk2-devel libusb-devel libusb1-devel zlib-devel
$ yum install `rpm -qa | sed s/.x86_64$/.i686/`
```
5. Checkout `https://github.com/bigbluebutton/javacpp-presets` and use branch `min-build-1.2-svc2`
6. cd to `javacpp-presets/ffmpeg`
7. If you want to build SVC2 libraries, you copy `cppbuild.sh.svc2` to `cppbuild.sh`
8. After which the following commands inside the `ffmpeg` dir:
```bash
bash cppbuild.sh -platform linux-xxx install
mvn clean install -Djavacpp.platform=linux-xxx
```
where `linux-xxx` is either `linux-x86` or `linux-x86_64`.
If things go well, copy the resulting jar into `native-libs/ffmpeg-linux-xxx` and sign the jar.
Mac OS X (x86_64)
-----------------
OS X Mavericks (10.9) is the first version of Mac OS X to support C++11 fully and properly, so to preserve your sanity, we do not recommend trying to build or use the JavaCPP Presets on any older versions of Mac OS X.
### Preparations
1. Install [Xcode](https://developer.apple.com/xcode/) and [Homebrew](http://brew.sh/)
2. Ensure the command line tools for Xcode are installed
```bash
$ xcode-select --install
```
3. Run the following commands to install the JDK, among other things Apple left out of Xcode:
```bash
$ brew install caskroom/cask/brew-cask
$ brew cask install cuda java
$ brew install gcc5 swig bazel cmake libusb maven nasm yasm xz pkg-config
```
4. Checkout `https://github.com/bigbluebutton/javacpp-presets` and use branch `min-build-1.2-svc2`
5. cd to `javacpp-presets/ffmpeg`
6. If you want to build SVC2 libraries, you copy `cppbuild.sh.svc2` to `cppbuild.sh`
7. After which the following commands inside the `ffmpeg` dir:
```bash
$ bash cppbuild.sh install
$ mvn clean install
```
If things go well, copy the resulting jar into `native-libs/ffmpeg-macosx-x86_64` and sign the jar.
Windows (x86 and x86_64)
------------------------
Visual Studio Community 2013 is the first free version to have been decently bundled with support for C++11, OpenMP, the Windows SDK, and everything else from Microsoft, so we recommend installing that version of Visual Studio, which consequently requires Windows 7. Still, to run the bash scripts and compile some things that the Microsoft C/C++ Compiler does not support, we need to install manually a few other things.
### Preparations
1. Install the [Java SE Development Kit](http://www.oracle.com/technetwork/java/javase/downloads/), [Maven](https://maven.apache.org/download.cgi), [MSYS2](https://msys2.github.io/), [Visual Studio Community 2013](https://www.visualstudio.com/en-us/news/vs2013-community-vs.aspx), and [CUDA](https://developer.nvidia.com/cuda-downloads)
2. Under an "MSYS2 Shell", run:
```bash
$ pacman -S base-devel tar patch make git unzip zip nasm yasm pkg-config mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc mingw-w64-i686-gcc mingw-w64-x86_64-gcc-fortran mingw-w64-i686-gcc-fortran mingw-w64-x86_64-libwinpthread-git mingw-w64-i686-libwinpthread-git
```
3. From the "Visual Studio Tools" found inside the Start menu, open:
- "VS2013 x86 Native Tools Command Prompt" and run `c:\msys64\mingw32_shell.bat` inside
- "VS2013 x64 Native Tools Command Prompt" and run `c:\msys64\mingw64_shell.bat` inside
- Making sure the `set MSYS2_PATH_TYPE=inherit` line is *not* commented out in either of those batch files.
4. Run the "Prerequisites for all platforms" tasks inside the shell
5. Checkout `https://github.com/bigbluebutton/javacpp-presets` and use branch `min-build-1.2-svc2`
6. cd to `javacpp-presets/ffmpeg`
7. If you want to build SVC2 libraries, you copy `cppbuild.sh.svc2` to `cppbuild.sh`
8. After which the following commands inside the `ffmpeg` dir:
```bash
$ bash cppbuild.sh -platform windows-xxx install
$ mvn clean install -Djavacpp.platform=windows-xxx
```
where `windows-xxx` is either `windows-x86` or `windows-x86_64`. Run the builds for `windows-x86` inside the "MINGW32" window, and the ones for `windows-x86_64` in the "MINGW64" one.
If things go well, copy the resulting jar into `native-libs/ffmpeg-windows-xxx` and sign the jar.
Signing the jar files
---------------------
To sign the native libraries, cd to the location of the jar. Copy tour cert into the dir and run `sign-jar.sh`. You will be prompted for
your cert file and password of your cert.
Example:
```
cd ffmpeg-linux-x86/svc2
Copy your cert into this directory
./sign-jar.sh
You will be prompted for your cert file and password.
```
The resulting signed jar file will be in `bbb-screenshare/apps/jws/lib`
Aside from the native jar files, you will need to sign the `ffmpeg.jar` found in `jws/signed-jars`. Follow the README doc in that directory.
Building screenshare webstart application
-----------------------------------------
1. Go to `jws/webstart` directory.
2. Copy your cert into the dir.
3. Run `build.sh` and you will be prompted for your cert file and cert password in order to sign the jar file.
Deploying and testing the screenshare application
-------------------------------------------------
1. Go to `app` directory.
2. Edit `src/main/webapp/WEB-INF/screenshare.properties` to point to your server's IP address.
3. Run `deploy.sh` to build the whole application and deploy to your local red5 server.

View File

@ -1,30 +1,30 @@
#
# NOTE: default properties.
#
# NOTE!!!! NOTE!!!! NOTE!!!! NOTE!!!! NOTE!!!!
# When making changes that you don't want checked-in, do
# git update-index --assume-unchanged <file>
#
# To have git track the changes again
# git update-index --no-assume-unchanged <file>
#
recordingDirectory=/usr/share/red5/webapps/screenshare/streams
redis.host=127.0.0.1
redis.port=6379
streamBaseUrl=rtmp://192.168.23.53/screenshare
jnlpUrl=http://192.168.23.53/screenshare
jnlpFile=http://192.168.23.53/screenshare/screenshare.jnlp
useH264=false
# NOTES:
# 1. GOP (group of pictures) is calculated as frameRate * keyFrameInterval
# 2. intra-refresh=1 doesn't work in Chrome. Late comers can't view the stream as
# the user missed the key frame
# 3. keyFrameInterval is in seconds
# 4. Make sure you encode & into &amp; as it will break the JNLP XML
#codecOptions=crf=36&amp;preset=veryfast&amp;tune=animation,zerolatency&amp;frameRate=12.0&amp;keyFrameInterval=6
codecOptions=crf=38&amp;preset=veryfast&amp;tune=zerolatency&amp;frameRate=5.0&amp;keyFrameInterval=5
#
# NOTE: default properties.
#
# NOTE!!!! NOTE!!!! NOTE!!!! NOTE!!!! NOTE!!!!
# When making changes that you don't want checked-in, do
# git update-index --assume-unchanged <file>
#
# To have git track the changes again
# git update-index --no-assume-unchanged <file>
#
recordingDirectory=/usr/share/red5/webapps/screenshare/streams
redis.host=127.0.0.1
redis.port=6379
streamBaseUrl=rtmp://192.168.23.22/screenshare
jnlpUrl=http://192.168.23.22/screenshare
jnlpFile=http://192.168.23.22/screenshare/screenshare.jnlp
useH264=false
# NOTES:
# 1. GOP (group of pictures) is calculated as frameRate * keyFrameInterval
# 2. intra-refresh=1 doesn't work in Chrome. Late comers can't view the stream as
# the user missed the key frame
# 3. keyFrameInterval is in seconds
# 4. Make sure you encode & into &amp; as it will break the JNLP XML
#codecOptions=crf=36&amp;preset=veryfast&amp;tune=animation,zerolatency&amp;frameRate=12.0&amp;keyFrameInterval=6
codecOptions=crf=38&amp;preset=veryfast&amp;tune=zerolatency&amp;frameRate=5.0&amp;keyFrameInterval=5

View File

@ -1 +0,0 @@
# bigbluebutton-screenshare

View File

@ -1,11 +1,15 @@
=== Signing jars ===
To sign the ffmpeg.jar and javacpp.jar, copy them to the ```workdir``` directory and
run "```ant sign-ffmpeg-jar```" or "```ant sign-javacpp-jar```".
In this version of screenshare, you only need to sign `ffmpeg.jar`.
The resulting jar files will now be signed. To verify, run
Copy your certificate in this directory and run `sign-ffmpeg.sh`. It will prompt for
your cert file as well as password of your cert file.
The resulting signed jar file will be found in `bbb-screenshare/apps/jws/lib`
To verify that the jar has been signed, run
```
jarsigner -verify ffmpeg.jar
jarsigner -verify javacpp.jar
```

View File

@ -1,16 +0,0 @@
FFMPEG=ffmpeg-3.0.2-1.2-svc2.jar
if [ -d "workdir" ]; then
rm -rf workdir
fi
mkdir workdir
cp $FFMPEG workdir
cd workdir
jar xf $FFMPEG
rm $FFMPEG
rm -rf META-INF
jar cf ffmpeg.jar *
cd ..
ant sign-ffmpeg-jar
cp workdir/ffmpeg.jar ../../../app/jws/lib/ffmpeg-svc2.jar
rm -rf workdir

View File

@ -2,9 +2,7 @@ if [ -d "lib" ]; then
rm -rf lib
fi
mkdir lib
cp ../../app/jws/lib/*.jar lib
rm lib/javacv.jar
rm lib/javacpp.jar
cp ../../app/jws/lib/ffmpeg.jar lib
gradle clean
gradle jar
ant sign-jar

View File

@ -36,16 +36,20 @@ import org.red5.server.stream.ClientBroadcastStream;
import org.slf4j.Logger;
import com.google.gson.Gson;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class VideoApplication extends MultiThreadedApplicationAdapter {
private static Logger log = Red5LoggerFactory.getLogger(VideoApplication.class, "video");
private MessagePublisher publisher;
private boolean recordVideoStream = false;
private EventRecordingService recordingService;
private final Map<String, IStreamListener> streamListeners = new HashMap<String, IStreamListener>();
private int packetTimeout = 10000;
private final Pattern RECORD_STREAM_ID_PATTERN = Pattern.compile("(.*)(-recorded)$");
@Override
public boolean appStart(IScope app) {
@ -190,14 +194,21 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
String meetingId = conn.getScope().getName();
String streamId = stream.getPublishedName();
VideoStreamListener listener = new VideoStreamListener(conn.getScope(), stream, recordVideoStream, userId, packetTimeout);
listener.setEventRecordingService(recordingService);
stream.addStreamListener(listener);
streamListeners.put(conn.getScope().getName() + "-" + stream.getPublishedName(), listener);
if (recordVideoStream) {
recordStream(stream);
}
Matcher matcher = RECORD_STREAM_ID_PATTERN.matcher(stream.getPublishedName());
if (matcher.matches()) {
log.info("Start recording of stream=[" + stream.getPublishedName() + "] for meeting=[" + conn.getScope().getName() + "]");
Boolean recordVideoStream = true;
VideoStreamListener listener = new VideoStreamListener(conn.getScope(), stream, recordVideoStream, userId, packetTimeout);
listener.setEventRecordingService(recordingService);
stream.addStreamListener(listener);
streamListeners.put(conn.getScope().getName() + "-" + stream.getPublishedName(), listener);
recordStream(stream);
}
}
private Long genTimestamp() {
@ -222,24 +233,26 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
String meetingId = conn.getScope().getName();
String streamId = stream.getPublishedName();
IStreamListener listener = streamListeners.remove(scopeName + "-" + stream.getPublishedName());
if (listener != null) {
((VideoStreamListener) listener).streamStopped();
stream.removeStreamListener(listener);
}
if (recordVideoStream) {
long publishDuration = (System.currentTimeMillis() - stream.getCreationTime()) / 1000;
log.info("Stop recording event for stream=[{}] meeting=[{}]", stream.getPublishedName(), scopeName);
Map<String, String> event = new HashMap<String, String>();
event.put("module", "WEBCAM");
event.put("timestamp", genTimestamp().toString());
event.put("meetingId", scopeName);
event.put("stream", stream.getPublishedName());
event.put("duration", new Long(publishDuration).toString());
event.put("eventName", "StopWebcamShareEvent");
recordingService.record(scopeName, event);
}
Matcher matcher = RECORD_STREAM_ID_PATTERN.matcher(stream.getPublishedName());
if (matcher.matches()) {
IStreamListener listener = streamListeners.remove(scopeName + "-" + stream.getPublishedName());
if (listener != null) {
((VideoStreamListener) listener).streamStopped();
stream.removeStreamListener(listener);
}
long publishDuration = (System.currentTimeMillis() - stream.getCreationTime()) / 1000;
log.info("Stop recording event for stream=[{}] meeting=[{}]", stream.getPublishedName(), scopeName);
Map<String, String> event = new HashMap<String, String>();
event.put("module", "WEBCAM");
event.put("timestamp", genTimestamp().toString());
event.put("meetingId", scopeName);
event.put("stream", stream.getPublishedName());
event.put("duration", new Long(publishDuration).toString());
event.put("eventName", "StopWebcamShareEvent");
recordingService.record(scopeName, event);
}
}
/**
@ -261,10 +274,7 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
}
}
public void setRecordVideoStream(boolean recordVideoStream) {
this.recordVideoStream = recordVideoStream;
}
public void setPacketTimeout(int timeout) {
this.packetTimeout = timeout;
}

View File

@ -47,7 +47,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<bean id="web.handler" class="org.bigbluebutton.app.video.VideoApplication">
<property name="packetTimeout" value="10000"/>
<property name="recordVideoStream" value="true"/>
<property name="eventRecordingService" ref="redisRecorder"/>
<property name="messagePublisher" ref="redisPublisher"/>
</bean>

View File

@ -1043,6 +1043,11 @@ PollChoicesModal {
fontFamily: Arial;
}
.chatMessageListStyle {
rollOverColor: #ffffff;
selectionColor: #f3f3f3;
}
EmojiGrid {
backgroundColor: #ffffff;
horizontalAlign: center;

View File

@ -249,12 +249,13 @@ bbb.chat.usersList.accessibilityName = Select user to open private chat. Use the
bbb.chat.chatOptions = Chat Options
bbb.chat.fontSize = Chat Message Font Size
bbb.chat.cmbFontSize.toolTip = Select Chat Message Font Size
bbb.chat.messageList = Message Box
bbb.chat.messageList = Chat Messages
bbb.chat.minimizeBtn.accessibilityName = Minimize the Chat Window
bbb.chat.maximizeRestoreBtn.accessibilityName = Maximize the Chat Window
bbb.chat.closeBtn.accessibilityName = Close the Chat Window
bbb.chat.chatTabs.accessibleNotice = New messages in this tab.
bbb.chat.chatMessage.systemMessage = System
bbb.chat.chatMessage.stringRespresentation = From {0} {1} at {2}
bbb.chat.chatMessage.tooLong = The message is {0} character(s) too long
bbb.publishVideo.changeCameraBtn.labelText = Change Webcam
bbb.publishVideo.changeCameraBtn.toolTip = Open the change webcam dialog box
@ -332,6 +333,8 @@ bbb.screensharePublish.startFailed.label = Did not detect start of screen sharin
bbb.screensharePublish.restartFailed.label = Did not detect restart of screen sharing.
bbb.screensharePublish.jwsCrashed.label = The screen sharing application closed unexpectedly.
bbb.screensharePublish.commonErrorMessage.label = Select 'Cancel' and try again.
bbb.screensharePublish.tunnelingErrorMessage.one = Screen Sharing is unable to run.
bbb.screensharePublish.tunnelingErrorMessage.two = Try refreshing the client (click the refresh button on the browser). If after refresh you still see the words '[ Tunneling ]' in the lower right-hand corner of the client, try connecting from a different network location.
bbb.screensharePublish.cancelButton.label = Cancel
bbb.screensharePublish.startButton.label = Start
bbb.screensharePublish.stopButton.label = Stop
@ -351,12 +354,12 @@ bbb.toolbar.phone.toolTip.stop = Stop Sharing Your Microphone
bbb.toolbar.phone.toolTip.mute = Stop listening the conference
bbb.toolbar.phone.toolTip.unmute = Start listening the conference
bbb.toolbar.phone.toolTip.nomic = No microphone detected
bbb.toolbar.deskshare.toolTip.start = Share Your Screen
bbb.toolbar.deskshare.toolTip.start = Open Screen Share Publish Window
bbb.toolbar.deskshare.toolTip.stop = Stop Sharing Your Screen
bbb.toolbar.video.toolTip.start = Share Your Webcam
bbb.toolbar.video.toolTip.stop = Stop Sharing Your Webcam
bbb.layout.addButton.toolTip = Add the custom layout to the list
bbb.layout.broadcastButton.toolTip = Apply Current Layout to All Viewers
bbb.layout.broadcastButton.toolTip = Apply current layout to all users except moderators
bbb.layout.combo.toolTip = Change Your Layout
bbb.layout.loadButton.toolTip = Load layouts from a file
bbb.layout.saveButton.toolTip = Save layouts to a file
@ -442,6 +445,7 @@ ltbcustom.bbb.highlighter.toolbar.text.accessibilityName = Switch whiteboard cur
ltbcustom.bbb.highlighter.texttoolbar.textColorPicker = Text color
ltbcustom.bbb.highlighter.texttoolbar.textSizeMenu = Font size
bbb.caption.window.title = Closed Caption
bbb.caption.quickLink.label = Closed Caption Window
bbb.caption.window.titleBar = Closed Caption Window Title Bar
bbb.caption.window.minimizeBtn.accessibilityName = Minimize the Closed Caption Window
bbb.caption.window.maximizeRestoreBtn.accessibilityName = Maximize the Closed Caption Window
@ -487,6 +491,7 @@ bbb.shortcuthelp.dropdown.general = Global shortcuts
bbb.shortcuthelp.dropdown.presentation = Presentation shortcuts
bbb.shortcuthelp.dropdown.chat = Chat shortcuts
bbb.shortcuthelp.dropdown.users = Users shortcuts
bbb.shortcuthelp.dropdown.caption = Closed Caption shortcuts
bbb.shortcuthelp.headers.shortcut = Shortcut
bbb.shortcuthelp.headers.function = Function
@ -514,6 +519,8 @@ bbb.shortcutkey.focus.presentation = 51
bbb.shortcutkey.focus.presentation.function = Move focus to the Presentation window
bbb.shortcutkey.focus.chat = 52
bbb.shortcutkey.focus.chat.function = Move focus to the Chat window
bbb.shortcutkey.focus.caption = 53
bbb.shortcutkey.focus.caption.function = Move focus to the Closed Caption window
bbb.shortcutkey.share.desktop = 68
bbb.shortcutkey.share.desktop.function = Open desktop sharing window
@ -552,6 +559,14 @@ bbb.shortcutkey.users.focusUsers = 85
bbb.shortcutkey.users.focusUsers.function = Focus to users list
bbb.shortcutkey.users.muteAllButPres = 65
bbb.shortcutkey.users.muteAllButPres.function = Mute everyone but the Presenter
bbb.shortcutkey.users.breakoutRooms = 75
bbb.shortcutkey.users.breakoutRooms.function = Breakout rooms window
bbb.shortcutkey.users.focusBreakoutRooms = 82
bbb.shortcutkey.users.focusBreakoutRooms.function = Focus to breakout rooms list
bbb.shortcutkey.users.listenToBreakoutRoom = 76
bbb.shortcutkey.users.listenToBreakoutRoom.function = Listen to selected breakout room
bbb.shortcutkey.users.joinBreakoutRoom = 74
bbb.shortcutkey.users.joinBreakoutRoom.function = Join selected breakout room
bbb.shortcutkey.chat.focusTabs = 89
bbb.shortcutkey.chat.focusTabs.function = Focus to chat tabs
@ -581,6 +596,9 @@ bbb.shortcutkey.chat.chatbox.goread.function = Navigate to the most recent messa
bbb.shortcutkey.chat.chatbox.debug = 71
bbb.shortcutkey.chat.chatbox.debug.function = Temporary debug hotkey
bbb.shortcutkey.caption.takeOwnership = 79
bbb.shortcutkey.caption.takeOwnership.function = Take ownsership of selected language
bbb.polling.startButton.tooltip = Start a poll
bbb.polling.startButton.label = Start Poll
bbb.polling.publishButton.label = Publish
@ -620,14 +638,14 @@ bbb.shortcutkey.specialKeys.plus = Plus
bbb.shortcutkey.specialKeys.minus = Minus
bbb.toolbar.videodock.toolTip.closeAllVideos = Close all videos
bbb.users.settings.lockAll=Lock All Users
bbb.users.settings.lockAllExcept=Lock Users Except Presenter
bbb.users.settings.lockSettings=Lock Viewers ...
bbb.users.settings.breakoutRooms=Breakout Rooms ...
bbb.users.settings.sendBreakoutRoomsInvitations=Send Breakout Rooms Invitations ...
bbb.users.settings.unlockAll=Unlock All Viewers
bbb.users.settings.roomIsLocked=Locked by default
bbb.users.settings.roomIsMuted=Muted by default
bbb.users.settings.lockAll = Lock All Users
bbb.users.settings.lockAllExcept = Lock Users Except Presenter
bbb.users.settings.lockSettings = Lock Viewers ...
bbb.users.settings.breakoutRooms = Breakout Rooms ...
bbb.users.settings.sendBreakoutRoomsInvitations = Send Breakout Rooms Invitations ...
bbb.users.settings.unlockAll = Unlock All Viewers
bbb.users.settings.roomIsLocked = Locked by default
bbb.users.settings.roomIsMuted = Muted by default
bbb.lockSettings.save = Apply
bbb.lockSettings.save.tooltip = Apply lock settings

View File

@ -189,7 +189,7 @@
<button id="enterFlash" type="button" class="visually-hidden" onclick="startFlashFocus();">Set focus to client</button>
<div id="content">
<div id="altFlash" style="width:50%; margin-left: auto; margin-right: auto; ">
<h2>You need Flash installed and enabled in order to use the Flash client.</h2>
You need Adobe Flash installed and enabled in order to use this client.
<br/>
<div style="width:50%; margin-left: auto; margin-right: auto; ">
<a href="http://www.adobe.com/go/getflashplayer">

View File

@ -29,20 +29,24 @@ var registerListeners = function() {
console.log("AmISharingCamQueryResponse [isPublishing=" + bbbEvent2.isPublishing + ",camIndex=" + bbbEvent2.camIndex + "]");
});
BBB.amISharingWebcam();
BBB.amISharingWebcam(function(bbbEvent3) {
console.log("amISharingWebcam [isPublishing=" + bbbEvent3.isPublishing
+ ",camIndex=" + bbbEvent3.camIndex
+ ",camWidth=" + bbbEvent3.camWidth
+ ",camHeight=" + bbbEvent3.camHeight
+ ",camKeyFrameInterval=" + bbbEvent3.camKeyFrameInterval
+ ",camModeFps=" + bbbEvent3.camModeFps
+ ",camQualityBandwidth=" + bbbEvent3.camQualityBandwidth
+ ",camQualityPicture=" + bbbEvent3.camQualityPicture
+ "]");
if (bbbEvent3.isPublishing) {
CAM_PREVIEW.stopPreviewCamera(bbbEvent3.avatarURL);
CAM_PREVIEW.previewCamera(bbbEvent3.camIndex, bbbEvent3.camWidth, bbbEvent3.camHeight, bbbEvent3.camKeyFrameInterval,
bbbEvent3.camModeFps, bbbEvent3.camQualityBandwidth, bbbEvent3.camQualityPicture, bbbEvent3.avatarURL);
var cameras = bbbEvent3.cameras;
for(var aCamera in cameras){
console.log("amISharingWebcam [isPublishing=" + aCamera.isPublishing
+ ",camIndex=" + aCamera.camIndex
+ ",camWidth=" + aCamera.camWidth
+ ",camHeight=" + aCamera.camHeight
+ ",camKeyFrameInterval=" + aCamera.camKeyFrameInterval
+ ",camModeFps=" + aCamera.camModeFps
+ ",camQualityBandwidth=" + aCamera.camQualityBandwidth
+ ",camQualityPicture=" + aCamera.camQualityPicture
+ "]");
if (aCamera.isPublishing) {
CAM_PREVIEW.stopPreviewCamera(aCamera.avatarURL);
CAM_PREVIEW.previewCamera(aCamera.camIndex, aCamera.camWidth, aCamera.camHeight, aCamera.camKeyFrameInterval,
aCamera.camModeFps, aCamera.camQualityBandwidth, aCamera.camQualityPicture, aCamera.avatarURL);
}
}
});
} else {

View File

@ -33,19 +33,22 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import flash.events.Event;
import com.asfusion.mate.events.Dispatcher;
import flash.events.Event;
import mx.managers.HistoryManager;
import mx.managers.IDragManager;
import mx.managers.ToolTipManager;
import mx.utils.URLUtil;
import mx.utils.URLUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.KeyboardUtil;
import org.bigbluebutton.main.api.ExternalApiCallbacks;
import org.bigbluebutton.main.events.ShortcutEvent;
import org.bigbluebutton.main.model.ShortcutOptions;
import org.bigbluebutton.util.QueryStringParameters;
import org.bigbluebutton.util.i18n.ResourceUtil;
private static const LOGGER:ILogger = getClassLogger(BigBlueButtonMainContainer);
@ -163,9 +166,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
keyCombos[globalModifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.raiseHand') as String)] = ShortcutEvent.RAISE_HAND;
keyCombos[globalModifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.users.muteme') as String)] = ShortcutEvent.MUTE_ME_EVENT;
keyCombos[globalModifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.users.muteAllButPres') as String)] = ShortcutEvent.MUTE_ALL_BUT_PRES;
}
if (ShortcutOptions.videoDockActive){
keyCombos[globalModifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.focus.video') as String)] = ShortcutEvent.FOCUS_VIDEO_WINDOW;
keyCombos[globalModifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.users.breakoutRooms') as String)] = ShortcutEvent.OPEN_BREAKOUT_ROOMS;
}
if (ShortcutOptions.presentationActive){
keyCombos[globalModifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.focus.presentation') as String)] = ShortcutEvent.FOCUS_PRESENTATION_WINDOW;
@ -181,8 +182,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
keyCombos[globalModifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.polling.buttonClick') as String)] = ShortcutEvent.POLL_BUTTON_CLICK;
}
if (ShortcutOptions.webcamActive){
keyCombos[globalModifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.share.webcam') as String)] = ShortcutEvent.SHARE_WEBCAM;
keyCombos[globalModifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.focus.video') as String)] = ShortcutEvent.FOCUS_VIDEO_WINDOW;
keyCombos[globalModifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.share.webcam') as String)] = ShortcutEvent.SHARE_WEBCAM;
}
if (ShortcutOptions.closedCaptionActive){
keyCombos[globalModifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.focus.caption') as String)] = ShortcutEvent.FOCUS_CAPTION_WINDOW;
}
if (ShortcutOptions.deskshareActive){
keyCombos[globalModifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.share.desktop') as String)] = ShortcutEvent.SHARE_DESKTOP;
}
@ -197,9 +202,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
// Handle general-access hotkeys, regardless of what window the user is focused in
private function handleKeyDown(e:KeyboardEvent) :void {
if (keyCombos == null) loadKeyCombos(globalModifier);
if (keyCombos == null) loadKeyCombos(globalModifier);
var keyPress:String = (e.ctrlKey ? "control+" : "") + (e.shiftKey ? "shift+" : "") + (e.altKey ? "alt+" : "") + e.keyCode;
var keyPress:String = KeyboardUtil.buildPressedKeys(e);
if (e.keyCode < 64 || e.keyCode > 90){
LOGGER.debug("Keypress debugging: KeyCode {0} is nonalphabetic (probably)", [e.keyCode]);

View File

@ -0,0 +1,33 @@
package org.bigbluebutton.common {
import mx.controls.NumericStepper;
import mx.controls.TextInput;
import mx.core.mx_internal;
/* The purpose of this class is to propagate the toolTip value to the internal
* text field so screen readers can read out the description.
*/
public class AccessibleNumericStepper extends NumericStepper {
public function AccessibleNumericStepper() {
super();
}
override protected function createChildren():void {
var inputFieldCreated:Boolean = !mx_internal::inputField;
super.createChildren();
if (inputFieldCreated && toolTip && mx_internal::inputField is TextInput) {
(mx_internal::inputField as TextInput).toolTip = toolTip;
}
}
override public function set toolTip(value:String):void {
super.toolTip = value;
if (mx_internal::inputField && mx_internal::inputField is TextInput) {
(mx_internal::inputField as TextInput).toolTip = toolTip;
}
}
}
}

View File

@ -1,44 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.common.events
{
import flash.events.Event;
import flash.geom.Point;
import mx.core.UIComponent;
import flexlib.mdi.containers.*;
public class DragWindowEvent extends Event
{
public static const DRAG_WINDOW_EVENT:String = "DRAG_WINDOW_EVENT";
public static const DRAG_START:String = "DRAG_START";
public static const DRAG_END:String = "DRAG_END";
public static const DRAG:String = "DRAG";
public var mouseGlobal:Point;
public var window:MDIWindow;
public var mode:String;
public function DragWindowEvent(mode:String, type:String = DRAG_WINDOW_EVENT)
{
super(type, true, false);
this.mode = mode;
}
}
}

View File

@ -26,7 +26,6 @@ package org.bigbluebutton.core {
import org.bigbluebutton.core.managers.ConfigManager2;
import org.bigbluebutton.core.managers.ConnectionManager;
import org.bigbluebutton.core.managers.UserConfigManager;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.core.managers.VideoProfileManager;
import org.bigbluebutton.core.model.Session;
import org.bigbluebutton.core.model.VideoProfile;

View File

@ -1,13 +1,13 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* Copyright (c) 2017 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
@ -16,18 +16,13 @@
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.videoconf.model
{
public class PublishingModel
{
public var streamName;
public var camIndex:int;
public var camWidth:int;
public var camHeight:int;
public var isPublishing:Boolean = false;
public function PublishingModel()
{
package org.bigbluebutton.core {
import flash.events.KeyboardEvent;
public final class KeyboardUtil {
public static function buildPressedKeys(e:KeyboardEvent):String {
return (e.ctrlKey ? "control+" : "") + (e.shiftKey ? "shift+" : "") + (e.altKey ? "alt+" : "") + e.keyCode;
}
}
}
}
}

View File

@ -0,0 +1,92 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2017 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core {
import flash.display.DisplayObject;
import flash.utils.Dictionary;
import flash.utils.getQualifiedClassName;
import mx.core.FlexGlobals;
import mx.core.IChildList;
import mx.core.IFlexDisplayObject;
import mx.core.IUIComponent;
import mx.managers.PopUpManager;
import mx.managers.SystemManager;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
public final class PopUpUtil {
private static const LOGGER:ILogger = getClassLogger(PopUpUtil);
private static var popUpDict:Dictionary = new Dictionary(true);
public static function createNonModelPopUp(parent:DisplayObject, className:Class, center:Boolean = true):IFlexDisplayObject {
if (!checkPopUpExists(className)) {
return addPopUpToStage(parent, className, false, center);
}
return null;
}
public static function createModalPopUp(parent:DisplayObject, className:Class, center:Boolean = true):IFlexDisplayObject {
if (!checkPopUpExists(className)) {
return addPopUpToStage(parent, className, true, center);
}
return null;
}
public static function removePopUp(classOrInstance:*):void {
var fqcn:String = getQualifiedClassName(classOrInstance);
if (popUpDict[fqcn] != undefined) {
PopUpManager.removePopUp(popUpDict[fqcn])
delete popUpDict[fqcn];
LOGGER.debug("Removed PopUp with type [{0}]", [fqcn]);
}
}
private static function checkPopUpExists(className:Class):Boolean {
LOGGER.debug("Checking if [{0}] exists as a PopUp", [className]);
var systemManager:SystemManager = FlexGlobals.topLevelApplication.systemManager;
var childList:IChildList = systemManager.rawChildren;
for (var i:int = childList.numChildren - 1; i >= 0; i--) {
var childObject:IUIComponent = childList.getChildAt(i) as IUIComponent;
// PopUp already exists
if (childObject is className && childObject.isPopUp) {
LOGGER.debug("PopUp with type [{0}] found", [className]);
return true;
}
}
LOGGER.debug("No PopUp with type [{0}] not found", [className]);
return false;
}
private static function addPopUpToStage(parent:DisplayObject, className:Class, modal:Boolean = false, center:Boolean = true):IFlexDisplayObject {
var popUp:IFlexDisplayObject = PopUpManager.createPopUp(parent, className, modal);
if (center) {
PopUpManager.centerPopUp(popUp)
}
popUpDict[getQualifiedClassName(className)] = popUp;
LOGGER.debug("Created PopUp with type [{0}]", [className]);
return popUp;
}
}
}

View File

@ -71,18 +71,18 @@ package org.bigbluebutton.core
return UserManager.getInstance().getConference().record;
}
public static function amIPublishing():CameraSettingsVO {
return UserManager.getInstance().getConference().amIPublishing();
public static function amIPublishing():ArrayCollection {
return UserManager.getInstance().getConference().amIPublishing() as ArrayCollection;
}
public static function setIAmPublishing(publishing:Boolean):void {
UserManager.getInstance().getConference().setCamPublishing(publishing);
public static function addCameraSettings(camSettings:CameraSettingsVO):void {
UserManager.getInstance().getConference().addCameraSettings(camSettings);
}
public static function setCameraSettings(camSettings:CameraSettingsVO):void {
UserManager.getInstance().getConference().setCameraSettings(camSettings);
public static function removeCameraSettings(camIndex:int):void {
UserManager.getInstance().getConference().removeCameraSettings(camIndex);
}
public static function hasWebcamStream(userID:String):Boolean {
var u:BBBUser = getUser(userID);
if (u != null) {

View File

@ -1,29 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.managers {
import org.bigbluebutton.core.vo.Config;
public class ConfigManager {
public var configs:Config;
public function setConfig(conf:Config):void {
this.configs = configs;
}
}
}

View File

@ -21,7 +21,6 @@ package org.bigbluebutton.core.managers
import com.asfusion.mate.events.Dispatcher;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;

View File

@ -18,25 +18,26 @@
*/
package org.bigbluebutton.core.managers
{
import com.asfusion.mate.events.Dispatcher;
import com.asfusion.mate.events.Dispatcher;
import flash.display.DisplayObject;
import flash.events.TimerEvent;
import flash.utils.Dictionary;
import flash.utils.Timer;
import flash.utils.Timer;
import mx.collections.ArrayCollection;
import mx.core.FlexGlobals;
import mx.core.IFlexDisplayObject;
import mx.managers.PopUpManager;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.main.api.JSLog;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.ClientStatusEvent;
import org.bigbluebutton.main.events.LogoutEvent;
import org.bigbluebutton.main.model.users.AutoReconnect;
import org.bigbluebutton.main.views.ReconnectionPopup;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.util.i18n.ResourceUtil;
public class ReconnectionManager
{
@ -52,7 +53,6 @@ package org.bigbluebutton.core.managers
private var _reconnectTimer:Timer = new Timer(10000, 1);
private var _reconnectTimeout:Timer = new Timer(15000, 1);
private var _dispatcher:Dispatcher = new Dispatcher();
private var _popup:IFlexDisplayObject = null;
private var _canceled:Boolean = false;
public function ReconnectionManager() {
@ -97,8 +97,7 @@ package org.bigbluebutton.core.managers
_connections[type] = obj;
if (!_reconnectTimer.running) {
_popup = PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, ReconnectionPopup, true);
PopUpManager.centerPopUp(_popup);
PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, ReconnectionPopup, true);
_reconnectTimer.reset();
_reconnectTimer.start();
@ -163,8 +162,8 @@ package org.bigbluebutton.core.managers
msg, 'bbb.connection.reestablished'));
_reconnectTimeout.reset();
removePopUp();
}
PopUpUtil.removePopUp(ReconnectionPopup);
}
}
public function onCancelReconnection():void {
@ -172,15 +171,8 @@ package org.bigbluebutton.core.managers
for (var type:Object in _connections) delete _connections[type];
removePopUp();
}
private function removePopUp():void {
if (_popup != null) {
PopUpManager.removePopUp(_popup);
_popup = null;
}
}
PopUpUtil.removePopUp(ReconnectionPopup);
}
private function connectionReestablishedMessage():String {
var msg:String = "";

View File

@ -1,97 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.vo {
public class Config {
private var _version:String;
private var _localeVersion:String;
private var _portTestHost:String;
private var _portTestApplication:String;
private var _helpURL:String;
private var _application:String;
private var _host:String;
private var _numModules:int;
private var _languageEnabled:Boolean;
private var _shortcutKeysShowButton:Boolean;
private var _skinning:String = "";
private var _showDebug:Boolean = false;
public function Config(builder:ConfigBuilder) {
_version = builder.version;
_localeVersion = builder.localeVersion;
_portTestHost = builder.portTestHost;
_portTestApplication = builder.portTestApplication;
_helpURL = builder.helpURL;
_application = builder.application;
_host = builder.host;
_numModules = builder.numModules;
_languageEnabled = builder.languageEnabled;
_shortcutKeysShowButton = builder.shortcutKeysShowButton;
_skinning = builder.skinning;
_showDebug = builder.showDebug;
}
public function get version():String {
return _version;
}
public function get localeVersion():String {
return _localeVersion;
}
public function get portTestHost():String {
return _portTestHost;
}
public function get portTestApplication():String {
return _portTestApplication;
}
public function get helpURL():String {
return _helpURL;
}
public function get application():String {
return _application;
}
public function get host():String {
return _host;
}
public function get numModules():int {
return _numModules;
}
public function get languageEnabled():Boolean {
return _languageEnabled;
}
public function get shortcutKeysShowButton():Boolean {
return _shortcutKeysShowButton;
}
public function get skinning():String {
return _skinning;
}
public function get showDebug():Boolean {
return _showDebug;
}
}
}

View File

@ -1,93 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.vo {
public class ConfigBuilder {
internal var version:String;
internal var localeVersion:String;
internal var portTestHost:String;
internal var portTestApplication:String;
internal var helpURL:String;
internal var application:String;
internal var host:String;
internal var numModules:int;
internal var languageEnabled:Boolean;
internal var shortcutKeysShowButton:Boolean;
internal var skinning:String = "";
internal var showDebug:Boolean = false;
public function ConfigBuilder(version:String, localVersion:String){
this.version = version;
this.localeVersion = localVersion;
}
public function withPortTestHost(portTestHost:String):ConfigBuilder {
this.portTestHost = portTestHost;
return this;
}
public function withPortTestApplication(portTestApplication:String):ConfigBuilder {
this.portTestApplication = portTestApplication;
return this;
}
public function withHelpUrl(helpUrl:String):ConfigBuilder {
this.helpURL = helpUrl;
return this;
}
public function withApplication(application:String):ConfigBuilder {
this.application = application;
return this;
}
public function withHost(host:String):ConfigBuilder {
this.host = host;
return this;
}
public function withNumModule(numModules:int):ConfigBuilder {
this.numModules = numModules;
return this;
}
public function withLanguageEnabled(languageEnabled:Boolean):ConfigBuilder {
this.languageEnabled = languageEnabled;
return this;
}
public function withShortcutKeysShowButton(shortcutKeysShowButton:Boolean):ConfigBuilder {
this.shortcutKeysShowButton = shortcutKeysShowButton;
return this;
}
public function withSkinning(skinning:String):ConfigBuilder {
this.skinning = skinning;
return this;
}
public function withShowDebug(showDebug:Boolean):ConfigBuilder {
this.showDebug = showDebug;
return this;
}
public function build():Config {
return new Config(this);
}
}
}

View File

@ -1,70 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.core.vo
{
public class LockSettings
{
private var allowModeratorLocking:Boolean;
private var disableCam:Boolean;
private var disableMic:Boolean;
private var disablePrivateChat:Boolean;
private var disablePublicChat:Boolean;
public function LockSettings(pAllowModeratorLocking:Boolean, pDisableCam:Boolean, pDisableMic:Boolean, pDisablePrivateChat:Boolean, pDisablePublicChat:Boolean)
{
this.allowModeratorLocking = pAllowModeratorLocking;
this.disableCam = pDisableCam;
this.disableMic = pDisableMic;
this.disablePrivateChat = pDisablePrivateChat;
this.disablePublicChat = pDisablePublicChat;
}
public function toMap():Object {
var map:Object = {
allowModeratorLocking: this.allowModeratorLocking,
disableCam: this.disableCam,
disableMic: this.disableMic,
disablePrivateChat: this.disablePrivateChat,
disablePublicChat: this.disablePublicChat
};
return map;
}
public function getAllowModeratorLocking():Boolean {
return allowModeratorLocking;
}
public function getDisableCam():Boolean {
return disableCam;
}
public function getDisableMic():Boolean {
return disableMic;
}
public function getDisablePrivateChat():Boolean {
return disablePrivateChat;
}
public function getDisablePublicChat():Boolean {
return disablePublicChat;
}
}
}

View File

@ -18,9 +18,6 @@
*/
package org.bigbluebutton.core.vo
{
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.main.model.users.BBBUser;
public class LockSettingsVO
{
private var lockOnJoinConfigurable:Boolean;

View File

@ -19,7 +19,8 @@
package org.bigbluebutton.main.api
{
import com.asfusion.mate.events.Dispatcher;
import mx.collections.ArrayCollection;
import flash.external.ExternalInterface;
import org.bigbluebutton.core.BBB;
import org.as3commons.logging.api.ILogger;
@ -48,7 +49,7 @@ package org.bigbluebutton.main.api
import org.bigbluebutton.modules.videoconf.events.ClosePublishWindowEvent;
import org.bigbluebutton.modules.videoconf.events.ShareCameraRequestEvent;
import org.bigbluebutton.modules.videoconf.model.VideoConfOptions;
import org.bigbluebutton.util.SessionTokenUtil;
import org.bigbluebutton.util.SessionTokenUtil;
public class ExternalApiCallbacks {
private static const LOGGER:ILogger = getClassLogger(ExternalApiCallbacks);
@ -188,17 +189,26 @@ package org.bigbluebutton.main.api
private function handleAmISharingCameraRequestSync():Object {
var obj:Object = new Object();
var camSettings:CameraSettingsVO = UsersUtil.amIPublishing();
obj.isPublishing = camSettings.isPublishing;
obj.camIndex = camSettings.camIndex;
obj.camWidth = camSettings.videoProfile.width;
obj.camHeight = camSettings.videoProfile.height;
obj.camKeyFrameInterval = camSettings.videoProfile.keyFrameInterval;
obj.camModeFps = camSettings.videoProfile.modeFps;
obj.camQualityBandwidth = camSettings.videoProfile.qualityBandwidth;
obj.camQualityPicture = camSettings.videoProfile.qualityPicture;
obj.avatarURL = UsersUtil.getAvatarURL();
var camArray: ArrayCollection = new ArrayCollection();
var camSettingsArray:ArrayCollection = UsersUtil.amIPublishing();
for (var i:int = 0; i < camSettingsArray.length; i++) {
var camSettings:CameraSettingsVO = camSettingsArray.getItemAt(i) as CameraSettingsVO;
var cam:Object = new Object();
cam.isPublishing = camSettings.isPublishing;
cam.camIndex = camSettings.camIndex;
cam.camWidth = camSettings.videoProfile.width;
cam.camHeight = camSettings.videoProfile.height;
cam.camKeyFrameInterval = camSettings.videoProfile.keyFrameInterval;
cam.camModeFps = camSettings.videoProfile.modeFps;
cam.camQualityBandwidth = camSettings.videoProfile.qualityBandwidth;
cam.camQualityPicture = camSettings.videoProfile.qualityPicture;
cam.avatarURL = UsersUtil.getAvatarURL();
camArray.addItem(cam);
}
obj.cameras = camArray;
return obj;
}

View File

@ -19,6 +19,7 @@
package org.bigbluebutton.main.api
{
import flash.external.ExternalInterface;
import mx.collections.ArrayCollection;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
@ -158,21 +159,28 @@ package org.bigbluebutton.main.api
}
public function handleAmISharingCamQueryEvent(event:AmISharingWebcamQueryEvent):void {
var camSettings:CameraSettingsVO = UsersUtil.amIPublishing();
var camSettingsArray:ArrayCollection = UsersUtil.amIPublishing();
var payload:Object = new Object();
var camArray: ArrayCollection = new ArrayCollection();
for (var i:int = 0; i < camSettingsArray.length; i++) {
var camSettings:CameraSettingsVO = camSettingsArray.getItemAt(i) as CameraSettingsVO;
var cam:Object = new Object();
cam.isPublishing = camSettings.isPublishing;
cam.camIndex = camSettings.camIndex;
cam.camWidth = camSettings.videoProfile.width;
cam.camHeight = camSettings.videoProfile.height;
cam.camKeyFrameInterval = camSettings.videoProfile.keyFrameInterval;
cam.camModeFps = camSettings.videoProfile.modeFps;
cam.camQualityBandwidth = camSettings.videoProfile.qualityBandwidth;
cam.camQualityPicture = camSettings.videoProfile.qualityPicture;
cam.avatarURL = UsersUtil.getAvatarURL();
camArray.addItem(cam);
}
payload.eventName = EventConstants.AM_I_SHARING_CAM_RESP;
payload.isPublishing = camSettings.isPublishing;
payload.camIndex = camSettings.camIndex;
payload.camWidth = camSettings.videoProfile.width;
payload.camHeight = camSettings.videoProfile.height;
payload.camKeyFrameInterval = camSettings.videoProfile.keyFrameInterval;
payload.camModeFps = camSettings.videoProfile.modeFps;
payload.camQualityBandwidth = camSettings.videoProfile.qualityBandwidth;
payload.camQualityPicture = camSettings.videoProfile.qualityPicture;
payload.avatarURL = UsersUtil.getAvatarURL();
broadcastEvent(payload);
payload.cameras = camArray;
broadcastEvent(payload);
}

View File

@ -17,6 +17,7 @@
*
*/
package org.bigbluebutton.main.events {
import flash.events.Event;
public class ShortcutEvent extends Event {
@ -34,12 +35,6 @@ package org.bigbluebutton.main.events {
public static const FOCUS_CHAT_INPUT:String = 'FOCUS_CHAT_INPUT';
public static const UNDO_WHITEBOARD:String = 'UNDO_WHITEBOARD';
public static const FOCUS_SLIDE:String = 'FOCUS_SLIDE_VIEW';
public static const ADVANCE_MESSAGE:String = 'ADVANCE_MESSAGE';
public static const GOBACK_MESSAGE:String = 'GOBACK_MESSAGE';
public static const REPEAT_MESSAGE:String = 'REPEAT_MESSAGE';
public static const GOLATEST_MESSAGE:String = 'GOLATEST_MESSAGE';
public static const GOFIRST_MESSAGE:String = 'GOFIRST_MESSAGE';
public static const GOREAD_MESSAGE:String = 'GOREAD_MESSAGE';
public static const OPEN_SHORTCUT_WIN:String = 'OPEN_SHORTCUT_WIN';
public static const FOCUS_USERS_WINDOW:String = 'FOCUS_USERS_WINDOW';
@ -52,6 +47,8 @@ package org.bigbluebutton.main.events {
public static const SHARE_WEBCAM:String = 'SHARE_WEBCAM';
public static const PAUSE_REMOTE_STREAM:String = 'PAUSE_REMOTE_STREAM';
public static const FOCUS_CAPTION_WINDOW:String = 'FOCUS_CAPTION_WINDOW';
public static const REMOTE_FOCUS_DESKTOP:String = 'REMOTE_FOCUS_DESKTOP';
public static const REMOTE_FOCUS_WEBCAM:String = 'REMOTE_FOCUS_WEBCAM';
// Remote focus microphone not necessary; audio options already hog focus
@ -76,6 +73,7 @@ package org.bigbluebutton.main.events {
//public static const FOCUS_LOOP_END:String = 'FOCUS_LOOP_END';
public static const FOCUS_SHORTCUT_BUTTON:String = 'FOCUS_SHORTCUT_BUTTON';
public static const MUTE_ALL_BUT_PRES:String = 'MUTE_ALL_BUT_PRES';
public static const OPEN_BREAKOUT_ROOMS:String = 'OPEN_BREAKOUT_ROOMS';
public static const FOCUS_LOGOUT_BUTTON:String = 'FOCUS_LOGOUT_BUTTON';
public static const CLOSE_POLL_STATS:String = 'CLOSE_POLL_STATS';
@ -99,10 +97,7 @@ package org.bigbluebutton.main.events {
public static const REMOTE_CAST_VOTE:String = 'REMOTE_CAST_VOTE';
public static const SC_REFRESH_POLL:String = 'SC_REFRESH_POLL';
public static const SC_REPOST_POLL:String = 'SC_REPOST_POLL';
public static const SC_STOP_POLL:String = 'SC_STOP_POLL';
// Temporary string to help fix chat message navigation for screen readers
public static const CHAT_DEBUG:String = 'CHAT_DEBUG';
public static const SC_STOP_POLL:String = 'SC_STOP_POLL';
public var otherUserID:String;

View File

@ -29,7 +29,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
The FlexEvent.PREINITIALIZE event is a good place for creating and initializing managers.
-->
<ObjectBuilder generator="{ModulesProxy}" cache="global" />
<ObjectBuilder generator="{ConfigManager}" cache="global" />
<ObjectBuilder generator="{ReconnectionManager}" cache="global" />
<!--
Disabling temporarily the stream monitor
@ -100,13 +99,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<![CDATA[
import mx.events.FlexEvent;
import org.bigbluebutton.core.managers.ConfigManager;
import org.bigbluebutton.core.managers.ReconnectionManager;
import org.bigbluebutton.core.services.SkinningService;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.ConfigLoadedEvent;
import org.bigbluebutton.main.events.LoadConfigCommand;
import org.bigbluebutton.main.events.ConfigEvent;
import org.bigbluebutton.main.events.LogoutEvent;
import org.bigbluebutton.main.events.ModuleLoadEvent;
import org.bigbluebutton.main.events.PortTestEvent;

View File

@ -1,166 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.main.model
{
import com.asfusion.mate.events.Dispatcher;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import flash.utils.Dictionary;
import mx.core.FlexGlobals;
import mx.utils.URLUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.main.model.modules.ModuleDescriptor;
import org.bigbluebutton.util.QueryStringParameters;
public class ConfigParameters {
private static const LOGGER:ILogger = getClassLogger(ConfigParameters);
public static const CONFIG_XML:String = "bigbluebutton/api/configXML";
private var _urlLoader:URLLoader;
private var rawXML:XML;
public var version:String;
public var localeVersion:String;
public var suppressLocaleWarning:Boolean = false;
public var portTestHost:String;
public var portTestApplication:String;
public var portTestTimeout:Number;
public var helpURL:String;
public var application:String;
public var host:String;
public var numModules:int;
public var languageEnabled:Boolean;
public var shortcutKeysShowButton:Boolean;
public var skinning:String = "";
public var showDebug:Boolean = false;
private var loadedListener:Function;
private var dispatcher:Dispatcher = new Dispatcher();
private var _modules:Dictionary;
public function ConfigParameters(loadedListener:Function, file:String = CONFIG_XML) {
this.numModules = 0;
this.loadedListener = loadedListener;
}
public function loadConfig():void {
var p:QueryStringParameters = new QueryStringParameters();
p.collectParameters();
var sessionToken:String = p.getParameter("sessionToken");
var reqVars:URLVariables = new URLVariables();
reqVars.sessionToken = sessionToken;
_urlLoader = new URLLoader();
_urlLoader.addEventListener(Event.COMPLETE, handleComplete);
var date:Date = new Date();
var localeReqURL:String = buildRequestURL() + "?a=" + date.time;
LOGGER.debug(localeReqURL + " session=[" + sessionToken + "]");
var request:URLRequest = new URLRequest(localeReqURL);
request.method = URLRequestMethod.GET;
request.data = reqVars;
_urlLoader.load(request);
}
private function buildRequestURL():String {
var swfURL:String = FlexGlobals.topLevelApplication.url;
var protocol:String = URLUtil.getProtocol(swfURL);
var serverName:String = URLUtil.getServerNameWithPort(swfURL);
return protocol + "://" + serverName + "/" + CONFIG_XML;
}
private function handleComplete(e:Event):void{
LOGGER.debug("handleComplete [{0}]", [new XML(e.target.data)]);
parse(new XML(e.target.data));
buildModuleDescriptors();
this.loadedListener();
}
private function parse(xml:XML):void{
rawXML = xml;
portTestHost = xml.porttest.@host;
portTestApplication = xml.porttest.@application;
portTestTimeout = parseInt(xml.porttest.@timeout);
if(isNaN(portTestTimeout) || portTestTimeout < 500) portTestTimeout = 10000;
application = xml.application.@uri;
host = xml.application.@host;
helpURL = xml.help.@url;
version = xml.version;
localeVersion = xml.localeversion;
if (xml.localeversion.@suppressWarning == "true") suppressLocaleWarning = true;
if (xml.language.@userSelectionEnabled == "true") languageEnabled = true;
else languageEnabled = false;
if (xml.shortcutKeys.@showButton == "true") shortcutKeysShowButton = true;
else shortcutKeysShowButton = false;
if (xml.skinning.@enabled == "true") skinning = xml.skinning.@url;
if (xml.debug.@showDebugWindow == "true") showDebug = true;
}
public function getModulesXML():XMLList{
return rawXML.modules.module;
}
private function buildModuleDescriptors():Dictionary{
_modules = new Dictionary();
var list:XMLList = getModulesXML();
var item:XML;
for each(item in list){
var mod:ModuleDescriptor = new ModuleDescriptor(item);
_modules[item.@name] = mod;
numModules++;
}
return _modules;
}
public function getModules():Dictionary{
return _modules;
}
public function getModule(name:String):ModuleDescriptor {
for (var key:Object in _modules) {
var m:ModuleDescriptor = _modules[key] as ModuleDescriptor;
if (m.getName() == name) {
return m;
}
}
return null;
}
}
}

View File

@ -1,58 +1,55 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.main.model {
import flash.events.NetStatusEvent;
import flash.net.NetConnection;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.main.model.modules.ModulesDispatcher;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.main.model.modules.ModulesDispatcher;
public class PortTestProxy {
private static const LOGGER:ILogger = getClassLogger(PortTestProxy);
private var tunnel:Boolean;
private var port:String;
private var hostname:String;
private var application:String;
private var modulesDispatcher:ModulesDispatcher;
private var portTest:PortTest;
public function PortTestProxy(modulesDispatcher: ModulesDispatcher) {
this.modulesDispatcher = modulesDispatcher;
}
public function connect(tunnel:Boolean, hostname:String = "", port:String = "", application:String = "", testTimeout:Number = 10000):void {
this.tunnel = tunnel;
portTest = new PortTest(tunnel, hostname, port, application, testTimeout);
portTest.addConnectionSuccessListener(connectionListener);
public class PortTestProxy {
portTest.connect();
}
private function connectionListener(status:String, tunnel:Boolean, hostname:String, port:String, application:String):void {
if (status == "SUCCESS") {
modulesDispatcher.sendPortTestSuccessEvent(port, hostname, tunnel, application);
} else {
modulesDispatcher.sendPortTestFailedEvent(port, hostname, tunnel, application);
}
}
}
private static const LOGGER:ILogger = getClassLogger(PortTestProxy);
private var tunnel:Boolean;
private var port:String;
private var hostname:String;
private var application:String;
private var modulesDispatcher:ModulesDispatcher;
private var portTest:PortTest;
public function PortTestProxy(modulesDispatcher:ModulesDispatcher) {
this.modulesDispatcher = modulesDispatcher;
}
public function connect(tunnel:Boolean, hostname:String = "", port:String = "", application:String = "", testTimeout:Number = 10000):void {
this.tunnel = tunnel;
portTest = new PortTest(tunnel, hostname, port, application, testTimeout);
portTest.addConnectionSuccessListener(connectionListener);
portTest.connect();
}
private function connectionListener(status:String, tunnel:Boolean, hostname:String, port:String, application:String):void {
if (status == "SUCCESS") {
modulesDispatcher.sendPortTestSuccessEvent(port, hostname, tunnel, application);
} else {
modulesDispatcher.sendPortTestFailedEvent(port, hostname, tunnel, application);
}
}
}
}

View File

@ -1,14 +1,15 @@
package org.bigbluebutton.main.model
{
import org.bigbluebutton.core.BBB;
public class ShortcutOptions
{
private static var users:Boolean = true;
private static var videoDock:Boolean = true;
private static var presentation:Boolean = true;
private static var chat:Boolean = true;
private static var polling:Boolean = true;
private static var webcam:Boolean = true;
private static var closedCaption:Boolean = true;
private static var deskshare:Boolean = true;
private static var audio:Boolean = true;
private static var generalResource:Array;
@ -21,11 +22,6 @@ package org.bigbluebutton.main.model
users = false;
}
vxml = BBB.getConfigForModule("VideodockModule");
if (vxml == null) {
videoDock = false;
}
vxml = BBB.getConfigForModule("PresentModule");
if (vxml == null) {
presentation = false;
@ -56,16 +52,21 @@ package org.bigbluebutton.main.model
audio = false;
}
vxml = BBB.getConfigForModule("CaptionModule");
if (vxml == null) {
closedCaption = false;
}
generalResource = new Array();
generateGlobalKeys();
}
public static function get usersActive():Boolean{return users;}
public static function get videoDockActive():Boolean{return videoDock;}
public static function get presentationActive():Boolean{return presentation;}
public static function get chatActive():Boolean{return chat;}
public static function get pollingActive():Boolean{return polling;}
public static function get webcamActive():Boolean{return webcam;}
public static function get webcamActive():Boolean{return webcam;}
public static function get closedCaptionActive():Boolean{return closedCaption;}
public static function get deskshareActive():Boolean{return deskshare;}
public static function get audioActive():Boolean{return audio;}
public static function get genResource():Array{return generalResource;}
@ -78,9 +79,10 @@ package org.bigbluebutton.main.model
generalResource.push('bbb.shortcutkey.flash.exit');
if (users){generalResource.push('bbb.shortcutkey.focus.users');}
if (videoDock){generalResource.push('bbb.shortcutkey.focus.video');}
if (webcam){generalResource.push('bbb.shortcutkey.focus.video');}
if (presentation){generalResource.push('bbb.shortcutkey.focus.presentation');}
if (chat){generalResource.push('bbb.shortcutkey.focus.chat');}
if (closedCaption){generalResource.push('bbb.shortcutkey.focus.caption');}
if (deskshare){generalResource.push('bbb.shortcutkey.share.desktop');}
if (webcam){generalResource.push('bbb.shortcutkey.share.webcam');}
@ -88,13 +90,14 @@ package org.bigbluebutton.main.model
generalResource.push('bbb.shortcutkey.logout');
if (users){generalResource.push('bbb.shortcutkey.raiseHand');}
if (users){generalResource.push('bbb.shortcutkey.users.breakoutRooms');}
if (audio){generalResource.push('bbb.shortcutkey.users.muteme');}
if (audio){generalResource.push('bbb.shortcutkey.users.muteAllButPres');}
if (chat){generalResource.push('bbb.shortcutkey.chat.chatinput');}
}
public static function debugString():String{
return "USERS: " + users + " VIDEODOCK: " + videoDock + " PRESENTATION: " + presentation + " CHAT: " + chat + " POLLING: " + polling + " WEBCAM: " + webcam + " DESKSHARE: " + deskshare + " AUDIO: " + audio;
return "USERS: " + users + " PRESENTATION: " + presentation + " CHAT: " + chat + " CLOSED CAPTION: " + closedCaption + " POLLING: " + polling + " WEBCAM: " + webcam + " DESKSHARE: " + deskshare + " AUDIO: " + audio;
}
}
}

View File

@ -18,21 +18,14 @@
*/
package org.bigbluebutton.main.model.modules
{
import com.asfusion.mate.events.Dispatcher;
import flash.events.TimerEvent;
import com.asfusion.mate.events.Dispatcher;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.as3commons.logging.util.jsonXify;
import org.bigbluebutton.core.vo.Config;
import org.bigbluebutton.core.vo.ConfigBuilder;
import org.bigbluebutton.main.api.JSLog;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.ConfigEvent;
import org.bigbluebutton.main.events.ConfigLoadedEvent;
import org.bigbluebutton.main.events.ModuleLoadEvent;
import org.bigbluebutton.main.events.PortTestEvent;
import org.bigbluebutton.main.events.UserServicesEvent;
import org.bigbluebutton.main.model.ConfigParameters;
public class ModulesDispatcher
{
@ -41,12 +34,10 @@ package org.bigbluebutton.main.model.modules
private var dispatcher:Dispatcher;
private var enterApiService: EnterApiService;
private var meetingInfo:Object = new Object();
private var enterApiUrl:String;
public function ModulesDispatcher()
{
dispatcher = new Dispatcher();
}
public function sendLoadProgressEvent(moduleName:String, loadProgress:Number):void{
@ -74,49 +65,20 @@ package org.bigbluebutton.main.model.modules
dispatcher.dispatchEvent(e);
}
public function sendPortTestEvent():void {
//getMeetingAndUserInfo();
public function sendPortTestEvent():void{
doPortTesting();
}
private function getMeetingAndUserInfo():void {
enterApiService = new EnterApiService();
enterApiService.addResultListener(resultListener);
enterApiService.load(enterApiUrl);
}
private function resultListener(success:Boolean, result:Object):void {
if (success) {
meetingInfo.username = result.username;
meetingInfo.userId = result.userId;
meetingInfo.meetingName = result.meetingName;
meetingInfo.meetingId = result.meetingId;
doPortTesting();
} else {
var logData:Object = new Object();
JSLog.critical("Failed to get meeting and user info from Enter API", logData);
dispatcher.dispatchEvent(new PortTestEvent(PortTestEvent.TUNNELING_FAILED));
}
}
private function doPortTesting():void {
private function doPortTesting():void{
var e:PortTestEvent = new PortTestEvent(PortTestEvent.TEST_RTMP);
dispatcher.dispatchEvent(e);
}
private function timerHandler(e:TimerEvent):void{
var evt:PortTestEvent = new PortTestEvent(PortTestEvent.PORT_TEST_UPDATE);
dispatcher.dispatchEvent(evt);
}
public function sendTunnelingFailedEvent(server: String, app: String):void{
dispatcher.dispatchEvent(new PortTestEvent(PortTestEvent.TUNNELING_FAILED));
}
public function sendPortTestSuccessEvent(port:String, host:String, tunnel:Boolean, app:String):void{
var portEvent:PortTestEvent = new PortTestEvent(PortTestEvent.PORT_TEST_SUCCESS);
portEvent.port = port;
portEvent.hostname = host;
@ -140,26 +102,6 @@ package org.bigbluebutton.main.model.modules
var event:ModuleLoadEvent = new ModuleLoadEvent(ModuleLoadEvent.MODULE_LOADING_STARTED);
dispatcher.dispatchEvent(event);
}
public function sendConfigParameters(c:ConfigParameters):void{
enterApiUrl = c.host;
var event:ConfigEvent = new ConfigEvent(ConfigEvent.CONFIG_EVENT);
var config:Config;
config = new ConfigBuilder(c.version, c.localeVersion)
.withApplication(c.application)
.withHelpUrl(c.helpURL)
.withHost(c.host)
.withLanguageEnabled(c.languageEnabled)
.withShortcutKeysShowButton(c.shortcutKeysShowButton)
.withNumModule(c.numModules)
.withPortTestApplication(c.portTestApplication)
.withPortTestHost(c.portTestHost)
.withShowDebug(c.showDebug)
.withSkinning(c.skinning)
.build()
event.config = config;
dispatcher.dispatchEvent(event);
}
}
}

View File

@ -20,9 +20,9 @@ package org.bigbluebutton.main.model.modules
{
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.main.model.ConferenceParameters;
import org.bigbluebutton.main.model.PortTestProxy;
import org.bigbluebutton.core.UsersUtil;
public class ModulesProxy {
private static const LOGGER:ILogger = getClassLogger(ModulesProxy);

View File

@ -64,7 +64,7 @@ package org.bigbluebutton.main.model.users {
private var lockSettings:LockSettingsVO;
private var _myCamSettings:CameraSettingsVO = new CameraSettingsVO();
private var _myCamSettings:ArrayCollection = null;
[Bindable]
private var me:BBBUser = null;
@ -90,6 +90,7 @@ package org.bigbluebutton.main.model.users {
users.sort = sort;
users.refresh();
breakoutRooms = new ArrayCollection();
_myCamSettings = new ArrayCollection();
}
// Custom sort function for the users ArrayCollection. Need to put dial-in users at the very bottom.
@ -152,19 +153,28 @@ package org.bigbluebutton.main.model.users {
users.addItem(newuser);
users.refresh();
}
public function setCamPublishing(publishing:Boolean):void {
_myCamSettings.isPublishing = publishing;
public function addCameraSettings(camSettings: CameraSettingsVO): void {
if(!_myCamSettings.contains(camSettings)) {
_myCamSettings.addItem(camSettings);
}
}
public function setCameraSettings(camSettings:CameraSettingsVO):void {
_myCamSettings = camSettings;
public function removeCameraSettings(camIndex:int): void {
if (camIndex != -1) {
for(var i:int = 0; i < _myCamSettings.length; i++) {
if (_myCamSettings.getItemAt(i) != null && _myCamSettings.getItemAt(i).camIndex == camIndex) {
_myCamSettings.removeItemAt(i);
return;
}
}
}
}
public function amIPublishing():CameraSettingsVO {
public function amIPublishing():ArrayCollection {
return _myCamSettings;
}
public function setDefaultLayout(defaultLayout:String):void {
this.defaultLayout = defaultLayout;
}

View File

View File

@ -29,7 +29,7 @@
public var stream:String;
public var userid:String;
public var isPresenter:Boolean;
public var camSettings:CameraSettingsVO;
public var camSettings:CameraSettingsVO;
public function BroadcastStartedEvent(type:String = BROADCAST_STARTED_EVENT) {
super(type, true, false);

View File

@ -34,10 +34,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import mx.managers.PopUpManager;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.api.JSAPI;
@ -99,7 +98,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
dispatcher.dispatchEvent(command);
}
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function onListenClick():void {
@ -109,7 +108,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
command.mic = false;
dispatcher.dispatchEvent(command);
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function onCancelClicked():void {
@ -117,7 +116,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(new AudioSelectionWindowEvent(AudioSelectionWindowEvent.CLOSED_AUDIO_SELECTION));
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function handleBecomePresenter(e:MadePresenterEvent):void {

View File

@ -1,13 +1,13 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
@ -16,21 +16,19 @@
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.main.events
{
import flash.events.Event;
import org.bigbluebutton.core.vo.Config;
package org.bigbluebutton.main.views {
import mx.controls.DataGrid;
public class ConfigEvent extends Event
{
public static const CONFIG_EVENT:String = "config event";
public var config:Config;
public function ConfigEvent(type:String)
{
super(type, true, false);
}
}
}
public class BBBDataGrid extends DataGrid {
// This function needs to be overridden to avoid finding any
// first comumn value that starts the typed letter.
// It will make hotkeys work correctly gtriki (12 feb, 2017)
override protected function findKey(eventCode:int):Boolean {
if (eventCode >= 33 && eventCode <= 126) {
return false;
} else {
return super.findKey(eventCode);
}
}
}
}

View File

@ -21,7 +21,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:view="org.bigbluebutton.main.views.*"
xmlns:common="org.bigbluebutton.common.*"
layout="absolute"
layout="absolute"
verticalScrollPolicy="off" horizontalScrollPolicy="off"
width="630" height="450" creationComplete="onCreationComplete()" styleName="cameraDisplaySettingsWindowStyle"
showCloseButton="false" close="onCancelClicked()" keyDown="handleKeyDown(event)">
@ -34,11 +34,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import mx.collections.ArrayCollection;
import mx.collections.ArrayList;
import mx.events.CloseEvent;
import mx.managers.PopUpManager;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.common.Media;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.model.VideoProfile;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
@ -70,10 +70,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
{
return;
}
private function onCreationComplete():void {
tabIndex = 51;
}
public function updateCameraList() : void {
if(defaultCamera != null) {
var indexDefault:int = 0;
for (var i:int = 0; i < Media.availableCameras; i++){
@ -97,14 +99,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
for each (var value:VideoProfile in BBB.videoProfiles) {
var item:Object = {index:idx, label:value.name, profile:value};
_videoProfiles.addItem(item);
if (value.id == defaultProfile.id) {
cmbVideoProfile.selectedIndex = idx;
}
idx++;
}
if (_videoProfiles.length > 1) {
showResControls(true);
}
@ -197,11 +199,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function onCancelClicked():void {
close("cancel");
}
private function showCameraSettings():void {
Security.showSettings(SecurityPanel.CAMERA);
}
private function close(payload:String):void {
disableCamera();
@ -211,7 +209,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
var event:BBBEvent = new BBBEvent(BBBEvent.CAM_SETTINGS_CLOSED);
event.payload['clicked'] = payload;
dispatchEvent(event);
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
]]>

View File

@ -39,22 +39,21 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.modules.phone.events.WebRTCEchoTestEvent;
import org.bigbluebutton.modules.phone.events.WebRTCMediaEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
private function handleWebRTCMediaSuccessEvent(e:WebRTCMediaEvent):void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function handleWebRTCMediaFailEvent(e:WebRTCMediaEvent):void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function handleWebRTCEchoTestFailedEvent(e:WebRTCEchoTestEvent):void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
]]>

View File

@ -38,18 +38,17 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.model.users.events.BroadcastStartedEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
private function handleBroadcastStartedEvent(e:BroadcastStartedEvent):void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function handleCameraSettingsClosedEvent(e:BBBEvent):void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
]]>

View File

@ -28,8 +28,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
creationComplete="onCreationComplete();">
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.util.i18n.ResourceUtil;
private function onCreationComplete():void {
@ -41,7 +40,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function handleCloseButtonClick():void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
]]>
</mx:Script>

View File

@ -26,14 +26,13 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<![CDATA[
import flash.net.navigateToURL;
import mx.managers.PopUpManager;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.main.model.users.events.UsersConnectionEvent;
private function connectionReestablished(e:UsersConnectionEvent):void{
var url:URLRequest = new URLRequest(ExternalInterface.call("window.location.href.toString"));
navigateToURL(url, '_self');
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
]]>

View File

@ -39,24 +39,22 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.modules.phone.events.WebRTCEchoTestEvent;
import org.bigbluebutton.modules.phone.events.WebRTCMediaEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
private function handleWebRTCMediaSuccessEvent(e:WebRTCMediaEvent):void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function handleWebRTCMediaFailEvent(e:WebRTCMediaEvent):void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function handleWebRTCEchoTestFailedEvent(e:WebRTCEchoTestEvent):void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
]]>
</mx:Script>

View File

@ -39,17 +39,18 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import com.asfusion.mate.events.Dispatcher;
import flash.ui.Keyboard;
import org.bigbluebutton.core.UsersUtil;
import mx.controls.sliderClasses.Slider;
import mx.events.CloseEvent;
import mx.events.SliderEvent;
import mx.managers.PopUpManager;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.common.Media;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.modules.phone.events.AudioSelectionWindowEvent;
import org.bigbluebutton.modules.phone.events.FlashEchoTestFailedEvent;
import org.bigbluebutton.modules.phone.events.FlashEchoTestHasAudioEvent;
@ -241,7 +242,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function handleFlashJoinedVoiceConferenceEvent(event:FlashJoinedVoiceConferenceEvent):void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function echoTestButtonClickHandler():void {
@ -263,7 +264,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
stopEchoTest();
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(new AudioSelectionWindowEvent(AudioSelectionWindowEvent.CLOSED_AUDIO_SELECTION));
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function stopEchoTest():void {
@ -307,7 +308,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
dispatchEvent(new FlashEchoTestHasAudioEvent());
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(new AudioSelectionWindowEvent(AudioSelectionWindowEvent.CLOSED_AUDIO_SELECTION));
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function noButtonClicked():void {

View File

@ -22,7 +22,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
xmlns:mate="http://mate.asfusion.com/"
xmlns:common="org.bigbluebutton.common.*"
width="300" height="400"
creationComplete="creationCompleteHandler(event)"
styleName="lockSettingsWindowStyle"
showCloseButton="false"
close="onCancelClicked()"
@ -30,20 +29,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import mx.events.CloseEvent;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.events.LockControlEvent;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.core.vo.LockSettingsVO;
import org.bigbluebutton.main.model.ConferenceParameters;
import org.bigbluebutton.main.model.users.Conference;
import org.bigbluebutton.util.i18n.ResourceUtil;
private var images:Images = new Images();
[Bindable] private var cancelIcon:Class = images.cancel;
@ -65,24 +58,18 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
this.dispatchEvent(new CloseEvent(CloseEvent.CLOSE));
}
}
private function onSaveClicked():void {
var event:LockControlEvent = new LockControlEvent(LockControlEvent.SAVE_LOCK_SETTINGS);
var lockSettings:LockSettingsVO = new LockSettingsVO(chkDisableWebcam.selected, chkDisableMicrophone.selected, chkDisablePrivateChat.selected, chkDisablePublicChat.selected, chkDisableLayout.selected, chkLockOnJoin.selected, lockOnJoinConfigurable);
event.payload = lockSettings.toMap();
dispatchEvent(event);
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function onCancelClicked():void {
PopUpManager.removePopUp(this);
}
protected function creationCompleteHandler(event:FlexEvent):void
{
PopUpUtil.removePopUp(this);
}
]]>
</mx:Script>

View File

@ -28,19 +28,20 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import flash.net.navigateToURL;
import mx.managers.PopUpManager;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.events.ExitApplicationEvent;
import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
private static const LOGGER:ILogger = getClassLogger(LoggedOutWindow);
[Bindable]
@ -70,7 +71,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function handleComplete(e:Event):void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
exitApplication();
}
@ -79,13 +80,13 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
logData.tags = ["logout"];
logData.message = "Log out redirection returned with error.";
LOGGER.error(JSON.stringify(logData));
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
exitApplication();
}
private function onUserLoggedOutWindowClose(e:Event):void {
LOGGER.debug("Closing UserLoggedOutWindow");
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
public function setReason(reason:String):void {

View File

@ -86,7 +86,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import mx.core.IFlexDisplayObject;
import mx.core.UIComponent;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
import flexlib.mdi.effects.effectsLib.MDIVistaEffects;
@ -99,6 +98,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.common.events.ToolbarButtonEvent;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.events.LockControlEvent;
import org.bigbluebutton.core.managers.UserManager;
@ -133,7 +133,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private var stoppedModules:ArrayCollection;
private var logWindow:LogWindow;
private var scWindow:ShortcutHelpWindow;
private var logoutWindow:LoggedOutWindow;
private var connectionLostWindow:ConnectionLostWindow;
// LIVE or PLAYBACK
@ -165,7 +164,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
[Bindable] private var isTunneling:Boolean = false;
private var confirmingLogout:Boolean = false;
private var chromeBrowser:ChromeWebcamPermissionImage = null;
public function getLogWindow() : LogWindow
{
@ -408,141 +406,152 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
if (version != localeVersion) wrongLocaleVersion();
}
}
private function handleFlashMicSettingsEvent(event:FlashMicSettingsEvent):void {
/**
* There is a bug in Flex SDK 4.14 where the screen stays blurry if a
* pop-up is opened from another pop-up. I delayed the second open to
* avoid this case. - Chad
*/
this.callLater(function():void {
var micSettings:FlashMicSettings = PopUpUtil.createModalPopUp(mdiCanvas, FlashMicSettings, false) as FlashMicSettings;
if (micSettings) {
micSettings.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:Event):void {
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = width / 2;
point1.y = height / 2;
micSettings.x = point1.x - (micSettings.width / 2);
micSettings.y = point1.y - (micSettings.height / 2);
});
}
});
}
private function handleFlashMicSettingsEvent(event:FlashMicSettingsEvent):void {
/**
* There is a bug in Flex SDK 4.14 where the screen stays blurry if a
* pop-up is opened from another pop-up. I delayed the second open to
* avoid this case. - Chad
*/
this.callLater( function():void {
var micSettings:FlashMicSettings = PopUpManager.createPopUp(mdiCanvas, FlashMicSettings, true) as FlashMicSettings;
micSettings.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:Event):void {
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = width/2;
point1.y = height/2;
micSettings.x = point1.x - (micSettings.width/2);
micSettings.y = point1.y - (micSettings.height/2);
});
});
}
private function openVideoPreviewWindow(event:BBBEvent):void {
var camSettings:CameraDisplaySettings = CameraDisplaySettings(PopUpManager.createPopUp(mdiCanvas, CameraDisplaySettings, true));
camSettings.defaultCamera = event.payload.defaultCamera;
camSettings.camerasArray = event.payload.camerasArray;
camSettings.publishInClient = event.payload.publishInClient;
camSettings.chromePermissionDenied = event.payload.chromePermissionDenied;
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = width/2;
point1.y = height/2;
camSettings.x = point1.x - (camSettings.width/2);
camSettings.y = point1.y - (camSettings.height/2);
}
private function wrongLocaleVersion():void {
var localeWindow:OldLocaleWarnWindow = OldLocaleWarnWindow(PopUpManager.createPopUp(mdiCanvas, OldLocaleWarnWindow, false));
private function openVideoPreviewWindow(event:BBBEvent):void {
var camSettings:CameraDisplaySettings = PopUpUtil.createModalPopUp(mdiCanvas, CameraDisplaySettings, true) as CameraDisplaySettings;
if (camSettings) {
camSettings.defaultCamera = event.payload.defaultCamera;
camSettings.camerasArray = event.payload.camerasArray;
camSettings.publishInClient = event.payload.publishInClient;
camSettings.chromePermissionDenied = event.payload.chromePermissionDenied;
camSettings.updateCameraList();
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = width/2;
point1.y = height/2;
localeWindow.x = point1.x - (localeWindow.width/2);
localeWindow.y = point1.y - (localeWindow.height/2);
}
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = width / 2;
point1.y = height / 2;
camSettings.x = point1.x - (camSettings.width / 2);
camSettings.y = point1.y - (camSettings.height / 2);
}
}
private function handleShowAudioSelectionWindowEvent(event:AudioSelectionWindowEvent):void {
var audioSelection:IFlexDisplayObject = PopUpManager.createPopUp(mdiCanvas, AudioSelectionWindow, true);
PopUpManager.centerPopUp(audioSelection);
}
private function handleWebRTCMediaRequestEvent(event:WebRTCMediaEvent):void {
var browser:String = ExternalInterface.call("determineBrowser")[0];
if (browser == "Firefox") {
var ffBrowser:FirefoxMicPermissionImage = PopUpManager.createPopUp(mdiCanvas, FirefoxMicPermissionImage, true) as FirefoxMicPermissionImage;
ffBrowser.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:Event):void {
ffBrowser.x = 100;
ffBrowser.y = 150;
});
} else if (browser == "Chrome") {
var chromeBrowser:ChromeMicPermissionImage = PopUpManager.createPopUp(mdiCanvas, ChromeMicPermissionImage, true) as ChromeMicPermissionImage;
chromeBrowser.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:Event):void {
chromeBrowser.x = 20;
chromeBrowser.y = 130;
});
}
}
private function handleWebRTCEchoTestConnectingEvent(event:WebRTCEchoTestEvent):void {
var webRTCEchoTest:WebRTCEchoTest = PopUpManager.createPopUp(mdiCanvas, WebRTCEchoTest, true) as WebRTCEchoTest;
webRTCEchoTest.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:Event):void {
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = width/2;
point1.y = height/2;
webRTCEchoTest.x = point1.x - (webRTCEchoTest.width/2);
webRTCEchoTest.y = point1.y - (webRTCEchoTest.height/2);
});
}
private function wrongLocaleVersion():void {
var localeWindow:OldLocaleWarnWindow = PopUpUtil.createNonModelPopUp(mdiCanvas, OldLocaleWarnWindow, false) as OldLocaleWarnWindow;
if (localeWindow) {
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = width / 2;
point1.y = height / 2;
localeWindow.x = point1.x - (localeWindow.width / 2);
localeWindow.y = point1.y - (localeWindow.height / 2);
}
}
private function handleShareCameraRequestEvent(event:ShareCameraRequestEvent):void {
if (ExternalInterface.call("determineBrowser")[0] == "Chrome" && chromeBrowser == null ) {
chromeBrowser = PopUpManager.createPopUp(mdiCanvas, ChromeWebcamPermissionImage , true) as ChromeWebcamPermissionImage;
chromeBrowser.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:Event):void {
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = width/2;
point1.y = height/2;
if (Capabilities.os.indexOf("Mac") >= 0) {
chromeBrowser.x = (mdiCanvas.width - chromeBrowser.width);
}
else {
chromeBrowser.x = 20;
}
chromeBrowser.y = 20;
});
}
}
private function handleMeetingNotFoundEvent(e:MeetingNotFoundEvent):void {
showlogoutWindow(ResourceUtil.getInstance().getString('bbb.mainshell.meetingNotFound'));
}
private function handleShowAudioSelectionWindowEvent(event:AudioSelectionWindowEvent):void {
PopUpUtil.createModalPopUp(mdiCanvas, AudioSelectionWindow, true);
}
private function showlogoutWindow(reason:String):void {
if (layoutOptions!= null && layoutOptions.showLogoutWindow) {
if (UserManager.getInstance().getConference().iAskedToLogout) {
handleExitApplicationEvent();
return;
}
if (logoutWindow != null) return;
logoutWindow = LoggedOutWindow(PopUpManager.createPopUp( mdiCanvas, LoggedOutWindow, true));
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = width/2;
point1.y = height/2;
logoutWindow.x = point1.x - (logoutWindow.width/2);
logoutWindow.y = point1.y - (logoutWindow.height/2);
logoutWindow.setReason(reason);
mdiCanvas.removeAllPopUps();
removeToolBars();
} else {
mdiCanvas.removeAllPopUps();
removeToolBars();
var pageHost:String = FlexGlobals.topLevelApplication.url.split("/")[0];
var pageURL:String = FlexGlobals.topLevelApplication.url.split("/")[2];
LOGGER.debug("SingOut to [{0}//{1}/bigbluebutton/api/signOut]", [pageHost, pageURL]);
var request:URLRequest = new URLRequest(pageHost + "//" + pageURL + "/bigbluebutton/api/signOut");
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, handleLogoutComplete);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, handleLogoutError);
urlLoader.load(request);
}
}
private function handleWebRTCMediaRequestEvent(event:WebRTCMediaEvent):void {
var browser:String = ExternalInterface.call("determineBrowser")[0];
if (browser == "Firefox") {
var ffBrowser:FirefoxMicPermissionImage = PopUpUtil.createModalPopUp(mdiCanvas, FirefoxMicPermissionImage, false) as FirefoxMicPermissionImage;
if (ffBrowser) {
ffBrowser.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:Event):void {
ffBrowser.x = 100;
ffBrowser.y = 150;
});
}
} else if (browser == "Chrome") {
var chromeBrowser:ChromeMicPermissionImage = PopUpUtil.createModalPopUp(mdiCanvas, ChromeMicPermissionImage, false) as ChromeMicPermissionImage;
if (chromeBrowser) {
chromeBrowser.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:Event):void {
chromeBrowser.x = 20;
chromeBrowser.y = 130;
});
}
}
}
private function handleWebRTCEchoTestConnectingEvent(event:WebRTCEchoTestEvent):void {
var webRTCEchoTest:WebRTCEchoTest = PopUpUtil.createModalPopUp(mdiCanvas, WebRTCEchoTest, false) as WebRTCEchoTest;
if (webRTCEchoTest) {
webRTCEchoTest.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:Event):void {
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = width / 2;
point1.y = height / 2;
webRTCEchoTest.x = point1.x - (webRTCEchoTest.width / 2);
webRTCEchoTest.y = point1.y - (webRTCEchoTest.height / 2);
});
}
}
private function handleShareCameraRequestEvent(event:ShareCameraRequestEvent):void {
if (ExternalInterface.call("determineBrowser")[0] == "Chrome") {
var chromeWebcmPermissionImg : ChromeWebcamPermissionImage = PopUpUtil.createModalPopUp(mdiCanvas, ChromeWebcamPermissionImage, false) as ChromeWebcamPermissionImage;
if (chromeWebcmPermissionImg) {
chromeWebcmPermissionImg.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:Event):void {
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = width / 2;
point1.y = height / 2;
if (Capabilities.os.indexOf("Mac") >= 0) {
chromeWebcmPermissionImg.x = (mdiCanvas.width - chromeWebcmPermissionImg.width);
} else {
chromeWebcmPermissionImg.x = 20;
}
chromeWebcmPermissionImg.y = 20;
});
}
}
}
private function handleMeetingNotFoundEvent(e:MeetingNotFoundEvent):void {
showlogoutWindow(ResourceUtil.getInstance().getString('bbb.mainshell.meetingNotFound'));
}
private function showlogoutWindow(reason:String):void {
if (layoutOptions != null && layoutOptions.showLogoutWindow) {
if (UserManager.getInstance().getConference().iAskedToLogout) {
handleExitApplicationEvent();
return;
}
var logoutWindow:LoggedOutWindow = PopUpUtil.createModalPopUp(mdiCanvas, LoggedOutWindow, false) as LoggedOutWindow;
if (logoutWindow) {
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = width / 2;
point1.y = height / 2;
logoutWindow.x = point1.x - (logoutWindow.width / 2);
logoutWindow.y = point1.y - (logoutWindow.height / 2);
logoutWindow.setReason(reason);
mdiCanvas.removeAllPopUps();
removeToolBars();
}
} else {
mdiCanvas.removeAllPopUps();
removeToolBars();
var pageHost:String = FlexGlobals.topLevelApplication.url.split("/")[0];
var pageURL:String = FlexGlobals.topLevelApplication.url.split("/")[2];
LOGGER.debug("SingOut to [{0}//{1}/bigbluebutton/api/signOut]", [pageHost, pageURL]);
var request:URLRequest = new URLRequest(pageHost + "//" + pageURL + "/bigbluebutton/api/signOut");
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, handleLogoutComplete);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, handleLogoutError);
urlLoader.load(request);
}
}
/**
* Removes toolbars from the display list.
@ -635,33 +644,36 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function closeNetworkStatsWindow(e:Event = null):void {
networkStatsWindow.disappear();
}
private function openLockSettingsWindow(event:LockControlEvent):void {
var conference:Conference = UserManager.getInstance().getConference();
var lsv:LockSettingsVO = conference.getLockSettings();
var popUp:IFlexDisplayObject = PopUpManager.createPopUp(mdiCanvas, LockSettings, true);
var ls:LockSettings = LockSettings(popUp);
ls.disableCam = lsv.getDisableCam();
ls.disableMic = lsv.getDisableMic();
ls.disablePrivChat = lsv.getDisablePrivateChat();
ls.disablePubChat = lsv.getDisablePublicChat();
ls.lockedLayout = lsv.getLockedLayout();
ls.lockOnJoin = lsv.getLockOnJoin();
ls.lockOnJoinConfigurable = lsv.getLockOnJoinConfigurable();
var point1:Point = new Point();
point1.x = width/2;
point1.y = height/2;
ls.x = point1.x - (ls.width/2);
ls.y = point1.y - (ls.height/2);
}
private function openBreakoutRoomsWindow(e:BreakoutRoomEvent):void {
var popUp:IFlexDisplayObject = PopUpManager.createPopUp(mdiCanvas, BreakoutRoomSettings, true);
PopUpManager.centerPopUp(popUp);
BreakoutRoomSettings(popUp).initCreateBreakoutRooms(e.joinMode, e.record);
}
private function openLockSettingsWindow(event:LockControlEvent):void {
var conference:Conference = UserManager.getInstance().getConference();
var lsv:LockSettingsVO = conference.getLockSettings();
var popUp:IFlexDisplayObject = PopUpUtil.createModalPopUp(mdiCanvas, LockSettings, false);
if (popUp) {
var ls:LockSettings = LockSettings(popUp);
ls.disableCam = lsv.getDisableCam();
ls.disableMic = lsv.getDisableMic();
ls.disablePrivChat = lsv.getDisablePrivateChat();
ls.disablePubChat = lsv.getDisablePublicChat();
ls.lockedLayout = lsv.getLockedLayout();
ls.lockOnJoin = lsv.getLockOnJoin();
ls.lockOnJoinConfigurable = lsv.getLockOnJoinConfigurable();
var point1:Point = new Point();
point1.x = width / 2;
point1.y = height / 2;
ls.x = point1.x - (ls.width / 2);
ls.y = point1.y - (ls.height / 2);
}
}
private function openBreakoutRoomsWindow(e:BreakoutRoomEvent):void {
var popUp:IFlexDisplayObject = PopUpUtil.createModalPopUp(mdiCanvas, BreakoutRoomSettings, true);
if (popUp != null) {
BreakoutRoomSettings(popUp).initCreateBreakoutRooms(e.joinMode, e.record);
}
}
private function onFooterLinkClicked(e:TextEvent):void{
if (ExternalInterface.available) {
@ -672,7 +684,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
</mx:Script>
<common:TabIndexer id="tabIndexer" startIndex="100000"
tabIndices="{[langSelector, logBtn]}"/>
tabIndices="{[warningBtn, langSelector, logBtn]}"/>
<views:MainToolbar id="toolbar"
dock="true"

View File

@ -81,6 +81,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
/**
* Removes all display list containers created using PopUpManager
* @fixme: move to PopUpUtil and improve
*/
public function removeAllPopUps():void{
for (var i:int = systemManager.numChildren-1; i>0; i-=1){

View File

@ -24,21 +24,21 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
xmlns:mate="http://mate.asfusion.com/" xmlns:common="org.bigbluebutton.common.*"
xmlns:views="org.bigbluebutton.main.views.*"
enabled="true" visible="{showToolbar}"
initialize="init()" creationComplete="onCreationComplete()">
initialize="init()">
<mate:Listener type="{ToolbarButtonEvent.ADD}" method="handleAddToolbarButtonEvent" />
<mate:Listener type="{ToolbarButtonEvent.REMOVE}" method="handleRemoveToolbarButtonEvent"/>
<mate:Listener type="{BBBEvent.END_MEETING_EVENT}" method="handleEndMeetingEvent"/>
<mate:Listener type="{ConnectionFailedEvent.USER_LOGGED_OUT}" method="hideToolbar" />
<mate:Listener type="{ConnectionFailedEvent.CONNECTION_CLOSED}" method="hideToolbar" />
<mate:Listener type="{ConfigEvent.CONFIG_EVENT}" method="gotConfigParameters" />
<mate:Listener type="{ConfigLoadedEvent.CONFIG_LOADED_EVENT}" method="initOptions" />
<mate:Listener type="{SettingsEvent.SETTINGS_MODULE_LOADED}" method="showSettingsButton" />
<mate:Listener type="{ShortcutEvent.REMOTE_OPEN_SHORTCUT_WIN}" method="remoteShortcutClick" />
<mate:Listener type="{ShortcutEvent.LOGOUT}" method="remoteLogout" />
<mate:Listener type="{ShortcutEvent.FOCUS_SHORTCUT_BUTTON}" method="focusShortcutButton" />
<mate:Listener type="{ShortcutEvent.FOCUS_LOGOUT_BUTTON}" method="focusLogoutButton" />
<mate:Listener type="{ConferenceCreatedEvent.CONFERENCE_CREATED_EVENT}" method="retrieveMeetingName" />
<mate:Listener type="{BBBEvent.CHANGE_RECORDING_STATUS}" method="onRecordingStatusChanged" />
<mate:Listener type="{BBBEvent.CHANGE_RECORDING_STATUS}" method="onRecordingStatusChanged" />
<mx:Script>
<![CDATA[
@ -56,7 +56,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.ConfigEvent;
import org.bigbluebutton.main.events.ConfigLoadedEvent;
import org.bigbluebutton.main.events.LogoutEvent;
import org.bigbluebutton.main.events.SettingsEvent;
import org.bigbluebutton.main.events.ShortcutEvent;
@ -76,6 +76,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
[Bindable] private var showToolbar:Boolean = false;
[Bindable] public var toolbarOptions:LayoutOptions = new LayoutOptions();
[Bindable] private var numButtons:int;
private var logoutAlert:Alert;
/*
* Because of the de-centralized way buttons are added to the toolbar, there is a large gap between the tab indexes of the main buttons
@ -97,9 +99,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function onCreationComplete():void {
}
private function checkAccessiblity(e:TimerEvent):void {
// remove the quick links if there's no screen reader active
if (!Accessibility.active) {
@ -122,6 +121,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
case "chat":
dispatcher.dispatchEvent(new ShortcutEvent(ShortcutEvent.FOCUS_CHAT_WINDOW));
break;
case "caption":
dispatcher.dispatchEvent(new ShortcutEvent(ShortcutEvent.FOCUS_CAPTION_WINDOW));
break;
}
}
@ -208,7 +210,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function onHelpButtonClicked():void {
DEFAULT_HELP_URL = BBB.getConfigManager().config.help.url;
navigateToURL(new URLRequest(DEFAULT_HELP_URL))
}
@ -216,26 +217,24 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
LOGGER.debug("Received end meeting event.");
doLogout();
}
private function confirmLogout():void {
if (toolbarOptions.confirmLogout){
// Confirm logout using built-in alert
var alert:Alert = Alert.show(ResourceUtil.getInstance().getString('bbb.logout.confirm.message'), ResourceUtil.getInstance().getString('bbb.logout.confirm.title'), Alert.YES | Alert.NO, this, alertLogout, null, Alert.YES);
var newX:Number = btnLogout.x + btnLogout.width - alert.width;
var newY:Number = btnLogout.y + btnLogout.height + 5;
alert.validateNow();
alert.move(newX, newY);
//Accessibility.updateProperties();
}
else{
doLogout();
}
}
private function confirmLogout():void {
if (toolbarOptions.confirmLogout) {
if (logoutAlert == null) {
// Confirm logout using built-in alert
logoutAlert = Alert.show(ResourceUtil.getInstance().getString('bbb.logout.confirm.message'), ResourceUtil.getInstance().getString('bbb.logout.confirm.title'), Alert.YES | Alert.NO, this, alertLogout, null, Alert.YES);
var newX:Number = btnLogout.x + btnLogout.width - logoutAlert.width;
var newY:Number = btnLogout.y + btnLogout.height + 5;
logoutAlert.validateNow();
logoutAlert.move(newX, newY);
}
} else {
doLogout();
}
}
private function alertLogout(e:CloseEvent):void {
// Check to see if the YES button was pressed.
if (e.detail==Alert.YES) {
@ -249,6 +248,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*/
callLater(doLogout);
}
logoutAlert = null;
}
private function doLogout():void {
@ -314,12 +314,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
//}
}
}
private function gotConfigParameters(e:ConfigEvent):void{
shortcutKeysBtn.includeInLayout = shortcutKeysBtn.visible = e.config.shortcutKeysShowButton;
DEFAULT_HELP_URL = e.config.helpURL;
}
public function initOptions(e:Event):void {
shortcutKeysBtn.includeInLayout = shortcutKeysBtn.visible = BBB.getConfigManager().config.shortcutKeys['showButton'];
DEFAULT_HELP_URL = BBB.getConfigManager().config.help['url'];
}
private function onDisconnectTest():void{
var d:Dispatcher = new Dispatcher();
var e:LogoutEvent = new LogoutEvent(LogoutEvent.DISCONNECT_TEST);
@ -378,7 +378,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
]]>
</mx:Script>
<common:TabIndexer id="quickLinksIndexer" startIndex="102" tabIndices="{[usersLinkBtn, webcamLinkButton, presentationLinkBtn, chatLinkBtn]}"/>
<common:TabIndexer id="quickLinksIndexer" startIndex="102" tabIndices="{[usersLinkBtn, webcamLinkButton, presentationLinkBtn, chatLinkBtn, captionLinkBtn]}"/>
<common:TabIndexer id="buttonsIndexer" startIndex="{quickLinksIndexer.startIndex + numButtons + 10}"
tabIndices="{[recordBtn, muteMeBtn, shortcutKeysBtn, helpBtn, btnLogout]}"/>
@ -396,6 +396,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:LinkButton id="chatLinkBtn" click="onQuickLinkClicked('chat')" label="{ResourceUtil.getInstance().getString('bbb.chat.quickLink.label')}"
accessibilityDescription="{chatLinkBtn.label}" toolTip="{chatLinkBtn.label}"
height="22" styleName="quickWindowLinkStyle" />
<mx:LinkButton id="captionLinkBtn" click="onQuickLinkClicked('caption')" label="{ResourceUtil.getInstance().getString('bbb.caption.quickLink.label')}"
accessibilityDescription="{captionLinkBtn.label}" toolTip="{captionLinkBtn.label}"
height="22" styleName="quickWindowLinkStyle" />
</mx:HBox>
<mx:HBox id="addedBtns"/>
<views:RecordButton id="recordBtn"/>

View File

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mate="http://mate.asfusion.com/"
width="400"
horizontalAlign="center"
title="{ResourceUtil.getInstance().getString('bbb.micWarning.title')}" >
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import org.bigbluebutton.util.i18n.ResourceUtil;
public var micsettings:MicSettings;
private function joinAnyway():void {
PopUpManager.removePopUp(this);
micsettings.joinConference();
}
]]>
</mx:Script>
<mx:Text width="100%" textAlign="center" text="{ResourceUtil.getInstance().getString('bbb.micWarning.message')}" />
<mx:HBox>
<mx:Button label="{ResourceUtil.getInstance().getString('bbb.micWarning.joinBtn.label')}" click="joinAnyway();" />
<mx:Button label="{ResourceUtil.getInstance().getString('bbb.micWarning.testAgain.label')}" click="PopUpManager.removePopUp(this);"/>
</mx:HBox>
</mx:TitleWindow>

View File

@ -25,17 +25,17 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
x="168" y="86" layout="vertical" width="400" height="150" horizontalAlign="center">
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.util.i18n.ResourceUtil;
private static const LOGGER:ILogger = getClassLogger(OldLocaleWarnWindow);
private const windowTitleDefault:String = "Warning: Old Language Version";
private const reminder1Default:String = "You have an old language translation of BigBlueButton.";
private const reminder2Default:String = "Please clear your browser cache and try again.";
[Bindable] private var windowTitle:String;
[Bindable] private var oldLocalesReminder1:String;
[Bindable] private var oldLocalesReminder2:String;
@ -55,25 +55,25 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
if ((reminder2 == null) || (reminder2 == "")) oldLocalesReminder2 = reminder2Default;
else oldLocalesReminder2 = reminder2;
}
private function redirect():void {
var logoutURL:String = BBB.getLogoutURL();
var request:URLRequest = new URLRequest(logoutURL);
LOGGER.debug("Log out url: " + logoutURL);
request.method = URLRequestMethod.GET;
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, handleComplete);
urlLoader.load(request);
}
private function redirect():void {
var logoutURL:String = BBB.getLogoutURL();
var request:URLRequest = new URLRequest(logoutURL);
LOGGER.debug("Log out url: " + logoutURL);
request.method = URLRequestMethod.GET;
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, handleComplete);
urlLoader.load(request);
}
private function handleComplete(e:Event):void {
var request:URLRequest = new URLRequest(BBB.getLogoutURL());
navigateToURL(request, '_self');
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function onUserLoggedOutWindowClose(e:Event):void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
]]>
@ -82,4 +82,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:Label text="{oldLocalesReminder2}"/>
<mx:Button id="okBtn" label="OK" click="redirect()"/>
</mx:TitleWindow>
</mx:TitleWindow>

View File

@ -69,12 +69,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
'bbb.shortcutkey.present.fitWidth', 'bbb.shortcutkey.present.fitPage'];
private var chatResource:Array = ['bbb.shortcutkey.chat.focusTabs', 'bbb.shortcutkey.chat.focusBox', 'bbb.shortcutkey.chat.sendMessage',
'bbb.shortcutkey.chat.closePrivate', 'bbb.shortcutkey.chat.explanation', 'bbb.shortcutkey.chat.chatbox.gofirst',
'bbb.shortcutkey.chat.chatbox.goback', 'bbb.shortcutkey.chat.chatbox.advance', 'bbb.shortcutkey.chat.chatbox.golatest',
'bbb.shortcutkey.chat.chatbox.repeat', 'bbb.shortcutkey.chat.chatbox.goread'];
'bbb.shortcutkey.chat.closePrivate'];
private var userResource:Array = ['bbb.shortcutkey.users.focusUsers', 'bbb.shortcutkey.users.makePresenter', 'bbb.shortcutkey.users.mute',
/*'bbb.shortcutkey.users.kick',*/ 'bbb.shortcutkey.users.muteall'];
'bbb.shortcutkey.users.kick', 'bbb.shortcutkey.users.muteall', 'bbb.shortcutkey.users.focusBreakoutRooms',
'bbb.shortcutkey.users.listenToBreakoutRoom', 'bbb.shortcutkey.users.joinBreakoutRoom'];
[Bindable]
private var shownKeys:ArrayCollection;

View File

@ -36,14 +36,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import flash.globalization.DateTimeFormatter;
import flash.globalization.DateTimeStyle;
import flash.globalization.LocaleID;
import mx.controls.ToolTip;
import mx.core.FlexGlobals;
import mx.managers.PopUpManager;
import mx.managers.ToolTipManager;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.main.events.ClientStatusEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
@ -124,15 +124,16 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
return -1;
}
private function handleButtonClick():void {
hideNotification();
var clientStatusWindow:ClientStatusWindow = PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, ClientStatusWindow, true) as ClientStatusWindow;
clientStatusWindow.setMessages(messages);
PopUpManager.centerPopUp(clientStatusWindow);
}
private function handleButtonClick():void {
hideNotification();
var clientStatusWindow:ClientStatusWindow = PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, ClientStatusWindow, true) as ClientStatusWindow
if (clientStatusWindow) {
clientStatusWindow.setMessages(messages);
}
}
private function handleMove():void {
if (notification) {
var location:Point = localToGlobal(new Point(0,0));

View File

@ -24,8 +24,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
creationComplete="onCreationComplete()"
styleName="micSettingsWindowStyle"
showCloseButton="false"
close="onCancelClicked()"
keyDown="handleKeyDown(event)">
close="onCancelClicked()">
<mate:Listener type="{WebRTCEchoTestStartedEvent.WEBRTC_ECHO_TEST_STARTED}" method="handleWebRTCEchoTestStartedEvent" />
<mate:Listener type="{WebRTCEchoTestEvent.WEBRTC_ECHO_TEST_ENDED}" method="handleWebRTCEchoTestEndedEvent" />
@ -41,13 +40,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import mx.managers.PopUpManager;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.main.api.JSLog;
import org.bigbluebutton.modules.phone.PhoneModel;
import org.bigbluebutton.modules.phone.events.WebRTCCallEvent;
import org.bigbluebutton.modules.phone.events.WebRTCEchoTestEvent;
@ -55,7 +52,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.modules.phone.events.WebRTCJoinedVoiceConferenceEvent;
import org.bigbluebutton.modules.phone.models.Constants;
import org.bigbluebutton.util.i18n.ResourceUtil;
private static const LOGGER:ILogger = getClassLogger(WebRTCEchoTest);
private static var DEFAULT_HELP_URL:String = "http://www.bigbluebutton.org/content/videos";
@ -65,28 +62,24 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
override public function move(x:Number, y:Number):void {
return;
}
private function onCancelClicked():void {
if (dotTimer) dotTimer.stop();
PopUpManager.removePopUp(this);
}
private function handleKeyDown(event:KeyboardEvent):void {
}
private function onCreationComplete():void {
setCurrentState("connecting");
lblConnectMessage.text = lblConnectMessageMock.text = ResourceUtil.getInstance().getString('bbb.micSettings.webrtc.connecting');
dotTimer = new Timer(200, 0);
dotTimer.addEventListener(TimerEvent.TIMER, dotAnimate);
dotTimer.start();
var testState:String = PhoneModel.getInstance().webRTCModel.state;
if (testState == Constants.DO_ECHO_TEST) {
webRTCEchoTestStarted();
}
private function onCancelClicked():void {
if (dotTimer)
dotTimer.stop();
PopUpUtil.removePopUp(this);
}
private function onCreationComplete():void {
setCurrentState("connecting");
lblConnectMessage.text = lblConnectMessageMock.text = ResourceUtil.getInstance().getString('bbb.micSettings.webrtc.connecting');
dotTimer = new Timer(200, 0);
dotTimer.addEventListener(TimerEvent.TIMER, dotAnimate);
dotTimer.start();
var testState:String = PhoneModel.getInstance().webRTCModel.state;
if (testState == Constants.DO_ECHO_TEST) {
webRTCEchoTestStarted();
}
}
private function dotAnimate(e:TimerEvent):void {

View File

@ -29,27 +29,24 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
creationComplete="onCreationComplete()">
<mate:Listener type="{LocaleChangeEvent.LOCALE_CHANGED}" method="localeChanged" />
<mate:Listener type="{ShortcutEvent.FOCUS_CAPTION_WINDOW}" method="focusWindow" />
<mx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import flexlib.controls.tabBarClasses.SuperTab;
import mx.binding.utils.BindingUtils;
import mx.binding.utils.ChangeWatcher;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.controls.Button;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
import flexlib.controls.tabBarClasses.SuperTab;
import org.bigbluebutton.common.events.LocaleChangeEvent;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.events.ShortcutEvent;
import org.bigbluebutton.main.views.MainCanvas;
import org.bigbluebutton.modules.caption.events.RequestTranscriptsEvent;
import org.bigbluebutton.modules.caption.events.SendEditCaptionHistoryEvent;
import org.bigbluebutton.modules.caption.events.SendUpdateCaptionOwnerEvent;
import org.bigbluebutton.modules.caption.model.CaptionOptions;
import org.bigbluebutton.modules.caption.model.Transcript;
import org.bigbluebutton.modules.caption.model.Transcripts;
@ -233,7 +230,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
setTextTabLabel(currentTranscript.ownerID);
}
}
private function focusWindow(e:ShortcutEvent):void {
focusManager.setFocus(titleBarOverlay);
}
]]>
</mx:Script>
<mx:Box width="100%" height="100%" horizontalAlign="left">

View File

@ -17,6 +17,7 @@
*
*/
package org.bigbluebutton.modules.chat.model {
import org.bigbluebutton.util.i18n.ResourceUtil;
public class ChatMessage {
[Bindable] public var lastSenderId:String;
@ -42,8 +43,8 @@ package org.bigbluebutton.modules.chat.model {
public function toString() : String {
var result:String;
// Remember to localize this later
result = "Chat message " + name + " said " + stripTags(text) + " at " + time;
var accName:String = (!name || name == "" || name == " "? ResourceUtil.getInstance().getString("bbb.chat.chatMessage.systemMessage") : name);
result = ResourceUtil.getInstance().getString("bbb.chat.chatMessage.stringRespresentation", [accName, stripTags(text), time]);
return result;
}

View File

@ -18,7 +18,13 @@
*/
package org.bigbluebutton.modules.chat.views
{
import flash.display.CapsStyle;
import flash.display.Graphics;
import flash.display.JointStyle;
import flash.display.Sprite;
import mx.controls.List;
import mx.controls.listClasses.IListItemRenderer;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
@ -31,7 +37,7 @@ package org.bigbluebutton.modules.chat.views
{
super();
}
override protected function measure():void
{
super.measure();

View File

@ -48,12 +48,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
</mx:Style>
<mate:Listener type="{ChatOptionsEvent.CHANGE_FONT_SIZE}" method="changeFontSize" />
<mate:Listener type="{ShortcutEvent.ADVANCE_MESSAGE}" method="advanceMessage" />
<mate:Listener type="{ShortcutEvent.GOBACK_MESSAGE}" method="goBackOneMessage" />
<mate:Listener type="{ShortcutEvent.REPEAT_MESSAGE}" method="repeatMessage" />
<mate:Listener type="{ShortcutEvent.GOLATEST_MESSAGE}" method="goToLatestMessage" />
<mate:Listener type="{ShortcutEvent.GOFIRST_MESSAGE}" method="goToFirstMessage" />
<mate:Listener type="{ShortcutEvent.GOREAD_MESSAGE}" method="goToLatestReadMessage" />
<mate:Listener type="{PrivateChatMessageEvent.PRIVATE_CHAT_MESSAGE_EVENT}" method="handlePrivateChatMessageEvent"/>
<mate:Listener type="{PublicChatMessageEvent.PUBLIC_CHAT_MESSAGE_EVENT}" method="handlePublicChatMessageEvent"/>
<mate:Listener type="{ShortcutEvent.FOCUS_CHAT_INPUT}" method="focusChatInput" />
@ -62,7 +56,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mate:Listener type="{ShortcutEvent.FOCUS_CHAT_BOX}" method="focusChatBox" />
<mate:Listener type="{ShortcutEvent.CHANGE_FONT_COLOUR}" method="focusColourPicker" />
<mate:Listener type="{ShortcutEvent.SEND_MESSAGE}" method="remoteSendMessage" />
<mate:Listener type="{ShortcutEvent.CHAT_DEBUG}" method="chatDebugInfo" />
<mate:Listener type="{BBBEvent.RECONNECT_DISCONNECTED_EVENT}" receive="refreshChat(event)"/>
<mate:Listener type="{LockControlEvent.CHANGED_LOCK_SETTINGS}" method="lockSettingsChanged" />
@ -79,6 +72,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.as3commons.lang.StringUtils;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.KeyboardUtil;
import org.bigbluebutton.core.TimerUtil;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.events.LockControlEvent;
@ -106,36 +100,30 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private static const LOGGER:ILogger = getClassLogger(ChatBox);
public var publicChat:Boolean = false;
public var chatWithUserID:String;
public var chatWithUsername:String
public var publicChat:Boolean = false;
public var chatWithUserID:String;
public var chatWithUsername:String
public var read:Boolean = true;
public var userHasLeft:Boolean = false;
private var globalDispatcher:Dispatcher = new Dispatcher();
[Bindable] public var colorPickerColours:Array = ['0x000000', '0x7A7A7A' ,'0xFF0000', '0xFF8800',
'0x88FF00', '0x00FF00', '0x00FF88', '0x00FFFF', '0x0088FF', '0x0000FF', '0x8800FF', '0xFF00FF'];
[Bindable] public var colorPickerColours:Array = ['0x000000', '0x7A7A7A' ,'0xFF0000', '0xFF8800',
'0x88FF00', '0x00FF00', '0x00FF88', '0x00FFFF', '0x0088FF', '0x0000FF', '0x8800FF', '0xFF00FF'];
[Bindable]
private var backgroundColor:uint = 0x000000;
private var lastSenderId:String = "";
private var lastTime:String = "";
[Bindable]
private var chatMessages:ChatConversation = new ChatConversation();
[Bindable]
private var chatMessages:ChatConversation = new ChatConversation();
private var lastCount:Number = 0;
private var scrollTimer:Timer;
private var currentMessage:int;
private var latestMessage:int;
private var reachedLatest:String = ResourceUtil.getInstance().getString('bbb.accessibility.chat.chatBox.reachedLatest');
private var reachedFirst:String = ResourceUtil.getInstance().getString('bbb.accessibility.chat.chatBox.reachedFirst');
private var navLatestString:String = ResourceUtil.getInstance().getString('bbb.accessibility.chat.chatBox.navigatedLatest');
private var navRecentString:String = ResourceUtil.getInstance().getString('bbb.accessibility.chat.chatBox.navigatedLatestRead');
private var navFirstString:String = ResourceUtil.getInstance().getString('bbb.accessibility.chat.chatBox.navigatedFirst');
public var focus:Boolean = false;
private var keyCombos:Object;
@ -145,8 +133,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private var indicatorNeeded:Boolean = false
private var repeat:Boolean = false;
[Bindable]
private var chatListHeight:Number = 100;
[Bindable]
private var chatListHeight:Number = 100;
[Bindable] public var chatOptions:ChatOptions = new ChatOptions();
@ -161,26 +149,16 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
currentMessage = -1;
latestMessage = -1;
this.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown);
ResourceUtil.getInstance().addEventListener(Event.CHANGE, localeChanged); // Listen for locale changing
hotkeyCapture();
// Listen for the ENTER key to send the message.
txtMsgArea.addEventListener(TextEvent.TEXT_INPUT, handleTextInput);
txtMsgArea.addEventListener(KeyboardEvent.KEY_DOWN, handleMsgAreaKeyDown);
queryForChatHistory();
if(chatMessagesList.accessibilityProperties == null)
chatMessagesList.accessibilityProperties = new AccessibilityProperties();
chatMessagesList.accessibilityProperties.description = ResourceUtil.getInstance().getString('bbb.accessibility.chat.initialDescription');
if(Capabilities.hasAccessibility)
Accessibility.updateProperties();
if (publicChat && UserManager.getInstance().getConference().isBreakout){
var timerListener : Listener = new Listener();
timerListener.type = BreakoutRoomEvent.UPDATE_REMAINING_TIME_BREAKOUT;
@ -400,16 +378,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
}
// Determines for navigateMessages() whether the message to be spoken by the screen-reader needs an extra space added to the end or not
private function setDescription():Boolean{
var chatHistorySpacer:Boolean = false;
if (chatMessagesList.accessibilityProperties.description == chatMessages.messages.getItemAt(currentMessage).toString()) {
chatHistorySpacer = true;
}
return chatHistorySpacer;
}
public function getLatestMessage():int{
return latestMessage;
}
@ -420,189 +388,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function localeChanged(e:Event):void {
var modifier:String = ExternalInterface.call("determineModifier");
loadKeyCombos(modifier);
addContextMenuItems();
}
private function loadKeyCombos(modifier:String):void {
keyCombos = new Object(); // always start with a fresh array
//keyCombos[modifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.chat.chatbox.debug') as String)] = ShortcutEvent.CHAT_DEBUG;
//keyCombos[modifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.chat.chatbox.repeat') as String)] = ShortcutEvent.REPEAT_MESSAGE;
keyCombos[modifier+(ResourceUtil.getInstance().getString('bbb.shortcutkey.chat.chatbox.goread') as String)] = ShortcutEvent.GOREAD_MESSAGE;
// Special cases: Using the arrow keys with no modifiers
keyCombos[(ResourceUtil.getInstance().getString('bbb.shortcutkey.chat.chatbox.advance') as String)] = ShortcutEvent.ADVANCE_MESSAGE;
keyCombos[(ResourceUtil.getInstance().getString('bbb.shortcutkey.chat.chatbox.goback') as String)] = ShortcutEvent.GOBACK_MESSAGE;
keyCombos[(ResourceUtil.getInstance().getString('bbb.shortcutkey.chat.chatbox.golatest') as String)] = ShortcutEvent.GOLATEST_MESSAGE;
keyCombos[(ResourceUtil.getInstance().getString('bbb.shortcutkey.chat.chatbox.gofirst') as String)] = ShortcutEvent.GOFIRST_MESSAGE;
keyCombos[(ResourceUtil.getInstance().getString('bbb.shortcutkey.chat.chatbox.repeat') as String)] = ShortcutEvent.REPEAT_MESSAGE;
}
public function hotkeyCapture():void{
this.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown);
}
private function handleKeyDown(e:KeyboardEvent) :void {
var modifier:String = ExternalInterface.call("determineModifier");
loadKeyCombos(modifier);
var keyPress:String = (e.ctrlKey ? "control+" : "") + (e.shiftKey ? "shift+" : "") + (e.altKey ? "alt+" : "") + e.keyCode;
if (keyCombos[keyPress]) {
LOGGER.debug("WATERFALL: Caught shortcut in chat box, {0}", [keyCombos[keyPress]]);
var event:ShortcutEvent = new ShortcutEvent(keyCombos[keyPress]);
event.otherUserID = chatWithUserID;
globalDispatcher.dispatchEvent(event);
}
}
private function advanceMessage(e:ShortcutEvent):void{
if (e.otherUserID == chatWithUserID){
if (currentMessage < (chatMessages.numMessages() - 1)){
currentMessage++;
} else {
chatMessagesList.accessibilityProperties.description += " ";
repeat = true;
}
navigationMaintenance();
}
}
private function goBackOneMessage(e:ShortcutEvent):void {
if (e.otherUserID == chatWithUserID){
if (currentMessage > 0){
currentMessage--;
}
else if (currentMessage < 0){
currentMessage = 0;
latestMessage = 0;
}
else{
chatMessagesList.accessibilityProperties.description += " ";
repeat = true;
}
navigationMaintenance();
}
}
private function repeatMessage(e:ShortcutEvent):void {
if (currentMessage < 0){
currentMessage = 0;
latestMessage = 0;
if (chatMessages.messages.length > 0)
chatMessagesList.accessibilityProperties.description = chatMessages.messages.getItemAt(currentMessage).toString();
}
if (e.otherUserID == chatWithUserID){
chatMessagesList.accessibilityProperties.description += " ";
repeat = true;
navigationMaintenance();
}
}
private function goToLatestMessage(e:ShortcutEvent):void {
if (latestMessage < 0){
currentMessage = 0;
latestMessage = 0;
}
if (e.otherUserID == chatWithUserID){
currentMessage = chatMessages.numMessages() - 1;
navToLatest = true;
spacerNeeded = setDescription();
indicatorNeeded = true;
chatMessagesList.accessibilityProperties.description = navLatestString + " " + chatMessages.messages.getItemAt(currentMessage).toString();
navigationMaintenance();
}
}
private function goToFirstMessage(e:ShortcutEvent):void {
if (e.otherUserID == chatWithUserID){
currentMessage = 0;
navToFirst = true;
spacerNeeded = setDescription();
indicatorNeeded = true;
chatMessagesList.accessibilityProperties.description = navFirstString + " " + chatMessages.messages.getItemAt(currentMessage).toString();
navigationMaintenance();
}
}
private function goToLatestReadMessage(e:ShortcutEvent):void {
if (e.otherUserID == chatWithUserID){
if (latestMessage < 0) {
latestMessage = 0;
}
currentMessage = latestMessage;
chatMessagesList.accessibilityProperties.description = navRecentString + " " + chatMessages.messages.getItemAt(currentMessage).toString();
navigationMaintenance();
}
}
private function navigationMaintenance():void {
// Update the latestMessage counter for new message notifications
if (currentMessage > latestMessage)
latestMessage = currentMessage;
if (!repeat){
// Make it clear to the user that they have either navigated to or reached one end of the message history or the other.
if (currentMessage == 0){
if (!navToFirst){
indicatorNeeded = true;
chatMessagesList.accessibilityProperties.description = reachedFirst + " " + chatMessages.messages.getItemAt(currentMessage).toString();
}
}
else if (currentMessage == chatMessages.numMessages() - 1){
if (!navToLatest){
indicatorNeeded = true;
chatMessagesList.accessibilityProperties.description = reachedLatest + " " + chatMessages.messages.getItemAt(currentMessage).toString();
}
}
else{
// Set the accessibility description to the indicated message
chatMessagesList.accessibilityProperties.description = chatMessages.messages.getItemAt(currentMessage).toString();
}
// Add a single space to the end of the accessibilityProperties.description if necessary to ensure that it reflects the current message after being updated.
if (spacerNeeded || setDescription()){
chatMessagesList.accessibilityProperties.description += " ";
}
}
if(Capabilities.hasAccessibility)
Accessibility.updateProperties();
navToFirst = false;
navToLatest = false;
spacerNeeded = false;
indicatorNeeded = false
repeat = false;
LOGGER.debug("Done with navigationMaintenance(); description is now {0}", [chatMessagesList.accessibilityProperties.description]);
}
// General-purpose developer method, used during testing of ChatBox accessibility
private function chatDebugInfo(e:ShortcutEvent):void{
LOGGER.debug("----CHAT DEBUG INFORMATION----");
var num:int = chatMessages.numMessages();
LOGGER.debug("Printing all chat messages of the {0} present:", [num]);
for (var i:int = 0; i < num; i++){
if (chatMessages.messages.getItemAt(i) != null)
LOGGER.debug("Message {0}: {1}", [i, chatMessages.messages.getItemAt(i).toString()]);
else
LOGGER.debug("Message {0} is NULL", [i]);
}
/*
LogUtil.debug("chatWithUserID is: " + chatWithUserID);
LogUtil.debug("currentMessage is: " + currentMessage);
LogUtil.debug("latestMessage is: " + latestMessage);
LogUtil.debug("Focused message is: " + chatMessages.messages.getItemAt(currentMessage).toString());
LogUtil.debug("Number of messages is: " + chatMessages.messages.length);
LogUtil.debug("chatMessagesList.accessibilityProperties.description is: " + chatMessagesList.accessibilityProperties.description);
*/
//LogUtil.debug("repeat is: " + repeat);
//LogUtil.debug("navToFirst is: " + navToFirst);
//LogUtil.debug("indicatorNeeded is: " + indicatorNeeded);
//LogUtil.debug("navToLatest is: " + navToLatest);
//LogUtil.debug(" is: " + );
LOGGER.debug("------------------------------");
}
private function sendStartCustomPollEvent(answers:Array):void {
var dispatcher:Dispatcher = new Dispatcher();
@ -775,9 +563,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<common:TabIndexer id="tabIndexer" tabIndices="{[chatMessagesList, txtMsgArea, sendBtn, cmpColorPicker]}"/>
<mx:VBox width="100%" height="{chatListHeight}" verticalScrollPolicy="off">
<chat:AdvancedList width="100%" height="{chatListHeight - timerBox.height}" id="chatMessagesList" selectable="false" variableRowHeight="true"
<chat:AdvancedList width="100%" height="{chatListHeight - timerBox.height}" id="chatMessagesList" selectable="true" variableRowHeight="true"
itemRenderer="org.bigbluebutton.modules.chat.views.ChatMessageRenderer" verticalScrollPolicy="on" horizontalScrollPolicy="off" wordWrap="true"
dataProvider="{chatMessages.messages}"
styleName="chatMessageListStyle"
accessibilityName="{ResourceUtil.getInstance().getString('bbb.chat.messageList')}" />
<mx:HBox id="timerBox" styleName="breakoutRoomTimerBox"
includeInLayout="false" visible="false"

View File

@ -43,6 +43,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.events.LocaleChangeEvent;
import org.bigbluebutton.core.KeyboardUtil;
import org.bigbluebutton.main.events.ShortcutEvent;
import org.bigbluebutton.modules.chat.model.ChatOptions;
import org.bigbluebutton.util.i18n.ResourceUtil;
@ -97,8 +98,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function handleKeyDown(e:KeyboardEvent) :void {
var modifier:String = ExternalInterface.call("determineModifier");
loadKeyCombos(modifier);
var keyPress:String = (e.ctrlKey ? "control+" : "") + (e.shiftKey ? "shift+" : "") +
(e.altKey ? "alt+" : "") + e.keyCode;
var keyPress:String = KeyboardUtil.buildPressedKeys(e);
if (keyCombos[keyPress]) {
disp.dispatchEvent(new ShortcutEvent(keyCombos[keyPress]));
}

View File

@ -18,27 +18,29 @@ You should have received a copy of the GNU Lesser General Public License along
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-->
<mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mate="http://mate.asfusion.com/"
toolTip="{ResourceUtil.getInstance().getString('bbb.layout.combo.toolTip')}"
prompt="{ResourceUtil.getInstance().getString('bbb.layout.combo.prompt')}"
height="{LayoutButton.BUTTON_SIZE}" creationComplete="init()"
disabledColor="{getStyle('color')}" rowCount="10"
styleName="languageSelectorStyle" >
<mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mate="http://mate.asfusion.com/"
toolTip="{ResourceUtil.getInstance().getString('bbb.layout.combo.toolTip')}"
prompt="{ResourceUtil.getInstance().getString('bbb.layout.combo.prompt')}"
height="{LayoutButton.BUTTON_SIZE}"
creationComplete="init()"
disabledColor="{getStyle('color')}"
rowCount="10"
styleName="languageSelectorStyle">
<mate:Listener type="{SwitchedLayoutEvent.SWITCHED_LAYOUT_EVENT}" method="onLayoutChanged" />
<mate:Listener type="{LayoutsReadyEvent.LAYOUTS_READY}" method="populateLayoutsList"/>
<mate:Listener type="{LockControlEvent.CHANGED_LOCK_SETTINGS}" method="lockSettingsChanged" />
<mate:Listener type="{LockControlEvent.CHANGED_LOCK_SETTINGS}" method="lockSettingsChanged" />
<mate:Listener type="{LocaleChangeEvent.LOCALE_CHANGED}" method="localeChanged" />
<mx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import mx.collections.ArrayCollection;
import mx.events.DropdownEvent;
import mx.events.ListEvent;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.events.LocaleChangeEvent;
@ -51,87 +53,92 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.modules.layout.events.LayoutsReadyEvent;
import org.bigbluebutton.modules.layout.model.LayoutModel;
import org.bigbluebutton.util.i18n.ResourceUtil;
private static const LOGGER:ILogger = getClassLogger(LayoutsCombo);
private var _dispatcher:Dispatcher = new Dispatcher();
[Bindable] private var layoutNames:ArrayCollection = new ArrayCollection();
private function init():void {
//trace(LOG + "initing");
dataProvider = layoutNames;
populateComboBox();
this.addEventListener(DropdownEvent.OPEN, openDropdownHandler);
}
private function lockSettingsChanged(e:LockControlEvent):void {
var conference:Conference = UserManager.getInstance().getConference();
var thisUser:BBBUser = conference.getMyUser();
this.enabled = ! thisUser.lockedLayout;
}
private function populateLayoutsList(e:LayoutsReadyEvent):void {
//trace(LOG + " handling layout ready event.");
populateComboBox();
}
private function populateComboBox():void {
//trace(LOG + " populating layout combo.");
layoutNames = new ArrayCollection();
var layouts:Array = LayoutModel.getInstance().getLayoutNames();
var idx:int = 0, currentLayoutIndex:int = -1;
for each (var lay:Object in layouts) {
var translatedName:String = ResourceUtil.getInstance().getString(lay.name)
if (translatedName == "undefined") translatedName = lay.name;
var item:Object = {index: idx, label: translatedName, localeKey: lay.name, currentLayout: lay.currentLayout };
//trace(LOG + " layout [" + lay.name + ", current=" + lay.currentLayout + "]");
layoutNames.addItem(item);
if (lay.currentLayout) {
currentLayoutIndex = idx;
}
idx++;
}
dataProvider = layoutNames;
selectedIndex = currentLayoutIndex;
invalidateDisplayList();
}
private function onLayoutChanged(e:SwitchedLayoutEvent):void {
lockSettingsChanged(null);
//trace(LOG + " handling SwitchedLayoutEvent layout=[" + e.layoutID + "]");
populateComboBox();
//trace(LOG + " selected layout coming in is: " + selectedIndex);
var idx:int = -1;
for each (var obj:Object in dataProvider) {
if (obj.localeKey == e.layoutID)
idx = obj.index;
}
selectedIndex = idx;
if (idx == -1) {
prompt = e.layoutID;
} else {
prompt = ResourceUtil.getInstance().getString('bbb.layout.combo.prompt');
}
invalidateDisplayList();
//trace(LOG + " selected layout afterwards is: " + selectedIndex);
}
private static const LOGGER:ILogger = getClassLogger(LayoutsCombo);
private var _dispatcher:Dispatcher = new Dispatcher();
[Bindable]
private var layoutNames:ArrayCollection = new ArrayCollection();
private function init():void {
dataProvider = layoutNames;
populateComboBox();
this.addEventListener(DropdownEvent.OPEN, openDropdownHandler);
this.addEventListener(KeyboardEvent.KEY_UP, keyboardUpHandler);
}
private function lockSettingsChanged(e:LockControlEvent):void {
var conference:Conference = UserManager.getInstance().getConference();
var thisUser:BBBUser = conference.getMyUser();
this.enabled = !thisUser.lockedLayout;
}
private function populateLayoutsList(e:LayoutsReadyEvent):void {
populateComboBox();
}
private function populateComboBox():void {
layoutNames = new ArrayCollection();
var layouts:Array = LayoutModel.getInstance().getLayoutNames();
var idx:int = 0, currentLayoutIndex:int = -1;
for each (var lay:Object in layouts) {
var translatedName:String = ResourceUtil.getInstance().getString(lay.name)
if (translatedName == "undefined")
translatedName = lay.name;
var item:Object = {index: idx, label: translatedName, localeKey: lay.name, currentLayout: lay.currentLayout};
layoutNames.addItem(item);
if (lay.currentLayout) {
currentLayoutIndex = idx;
}
idx++;
}
dataProvider = layoutNames;
selectedIndex = currentLayoutIndex;
invalidateDisplayList();
}
private function onLayoutChanged(e:SwitchedLayoutEvent):void {
lockSettingsChanged(null);
populateComboBox();
var idx:int = -1;
for each (var obj:Object in dataProvider) {
if (obj.localeKey == e.layoutID)
idx = obj.index;
}
selectedIndex = idx;
if (idx == -1) {
prompt = e.layoutID;
} else {
prompt = ResourceUtil.getInstance().getString('bbb.layout.combo.prompt');
}
invalidateDisplayList();
}
private function localeChanged(e:LocaleChangeEvent):void {
//trace(LOG + " locale change recieved");
populateComboBox();
}
private function openDropdownHandler(e:DropdownEvent):void {
// a new dropdown object is created everytime the menu is opened
this.dropdown.addEventListener(ListEvent.ITEM_CLICK, itemClickHandler);
}
private function itemClickHandler(e:ListEvent):void {
_dispatcher.dispatchEvent(new ChangeLayoutEvent(e.currentTarget.selectedItem.localeKey));
}
private function openDropdownHandler(e:DropdownEvent):void {
// a new dropdown object is created everytime the menu is opened
this.dropdown.addEventListener(ListEvent.ITEM_CLICK, itemSelectHandler);
}
private function keyboardUpHandler(e:KeyboardEvent):void {
if (e.keyCode == Keyboard.ENTER || e.keyCode == Keyboard.SPACE) {
setNewLayout(this.selectedItem.localeKey);
}
}
private function itemSelectHandler(e:ListEvent):void {
this.dropdown.removeEventListener(ListEvent.ITEM_CLICK, itemSelectHandler);
setNewLayout(e.currentTarget.selectedItem.localeKey);
}
private function setNewLayout(layout:String):void {
_dispatcher.dispatchEvent(new ChangeLayoutEvent(layout));
}
]]>
</mx:Script>
</mx:ComboBox>

View File

@ -27,14 +27,13 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import mx.managers.PopUpManager;
import org.as3commons.lang.ArrayUtils;
import org.as3commons.lang.StringUtils;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.modules.polling.events.StartCustomPollEvent;
import org.bigbluebutton.modules.present.ui.views.PresentationWindow;
import org.bigbluebutton.util.i18n.ResourceUtil;
private var _presentationWindow : PresentationWindow;
public function setPresentationWindow(window:PresentationWindow):void {
@ -47,7 +46,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
_presentationWindow.slideView.onZoomSlide(100);
var dispatcher:Dispatcher = new Dispatcher();
dispatchEvent(new StartCustomPollEvent("Custom", answers));
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
}
@ -83,7 +82,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:HBox width="100%" horizontalGap="10" horizontalAlign="right">
<mx:Button id="publishButton" click="publishButton_clickHandler(event)"
label="{ResourceUtil.getInstance().getString('bbb.polling.startButton.label')}"/>
<mx:Button id="closeButton" click="PopUpManager.removePopUp(this)"
<mx:Button id="closeButton" click="PopUpUtil.removePopUp(this)"
label="{ResourceUtil.getInstance().getString('bbb.polling.closeButton.label')}"/>
</mx:HBox>

View File

@ -14,8 +14,8 @@ package org.bigbluebutton.modules.polling.views
import mx.controls.Label;
import mx.controls.TextArea;
import mx.core.ScrollPolicy;
import mx.managers.PopUpManager;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.modules.polling.events.PollStoppedEvent;
import org.bigbluebutton.modules.polling.events.PollVotedEvent;
import org.bigbluebutton.modules.polling.events.ShowPollResultEvent;
@ -193,7 +193,7 @@ package org.bigbluebutton.modules.polling.views
_stopPollListener.method = null;
_stopPollListener = null;
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
private function dotAnimate(e:TimerEvent):void {

View File

@ -24,10 +24,10 @@ package org.bigbluebutton.modules.present.managers
import flash.geom.Point;
import mx.core.FlexGlobals;
import mx.managers.PopUpManager;
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.modules.present.events.PresentModuleEvent;
import org.bigbluebutton.modules.present.events.UploadEvent;
import org.bigbluebutton.modules.present.ui.views.FileUploadWindow;
@ -36,7 +36,6 @@ package org.bigbluebutton.modules.present.managers
public class PresentManager
{
private var globalDispatcher:Dispatcher;
private var uploadWindow:FileUploadWindow;
private var presentWindow:PresentationWindow;
public function PresentManager() {
@ -62,24 +61,23 @@ package org.bigbluebutton.modules.present.managers
event.window = window;
globalDispatcher.dispatchEvent(event);
}
public function handleOpenUploadWindow(e:UploadEvent):void{
if (uploadWindow != null) return;
uploadWindow = FileUploadWindow(PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, FileUploadWindow, true));
uploadWindow.maxFileSize = e.maxFileSize;
var point1:Point = new Point();
point1.x = FlexGlobals.topLevelApplication.width / 2;
point1.y = FlexGlobals.topLevelApplication.height / 2;
uploadWindow.x = point1.x - (uploadWindow.width/2);
uploadWindow.y = point1.y - (uploadWindow.height/2);
public function handleOpenUploadWindow(e:UploadEvent):void{
var uploadWindow : FileUploadWindow = PopUpUtil.createModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, FileUploadWindow, false) as FileUploadWindow;
if (uploadWindow) {
uploadWindow.maxFileSize = e.maxFileSize;
var point1:Point = new Point();
point1.x = FlexGlobals.topLevelApplication.width / 2;
point1.y = FlexGlobals.topLevelApplication.height / 2;
uploadWindow.x = point1.x - (uploadWindow.width/2);
uploadWindow.y = point1.y - (uploadWindow.height/2);
}
}
public function handleCloseUploadWindow():void{
PopUpManager.removePopUp(uploadWindow);
uploadWindow = null;
PopUpUtil.removePopUp(FileUploadWindow);
}
}
}
}

View File

@ -20,10 +20,15 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-->
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mate="http://mate.asfusion.com/"
layout="absolute" width="580" height="410" styleName="presentationFileUploadWindowStyle"
initialize="initData();">
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mate="http://mate.asfusion.com/"
layout="absolute"
width="580"
height="410"
verticalScrollPolicy="off"
horizontalScrollPolicy="off"
styleName="presentationFileUploadWindowStyle"
initialize="initData();">
<mate:Dispatcher id="globalDispatch" />
<mate:Listener type="{UploadProgressEvent.UPLOAD_PROGRESS_UPDATE}" method="handleUploadProgressUpdate" />
@ -308,9 +313,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:TextArea borderSkin="{null}"
text="{ResourceUtil.getInstance().getString('bbb.fileupload.title')}"
editable="false" styleName="presentationUploadTitleStyle"
width="400" left="0"/>
<mx:HBox id="fileUploadBox" width="100%" paddingLeft="5" paddingTop="0" verticalAlign="middle">
<mx:Label id="lblFileName" width="{fileUploadBox.width-selectBtn.width-uploadBtn.width-30}" selectable="false" click="selectFile()" text="{ResourceUtil.getInstance().getString('bbb.fileupload.lblFileName.defaultText')}" />
width="100%"/>
<mx:HBox id="fileUploadBox" width="100%" paddingLeft="5" paddingRight="5" paddingTop="0" verticalAlign="middle">
<mx:Label id="lblFileName" truncateToFit="true" width="{fileUploadBox.width-selectBtn.width-uploadBtn.width-30}" selectable="false" click="selectFile()" text="{ResourceUtil.getInstance().getString('bbb.fileupload.lblFileName.defaultText')}" />
<mx:Button id="selectBtn" label="{ResourceUtil.getInstance().getString('bbb.fileupload.selectBtn.label')}"
toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.selectBtn.toolTip')}"
click="selectFile()" styleName="presentationUploadChooseFileButtonStyle"/>
@ -318,11 +323,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
toolTip="{ResourceUtil.getInstance().getString('bbb.fileupload.uploadBtn.toolTip')}" click="startUpload()"
enabled="false" icon="{bulletGoIcon}"/>
</mx:HBox>
<mx:HBox id="progressReportBox" width="100%" paddingLeft="10" paddingTop="5" paddingBottom="10" includeInLayout="true" visible="false">
<mx:HBox id="progressReportBox" width="100%" paddingLeft="10" paddingRight="10" paddingTop="5" paddingBottom="10" includeInLayout="true" visible="false">
<mx:Label id="progBarLbl" text="{ResourceUtil.getInstance().getString('bbb.fileupload.progBarLbl')}"
styleName="presentationUploadProgressBarLabelStyle" visible="false"/>
<mx:ProgressBar id="progressBar" mode="manual" label="{ResourceUtil.getInstance().getString('bbb.fileupload.progBarLbl')}"
styleName="presentationUploadProgressBarStyle" labelPlacement="center" width="460" visible="false"/>
styleName="presentationUploadProgressBarStyle" labelPlacement="center" width="100%" visible="false"/>
</mx:HBox>
<mx:Box width="100%" height="100%" paddingLeft="5" paddingRight="5">
<mx:Box width="100%" height="100%" verticalAlign="middle" horizontalAlign="center" styleName="presentationUploadFileFormatHintBoxStyle">
@ -330,7 +335,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
</mx:Box>
</mx:Box>
<mx:Canvas width="100%" height="145" verticalScrollPolicy="off">
<mx:List width="100%" height="142" left="5" top="5" right="5" bottom="5" id="uploadedFilesList" alternatingItemColors="[#EFEFEF, #FEFEFE]" allowMultipleSelection="false"
<mx:List height="142" left="5" top="5" right="5" bottom="5" id="uploadedFilesList" alternatingItemColors="[#EFEFEF, #FEFEFE]" allowMultipleSelection="false"
itemRenderer="org.bigbluebutton.modules.present.ui.views.UploadedPresentationRenderer"
dragEnabled="false" dataProvider="{presentationNamesAC}">
</mx:List>

View File

@ -1,66 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
This program is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 3.0 of the License, or (at your option) any later
version.
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-->
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
width="195" height="70"
layout="horizontal"
creationComplete="onCreationComplete()"
keyDown="onKeyDown(event)">
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import org.bigbluebutton.modules.present.events.PresenterCommands;
public static const SWITCH_PAGE:String = "switch to page";
[Bindable] public var totalSlides:int;
public var window:PresentationWindow;
private function closeDialog():void{
if( !isNaN( Number( txtPageNum.text ) ) ){
var page:Number = parseInt(txtPageNum.text);
if( page > 0 && page <= totalSlides ){
dispatchEvent(new PresenterCommands(PresenterCommands.GOTO_SLIDE, page));
}
}
PopUpManager.removePopUp(this);
}
private function onCreationComplete():void{
txtPageNum.setFocus();
}
private function onKeyDown(e:KeyboardEvent):void{
if (e.keyCode == Keyboard.ENTER){
closeDialog();
}
}
]]>
</mx:Script>
<mx:Label text="Page" />
<mx:TextInput id="txtPageNum" width="25" />
<mx:Label id="totalPages" text="{'/' + totalSlides}" />
<mx:Button id="okButton" click="closeDialog()" label="Ok" />
</mx:TitleWindow>

View File

@ -71,7 +71,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import mx.controls.Menu;
import mx.events.MenuEvent;
import mx.events.ResizeEvent;
import mx.managers.PopUpManager;
import flexlib.mdi.events.MDIWindowEvent;
@ -81,6 +80,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.events.LocaleChangeEvent;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.KeyboardUtil;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.main.events.MadePresenterEvent;
import org.bigbluebutton.main.events.ShortcutEvent;
@ -107,13 +108,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private static const LOGGER:ILogger = getClassLogger(PresentationWindow);
public static const TITLE:String = "Presentation";
public static const TITLE:String = "Presentation";
private static const GOTO_PAGE_BUTTON:String = "Go to Page...";
[Bindable]
private var thumbY:Number;
private var thumbY:Number;
public var uploadWindow:FileUploadWindow = null;
private var pageDialog:GotoPageDialog;
[Bindable] private var DEFAULT_X_POSITION:Number = 237;
[Bindable] private var DEFAULT_Y_POSITION:Number = 0;
@ -142,9 +142,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private var pollMenuData:Array;
private var pollMenu:Menu;
private var pollResultsPopUp:PollResultsModal
private var pollChoicesPopUp:PollChoicesModal
[Embed(source="../../../polling/sounds/Poll.mp3")]
private var noticeSoundClass:Class;
private var noticeSound:Sound = new noticeSoundClass() as Sound;
@ -225,7 +222,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
var modifier:String = ExternalInterface.call("determineModifier");
loadKeyCombos(modifier);
var keyPress:String = (e.ctrlKey ? "control+" : "") + (e.shiftKey ? "shift+" : "") + (e.altKey ? "alt+" : "") + e.keyCode;
var keyPress:String = KeyboardUtil.buildPressedKeys(e);
if (keyCombos[keyPress]) {
//globalDispatcher.dispatchEvent(new ShortcutEvent(keyCombos[keyPress]));
@ -639,15 +636,16 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
pollMenu.show();
}
private function sendStartCustomPollEvent(pollType:String):void {
// Let's reset the page to display full size so we can display the result
// on the bottom right-corner.
pollChoicesPopUp = PopUpManager.createPopUp(this, PollChoicesModal, true) as PollChoicesModal;
pollChoicesPopUp.setPresentationWindow(this);
PopUpManager.centerPopUp(pollChoicesPopUp);
}
private function sendStartCustomPollEvent(pollType:String):void {
// Let's reset the page to display full size so we can display the result
// on the bottom right-corner.
var pollChoicesPopUp:PollChoicesModal = PopUpUtil.createModalPopUp(this, PollChoicesModal, true) as PollChoicesModal;
if (pollChoicesPopUp) {
pollChoicesPopUp.setPresentationWindow(this);
}
}
private function sendStartPollEvent(pollType:String):void {
// Let's reset the page to display full size so we can display the result
// on the bottom right-corner.
@ -703,9 +701,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
// the event for this doesn't exist yet
if (UsersUtil.amIPresenter()) {
// display the results view
pollResultsPopUp = PopUpManager.createPopUp(this, PollResultsModal, true) as PollResultsModal;
pollResultsPopUp.setPoll(e.poll);
PopUpManager.centerPopUp(pollResultsPopUp);
var pollResultsPopUp : PollResultsModal = PopUpUtil.createModalPopUp(this, PollResultsModal, true) as PollResultsModal;
if (pollResultsPopUp) {
pollResultsPopUp.setPoll(e.poll);
}
} else {
//switch to vote state
setControlBarState("vote");
@ -769,7 +768,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function pollStoppedHandler(e:PollStoppedEvent):void {
setControlBarState("presenter");
PopUpManager.removePopUp(pollResultsPopUp);
PopUpUtil.removePopUp(PollResultsModal);
}
private function pollShowResultHandler(e:PollShowResultEvent):void {

View File

@ -50,11 +50,11 @@ package org.bigbluebutton.modules.screenshare.managers {
if (shareWindow != null) shareWindow.stopSharing();
}
public function startSharing(uri:String, room:String):void {
public function startSharing(uri:String, room:String, tunnel:Boolean):void {
LOGGER.debug("DS:PublishWindowManager::opening desk share window");
if (shareWindow == null) {
shareWindow = new ScreensharePublishWindow();
shareWindow.initWindow(service.getConnection(), uri, room);
shareWindow.initWindow(service.getConnection(), uri, room, tunnel);
shareWindow.visible = true;
openWindow(shareWindow);
}

View File

@ -153,13 +153,13 @@ package org.bigbluebutton.modules.screenshare.managers {
if (force || (option.tryWebRTCFirst && !BrowserCheck.isWebRTCSupported())) {
usingJava = true;
publishWindowManager.startSharing(module.getCaptureServerUri(), module.getRoom());
publishWindowManager.startSharing(module.getCaptureServerUri(), module.getRoom(), module.tunnel());
sharing = true;
service.requestShareToken();
} else {
sharing = true;
usingJava = false;
publishWindowManager.startSharing(module.getCaptureServerUri(), module.getRoom());
publishWindowManager.startSharing(module.getCaptureServerUri(), module.getRoom(), module.tunnel());
service.requestShareToken();
}
}
@ -205,7 +205,7 @@ package org.bigbluebutton.modules.screenshare.managers {
toolbarButtonManager.startedSharing();
var option:ScreenshareOptions = new ScreenshareOptions();
option.parseOptions();
publishWindowManager.startSharing(module.getCaptureServerUri(), module.getRoom());
publishWindowManager.startSharing(module.getCaptureServerUri(), module.getRoom(), module.tunnel());
sharing = true;
}

View File

@ -25,6 +25,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
implements="org.bigbluebutton.common.IBbbModuleWindow"
xmlns:mate="http://mate.asfusion.com/"
xmlns:dspub="flexlib.mdi.containers.*"
xmlns:common="org.bigbluebutton.common.*"
backgroundColor="#C0C0C0"
initialize="init()"
creationComplete="onCreationComplete()"
@ -49,13 +50,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import mx.core.UIComponent;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.common.events.LocaleChangeEvent;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.ReconnectionManager;
import org.bigbluebutton.main.events.BBBEvent;
@ -66,8 +64,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.modules.screenshare.events.RequestToRestartSharing;
import org.bigbluebutton.modules.screenshare.events.RequestToStopSharing;
import org.bigbluebutton.modules.screenshare.events.ScreenSharePausedEvent;
import org.bigbluebutton.modules.screenshare.events.ShareStoppedEvent;
import org.bigbluebutton.modules.screenshare.events.ShareStartEvent;
import org.bigbluebutton.modules.screenshare.events.ShareStoppedEvent;
import org.bigbluebutton.modules.screenshare.events.ShareWindowEvent;
import org.bigbluebutton.modules.screenshare.events.StartShareRequestSuccessEvent;
import org.bigbluebutton.modules.screenshare.events.StopSharingButtonEvent;
@ -89,6 +87,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private var connection:Connection;
private var uri:String;
private var room:String;
private var tunnel:Boolean = false;
private var sharingFullScreen:Boolean = false;
private var streaming:Boolean = false;
@ -134,14 +133,22 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
windowControls.maximizeRestoreBtn.enabled = false;
titleBarOverlay.tabIndex = baseIndex;
titleBarOverlay.focusEnabled = true;
minimizeBtn.tabIndex = baseIndex+1;
maximizeRestoreBtn.tabIndex = baseIndex+2;
closeBtn.tabIndex = baseIndex+3;
resourcesChanged();
focusManager.setFocus(titleBarOverlay);
if (tunnel) {
helpInfoBox.visible = helpInfoBox.includeInLayout = false;
previewBox.visible = previewBox.includeInLayout = false;
tunnelBox.visible = tunnelBox.includeInLayout = true;
shareTypeBox.visible = false;
cancelBtn.visible = cancelBtn.includeInLayout = true;
startBtn.visible = startBtn.includeInLayout = false;
stopBtn.visible = stopBtn.includeInLayout = false;
}
}
private function remoteFocus(e:ShortcutEvent):void{
@ -179,10 +186,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*/
public function resetWidthAndHeight():void{/* do nothing */}
public function initWindow(connection:Connection, uri:String, room:String):void {
public function initWindow(connection:Connection, uri:String, room:String, tunnel:Boolean):void {
this.connection = connection;
this.uri = uri;
this.room = room;
this.tunnel = tunnel;
}
private function handleStartShareRequestSuccessEvent(event:StartShareRequestSuccessEvent):void {
@ -522,6 +530,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
helpInfoBox.visible = helpInfoBox.includeInLayout = showHelp;
previewBox.visible = !showHelp;
titleBarOverlay.tabIndex = dsOptions.baseTabIndex;
shareTypeBox.visible = showHelp;
cancelBtn.visible = cancelBtn.includeInLayout = showHelp;
startBtn.visible = startBtn.includeInLayout = showHelp;
@ -530,6 +540,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
]]>
</mx:Script>
<common:TabIndexer id="tabIndexer" startIndex="{dsOptions.baseTabIndex + 1}"
tabIndices="{[minimizeBtn, maximizeRestoreBtn, closeBtn, helpButton, shareTypeCombo, startBtn, cancelBtn, stopBtn, pauseBtn, restartBtn]}"/>
<!--http://stackoverflow.com/questions/369120/why-does-mxstates-have-trouble-being-resolved-to-a-component-implementation-->
<mx:Box id="publishView" height="100%" width="100%" styleName="desktopShareViewStyle">
<mx:VBox id="helpInfoBox" width="100%" height="100%" verticalAlign="middle" verticalGap="12">
@ -568,7 +581,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:Box id="videoHolder" width="100%" height="90%" horizontalAlign="center">
<mx:UIComponent id="videoWrapper" width="100%" height="100%" />
<mx:VBox id="pauseBox" visible="false" includeInLayout="false" styleName="desksharePublishPauseBox" >
<mx:Label width="100%" textAlign="center" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.pauseMessage.label')}" />
<mx:Text width="100%" textAlign="center" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.pauseMessage.label')}" />
</mx:VBox>
</mx:Box>
<mx:Button id="pauseBtn"
@ -582,10 +595,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
label="{ResourceUtil.getInstance().getString('bbb.screensharePublish.restart.label')}" />
</mx:VBox>
<mx:VBox id="errorBox" width="100%" height="100%" visible="false" includeInLayout="false" horizontalAlign="center" verticalAlign="middle">
<mx:Label id="startFailedLbl" width="70%" visible="false" includeInLayout="false" textAlign="center" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.startFailed.label')}"/>
<mx:Label id="restartFailedLbl" width="70%" textAlign="center" visible="false" includeInLayout="false" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.restartFailed.label')}"/>
<mx:Label id="jwsCrashedLbl" width="70%" textAlign="center" visible="false" includeInLayout="false" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.jwsCrashed.label')}"/>
<mx:Label width="70%" textAlign="center" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.commonErrorMessage.label')}"/>
<mx:Text id="startFailedLbl" width="70%" visible="false" includeInLayout="false" textAlign="center" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.startFailed.label')}"/>
<mx:Text id="restartFailedLbl" width="70%" textAlign="center" visible="false" includeInLayout="false" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.restartFailed.label')}"/>
<mx:Text id="jwsCrashedLbl" width="70%" textAlign="center" visible="false" includeInLayout="false" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.jwsCrashed.label')}"/>
<mx:Text width="70%" textAlign="center" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.commonErrorMessage.label')}"/>
</mx:VBox>
<mx:VBox id="tunnelBox" width="100%" height="100%" visible="false" includeInLayout="false" horizontalAlign="center" verticalAlign="middle">
<mx:Text width="80%" textAlign="center" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.tunnelingErrorMessage.one')}" />
<mx:Text width="80%" textAlign="center" styleName="desktopShareTextStyle" text="{ResourceUtil.getInstance().getString('bbb.screensharePublish.tunnelingErrorMessage.two')}" />
</mx:VBox>
</mx:Box>
<mx:ControlBar horizontalAlign="right">

View File

@ -22,7 +22,7 @@
<MDIWindow xmlns="flexlib.mdi.containers.*"
xmlns:mx="http://www.adobe.com/2006/mxml"
width="600"
width="600"
height="400"
initialize="init()"
creationComplete="onCreationComplete()"
@ -38,27 +38,25 @@
<mx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import flexlib.mdi.events.MDIWindowEvent;
import mx.core.UIComponent;
import mx.core.UIComponent;
import flexlib.mdi.events.MDIWindowEvent;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.common.events.LocaleChangeEvent;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.ReconnectionManager;
import org.bigbluebutton.main.api.JSLog;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.views.MainCanvas;
import org.bigbluebutton.modules.screenshare.events.CursorEvent;
import org.bigbluebutton.modules.screenshare.events.StartedViewingEvent;
import org.bigbluebutton.modules.screenshare.events.ViewStreamEvent;
import org.bigbluebutton.modules.screenshare.events.ViewWindowEvent;
import org.bigbluebutton.modules.screenshare.model.ScreenshareModel;
import org.bigbluebutton.modules.screenshare.model.ScreenshareOptions;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.managers.ReconnectionManager;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.modules.screenshare.services.red5.Connection;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.util.i18n.ResourceUtil;
private static const LOG:String = "SC::ScreenshareViewWIndow - ";
private static const LOGGER:ILogger = getClassLogger(ScreenshareViewWindow);
@ -70,7 +68,7 @@
[Bindable] public var fitToWidthIcon:Class = images.magnifier;
[Bindable] public var fitToActualSizeIcon:Class = images.mag_reset;
private var streamAvailable:Boolean = false;
private var streamAvailable:Boolean = false;
private var video:Video;
private var ns:NetStream;
@ -100,7 +98,7 @@
}
private function onCreationComplete():void{
viewScreenshareStream();
viewScreenshareStream();
videoHolder.addChild(video);
this.addChild(videoHolder);
@ -116,14 +114,14 @@
minimizeBtn.tabIndex = baseIndex+1;
maximizeRestoreBtn.tabIndex = baseIndex+2;
closeBtn.tabIndex = baseIndex+3;
var logData:Object = UsersUtil.initLogData();
logData.tags = ["screenshare"];
logData.width = videoWidth;
logData.height = videoHeight;
logData.streamId = streamId;
LOGGER.info(JSON.stringify(logData));
var logData:Object = UsersUtil.initLogData();
logData.tags = ["screenshare"];
logData.width = videoWidth;
logData.height = videoHeight;
logData.streamId = streamId;
LOGGER.info(JSON.stringify(logData));
}
private function onResizeEndEvent(event:MDIWindowEvent):void {
@ -238,22 +236,24 @@
public function getPrefferedPosition():String{
return MainCanvas.DESKTOP_SHARING_VIEW;
}
/**
* resizes the desktop sharing video to fit to this window
*/
private function fitToWindow():void{
if (!streamAvailable) return;
if (videoIsSmallerThanWindow()) {
fitWindowToVideo();
}
// Ignore if we are displaying the actual size of the video
if (! btnActualSize.selected) {
fitVideoToWindow();
}
}
/**
* resizes the desktop sharing video to fit to this window
*/
private function fitToWindow():void {
if (!streamAvailable)
return;
if (videoIsSmallerThanWindow()) {
fitWindowToVideo();
}
// Ignore if we are displaying the actual size of the video
if (!btnActualSize.selected) {
fitVideoToWindow();
}
}
private function fitVideoToWindow():void {
if (this.width < this.height) {
@ -344,13 +344,12 @@
private function localeChanged(e:Event):void{
resourcesChanged();
}
public function handleDisconnectedEvent(event:BBBEvent):void {
if (event.payload.type == ReconnectionManager.DESKSHARE_CONNECTION) {
closeWindow();
}
}
public function handleDisconnectedEvent(event:BBBEvent):void {
if (event.payload.type == ReconnectionManager.DESKSHARE_CONNECTION) {
closeWindow();
}
}
]]>
</mx:Script>

View File

@ -24,6 +24,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:mate="http://mate.asfusion.com/"
xmlns:common="org.bigbluebutton.common.*"
width="630" height="650"
close="onCloseClicked()"
visible="false"
@ -35,8 +36,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.managers.PopUpManager;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.events.BreakoutRoomEvent;
import org.bigbluebutton.main.model.users.BBBUser;
@ -56,7 +57,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private static var assignement : Dictionary;
private function onCloseClicked():void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
/**
@ -87,7 +88,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
event.record = recordCheckbox.selected;
dispatcher.dispatchEvent(event);
storeAssignement();
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
} else {
Alert.show(ResourceUtil.getInstance().getString('bbb.users.breakout.insufficientUsers'));
}
@ -114,7 +115,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
}
if (usersInvited) {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
} else {
Alert.show(ResourceUtil.getInstance().getString('bbb.users.breakout.insufficientUsers'));
}
@ -292,8 +293,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mx:HBox id="durationBox" width="100%" paddingTop="12">
<mx:Label text="{ResourceUtil.getInstance().getString('bbb.users.breakout.timeLimit')}" />
<mx:NumericStepper id="durationStepper" value="15" minimum="1" maximum="600"
accessibilityName="{ResourceUtil.getInstance().getString('bbb.users.breakout.durationStepper.accessibilityName')}"/>
<common:AccessibleNumericStepper id="durationStepper" value="15" minimum="1" maximum="600"
toolTip="{ResourceUtil.getInstance().getString('bbb.users.breakout.durationStepper.accessibilityName')}"/>
<mx:Label text="{ResourceUtil.getInstance().getString('bbb.users.breakout.minutes')}"/>
</mx:HBox>

View File

@ -23,15 +23,14 @@ package org.bigbluebutton.modules.users.views {
import flash.events.MouseEvent;
import mx.containers.HBox;
import mx.containers.Tile;
import mx.containers.VBox;
import mx.controls.Button;
import mx.controls.Label;
import mx.core.ScrollPolicy;
import mx.events.FlexMouseEvent;
import mx.managers.PopUpManager;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.model.users.events.EmojiStatusEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
@ -121,7 +120,7 @@ package org.bigbluebutton.modules.users.views {
* Hides the menu
*/
public function hide():void {
PopUpManager.removePopUp(this);
PopUpUtil.removePopUp(this);
}
}
}

View File

@ -51,8 +51,8 @@
]]>
</mx:Script>
<mx:Button id="joinImg" width="20" height="20"
includeInLayout="{UserManager.getInstance().getConference().breakoutRoomsReady}" visible="{joinImg.includeInLayout}"
<mx:Button id="joinBtn" width="20" height="20"
includeInLayout="{UserManager.getInstance().getConference().breakoutRoomsReady}" visible="{joinBtn.includeInLayout}"
icon="{images.join}" toolTip="{ResourceUtil.getInstance().getString('bbb.users.roomsGrid.join')}"
click="requestBreakoutJoinUrl(event)"/>
<mx:Button id="listenBtn" toggle="true"

View File

@ -25,6 +25,7 @@
xmlns:flc="flexlib.controls.*"
implements="org.bigbluebutton.common.IBbbModuleWindow"
xmlns:mate="http://mate.asfusion.com/"
xmlns:views="org.bigbluebutton.main.views.*"
creationComplete="onCreationComplete()"
title="{ResourceUtil.getInstance().getString('bbb.users.title')}"
showCloseButton="false">
@ -33,6 +34,7 @@
<mate:Listener type="{ShortcutEvent.RAISE_HAND}" method="remoteRaiseHand" />
<mate:Listener type="{ShortcutEvent.FOCUS_USERS_WINDOW}" method="focusWindow" />
<mate:Listener type="{ShortcutEvent.MUTE_ALL_BUT_PRES}" method="remoteMuteAllButPres" />
<mate:Listener type="{ShortcutEvent.OPEN_BREAKOUT_ROOMS}" method="handleOpenBreakoutRooms" />
<mate:Listener type="{MeetingMutedEvent.MEETING_MUTED}" method="handleMeetingMuted" />
<mate:Listener type="{LockControlEvent.CHANGED_LOCK_SETTINGS}" method="handleChangedLockSettingsEvent" />
<mate:Listener type="{BreakoutRoomEvent.UPDATE_REMAINING_TIME_PARENT}" method="handleRemainingTimeUpdate" />
@ -47,8 +49,10 @@
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.controls.Menu;
import mx.controls.dataGridClasses.DataGridColumn;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.FlexGlobals;
import mx.core.mx_internal;
import mx.events.CloseEvent;
import mx.events.CollectionEvent;
import mx.events.ListEvent;
@ -60,6 +64,8 @@
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.common.events.LocaleChangeEvent;
import org.bigbluebutton.core.KeyboardUtil;
import org.bigbluebutton.core.PopUpUtil;
import org.bigbluebutton.core.TimerUtil;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.events.LockControlEvent;
@ -127,7 +133,10 @@
private const KICK_USER:String = "Kick User";
private const MUTE_USER:String = "Mute User";
private const MUTE_ALL_USER:String = "Mute All User";
private const FOCUS_BREAKOUT_ROOMS_LIST:String = "Focus Breakout Rooms";
private const LISTEN_TO_BREAKOUT_ROOM:String = "Listen To Breakout Room";
private const JOIN_BREAKOUT_ROOM:String = "Join Breakout Room";
private var muteMeRolled:Boolean = false;
private function onCreationComplete():void {
@ -251,12 +260,12 @@
dispatcher.dispatchEvent(rollEvent);
}
private function openEmojiStatusMenu():void {
var grid:EmojiGrid = PopUpManager.createPopUp(DisplayObject(FlexGlobals.topLevelApplication), EmojiGrid, false) as EmojiGrid;
var menuXY:Point = emojiStatusBtn.localToGlobal(new Point(emojiStatusBtn.width + 2, emojiStatusBtn.height - grid.height));
grid.x = menuXY.x;
grid.y = menuXY.y;
}
private function openEmojiStatusMenu():void {
var grid:EmojiGrid = PopUpUtil.createNonModelPopUp(DisplayObject(FlexGlobals.topLevelApplication), EmojiGrid, false) as EmojiGrid;
var menuXY:Point = emojiStatusBtn.localToGlobal(new Point(emojiStatusBtn.width + 2, emojiStatusBtn.height - grid.height));
grid.x = menuXY.x;
grid.y = menuXY.y;
}
private function openSettings():void {
paramsMenuData = [];
@ -362,50 +371,11 @@
private function removeJoinAlert():void {
if (joinAlert != null) {
// @todo: any way using PopUpUtil ?
PopUpManager.removePopUp(joinAlert);
}
}
/*private function unlockAll():void {
LogUtil.traceObject("Action: unlockAll");
if (amIModerator) {
if (roomLocked) {
var unlockCommand:LockControlEvent = new LockControlEvent(LockControlEvent.UNLOCK_ALL);
dispatchEvent(unlockCommand);
roomLocked = false;
} else {
LogUtil.error("Action: unlockAll, but room is not locked");
}
}
}
private function lockAll():void {
LogUtil.traceObject("Action: lockAll");
if (amIModerator) {
if (!roomLocked) {
var lockCommand:LockControlEvent = new LockControlEvent(LockControlEvent.LOCK_ALL);
dispatchEvent(lockCommand);
roomLocked = true;
} else {
LogUtil.error("Action: lockAll, but room is already locked");
}
}
}
private function lockAlmostAll():void {
LogUtil.traceObject("Action: lockAlmostAll");
if (amIModerator) {
if (!roomLocked) {
var lockCommand:LockControlEvent = new LockControlEvent(LockControlEvent.LOCK_ALMOST_ALL);
dispatchEvent(lockCommand);
roomLocked = true;
} else {
LogUtil.error("Action: lockAlmostAll, but room is already locked");
}
}
}
*/
private function handleMeetingMuted(e:MeetingMutedEvent):void {
roomMuted = MeetingModel.getInstance().meetingMuted;
}
@ -475,6 +445,9 @@
keyCombos[modifier + (ResourceUtil.getInstance().getString('bbb.shortcutkey.users.kick') as String)] = KICK_USER;
keyCombos[modifier + (ResourceUtil.getInstance().getString('bbb.shortcutkey.users.mute') as String)] = MUTE_USER;
keyCombos[modifier + (ResourceUtil.getInstance().getString('bbb.shortcutkey.users.muteall') as String)] = MUTE_ALL_USER;
keyCombos[modifier + (ResourceUtil.getInstance().getString('bbb.shortcutkey.users.focusBreakoutRooms') as String)] = FOCUS_BREAKOUT_ROOMS_LIST;
keyCombos[modifier + (ResourceUtil.getInstance().getString('bbb.shortcutkey.users.listenToBreakoutRoom') as String)] = LISTEN_TO_BREAKOUT_ROOM;
keyCombos[modifier + (ResourceUtil.getInstance().getString('bbb.shortcutkey.users.joinBreakoutRoom') as String)] = JOIN_BREAKOUT_ROOM;
//TODO Include shortcuts to lock control
keyCombos[modifier + (ResourceUtil.getInstance().getString('bbb.shortcutkey.general.maximize') as String)] = ShortcutEvent.MAXIMIZE_USERS;
keyCombos[modifier + (ResourceUtil.getInstance().getString('bbb.shortcutkey.general.minimize') as String)] = ShortcutEvent.MINIMIZE_USERS;
@ -483,8 +456,7 @@
// Handle general-access hotkeys, regardless of what window the user is focused in
private function handleKeyDown(e:KeyboardEvent):void {
if (keyCombos == null) loadKeyCombos(modifier);
var keyPress:String = (e.ctrlKey ? "control+" : "") + (e.shiftKey ? "shift+" : "") +
(e.altKey ? "alt+" : "") + e.keyCode;
var keyPress:String = KeyboardUtil.buildPressedKeys(e);
if (keyCombos[keyPress]) {
switch (keyCombos[keyPress]) {
case FOCUS_USERS_LIST:
@ -502,6 +474,15 @@
case MUTE_ALL_USER:
muteAll();
break;
case FOCUS_BREAKOUT_ROOMS_LIST:
remoteFocusBreakoutRooms();
break;
case LISTEN_TO_BREAKOUT_ROOM:
listenToBreakoutRoom();
break;
case JOIN_BREAKOUT_ROOM:
joinBreakoutRoom();
break;
case ShortcutEvent.MAXIMIZE_USERS:
remoteMaximize();
break;
@ -565,11 +546,11 @@
public function remoteMuteUser():void {
if (amIModerator && usersGrid.selectedIndex != -1) {
var selData:Object = usersGrid.selectedItem;
var selData:BBBUser = (usersGrid.selectedItem) as BBBUser;
if (selData.voiceJoined) {
var e:VoiceConfEvent = new VoiceConfEvent(VoiceConfEvent.MUTE_USER);
e.userid = selData.voiceUserid;
e.userid = selData.userID;
e.mute = !selData.voiceMuted;
dispatchEvent(e);
}
@ -581,6 +562,33 @@
usersGrid.drawFocus(true);
}
public function remoteFocusBreakoutRooms() : void {
if (roomsGrid && roomsGrid.visible) {
focusManager.setFocus(roomsGrid);
roomsGrid.drawFocus(true);
}
}
public function listenToBreakoutRoom() : void {
if (roomsGrid && roomsBox.visible && roomsGrid.selectedIndex > -1) {
// roomsGrid.selectedIndex + 1 is needed as the first index of rendererArray contains the header renderes
var renderer : RoomActionsRenderer = roomsGrid.mx_internal::rendererArray[roomsGrid.selectedIndex + 1][2];
if (renderer.listenBtn.visible) {
renderer.listenBtn.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
}
}
}
public function joinBreakoutRoom() : void {
if (roomsGrid && roomsBox.visible && roomsGrid.selectedIndex > -1) {
// roomsGrid.selectedIndex + 1 is needed as the first index of rendererArray contains the header renderes
var renderer : RoomActionsRenderer = roomsGrid.mx_internal::rendererArray[roomsGrid.selectedIndex + 1][2];
if (renderer.joinBtn.visible) {
renderer.joinBtn.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
}
}
}
private function remoteMuteAllButPres(e:ShortcutEvent):void{
if (!roomMuted) {
muteAlmostAll();
@ -588,7 +596,13 @@
muteAll();
}
}
private function handleOpenBreakoutRooms(e:ShortcutEvent):void{
if (breakoutOptions.enabled && amIModerator && !UserManager.getInstance().getConference().isBreakout) {
breakoutRooms();
}
}
private function breakoutRoomNameLabelFunction(item:Object, column:DataGridColumn) : String {
return ResourceUtil.getInstance().getString('bbb.users.roomsGrid.room') + " " + item.sequence;
}
@ -606,20 +620,20 @@
<mdi:TabIndexer id="tabIndexer" startIndex="{partOptions.baseTabIndex + 5}" tabIndices="{[usersGrid, roomsGrid, closeRoomsBtn, emojiStatusBtn, settingsBtn]}"/>
<mx:DataGrid id="usersGrid" dataProvider="{users}" editable="false" sortableColumns="true"
<views:BBBDataGrid id="usersGrid" dataProvider="{users}" editable="false" sortableColumns="true"
dragEnabled="false" width="100%" height="100%" draggableColumns="false"
itemRollOver="onItemRollOver(event)"
itemRollOut="onItemRollOut(event)"
accessibilityName="{ResourceUtil.getInstance().getString('bbb.users.usersGrid.accessibilityName')}" >
<mx:columns>
<views:columns>
<mx:DataGridColumn dataField="userStatus" headerText="{ResourceUtil.getInstance().getString('bbb.users.usersGrid.statusItemRenderer')}" editable="false" width="45" minWidth="45"
itemRenderer="org.bigbluebutton.modules.users.views.StatusItemRenderer" sortable="false" />
<mx:DataGridColumn dataField="displayName" headerText="{ResourceUtil.getInstance().getString('bbb.users.usersGrid.nameItemRenderer')}" editable="false" sortable="false" minWidth="60"
itemRenderer="org.bigbluebutton.modules.users.views.NameItemRenderer"/>
<mx:DataGridColumn dataField="media" headerText="{ResourceUtil.getInstance().getString('bbb.users.usersGrid.mediaItemRenderer')}" sortable="false" width="110" minWidth="110"
itemRenderer="org.bigbluebutton.modules.users.views.MediaItemRenderer"/>
</mx:columns>
</mx:DataGrid>
</views:columns>
</views:BBBDataGrid>
<mx:VBox id="roomsBox" styleName="breakoutRoomsBox"
visible="{breakoutRoomsList.length > 0 &amp;&amp; amIModerator}"
@ -632,11 +646,11 @@
text="..." toolTip="{ResourceUtil.getInstance().getString('bbb.users.breakout.timer.toolTip')}"/>
</mx:HBox>
<mx:DataGrid id="roomsGrid" editable="false" sortableColumns="false"
<views:BBBDataGrid id="roomsGrid" editable="false" sortableColumns="false"
dataProvider="{breakoutRoomsList}" dataTipFunction="breakoutRoomsToolTip"
dragEnabled="false" width="100%" height="100%" draggableColumns="false"
accessibilityName="{ResourceUtil.getInstance().getString('bbb.users.breakout.breakoutRooms')}">
<mx:columns>
<views:columns>
<mx:DataGridColumn labelFunction="breakoutRoomNameLabelFunction"
showDataTips="true"
headerText="{ResourceUtil.getInstance().getString('bbb.users.roomsGrid.room')}" />
@ -647,8 +661,8 @@
visible="{amIModerator}"
headerText="{ResourceUtil.getInstance().getString('bbb.users.roomsGrid.action')}"
itemRenderer="org.bigbluebutton.modules.users.views.RoomActionsRenderer"/>
</mx:columns>
</mx:DataGrid>
</views:columns>
</views:BBBDataGrid>
<mx:Button id="closeRoomsBtn" label="{ResourceUtil.getInstance().getString('bbb.users.breakout.closeAllRooms')}"
click="endAllBreakoutRoomsHandler(event)" width="100%"/>

View File

@ -60,8 +60,8 @@ package org.bigbluebutton.modules.videoconf.maps
public class VideoEventMapDelegate
{
private static const LOGGER:ILogger = getClassLogger(VideoEventMapDelegate);
private static var PERMISSION_DENIED_ERROR:String = "PermissionDeniedError";
private static const LOGGER:ILogger = getClassLogger(VideoEventMapDelegate);
private static var PERMISSION_DENIED_ERROR:String = "PermissionDeniedError";
private var options:VideoConfOptions = new VideoConfOptions();
private var uri:String;
@ -71,7 +71,6 @@ package org.bigbluebutton.modules.videoconf.maps
private var _dispatcher:IEventDispatcher;
private var _ready:Boolean = false;
private var _isPublishing:Boolean = false;
private var _isPreviewWebcamOpen:Boolean = false;
private var _isWaitingActivation:Boolean = false;
private var _chromeWebcamPermissionDenied:Boolean = false;
@ -79,18 +78,17 @@ package org.bigbluebutton.modules.videoconf.maps
private var _videoDock:VideoDock;
private var _graphics:GraphicsWrapper = new GraphicsWrapper();
private var streamList:ArrayList = new ArrayList();
private var numberOfWindows:Object = new Object();
private var _restream:Boolean = false;
private var _cameraIndex:int;
private var _videoProfile:VideoProfile;
private var globalDispatcher:Dispatcher;
private var _restream:Boolean = false;
private var _myCamSettings:ArrayCollection = null;
private var globalDispatcher:Dispatcher;
public function VideoEventMapDelegate(dispatcher:IEventDispatcher)
{
_dispatcher = dispatcher;
globalDispatcher = new Dispatcher();
globalDispatcher = new Dispatcher();
_myCamSettings = new ArrayCollection();
}
private function get me():String {
@ -119,14 +117,14 @@ package org.bigbluebutton.modules.videoconf.maps
}
}
public function handleStreamStoppedEvent(event:StreamStoppedEvent):void {
if (UserManager.getInstance().getConference().amIThisUser(event.userId)) {
closePublishWindowByStream(event.streamId);
} else {
closeViewWindowWithStream(event.userId, event.streamId);
}
}
public function handleStreamStoppedEvent(event:StreamStoppedEvent):void {
if (UserManager.getInstance().getConference().amIThisUser(event.userId)) {
closePublishWindowByStream(event.streamId);
} else {
closeViewWindowWithStream(event.userId, event.streamId);
}
}
public function handleUserLeftEvent(event:UserLeftEvent):void {
LOGGER.debug("VideoEventMapDelegate:: [{0}] handleUserLeftEvent. ready = [{1}]", [me, _ready]);
@ -136,7 +134,7 @@ package org.bigbluebutton.modules.videoconf.maps
}
public function handleUserJoinedEvent(event:UserJoinedEvent):void {
LOGGER.debug("VideoEventMapDelegate:: [{0}] handleUserJoinedEvent. ready = [{1}]", [me, _ready]);
LOGGER.debug("VideoEventMapDelegate:: [{0}] handleUserJoinedEvent. ready = [{1}]", [me, _ready]);
if (!_ready) return;
@ -165,7 +163,7 @@ package org.bigbluebutton.modules.videoconf.maps
var event:ToolbarButtonEvent = new ToolbarButtonEvent(ToolbarButtonEvent.ADD);
event.button = button;
event.module="Webcam";
event.module="Webcam";
_dispatcher.dispatchEvent(event);
}
}
@ -221,7 +219,7 @@ package org.bigbluebutton.modules.videoconf.maps
}
private function openWebcamWindows():void {
LOGGER.debug("VideoEventMapDelegate:: [{0}] openWebcamWindows. ready = [{1}]", [me, _ready]);
LOGGER.debug("VideoEventMapDelegate:: [{0}] openWebcamWindows. ready = [{1}]", [me, _ready]);
var uids:ArrayCollection = UsersUtil.getUserIDs();
@ -308,45 +306,42 @@ package org.bigbluebutton.modules.videoconf.maps
public function connectToVideoApp():void {
proxy = new VideoProxy(uri);
proxy.reconnectWhenDisconnected(true);
proxy.reconnectWhenDisconnected(true);
proxy.connect();
}
public function startPublishing(e:StartBroadcastEvent):void{
LOGGER.debug("VideoEventMapDelegate:: [{0}] startPublishing:: Publishing stream to: {1}/{2}", [me, proxy.connection.uri, e.stream]);
LOGGER.debug("VideoEventMapDelegate:: [{0}] startPublishing:: Publishing stream to: {1}/{2}", [me, proxy.connection.uri, e.stream]);
proxy.startPublishing(e);
_isWaitingActivation = false;
_isPublishing = true;
UsersUtil.setIAmPublishing(true);
_isWaitingActivation = false;
var broadcastEvent:BroadcastStartedEvent = new BroadcastStartedEvent();
streamList.addItem(e.stream);
broadcastEvent.stream = e.stream;
broadcastEvent.userid = UsersUtil.getMyUserID();
broadcastEvent.isPresenter = UsersUtil.amIPresenter();
broadcastEvent.camSettings = UsersUtil.amIPublishing();
var arr: ArrayCollection = UsersUtil.amIPublishing();
for (var i:int = 0; i < arr.length; i++) {
var broadcastEvent:BroadcastStartedEvent = new BroadcastStartedEvent();
streamList.addItem(e.stream);
broadcastEvent.stream = e.stream;
broadcastEvent.userid = UsersUtil.getMyUserID();
broadcastEvent.isPresenter = UsersUtil.amIPresenter();
broadcastEvent.camSettings = arr.getItemAt(i) as CameraSettingsVO;
_dispatcher.dispatchEvent(broadcastEvent);
if (proxy.videoOptions.showButton) {
button.callLater(button.publishingStatus, [button.START_PUBLISHING]);
}
_dispatcher.dispatchEvent(broadcastEvent);
}
if (proxy.videoOptions.showButton) {
button.callLater(button.publishingStatus, [button.START_PUBLISHING]);
}
}
public function stopPublishing(e:StopBroadcastEvent):void{
LOGGER.debug("VideoEventMapDelegate:: [{0}] Stop publishing. ready = [{1}]", [me, _ready]);
checkLastBroadcasting();
UsersUtil.removeCameraSettings(e.camId);
streamList.removeItem(e.stream);
stopBroadcasting(e.stream);
button.setCamAsInactive(e.camId);
}
private function checkLastBroadcasting():void {
LOGGER.debug("[VideoEventMapDelegate:checkLastBroadcasting]");
_isPublishing = streamList.length > 0;
UsersUtil.setIAmPublishing(streamList.length > 0);
}
private function stopBroadcasting(stream:String = ""):void {
if (stream == null) stream = "";
LOGGER.debug("Stopping broadcast{0}", [(stream.length > 0? " of stream [" + stream + "]": "")]);
@ -383,18 +378,18 @@ package org.bigbluebutton.modules.videoconf.maps
public function handleClosePublishWindowEvent(event:ClosePublishWindowEvent):void {
LOGGER.debug("Closing publish window");
if (_isPublishing || _chromeWebcamPermissionDenied) {
if (_myCamSettings.length > 0 || _chromeWebcamPermissionDenied) {
stopBroadcasting();
}
}
public function handleShareCameraRequestEvent(event:ShareCameraRequestEvent):void {
LOGGER.debug("[VideoEventMapDelegate:handleShareCameraRequestEvent]");
if (options.skipCamSettingsCheck) {
skipCameraSettingsCheck();
} else {
openWebcamPreview(event.publishInClient, event.defaultCamera, event.camerasArray);
}
LOGGER.debug("[VideoEventMapDelegate:handleShareCameraRequestEvent] {0} {1}", [options.skipCamSettingsCheck, event.toString()]);
if (options.skipCamSettingsCheck) {
skipCameraSettingsCheck();
} else {
openWebcamPreview(event.publishInClient, event.defaultCamera, event.camerasArray);
}
}
public function handleStopAllShareCameraRequestEvent(event:StopShareCameraRequestEvent):void {
@ -407,12 +402,15 @@ package org.bigbluebutton.modules.videoconf.maps
var userID:String = UsersUtil.getMyUserID();
var camIndex:int = event.camId;
// remove the camera from the settings so it does not resume sharing on refresh
removeCamera(camIndex);
_graphics.removeVideoByCamIndex(userID, camIndex);
}
public function handleCamSettingsClosedEvent(event:BBBEvent):void{
_isPreviewWebcamOpen = false;
}
public function handleCamSettingsClosedEvent(event:BBBEvent):void{
_isPreviewWebcamOpen = false;
}
private function openWebcamPreview(publishInClient:Boolean, defaultCamera:String, camerasArray:Object):void {
var openEvent:BBBEvent = new BBBEvent(BBBEvent.OPEN_WEBCAM_PREVIEW);
@ -421,7 +419,7 @@ package org.bigbluebutton.modules.videoconf.maps
openEvent.payload.camerasArray = camerasArray;
openEvent.payload.chromePermissionDenied = _chromeWebcamPermissionDenied;
_isPreviewWebcamOpen = true;
_isPreviewWebcamOpen = true;
_dispatcher.dispatchEvent(openEvent);
}
@ -432,13 +430,13 @@ package org.bigbluebutton.modules.videoconf.maps
var event:CloseWindowEvent = new CloseWindowEvent(CloseWindowEvent.CLOSE_WINDOW_EVENT);
event.window = _videoDock;
globalDispatcher.dispatchEvent(event);
proxy.reconnectWhenDisconnected(false);
proxy.reconnectWhenDisconnected(false);
proxy.disconnect();
}
private function closeAllWindows():void {
LOGGER.debug("VideoEventMapDelegate:: closing all windows");
if (_isPublishing) {
if (_myCamSettings.length > 0) {
stopBroadcasting();
}
@ -459,7 +457,7 @@ package org.bigbluebutton.modules.videoconf.maps
if (options.showButton){
LOGGER.debug("****************** Switching to viewer. Show video button?=[{0}]", [UsersUtil.amIPresenter()]);
displayToolbarButton();
if (_isPublishing && options.presenterShareOnly) {
if (_myCamSettings.length > 0 && options.presenterShareOnly) {
stopBroadcasting();
}
}
@ -478,33 +476,58 @@ package org.bigbluebutton.modules.videoconf.maps
openWebcamWindows();
}
public function handleCameraSetting(event:BBBEvent):void {
_cameraIndex = event.payload.cameraIndex;
_videoProfile = event.payload.videoProfile;
_restream = event.payload.restream;
LOGGER.debug("VideoEventMapDelegate::handleCameraSettings [{0},{1}]", [_cameraIndex, _videoProfile.id]);
initCameraWithSettings(_cameraIndex, _videoProfile);
private function addCamera(camIndex:int, videoProfile:VideoProfile):void {
var camSettings:CameraSettingsVO = new CameraSettingsVO();
camSettings.camIndex = camIndex;
camSettings.videoProfile = videoProfile;
camSettings.isPublishing = true;
if(!_myCamSettings.contains(camSettings)) {
_myCamSettings.addItem(camSettings);
}
}
private function removeCamera(camIndex:int):void {
for(var i:int = 0; i < _myCamSettings.length; i++) {
if (_myCamSettings.getItemAt(i) != null && _myCamSettings.getItemAt(i).camIndex == camIndex) {
_myCamSettings.removeItemAt(i);
}
}
}
public function handleCameraSetting(event:BBBEvent):void {
var camIndex:int = event.payload.cameraIndex;
var videoProfile:VideoProfile = event.payload.videoProfile;
addCamera(camIndex, videoProfile);
_restream = event.payload.restream;
LOGGER.debug("VideoEventMapDelegate::handleCameraSettings [{0},{1}] _restream={2}", [camIndex, videoProfile.id, _restream]);
initCameraWithSettings(camIndex, videoProfile);
}
public function handleEraseCameraSetting(event:BBBEvent):void {
_myCamSettings = new ArrayCollection();
LOGGER.debug("VideoEventMapDelegate::handleEraseCameraSetting [{0}]", [event.toString()]);
_restream = event.payload.restream;
}
private function handleRestream():void {
if(_restream){
for each(var aCamSettings:CameraSettingsVO in _myCamSettings) {
LOGGER.debug("VideoEventMapDelegate::handleRestream [{0},{1}]", [aCamSettings.camIndex, aCamSettings.videoProfile.id]);
initCameraWithSettings(aCamSettings.camIndex, aCamSettings.videoProfile);
}
}
}
public function handleEraseCameraSetting(event:BBBEvent):void {
_cameraIndex = -1;
_videoProfile = null;
_restream = event.payload.restream;
}
private function handleRestream():void {
if(_restream){
LOGGER.debug("VideoEventMapDelegate::handleRestream [{0},{1}]", [_cameraIndex, _videoProfile.id]);
initCameraWithSettings(_cameraIndex, _videoProfile);
}
}
private function initCameraWithSettings(camIndex:int, videoProfile:VideoProfile):void {
var camSettings:CameraSettingsVO = new CameraSettingsVO();
camSettings.camIndex = camIndex;
camSettings.videoProfile = videoProfile;
UsersUtil.setCameraSettings(camSettings);
camSettings.isPublishing = true;
UsersUtil.addCameraSettings(camSettings);
_isWaitingActivation = true;
button.setCamAsActive(camIndex);

View File

@ -67,7 +67,14 @@ package org.bigbluebutton.modules.videoconf.views
*/
var d:Date = new Date();
var curTime:Number = d.getTime();
return profile.id + "-" + userId + "-" + curTime;
var streamId: String = profile.id + "-" + userId + "-" + curTime;
if (UsersUtil.isRecorded()) {
// Append recorded to stream name to tell server to record this stream.
// ralam (feb 27, 2017)
streamId += "-recorded";
}
return streamId;
}
public static function getVideoProfile(stream:String):VideoProfile {

View File

@ -40,6 +40,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import mx.core.UIComponent;
import org.bigbluebutton.core.KeyboardUtil;
import org.bigbluebutton.main.events.ShortcutEvent;
import org.bigbluebutton.main.views.MainCanvas;
import org.bigbluebutton.modules.videoconf.model.VideoConfOptions;
@ -73,8 +74,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function handleKeyDown(e:KeyboardEvent) :void {
var modifier:String = ExternalInterface.call("determineModifier");
loadKeyCombos(modifier);
var keyPress:String = (e.ctrlKey ? "control+" : "") + (e.shiftKey ? "shift+" : "") +
(e.altKey ? "alt+" : "") + e.keyCode;
var keyPress:String = KeyboardUtil.buildPressedKeys(e);
if (keyCombos[keyPress]) {
disp.dispatchEvent(new ShortcutEvent(keyCombos[keyPress]));
}

View File

@ -1,247 +1,237 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.util.i18n
{
import com.asfusion.mate.events.Dispatcher;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.external.ExternalInterface;
import flash.net.URLLoader;
import flash.net.URLRequest;
import mx.core.FlexGlobals;
import mx.events.ResourceEvent;
import mx.resources.IResourceManager;
import mx.resources.ResourceManager;
import mx.utils.URLUtil;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.events.LocaleChangeEvent;
import org.bigbluebutton.main.events.AppVersionEvent;
public class ResourceUtil extends EventDispatcher {
private static const LOGGER:ILogger = getClassLogger(ResourceUtil);
public static const LOCALES_FILE:String = "client/conf/locales.xml";
public static const VERSION:String = "0.9.0";
private static var instance:ResourceUtil = null;
private var inited:Boolean = false;
private static var BBB_RESOURCE_BUNDLE:String = 'bbbResources';
private static var MASTER_LOCALE:String = "en_US";
[Bindable] public var localeCodes:Array = new Array();
[Bindable] public var localeNames:Array = new Array();
[Bindable] public var localeIndex:Number;
private var eventDispatcher:IEventDispatcher;
private var resourceManager:IResourceManager;
private var preferredLocale:String
public function ResourceUtil(enforcer:SingletonEnforcer) {
if (enforcer == null) {
throw new Error( "You Can Only Have One ResourceUtil" );
}
initialize();
}
private function isInited():Boolean {
return inited;
}
public function initialize():void {
resourceManager = ResourceManager.getInstance();
// Add a random string on the query so that we always get an up-to-date config.xml
var date:Date = new Date();
var _urlLoader:URLLoader = new URLLoader();
_urlLoader.addEventListener(Event.COMPLETE, handleComplete);
var localeReqURL:String = buildRequestURL() + LOCALES_FILE + "?a=" + date.time;
_urlLoader.load(new URLRequest(localeReqURL));
}
private function buildRequestURL():String {
var swfURL:String = FlexGlobals.topLevelApplication.url;
var protocol:String = URLUtil.getProtocol(swfURL);
var serverName:String = URLUtil.getServerNameWithPort(swfURL);
return protocol + "://" + serverName + "/";
}
private function handleComplete(e:Event):void{
parse(new XML(e.target.data));
preferredLocale = getDefaultLocale();
if (preferredLocale != MASTER_LOCALE) {
loadMasterLocale(MASTER_LOCALE);
}
setPreferredLocale(preferredLocale);
}
private function parse(xml:XML):void{
var list:XMLList = xml.locale;
var locale:XML;
for each(locale in list){
localeCodes.push(locale.@code);
localeNames.push(locale.@name);
}
}
private function getDefaultLocale():String {
return ExternalInterface.call("getLanguage");
}
private function isPreferredLocaleAvailable(prefLocale:String):Boolean {
for (var i:Number = 0; i < localeCodes.length; i++){
if (prefLocale == localeCodes[i])
return true;
}
return false;
}
private function getIndexForLocale(prefLocale:String):int {
for (var i:Number = 0; i < localeCodes.length; i++){
if (prefLocale == localeCodes[i])
return i;
}
return -1;
}
public function getPreferredLocaleName():String {
return localeNames[localeIndex];
}
public function setPreferredLocale(locale:String):void {
if (isPreferredLocaleAvailable(locale)) {
preferredLocale = locale;
}else{
preferredLocale = MASTER_LOCALE;
}
localeIndex = getIndexForLocale(preferredLocale);
changeLocale(preferredLocale);
}
private function loadMasterLocale(locale:String):void {
/**
* http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/resources/IResourceManager.html#localeChain
* Always load the default language, so if the chosen language
* doesn't provide a resource, the default language resource is used
*/
loadResource(locale);
}
private function loadResource(language:String):IEventDispatcher {
// Add a random string on the query so that we don't get a cached version.
var date:Date = new Date();
var localeURI:String = buildRequestURL() + 'client/locale/' + language + '_resources.swf?a=' + date.time;
return resourceManager.loadResourceModule( localeURI, false);
}
public static function getInstance():ResourceUtil {
if (instance == null) {
instance = new ResourceUtil(new SingletonEnforcer);
}
return instance;
}
public function changeLocale(locale:String):void{
eventDispatcher = loadResource(locale);
eventDispatcher.addEventListener(ResourceEvent.COMPLETE, localeChangeComplete);
eventDispatcher.addEventListener(ResourceEvent.ERROR, handleResourceNotLoaded);
}
private function localeChangeComplete(event:ResourceEvent):void {
// Set the preferred locale and master as backup.
if (preferredLocale != MASTER_LOCALE) {
resourceManager.localeChain = [preferredLocale, MASTER_LOCALE];
localeIndex = getIndexForLocale(preferredLocale);
} else {
if (preferredLocale != MASTER_LOCALE) {
var logData:Object = UsersUtil.initLogData();
logData.tags = ["locale"];
logData.message = "Failed to load locale = " + preferredLocale;
LOGGER.info(JSON.stringify(logData));
}
resourceManager.localeChain = [MASTER_LOCALE];
preferredLocale = MASTER_LOCALE;
localeIndex = getIndexForLocale(preferredLocale);
}
sendAppAndLocaleVersions();
update();
}
private function sendAppAndLocaleVersions():void {
var dispatcher:Dispatcher = new Dispatcher();
var versionEvent:AppVersionEvent = new AppVersionEvent();
versionEvent.configLocaleVersion = false;
dispatcher.dispatchEvent(versionEvent);
}
/**
* Defaults to DEFAULT_LANGUAGE when an error is thrown by the ResourceManager
* @param event
*/
private function handleResourceNotLoaded(event:ResourceEvent):void{
resourceManager.localeChain = [MASTER_LOCALE];
preferredLocale = MASTER_LOCALE;
localeIndex = getIndexForLocale(preferredLocale);
update();
}
public function update():void{
var dispatcher:Dispatcher = new Dispatcher;
dispatcher.dispatchEvent(new LocaleChangeEvent(LocaleChangeEvent.LOCALE_CHANGED));
dispatchEvent(new Event(Event.CHANGE));
}
[Bindable("change")]
public function getString(resourceName:String, parameters:Array = null, locale:String = null):String{
/**
* Get the translated string from the current locale. If empty, get the string from the master
* locale. Locale chaining isn't working because mygengo actually puts the key and empty value
* for untranslated strings into the locale file. So, when Flash does a lookup, it will see that
* the key is available in the locale and thus not bother falling back to the master locale.
* (ralam dec 15, 2011).
*/
var localeTxt:String = resourceManager.getString(BBB_RESOURCE_BUNDLE, resourceName, parameters, null);
if ((localeTxt == "") || (localeTxt == null)) {
localeTxt = resourceManager.getString(BBB_RESOURCE_BUNDLE, resourceName, parameters, MASTER_LOCALE);
}
return localeTxt;
}
public function getCurrentLanguageCode():String{
return preferredLocale;
}
public function getLocaleCodeForIndex(index:int):String {
return localeCodes[index];
}
}
}
class SingletonEnforcer{}
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.util.i18n
{
import com.asfusion.mate.events.Dispatcher;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.external.ExternalInterface;
import flash.net.URLLoader;
import flash.net.URLRequest;
import mx.core.FlexGlobals;
import mx.events.ResourceEvent;
import mx.resources.IResourceManager;
import mx.resources.ResourceManager;
import mx.utils.URLUtil;
import org.as3commons.lang.StringUtils;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.events.LocaleChangeEvent;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.main.events.AppVersionEvent;
public class ResourceUtil extends EventDispatcher {
private static const LOGGER:ILogger = getClassLogger(ResourceUtil);
public static const LOCALES_FILE:String = "client/conf/locales.xml";
public static const VERSION:String = "0.9.0";
private static var instance:ResourceUtil = null;
private var inited:Boolean = false;
private static var BBB_RESOURCE_BUNDLE:String = 'bbbResources';
private static var MASTER_LOCALE:String = "en_US";
[Bindable] public var localeCodes:Array = new Array();
[Bindable] public var localeNames:Array = new Array();
[Bindable] public var localeIndex:int;
private var eventDispatcher:IEventDispatcher;
private var resourceManager:IResourceManager;
private var preferredLocale:String
public function ResourceUtil(enforcer:SingletonEnforcer) {
if (enforcer == null) {
throw new Error( "You Can Only Have One ResourceUtil" );
}
initialize();
}
private function isInited():Boolean {
return inited;
}
public function initialize():void {
resourceManager = ResourceManager.getInstance();
// Add a random string on the query so that we always get an up-to-date config.xml
var date:Date = new Date();
var _urlLoader:URLLoader = new URLLoader();
_urlLoader.addEventListener(Event.COMPLETE, handleComplete);
var localeReqURL:String = buildRequestURL() + LOCALES_FILE + "?a=" + date.time;
_urlLoader.load(new URLRequest(localeReqURL));
}
private function buildRequestURL():String {
var swfURL:String = FlexGlobals.topLevelApplication.url;
var protocol:String = URLUtil.getProtocol(swfURL);
var serverName:String = URLUtil.getServerNameWithPort(swfURL);
return protocol + "://" + serverName + "/";
}
private function handleComplete(e:Event):void{
parse(new XML(e.target.data));
preferredLocale = getDefaultLocale();
if (preferredLocale != MASTER_LOCALE) {
loadMasterLocale(MASTER_LOCALE);
}
setPreferredLocale(preferredLocale);
}
private function parse(xml:XML):void{
var list:XMLList = xml.locale;
var locale:XML;
for each(locale in list){
localeCodes.push(locale.@code.toString());
localeNames.push(locale.@name.toString());
}
}
private function getDefaultLocale():String {
return ExternalInterface.call("getLanguage");
}
private function getIndexForLocale(prefLocale:String):int {
return localeCodes.indexOf(prefLocale);
}
public function getPreferredLocaleName():String {
return localeNames[localeIndex];
}
public function setPreferredLocale(locale:String):void {
if (localeCodes.indexOf(locale) > -1) {
preferredLocale = locale;
}else{
preferredLocale = MASTER_LOCALE;
}
localeIndex = getIndexForLocale(preferredLocale);
changeLocale(preferredLocale);
}
private function loadMasterLocale(locale:String):void {
/**
* http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/resources/IResourceManager.html#localeChain
* Always load the default language, so if the chosen language
* doesn't provide a resource, the default language resource is used
*/
loadResource(locale);
}
private function loadResource(language:String):IEventDispatcher {
// Add a random string on the query so that we don't get a cached version.
var date:Date = new Date();
var localeURI:String = buildRequestURL() + 'client/locale/' + language + '_resources.swf?a=' + date.time;
return resourceManager.loadResourceModule( localeURI, false);
}
public static function getInstance():ResourceUtil {
if (instance == null) {
instance = new ResourceUtil(new SingletonEnforcer);
}
return instance;
}
public function changeLocale(locale:String):void{
eventDispatcher = loadResource(locale);
eventDispatcher.addEventListener(ResourceEvent.COMPLETE, localeChangeComplete);
eventDispatcher.addEventListener(ResourceEvent.ERROR, handleResourceNotLoaded);
}
private function localeChangeComplete(event:ResourceEvent):void {
// Set the preferred locale and master as backup.
if (preferredLocale != MASTER_LOCALE) {
resourceManager.localeChain = [preferredLocale, MASTER_LOCALE];
} else {
if (preferredLocale != MASTER_LOCALE) {
var logData:Object = UsersUtil.initLogData();
logData.tags = ["locale"];
logData.message = "Failed to load locale = " + preferredLocale;
LOGGER.info(JSON.stringify(logData));
}
resourceManager.localeChain = [MASTER_LOCALE];
preferredLocale = MASTER_LOCALE;
}
localeIndex = getIndexForLocale(preferredLocale);
sendAppAndLocaleVersions();
update();
}
private function sendAppAndLocaleVersions():void {
var dispatcher:Dispatcher = new Dispatcher();
var versionEvent:AppVersionEvent = new AppVersionEvent();
versionEvent.configLocaleVersion = false;
dispatcher.dispatchEvent(versionEvent);
}
/**
* Defaults to DEFAULT_LANGUAGE when an error is thrown by the ResourceManager
* @param event
*/
private function handleResourceNotLoaded(event:ResourceEvent):void{
resourceManager.localeChain = [MASTER_LOCALE];
preferredLocale = MASTER_LOCALE;
localeIndex = getIndexForLocale(preferredLocale);
update();
}
public function update():void{
var dispatcher:Dispatcher = new Dispatcher;
dispatcher.dispatchEvent(new LocaleChangeEvent(LocaleChangeEvent.LOCALE_CHANGED));
dispatchEvent(new Event(Event.CHANGE));
}
[Bindable("change")]
public function getString(resourceName:String, parameters:Array = null, locale:String = null):String{
/**
* @fixme: to be reviewed when all locales from transifex are updated (gtriki feb 7, 2017)
* Get the translated string from the current locale. If empty, get the string from the master
* locale. Locale chaining isn't working because mygengo actually puts the key and empty value
* for untranslated strings into the locale file. So, when Flash does a lookup, it will see that
* the key is available in the locale and thus not bother falling back to the master locale.
* (ralam dec 15, 2011).
*/
var localeTxt:String = resourceManager.getString(BBB_RESOURCE_BUNDLE, resourceName, parameters, null);
if (StringUtils.isEmpty(localeTxt)) {
localeTxt = resourceManager.getString(BBB_RESOURCE_BUNDLE, resourceName, parameters, MASTER_LOCALE);
}
return localeTxt;
}
public function getCurrentLanguageCode():String{
return preferredLocale;
}
public function getLocaleCodeForIndex(index:int):String {
return localeCodes[index];
}
}
}
class SingletonEnforcer{}

View File

@ -638,10 +638,10 @@ while [ $# -gt 0 ]; do
if [ "$1" = "--lti" -o "$1" = "-lti" ]; then
if [ -z "$SALT" ]; then
if [ -f ${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties ]; then
LTI_URL='http://'$(cat ${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties | grep -v '#' | sed -n '/^ltiEndPoint/{s/^.*=//;p}')'/lti/tool'
CUSTOMER=$(cat ${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties | grep -v '#' | sed -n '/^ltiConsumer/{s/^.*=//;s/:.*//p}')
SECRET=$(cat ${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties | grep -v '#' | sed -n '/^ltiConsumer/{s/^[^:]*://;p}')
if [ -f ${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties ]; then
LTI_URL='http://'$(cat ${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties | grep -v '#' | sed -n '/^ltiEndPoint/{s/^.*=//;p}')'/lti/tool'
CUSTOMER=$(cat ${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties | grep -v '#' | sed -n '/^ltiConsumer/{s/^.*=//;s/:.*//p}')
SECRET=$(cat ${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties | grep -v '#' | sed -n '/^ltiConsumer/{s/^[^:]*://;p}')
echo
echo " URL: $LTI_URL"
echo " Customer: $CUSTOMER"
@ -889,13 +889,13 @@ check_configuration() {
fi
fi
if [ -f ${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties ]; then
LTI_SALT=$(cat ${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties | grep -v '#' | tr -d '\r' | sed -n '/^bigbluebuttonSalt/{s/.*=//;p}')
if [ -f ${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties ]; then
LTI_SALT=$(cat ${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties | grep -v '#' | tr -d '\r' | sed -n '/^bigbluebuttonSalt/{s/.*=//;p}')
BBB_SALT=$(cat ${SERVLET_DIR}/bigbluebutton/WEB-INF/classes/bigbluebutton.properties | grep -v '#' | tr -d '\r' | sed -n '/securitySalt/{s/.*=//;p}')
if [ "$LTI_SALT" != "$BBB_SALT" ]; then
echo "# Warning: LTI shared secret (salt) mismatch:"
echo "# ${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties = $LTI_SALT"
echo "# ${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties = $LTI_SALT"
echo "# ${SERVLET_DIR}/bigbluebutton/WEB-INF/classes/bigbluebutton.properties = $BBB_SALT"
echo
fi
@ -1395,8 +1395,8 @@ check_state() {
fi
if [ -f ${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties ]; then
LTI_URL='http://'$(cat ${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties | grep -v '#' | sed -n '/^ltiEndPoint/{s/^.*=//;p}')'/lti/tool'
if [ -f ${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties ]; then
LTI_URL='http://'$(cat ${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties | grep -v '#' | sed -n '/^ltiEndPoint/{s/^.*=//;p}')'/lti/tool'
echo "# Warning: The IMS Learning Tools Integration (LTI) is accessible from:"
echo "#"
echo "# $LTI_URL"
@ -1542,10 +1542,10 @@ if [ $CHECK ]; then
echo " url: $BBB_WEB_URL"
fi
if [ -f ${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties ]; then
LTI_URL=$(cat ${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties | grep -v '#' | sed -n '/^bigbluebuttonURL/{s/.*http[s]:\/\///;s/\/.*//;p}' | tr -d '\015')
if [ -f ${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties ]; then
LTI_URL=$(cat ${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties | grep -v '#' | sed -n '/^bigbluebuttonURL/{s/.*http[s]:\/\///;s/\/.*//;p}' | tr -d '\015')
echo
echo "${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties (LTI integration)"
echo "${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties (LTI integration)"
echo " api url: $LTI_URL"
fi
@ -1791,15 +1791,15 @@ if [ -n "$HOST" ]; then
fi
if [ -f ${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties ]; then
echo "Assigning $HOST for LTI integration in ${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties"
if [ -f ${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties ]; then
echo "Assigning $HOST for LTI integration in ${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties"
# We don't wat to guess on http/https as the lti endpoint may be a different BigBlueButton server
sed -i "s/bigbluebuttonURL=http:\/\/.*/bigbluebuttonURL=http:\/\/$HOST\/bigbluebutton/g" \
${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties
${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties
sed -i "s/bigbluebuttonURL=https:\/\/.*/bigbluebuttonURL=https:\/\/$HOST\/bigbluebutton/g" \
${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties
${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties
sed -i "s/ltiEndPoint=.*/ltiEndPoint=$HOST/g" \
${SERVLET_DIR}/lti/WEB-INF/classes/lti.properties
${SERVLET_DIR}/lti/WEB-INF/classes/lti-config.properties
fi

View File

@ -38,7 +38,7 @@ find /var/bigbluebutton/ -maxdepth 1 -type d -name "*-*" -mtime +$history -exec
find /usr/share/red5/webapps/video/streams/ -name "*.flv" -mtime +$history -exec rm '{}' +
find /usr/share/red5/webapps/video/streams/ -name "*.flv.ser" -mtime +$history -exec rm '{}' +
find /usr/share/red5/webapps/video/streams/ -name "*.flv.info" -mtime +$history -exec rm '{}' +
find /usr/share/red5/webapps/video/streams/ -name "*.flv.meta" -mtime +$history -exec rm '{}' +
find /usr/share/red5/webapps/video/streams/ -name "*.meta" -mtime +$history -exec rm '{}' +
find /usr/share/red5/webapps/video/streams/ -type d -empty -mtime +$history -exec rmdir '{}' +
#

View File

@ -2,7 +2,7 @@ import { check } from 'meteor/check';
import Logger from '/imports/startup/server/logger';
import Meetings from '/imports/api/meetings';
import { Meteor } from 'meteor/meteor';
import handleLockingMic from '/imports/api/users/server/modifiers/handleLockingMic';
import lockAllViewersMic from '/imports/api/users/server/modifiers/lockAllViewersMic';
export default function handlePermissionSettingsChange({ payload }) {
const meetingId = payload.meeting_id;
@ -41,7 +41,7 @@ export default function handlePermissionSettingsChange({ payload }) {
}
if (permissions.disableMic) {
handleLockingMic(meetingId, permissions);
lockAllViewersMic(meetingId);
}
if (numChanged) {

View File

@ -2,7 +2,7 @@ import Meetings from '/imports/api/chat';
import Logger from '/imports/startup/server/logger';
import removeMeeting from './removeMeeting';
import { clearUsersCollection } from '/imports/api/users/server/modifiers/clearUsersCollection';
import clearUsers from '/imports/api/users/server/modifiers/clearUsers';
import clearChats from '/imports/api/chat/server/modifiers/clearChats';
import clearBreakouts from '/imports/api/breakouts/server/modifiers/clearBreakouts';
import clearShapes from '/imports/api/shapes/server/modifiers/clearShapes';
@ -22,7 +22,7 @@ export default function clearMeetings() {
clearPolls();
clearShapes();
clearSlides();
clearUsersCollection();
clearUsers();
return Logger.info('Cleared Meetings (all)');
});

View File

@ -2,7 +2,7 @@ import { check } from 'meteor/check';
import Meetings from '/imports/api/meetings';
import Logger from '/imports/startup/server/logger';
import { clearUsersCollection } from '/imports/api/users/server/modifiers/clearUsersCollection';
import clearUsers from '/imports/api/users/server/modifiers/clearUsers';
import clearChats from '/imports/api/chat/server/modifiers/clearChats';
import clearShapes from '/imports/api/shapes/server/modifiers/clearShapes';
import clearSlides from '/imports/api/slides/server/modifiers/clearSlides';
@ -31,7 +31,7 @@ export default function removeMeeting(meetingId) {
clearPolls(meetingId);
clearShapes(meetingId);
clearSlides(meetingId);
clearUsersCollection(meetingId);
clearUsers(meetingId);
return Logger.info(`Removed meeting id=${meetingId}`);
}

View File

@ -1,3 +1,4 @@
// TODO: This file should be a `service.js` somewhere in the /ui folder
import Users from '/imports/api/users';
import Meetings from '/imports/api/meetings';
import Auth from '/imports/ui/services/auth';

View File

@ -1,21 +0,0 @@
import { publish } from '/imports/api/common/server/helpers';
import { isAllowedTo } from '/imports/startup/server/userPermissions';
import { appendMessageHeader } from '/imports/api/common/server/helpers';
import { logger } from '/imports/startup/server/logger';
import Meetings from '/imports/api/meetings';
export default function getStun(credentials) {
const REDIS_CONFIG = Meteor.settings.redis;
const { meetingId, requesterUserId } = credentials;
const eventName = 'send_stun_turn_info_request_message';
let message = {
payload: {
meeting_id: meetingId,
requester_id: requesterUserId,
},
};
message = appendMessageHeader(eventName, message);
return publish(REDIS_CONFIG.channels.fromBBBUsers, message);
};

View File

@ -1,41 +0,0 @@
import { eventEmitter } from '/imports/startup/server';
import { updateVoiceUser } from '/imports/api/users/server/modifiers/updateVoiceUser';
eventEmitter.on('user_left_voice_message', function (arg) {
handleVoiceEvent(arg);
});
eventEmitter.on('user_joined_voice_message', function (arg) {
handleVoiceEvent(arg);
});
eventEmitter.on('user_voice_talking_message', function (arg) {
handleVoiceEvent(arg);
});
eventEmitter.on('user_voice_muted_message', function (arg) {
handleVoiceEvent(arg);
});
eventEmitter.on('user_listening_only', function (arg) {
const voiceUserObj = {
web_userid: arg.payload.userid,
listen_only: arg.payload.listen_only,
};
const meetingId = arg.payload.meeting_id;
return updateVoiceUser(meetingId, voiceUserObj, arg.callback);
});
const handleVoiceEvent = function (arg) {
const meetingId = arg.payload.meeting_id;
const voiceUser = arg.payload.user.voiceUser;
const voiceUserObj = {
web_userid: voiceUser.web_userid,
listen_only: arg.payload.listen_only,
talking: voiceUser.talking,
joined: voiceUser.joined,
locked: voiceUser.locked,
muted: voiceUser.muted,
};
return updateVoiceUser(meetingId, voiceUserObj, arg.callback);
};

View File

@ -1,8 +1,10 @@
import Logger from '/imports/startup/server/logger';
import { check } from 'meteor/check';
import { inReplyToHTML5Client } from '/imports/api/common/server/helpers';
import Presentations from '/imports/api/presentations';
import addPresentation from '../modifiers/addPresentation';
import removePresentation from '../modifiers/removePresentation';
export default function handlePresentationInfoReply({ payload }) {
if (!inReplyToHTML5Client({ payload })) {
@ -15,6 +17,14 @@ export default function handlePresentationInfoReply({ payload }) {
check(meetingId, String);
check(presentations, Array);
const presentationsIds = presentations.map(_ => _.id);
const presentationsToRemove = Presentations.find({
meetingId,
'presentation.id': { $nin: presentationsIds },
}).fetch();
presentationsToRemove.forEach(p => removePresentation(meetingId, p.presentation.id));
let presentationsAdded = [];
presentations.forEach(presentation => {
presentationsAdded.push(addPresentation(meetingId, presentation));

View File

@ -1,8 +1,10 @@
import Logger from '/imports/startup/server/logger';
import { check } from 'meteor/check';
import { inReplyToHTML5Client } from '/imports/api/common/server/helpers';
import Shapes from '/imports/api/shapes';
import addShape from '../modifiers/addShape';
import removeShape from '../modifiers/removeShape';
export default function handleWhiteboardGetReply({ payload }) {
if (!inReplyToHTML5Client({ payload })) {
@ -15,6 +17,14 @@ export default function handleWhiteboardGetReply({ payload }) {
check(meetingId, String);
check(shapes, Array);
const shapesIds = shapes.map(_ => _.id);
const shapesToRemove = Shapes.find({
meetingId,
'shape.id': { $nin: shapesIds },
}).fetch();
shapesToRemove.forEach(s => removeShape(meetingId, s.shape.wb_id, s.shape.id));
let shapesAdded = [];
shapes.forEach(shape => {
let whiteboardId = shape.wb_id;

View File

@ -65,8 +65,9 @@ export default function addSlide(meetingId, presentationId, slide) {
const { insertedId } = numChanged;
requestWhiteboardHistory(meetingId, slide.id);
if (insertedId) {
requestWhiteboardHistory(meetingId, slide.id);
return Logger.info(`Added slide id=${slide.id} to presentation=${presentationId}`);
}

View File

@ -0,0 +1,26 @@
import RedisPubSub from '/imports/startup/server/redis';
import handleGetUsers from './handlers/getUsers';
import handleRemoveUser from './handlers/removeUser';
import handlePresenterAssigned from './handlers/presenterAssigned';
import handleEmojiStatus from './handlers/emojiStatus';
import handleLockedStatusChange from './handlers/lockedStatusChange';
import handleUserJoined from './handlers/userJoined';
import handleValidateAuthToken from './handlers/validateAuthToken';
import handleVoiceUpdate from './handlers/voiceUpdate';
import handleListeningOnly from './handlers/listeningOnly';
RedisPubSub.on('validate_auth_token_reply', handleValidateAuthToken);
RedisPubSub.on('get_users_reply', handleGetUsers);
RedisPubSub.on('user_joined_message', handleUserJoined);
RedisPubSub.on('user_eject_from_meeting', handleRemoveUser);
RedisPubSub.on('disconnect_user_message', handleRemoveUser);
RedisPubSub.on('user_left_message', handleRemoveUser);
RedisPubSub.on('presenter_assigned_message', handlePresenterAssigned);
RedisPubSub.on('user_emoji_status_message', handleEmojiStatus);
RedisPubSub.on('user_locked_message', handleLockedStatusChange);
RedisPubSub.on('user_unlocked_message', handleLockedStatusChange);
RedisPubSub.on('user_left_voice_message', handleVoiceUpdate);
RedisPubSub.on('user_joined_voice_message', handleVoiceUpdate);
RedisPubSub.on('user_voice_talking_message', handleVoiceUpdate);
RedisPubSub.on('user_voice_muted_message', handleVoiceUpdate);
RedisPubSub.on('user_listening_only', handleListeningOnly);

View File

@ -0,0 +1,37 @@
import Logger from '/imports/startup/server/logger';
import { check } from 'meteor/check';
import Users from '/imports/api/users';
export default function handleEmojiStatus({ payload }) {
const meetingId = payload.meeting_id;
const userId = payload.userid;
const status = payload.emoji_status;
check(meetingId, String);
check(userId, String);
check(status, String);
const selector = {
meetingId,
userId,
};
const modifier = {
$set: {
'user.set_emoji_time': (new Date()).getTime(),
'user.emoji_status': status,
},
};
const cb = (err, numChanged) => {
if (err) {
return Logger.error(`Assigning user emoji status: ${err}`);
}
if (numChanged) {
return Logger.info(`Assigned user emoji status '${status}' id=${userId} meeting=${meetingId}`);
}
};
return Users.update(selector, modifier, cb);
};

View File

@ -0,0 +1,35 @@
import { check } from 'meteor/check';
import { inReplyToHTML5Client } from '/imports/api/common/server/helpers';
import Logger from '/imports/startup/server/logger';
import Users from '/imports/api/users';
import addUser from '../modifiers/addUser';
import removeUser from '../modifiers/removeUser';
export default function handleGetUsers({ payload }) {
if (!inReplyToHTML5Client({ payload })) {
return;
}
const meetingId = payload.meeting_id;
const users = payload.users;
check(meetingId, String);
check(users, Array);
const usersIds = users.map(m => m.userid);
const usersToRemove = Users.find({
meetingId,
userId: { $nin: usersIds },
}).fetch();
usersToRemove.forEach(user => removeUser(meetingId, user.userId));
let usersAdded = [];
users.forEach(user => {
usersAdded.push(addUser(meetingId, user));
});
return usersAdded;
};

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