Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
galene
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
galene
Commits
b077ae78
Commit
b077ae78
authored
Jan 05, 2025
by
Juliusz Chroboczek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add some documentation to galene.js.
parent
b537a929
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
122 additions
and
20 deletions
+122
-20
static/galene.js
static/galene.js
+122
-20
No files found.
static/galene.js
View file @
b077ae78
...
@@ -20,26 +20,52 @@
...
@@ -20,26 +20,52 @@
'
use strict
'
;
'
use strict
'
;
/** @type {string} */
/**
* The name of the group that we join.
*
* @type {string}
*/
let
group
;
let
group
;
/** @type {ServerConnection} */
/**
* The connection to the server.
*
* @type {ServerConnection}
*/
let
serverConnection
;
let
serverConnection
;
/** @type {Object} */
/**
* The group status. This is set twice, once over HTTP in the start
* function in order to obtain the WebSocket address, and a second time
* after joining.
*
* @type {Object}
*/
let
groupStatus
=
{};
let
groupStatus
=
{};
/** @type {boolean} */
/**
* True if we need to request a password.
*
* type {boolean}
*/
let
pwAuth
=
false
;
let
pwAuth
=
false
;
/** @type {string} */
/**
* The token we use to login. This is erased as soon as possible.
*
* @type {string}
*/
let
token
=
null
;
let
token
=
null
;
/** @type {string} */
/**
* The state of the login automaton.
*
* @type {"probing" | "need-username" | "success"}
*/
let
probingState
=
null
;
let
probingState
=
null
;
/**
/**
* @typedef {Object} settings
* @typedef {Object} settings
- the type of stored settings
* @property {boolean} [localMute]
* @property {boolean} [localMute]
* @property {string} [video]
* @property {string} [video]
* @property {string} [audio]
* @property {string} [audio]
...
@@ -57,10 +83,18 @@ let probingState = null;
...
@@ -57,10 +83,18 @@ let probingState = null;
* @property {boolean} [forceRelay]
* @property {boolean} [forceRelay]
*/
*/
/** @type{settings} */
/**
* fallbackSettings is used to store settings if session storage is not
* available.
*
* @type{settings}
*/
let
fallbackSettings
=
null
;
let
fallbackSettings
=
null
;
/**
/**
* Overwrite settings with the parameter. This uses session storage if
* available, and the global variable fallbackSettings otherwise.
*
* @param {settings} settings
* @param {settings} settings
*/
*/
function
storeSettings
(
settings
)
{
function
storeSettings
(
settings
)
{
...
@@ -74,7 +108,8 @@ function storeSettings(settings) {
...
@@ -74,7 +108,8 @@ function storeSettings(settings) {
}
}
/**
/**
* This always returns a dictionary.
* Return the current value of stored settings. This always returns
* a dictionary, even when there are no stored settings.
*
*
* @returns {settings}
* @returns {settings}
*/
*/
...
@@ -92,6 +127,8 @@ function getSettings() {
...
@@ -92,6 +127,8 @@ function getSettings() {
}
}
/**
/**
* Update stored settings with the key/value pairs stored in the parameter.
*
* @param {settings} settings
* @param {settings} settings
*/
*/
function
updateSettings
(
settings
)
{
function
updateSettings
(
settings
)
{
...
@@ -102,6 +139,8 @@ function updateSettings(settings) {
...
@@ -102,6 +139,8 @@ function updateSettings(settings) {
}
}
/**
/**
* Update a single key/value pair in the stored settings.
*
* @param {string} key
* @param {string} key
* @param {any} value
* @param {any} value
*/
*/
...
@@ -112,6 +151,8 @@ function updateSetting(key, value) {
...
@@ -112,6 +151,8 @@ function updateSetting(key, value) {
}
}
/**
/**
* Remove a single key/value pair from the stored settings.
*
* @param {string} key
* @param {string} key
*/
*/
function
delSetting
(
key
)
{
function
delSetting
(
key
)
{
...
@@ -123,6 +164,8 @@ function delSetting(key) {
...
@@ -123,6 +164,8 @@ function delSetting(key) {
}
}
/**
/**
* getElementById, then assert that the result is an HTMLSelectElement.
*
* @param {string} id
* @param {string} id
*/
*/
function
getSelectElement
(
id
)
{
function
getSelectElement
(
id
)
{
...
@@ -133,6 +176,8 @@ function getSelectElement(id) {
...
@@ -133,6 +176,8 @@ function getSelectElement(id) {
}
}
/**
/**
* getElementById, then assert that the result is an HTMLInputElement.
*
* @param {string} id
* @param {string} id
*/
*/
function
getInputElement
(
id
)
{
function
getInputElement
(
id
)
{
...
@@ -143,6 +188,8 @@ function getInputElement(id) {
...
@@ -143,6 +188,8 @@ function getInputElement(id) {
}
}
/**
/**
* getElementById, then assert that the result is an HTMLButtonElement.
*
* @param {string} id
* @param {string} id
*/
*/
function
getButtonElement
(
id
)
{
function
getButtonElement
(
id
)
{
...
@@ -152,6 +199,9 @@ function getButtonElement(id) {
...
@@ -152,6 +199,9 @@ function getButtonElement(id) {
return
elt
;
return
elt
;
}
}
/**
* Ensure that the UI reflects the stored settings.
*/
function
reflectSettings
()
{
function
reflectSettings
()
{
let
settings
=
getSettings
();
let
settings
=
getSettings
();
let
store
=
false
;
let
store
=
false
;
...
@@ -251,13 +301,18 @@ function reflectSettings() {
...
@@ -251,13 +301,18 @@ function reflectSettings() {
storeSettings
(
settings
);
storeSettings
(
settings
);
}
}
/**
* Returns true if we should use the mobile layout. This should be kept
* in sync with the CSS.
*/
function
isMobileLayout
()
{
function
isMobileLayout
()
{
if
(
window
.
matchMedia
(
'
only screen and (max-width: 1024px)
'
).
matches
)
return
!!
window
.
matchMedia
(
'
only screen and (max-width: 1024px)
'
).
matches
return
true
;
return
false
;
}
}
/**
/**
* Conditionally hide the video pane. If force is true, hide it even if
* there are videos.
*
* @param {boolean} [force]
* @param {boolean} [force]
*/
*/
function
hideVideo
(
force
)
{
function
hideVideo
(
force
)
{
...
@@ -268,6 +323,9 @@ function hideVideo(force) {
...
@@ -268,6 +323,9 @@ function hideVideo(force) {
scheduleReconsiderDownRate
();
scheduleReconsiderDownRate
();
}
}
/**
* Show the video pane.
*/
function
showVideo
()
{
function
showVideo
()
{
let
hasmedia
=
document
.
getElementById
(
'
peers
'
).
childElementCount
>
0
;
let
hasmedia
=
document
.
getElementById
(
'
peers
'
).
childElementCount
>
0
;
if
(
isMobileLayout
())
{
if
(
isMobileLayout
())
{
...
@@ -278,20 +336,33 @@ function showVideo() {
...
@@ -278,20 +336,33 @@ function showVideo() {
scheduleReconsiderDownRate
();
scheduleReconsiderDownRate
();
}
}
/**
* Returns true if we are running on Safari.
*/
function
isSafari
()
{
function
isSafari
()
{
let
ua
=
navigator
.
userAgent
.
toLowerCase
();
let
ua
=
navigator
.
userAgent
.
toLowerCase
();
return
ua
.
indexOf
(
'
safari
'
)
>=
0
&&
ua
.
indexOf
(
'
chrome
'
)
<
0
;
return
ua
.
indexOf
(
'
safari
'
)
>=
0
&&
ua
.
indexOf
(
'
chrome
'
)
<
0
;
}
}
/**
* Returns true if we are running on Firefox.
*/
function
isFirefox
()
{
function
isFirefox
()
{
let
ua
=
navigator
.
userAgent
.
toLowerCase
();
let
ua
=
navigator
.
userAgent
.
toLowerCase
();
return
ua
.
indexOf
(
'
firefox
'
)
>=
0
;
return
ua
.
indexOf
(
'
firefox
'
)
>=
0
;
}
}
/** @type {MediaStream} */
/**
* Under Safari, we request access to the camera at startup in order to
* enable autoplay. The camera stream is stored in safariStream.
*
* @type {MediaStream}
*/
let
safariStream
=
null
;
let
safariStream
=
null
;
/**
/**
* setConnected is called whenever we connect or disconnect to the server.
*
* @param{boolean} connected
* @param{boolean} connected
*/
*/
function
setConnected
(
connected
)
{
function
setConnected
(
connected
)
{
...
@@ -323,6 +394,8 @@ function setConnected(connected) {
...
@@ -323,6 +394,8 @@ function setConnected(connected) {
}
}
/**
/**
* Called when we connect to the server.
*
* @this {ServerConnection}
* @this {ServerConnection}
*/
*/
async
function
gotConnected
()
{
async
function
gotConnected
()
{
...
@@ -331,6 +404,8 @@ async function gotConnected() {
...
@@ -331,6 +404,8 @@ async function gotConnected() {
}
}
/**
/**
* Sets the href field of the "change password" link.
*
* @param {string} username
* @param {string} username
*/
*/
function
setChangePassword
(
username
)
{
function
setChangePassword
(
username
)
{
...
@@ -348,6 +423,9 @@ function setChangePassword(username) {
...
@@ -348,6 +423,9 @@ function setChangePassword(username) {
}
}
}
}
/**
* Join a group.
*/
async
function
join
()
{
async
function
join
()
{
let
username
=
getInputElement
(
'
username
'
).
value
.
trim
();
let
username
=
getInputElement
(
'
username
'
).
value
.
trim
();
let
credentials
;
let
credentials
;
...
@@ -516,6 +594,9 @@ function setVisibility(id, visible) {
...
@@ -516,6 +594,9 @@ function setVisibility(id, visible) {
elt
.
classList
.
add
(
'
invisible
'
);
elt
.
classList
.
add
(
'
invisible
'
);
}
}
/**
* Shows and hides various UI elements depending on the protocol state.
*/
function
setButtonsVisibility
()
{
function
setButtonsVisibility
()
{
let
connected
=
serverConnection
&&
serverConnection
.
socket
;
let
connected
=
serverConnection
&&
serverConnection
.
socket
;
let
permissions
=
serverConnection
.
permissions
;
let
permissions
=
serverConnection
.
permissions
;
...
@@ -549,6 +630,8 @@ function setButtonsVisibility() {
...
@@ -549,6 +630,8 @@ function setButtonsVisibility() {
}
}
/**
/**
* Sets the local mute state. If reflect is true, updates the stored settings.
*
* @param {boolean} mute
* @param {boolean} mute
* @param {boolean} [reflect]
* @param {boolean} [reflect]
*/
*/
...
@@ -649,7 +732,11 @@ getSelectElement('filterselect').onchange = async function(e) {
...
@@ -649,7 +732,11 @@ getSelectElement('filterselect').onchange = async function(e) {
}
}
};
};
/** @returns {number} */
/**
* Returns the desired max video throughput depending on the settings.
*
* @returns {number}
*/
function
getMaxVideoThroughput
()
{
function
getMaxVideoThroughput
()
{
let
v
=
getSettings
().
send
;
let
v
=
getSettings
().
send
;
switch
(
v
)
{
switch
(
v
)
{
...
@@ -682,6 +769,8 @@ getSelectElement('simulcastselect').onchange = async function(e) {
...
@@ -682,6 +769,8 @@ getSelectElement('simulcastselect').onchange = async function(e) {
};
};
/**
/**
* Maps the state of the receive UI element to a protocol request.
*
* @param {string} what
* @param {string} what
* @returns {Object<string,Array<string>>}
* @returns {Object<string,Array<string>>}
*/
*/
...
@@ -709,6 +798,8 @@ function mapRequest(what) {
...
@@ -709,6 +798,8 @@ function mapRequest(what) {
}
}
/**
/**
* Like mapRequest, but for a single label.
*
* @param {string} what
* @param {string} what
* @param {string} label
* @param {string} label
* @returns {Array<string>}
* @returns {Array<string>}
...
@@ -836,6 +927,8 @@ function gotDownStats(stats) {
...
@@ -836,6 +927,8 @@ function gotDownStats(stats) {
}
}
/**
/**
* Add an option to an HTMLSelectElement.
*
* @param {HTMLSelectElement} select
* @param {HTMLSelectElement} select
* @param {string} label
* @param {string} label
* @param {string} [value]
* @param {string} [value]
...
@@ -864,6 +957,8 @@ function addSelectOption(select, label, value) {
...
@@ -864,6 +957,8 @@ function addSelectOption(select, label, value) {
}
}
/**
/**
* Returns true if an HTMLSelectElement has an option with a given value.
*
* @param {HTMLSelectElement} select
* @param {HTMLSelectElement} select
* @param {string} value
* @param {string} value
*/
*/
...
@@ -900,13 +995,20 @@ function selectOptionDefault(select) {
...
@@ -900,13 +995,20 @@ function selectOptionDefault(select) {
return
''
;
return
''
;
}
}
/* media names might not be available before we call getDisplayMedia. So
/**
we call this twice, the second time to update the menu with user-readable
* True if we already went through setMediaChoices twice.
labels. */
*
/** @type {boolean} */
* @type {boolean}
*/
let
mediaChoicesDone
=
false
;
let
mediaChoicesDone
=
false
;
/**
/**
* Populate the media choices menu.
*
* Since media names might not be available before we call
* getDisplayMedia, we call this function twice, the second time in order
* to update the menu with user-readable labels.
*
* @param{boolean} done
* @param{boolean} done
*/
*/
async
function
setMediaChoices
(
done
)
{
async
function
setMediaChoices
(
done
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment