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
84948418
Commit
84948418
authored
Jan 16, 2023
by
Alain Takoudjou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add initial push to talk version
parent
6669a93a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1031 additions
and
804 deletions
+1031
-804
static/audio/button-124476.mp3
static/audio/button-124476.mp3
+0
-0
static/galene.css
static/galene.css
+823
-757
static/galene.html
static/galene.html
+35
-19
static/galene.js
static/galene.js
+173
-28
No files found.
static/audio/button-124476.mp3
0 → 100644
View file @
84948418
File added
static/galene.css
View file @
84948418
.nav-fixed
.topnav
{
.nav-fixed
.topnav
{
z-index
:
1039
;
z-index
:
1039
;
}
}
.fixed-top
{
.fixed-top
{
position
:
fixed
;
position
:
fixed
;
top
:
0
;
top
:
0
;
right
:
0
;
right
:
0
;
left
:
0
;
left
:
0
;
z-index
:
1030
;
z-index
:
1030
;
}
}
.topnav
{
.topnav
{
padding-left
:
0
;
padding-left
:
0
;
height
:
3
.5rem
;
height
:
2
.5rem
;
z-index
:
1039
;
z-index
:
1039
;
}
}
.navbar
.form-control
,
.topnav
{
.navbar
.form-control
,
.topnav
{
font-size
:
1rem
;
font-size
:
1rem
;
}
}
.form-control
{
.form-control
{
display
:
block
;
display
:
block
;
padding
:
.375rem
.75rem
;
padding
:
.375rem
.75rem
;
font-size
:
1rem
;
font-size
:
1rem
;
line-height
:
1.5
;
line-height
:
1.5
;
color
:
#495057
;
color
:
#495057
;
background-color
:
#fff
;
background-color
:
#fff
;
background-clip
:
padding-box
;
background-clip
:
padding-box
;
border
:
1px
solid
#ced4da
;
border
:
1px
solid
#ced4da
;
border-radius
:
.25rem
;
border-radius
:
.25rem
;
transition
:
border-color
.15s
ease-in-out
,
box-shadow
.15s
ease-in-out
;
transition
:
border-color
.15s
ease-in-out
,
box-shadow
.15s
ease-in-out
;
}
}
.form-control-inline
{
.form-control-inline
{
display
:
inline-block
;
display
:
inline-block
;
}
}
.shadow
{
.shadow
{
box-shadow
:
0
.15rem
1.75rem
0
rgba
(
31
,
45
,
65
,
.15
);
box-shadow
:
0
.15rem
1.75rem
0
rgba
(
31
,
45
,
65
,
.15
);
}
}
.bg-white
{
.bg-white
{
background-color
:
#fff
;
background-color
:
#fff
;
}
}
.bg-gray
{
.bg-gray
{
background-color
:
#eee
;
background-color
:
#eee
;
}
}
.profile
{
.profile
{
width
:
230px
;
width
:
230px
;
}
}
.profile-logo
{
.profile-logo
{
float
:
left
;
float
:
left
;
width
:
50px
;
width
:
50px
;
height
:
50px
;
height
:
50px
;
background
:
#b681c3
;
background
:
#b681c3
;
border-radius
:
25px
;
border-radius
:
25px
;
text-align
:
center
;
text-align
:
center
;
vertical-align
:
middle
;
vertical-align
:
middle
;
font-size
:
1.4em
;
font-size
:
1.4em
;
padding
:
7px
;
padding
:
7px
;
color
:
#f9f9f9
;
color
:
#f9f9f9
;
}
}
.profile-info
{
.profile-info
{
float
:
left
;
float
:
left
;
margin-left
:
10px
;
margin-left
:
10px
;
margin-top
:
8px
;
margin-top
:
8px
;
color
:
#616263
;
color
:
#616263
;
width
:
120px
;
width
:
120px
;
}
}
.user-logout
{
.user-logout
{
float
:
right
;
float
:
right
;
text-align
:
center
;
text-align
:
center
;
}
}
.logout-icon
{
.logout-icon
{
display
:
block
;
display
:
block
;
font-size
:
1.5em
;
font-size
:
1.5em
;
}
}
.logout-text
{
.logout-text
{
font-size
:
.7em
;
font-size
:
.7em
;
}
}
.profile-info
span
{
.profile-info
span
{
display
:
block
;
display
:
block
;
line-height
:
1.2
;
line-height
:
1.2
;
text-transform
:
capitalize
;
text-transform
:
capitalize
;
}
}
#permspan
{
#permspan
{
font-size
:
.9em
;
font-size
:
.9em
;
color
:
#108e07
;
color
:
#108e07
;
font-style
:
italic
;
font-style
:
italic
;
}
}
.sidenav
.user-logout
a
{
.sidenav
.user-logout
a
{
font-size
:
1em
;
font-size
:
1em
;
padding
:
7px
0
0
;
padding
:
7px
0
0
;
color
:
#e4157e
;
color
:
#e4157e
;
cursor
:
pointer
;
cursor
:
pointer
;
line-height
:
.7
;
line-height
:
.7
;
}
}
.sidenav
.user-logout
a
:hover
{
.sidenav
.user-logout
a
:hover
{
color
:
#ab0659
;
color
:
#ab0659
;
}
}
.navbar
,
.navbar
.container
,
.navbar
.container-fluid
,
.navbar
.container-lg
,
.navbar
.container-md
,
.navbar
.container-sm
,
.navbar
.container-xl
{
.navbar
,
.navbar
.container
,
.navbar
.container-fluid
,
.navbar
.container-lg
,
.navbar
.container-md
,
.navbar
.container-sm
,
.navbar
.container-xl
{
display
:
-webkit-box
;
display
:
-webkit-box
;
display
:
flex
;
display
:
flex
;
flex-wrap
:
wrap
;
flex-wrap
:
wrap
;
-webkit-box-align
:
center
;
-webkit-box-align
:
center
;
align-items
:
center
;
align-items
:
center
;
-webkit-box-pack
:
justify
;
-webkit-box-pack
:
justify
;
justify-content
:
space-between
;
justify-content
:
space-between
;
background
:
#610a86
;
background
:
#610a86
;
}
}
.navbar
{
.navbar
{
position
:
relative
;
position
:
relative
;
padding
:
.1rem
;
padding
:
.1rem
;
}
}
.topnav
.navbar-brand
{
.topnav
.navbar-brand
{
width
:
15rem
;
width
:
15rem
;
padding-left
:
1rem
;
padding-left
:
1rem
;
padding-right
:
1rem
;
padding-right
:
1rem
;
margin
:
0
;
margin
:
0
;
font-size
:
1rem
;
font-size
:
1rem
;
font-weight
:
700
;
font-weight
:
700
;
}
}
.btn
{
.btn
{
display
:
inline-block
;
display
:
inline-block
;
font-weight
:
400
;
font-weight
:
400
;
font-size
:
1em
;
font-size
:
1em
;
text-align
:
center
;
text-align
:
center
;
white-space
:
nowrap
;
white-space
:
nowrap
;
vertical-align
:
middle
;
vertical-align
:
middle
;
-webkit-user-select
:
none
;
-webkit-user-select
:
none
;
-moz-user-select
:
none
;
-moz-user-select
:
none
;
-ms-user-select
:
none
;
-ms-user-select
:
none
;
user-select
:
none
;
user-select
:
none
;
border
:
1px
solid
transparent
;
border
:
1px
solid
transparent
;
padding
:
0.255rem
.75rem
;
padding
:
0.255rem
.75rem
;
line-height
:
1.5
;
line-height
:
1.5
;
border-radius
:
.25rem
;
border-radius
:
.25rem
;
transition
:
color
.15s
ease-in-out
,
background-color
.15s
ease-in-out
,
border-color
.15s
ease-in-out
,
box-shadow
.15s
ease-in-out
;
transition
:
color
.15s
ease-in-out
,
background-color
.15s
ease-in-out
,
border-color
.15s
ease-in-out
,
box-shadow
.15s
ease-in-out
;
}
.btn-big
,
.btn-big
:focus
{
font-size
:
2.5em
;
padding
:
1rem
2rem
;
border-radius
:
3rem
;
user-select
:
none
;
box-shadow
:
rgba
(
50
,
50
,
93
,
0.25
)
0px
6px
12px
-2px
,
rgba
(
0
,
0
,
0
,
0.3
)
0px
3px
7px
-3px
;
}
.btn-big
:active
{
transition-duration
:
0.8s
;
box-shadow
:
rgba
(
50
,
50
,
93
,
0.25
)
0px
30px
60px
-12px
inset
,
rgba
(
0
,
0
,
0
,
0.3
)
0px
18px
36px
-18px
inset
;
}
}
.btn
{
.btn
{
transition-duration
:
0.4s
;
transition-duration
:
0.4s
;
}
}
.btn-default
:hover
{
.btn-default
:hover
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#545b62
;
background-color
:
#545b62
;
border-color
:
#4e555b
;
border-color
:
#4e555b
;
}
}
.btn-default
{
.btn-default
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#6c757d
;
background-color
:
#6c757d
;
border-color
:
#6c757d
;
border-color
:
#6c757d
;
}
}
.btn
:not
(
:disabled
)
:not
(
.disabled
)
{
.btn
:not
(
:disabled
)
:not
(
.disabled
)
{
cursor
:
pointer
;
cursor
:
pointer
;
}
}
.btn-success
{
.btn-success
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#28a745
;
background-color
:
#28a745
;
border-color
:
#28a745
;
border-color
:
#28a745
;
}
}
.btn-success
:hover
{
.btn-success
:hover
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#218838
;
background-color
:
#218838
;
border-color
:
#1e7e34
;
border-color
:
#1e7e34
;
}
}
.btn-cancel
{
.btn-cancel
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#dc3545
;
background-color
:
#dc3545
;
border-color
:
#dc3545
;
border-color
:
#dc3545
;
}
}
.btn-cancel
:hover
{
.btn-cancel
:hover
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#c82333
;
background-color
:
#c82333
;
border-color
:
#bd2130
;
border-color
:
#bd2130
;
}
}
.btn-blue
{
.btn-blue
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#007bff
;
background-color
:
#007bff
;
border-color
:
#007bff
;
border-color
:
#007bff
;
}
}
.btn-blue
:hover
{
.btn-blue
:hover
{
color
:
#fff
;
color
:
#fff
;
background-color
:
#0069d9
;
background-color
:
#0069d9
;
border-color
:
#0062cc
;
border-color
:
#0062cc
;
}
}
.btn-warn
{
.btn-warn
{
color
:
#ffc107
;
color
:
#ffc107
;
background-color
:
transparent
;
background-color
:
transparent
;
background-image
:
none
;
background-image
:
none
;
border-color
:
#ffc107
;
border-color
:
#ffc107
;
}
}
.btn-warn
:hover
{
.btn-warn
:hover
{
color
:
#212529
;
color
:
#212529
;
background-color
:
#ffc107
;
background-color
:
#ffc107
;
border-color
:
#ffc107
;
border-color
:
#ffc107
;
}
.btn-big
:active
{
border-color
:
#2d773e
;
background-color
:
#dc3545
;
border-color
:
#dc3545
;
}
}
.btn-large
{
.btn-large
{
font-size
:
110%
;
font-size
:
110%
;
}
}
.app
{
.app
{
background-color
:
#f4f4f4
;
background-color
:
#f4f4f4
;
overflow
:
hidden
;
overflow
:
hidden
;
margin
:
0
;
margin
:
0
;
padding
:
0
;
padding
:
0
;
box-shadow
:
0
1px
1px
0
rgba
(
0
,
0
,
0
,
.06
),
0
2px
5px
0
rgba
(
0
,
0
,
0
,
.2
);
box-shadow
:
0
1px
1px
0
rgba
(
0
,
0
,
0
,
.06
),
0
2px
5px
0
rgba
(
0
,
0
,
0
,
.2
);
}
}
.coln-left
{
.coln-left
{
flex
:
30%
;
flex
:
30%
;
padding
:
0
;
padding
:
0
;
margin
:
0
;
margin
:
0
;
}
}
.coln-left-hide
{
.coln-left-hide
{
flex
:
0
;
flex
:
0
;
}
}
.coln-right
{
.coln-right
{
flex
:
70%
;
flex
:
70%
;
position
:
relative
;
position
:
relative
;
}
}
/* Clear floats after the columns */
/* Clear floats after the columns */
.row
{
.row
{
display
:
flex
;
display
:
flex
;
}
}
.full-height
{
.full-height
{
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
);
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
);
}
}
.full-width
{
.full-width
{
width
:
calc
(
100vw
-
200px
);
width
:
calc
(
100vw
-
200px
);
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
-
56
px
);
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
-
40
px
);
}
}
.full-width-active
{
.full-width-active
{
width
:
100vw
;
width
:
100vw
;
}
}
.container
{
.container
{
width
:
100%
;
width
:
100%
;
}
}
.users-header
{
.users-header
{
height
:
3
.5rem
;
height
:
2
.5rem
;
padding
:
10
px
;
padding
:
5
px
;
background
:
#610a86
;
background
:
#610a86
;
font-size
:
.95rem
;
font-size
:
.95rem
;
font-weight
:
500
;
font-weight
:
500
;
}
}
.users-header
:after
,
.profile-user
:after
,
.users-header
:before
{
.users-header
:after
,
.profile-user
:after
,
.users-header
:before
{
display
:
table
;
display
:
table
;
content
:
" "
;
content
:
" "
;
}
}
.users-header
:after
,
.profile-user
:after
{
.users-header
:after
,
.profile-user
:after
{
clear
:
both
;
clear
:
both
;
}
}
.reply
{
.reply
{
height
:
53px
;
height
:
53px
;
width
:
100%
;
width
:
100%
;
background-color
:
#eae7e5
;
background-color
:
#eae7e5
;
padding
:
10px
5px
10px
5px
;
padding
:
10px
5px
10px
5px
;
margin
:
0
;
margin
:
0
;
z-index
:
1000
;
z-index
:
1000
;
}
}
.reply
textarea
{
.reply
textarea
{
width
:
100%
;
width
:
100%
;
resize
:
none
;
resize
:
none
;
overflow
:
hidden
;
overflow
:
hidden
;
padding
:
5px
;
padding
:
5px
;
outline
:
none
;
outline
:
none
;
border
:
none
;
border
:
none
;
text-indent
:
5px
;
text-indent
:
5px
;
box-shadow
:
none
;
box-shadow
:
none
;
height
:
100%
;
height
:
100%
;
}
}
textarea
.form-reply
{
textarea
.form-reply
{
height
:
2.1em
;
height
:
2.1em
;
margin-right
:
.5em
;
margin-right
:
.5em
;
}
}
.form-reply
{
.form-reply
{
display
:
block
;
display
:
block
;
width
:
100%
;
width
:
100%
;
height
:
34px
;
height
:
34px
;
padding
:
6px
12px
;
padding
:
6px
12px
;
font-size
:
1rem
;
font-size
:
1rem
;
color
:
#555
;
color
:
#555
;
background-color
:
#fff
;
background-color
:
#fff
;
background-image
:
none
;
background-image
:
none
;
border
:
1px
solid
#ccc
;
border
:
1px
solid
#ccc
;
border-radius
:
4px
;
border-radius
:
4px
;
box-shadow
:
inset
0
1px
1px
rgba
(
0
,
0
,
0
,
.075
);
box-shadow
:
inset
0
1px
1px
rgba
(
0
,
0
,
0
,
.075
);
transition
:
border-color
ease-in-out
.15s
,
box-shadow
ease-in-out
.15s
;
transition
:
border-color
ease-in-out
.15s
,
box-shadow
ease-in-out
.15s
;
}
}
.form-reply
::placeholder
{
.form-reply
::placeholder
{
opacity
:
.7
;
opacity
:
.7
;
}
}
.select
{
.select
{
display
:
block
;
display
:
block
;
width
:
100%
;
width
:
100%
;
padding
:
.275rem
.75rem
;
padding
:
.275rem
.75rem
;
font-size
:
1rem
;
font-size
:
1rem
;
line-height
:
1.5
;
line-height
:
1.5
;
color
:
#495057
;
color
:
#495057
;
background-color
:
#fff
;
background-color
:
#fff
;
background-clip
:
padding-box
;
background-clip
:
padding-box
;
border
:
1px
solid
#ced4da
;
border
:
1px
solid
#ced4da
;
border-radius
:
.25rem
;
border-radius
:
.25rem
;
transition
:
border-color
.15s
ease-in-out
,
box-shadow
.15s
ease-in-out
;
transition
:
border-color
.15s
ease-in-out
,
box-shadow
.15s
ease-in-out
;
}
}
.select-inline
{
.select-inline
{
display
:
inline-block
;
display
:
inline-block
;
}
}
.message
{
.message
{
width
:
auto
!important
;
width
:
auto
!important
;
padding
:
4px
10px
7px
!important
;
padding
:
4px
10px
7px
!important
;
background
:
#daf1c6
;
background
:
#daf1c6
;
font-size
:
12px
;
font-size
:
12px
;
box-shadow
:
0
1px
1px
rgba
(
43
,
43
,
43
,
0.16
);
box-shadow
:
0
1px
1px
rgba
(
43
,
43
,
43
,
0.16
);
border-radius
:
5px
;
border-radius
:
5px
;
word-wrap
:
break-word
;
word-wrap
:
break-word
;
display
:
inline-block
;
display
:
inline-block
;
margin
:
1em
0
0
;
margin
:
1em
0
0
;
max-width
:
90%
;
max-width
:
90%
;
text-align
:
left
;
text-align
:
left
;
}
}
.message-sender
{
.message-sender
{
background
:
#e6e6e6
;
background
:
#e6e6e6
;
}
}
.message-private
{
.message-private
{
background
:
white
;
background
:
white
;
}
}
.message-private
.message-header
:after
{
.message-private
.message-header
:after
{
content
:
"(private)"
;
content
:
"(private)"
;
margin-left
:
1em
;
margin-left
:
1em
;
}
}
.message-system
{
.message-system
{
font-size
:
10px
;
font-size
:
10px
;
background
:
#ececec
;
background
:
#ececec
;
}
}
.message-row
:after
,
.message-row
:before
{
.message-row
:after
,
.message-row
:before
{
display
:
table
;
display
:
table
;
content
:
" "
;
content
:
" "
;
}
}
.message-row
:after
{
.message-row
:after
{
clear
:
both
;
clear
:
both
;
}
}
.message-content
{
.message-content
{
white-space
:
pre-wrap
;
white-space
:
pre-wrap
;
margin
:
0
;
margin
:
0
;
padding
:
0
;
padding
:
0
;
padding-left
:
5px
;
padding-left
:
5px
;
word-wrap
:
break-word
;
word-wrap
:
break-word
;
word-break
:
break-word
;
word-break
:
break-word
;
font-weight
:
400
;
font-weight
:
400
;
font-size
:
14px
;
font-size
:
14px
;
color
:
#202035
;
color
:
#202035
;
}
}
.message-header
{
.message-header
{
margin
:
0
;
margin
:
0
;
font-style
:
italic
;
font-style
:
italic
;
text-shadow
:
none
;
text-shadow
:
none
;
}
}
.message-footer
{
.message-footer
{
margin
:
0
;
margin
:
0
;
padding
:
0
;
padding
:
0
;
margin-bottom
:
-5px
;
margin-bottom
:
-5px
;
line-height
:
.9
;
line-height
:
.9
;
text-align
:
right
;
text-align
:
right
;
}
}
.message-time
{
.message-time
{
margin-left
:
1em
;
margin-left
:
1em
;
}
}
.message-me-asterisk
,
.message-me-user
{
.message-me-asterisk
,
.message-me-user
{
margin-right
:
0.33em
;
margin-right
:
0.33em
;
}
}
.video-container
{
.video-container
{
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
-
56px
);
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
-
56px
);
position
:
relative
;
position
:
relative
;
background
:
rgba
(
0
,
0
,
0
,
0.91
);
background
:
rgba
(
0
,
0
,
0
,
0.91
);
/* Display only when showing video */
/* Display only when showing video */
display
:
block
;
display
:
block
;
}
}
.chat-btn
{
.chat-btn
{
display
:
block
;
display
:
block
;
/*on top of video peers*/
/*on top of video peers*/
z-index
:
1002
;
z-index
:
1002
;
font-size
:
1.8em
;
font-size
:
1.8em
;
position
:
absolute
;
position
:
absolute
;
top
:
10px
;
top
:
10px
;
left
:
10px
;
left
:
10px
;
cursor
:
pointer
;
cursor
:
pointer
;
}
}
.chat-btn
.icon-chat
{
.chat-btn
.icon-chat
{
color
:
#cac7c7
;
color
:
#cac7c7
;
height
:
50px
;
height
:
50px
;
padding
:
10px
;
padding
:
10px
;
text-shadow
:
0px
0px
1px
#b3adad
;
text-shadow
:
0px
0px
1px
#b3adad
;
}
}
.collapse-video
{
.collapse-video
{
left
:
inherit
;
bottom
:
72px
;
right
:
30px
;
top
:
inherit
;
}
}
.video-controls
,
.top-video-controls
{
.video-controls
,
.top-video-controls
{
position
:
absolute
;
position
:
absolute
;
width
:
100%
;
width
:
100%
;
left
:
0
;
left
:
0
;
bottom
:
25px
;
bottom
:
25px
;
text-align
:
center
;
text-align
:
center
;
color
:
#eaeaea
;
color
:
#eaeaea
;
font-size
:
1.1em
;
font-size
:
1.1em
;
opacity
:
0
;
opacity
:
0
;
height
:
32px
;
height
:
32px
;
}
}
.video-controls
:after
,
.top-video-controls
:after
{
.video-controls
:after
,
.top-video-controls
:after
{
clear
:
both
;
clear
:
both
;
display
:
table
;
display
:
table
;
content
:
" "
;
content
:
" "
;
}
}
.top-video-controls
{
.top-video-controls
{
text-align
:
right
;
text-align
:
right
;
bottom
:
inherit
;
bottom
:
inherit
;
top
:
0
;
top
:
0
;
line-height
:
1.1
;
line-height
:
1.1
;
font-size
:
1.3em
;
font-size
:
1.3em
;
text-shadow
:
1px
1px
2px
rgb
(
90
86
86
);
text-shadow
:
1px
1px
2px
rgb
(
90
86
86
);
}
}
.controls-button
{
.controls-button
{
padding
:
3px
10px
;
padding
:
3px
10px
;
vertical-align
:
middle
;
vertical-align
:
middle
;
height
:
100%
;
height
:
100%
;
}
}
.controls-left
{
.controls-left
{
float
:
left
;
float
:
left
;
text-align
:
left
;
text-align
:
left
;
}
}
.controls-right
{
.controls-right
{
float
:
right
;
float
:
right
;
text-align
:
right
;
text-align
:
right
;
}
.video-off
{
color
:
#e83a4a
;
}
}
.vc-overlay
{
.vc-overlay
{
background
:
linear-gradient
(
180deg
,
rgb
(
0
0
0
/
20%
)
0%
,
rgb
(
0
0
0
/
50%
)
0%
,
rgb
(
0
0
0
/
70%
)
100%
);
background
:
linear-gradient
(
180deg
,
rgb
(
0
0
0
/
20%
)
0%
,
rgb
(
0
0
0
/
50%
)
0%
,
rgb
(
0
0
0
/
70%
)
100%
);
}
}
.peer
:hover
>
.video-controls
,
.peer
:hover
>
.top-video-controls
{
.peer
:hover
>
.video-controls
,
.peer
:hover
>
.top-video-controls
{
opacity
:
1
;
opacity
:
1
;
}
}
.video-controls
span
,
.top-video-controls
span
{
.video-controls
span
,
.top-video-controls
span
{
margin-right
:
20px
;
margin-right
:
20px
;
transition
:
opacity
.7s
ease-out
;
transition
:
opacity
.7s
ease-out
;
opacity
:
1
;
opacity
:
.7
;
cursor
:
pointer
;
cursor
:
pointer
;
}
}
.video-controls
span
:last-child
,
.top-video-controls
span
:last-child
{
.video-controls
span
:last-child
,
.top-video-controls
span
:last-child
{
margin-right
:
0
;
margin-right
:
0
;
}
}
.video-controls
span
:hover
,
.top-video-controls
span
:hover
{
.video-controls
span
:hover
,
.top-video-controls
span
:hover
{
opacity
:
.8
;
opacity
:
.8
;
transition
:
opacity
.5s
ease-out
;
transition
:
opacity
.5s
ease-out
;
}
}
.top-video-controls
.video-stop
{
.top-video-controls
.video-stop
{
display
:
flex
;
display
:
flex
;
width
:
1.5em
;
width
:
1.5em
;
height
:
1.5em
;
height
:
1.5em
;
background
:
rgba
(
0
,
0
,
0
,
0.5
);
background
:
rgba
(
0
,
0
,
0
,
0.5
);
border-radius
:
50%
;
border-radius
:
50%
;
justify-content
:
center
;
justify-content
:
center
;
align-items
:
center
;
align-items
:
center
;
color
:
#eaeaea
;
color
:
#eaeaea
;
display
:
none
;
}
}
.video-controls
.volume
{
.video-controls
.volume
{
display
:
inline-block
;
display
:
inline-block
;
text-align
:
center
;
text-align
:
center
;
}
}
.video-controls
.video-play
{
.video-controls
.video-play
{
font-size
:
0.85em
;
font-size
:
0.85em
;
}
}
.video-controls
.video-stop
{
.video-controls
.video-stop
{
color
:
#d03e3e
;
color
:
#d03e3e
;
}
}
.video-controls
span
.disabled
,
.video-controls
span
.disabled
:hover
,
.top-video-controls
span
.disabled
:hover
{
.video-controls
span
.disabled
,
.video-controls
span
.disabled
:hover
,
.top-video-controls
span
.disabled
:hover
{
opacity
:
.2
;
opacity
:
.2
;
color
:
#c8c8c8
color
:
#c8c8c8
}
}
.volume-mute
{
.volume-mute
{
vertical-align
:
middle
;
vertical-align
:
middle
;
width
:
25px
;
width
:
25px
;
display
:
var
(
--dv
,
inline
);
display
:
var
(
--dv
,
inline
);
}
}
.volume-slider
{
.volume-slider
{
height
:
4px
;
height
:
4px
;
width
:
60px
;
width
:
60px
;
cursor
:
pointer
;
cursor
:
pointer
;
margin
:
5px
5px
;
margin
:
5px
5px
;
vertical-align
:
middle
;
vertical-align
:
middle
;
opacity
:
var
(
--ov
,
0
);
opacity
:
var
(
--ov
,
0
);
transition
:
opacity
.5s
ease-out
;
transition
:
opacity
.5s
ease-out
;
}
}
.video-controls
.volume
:hover
{
.video-controls
.volume
:hover
{
--ov
:
1
;
--ov
:
1
;
--dv
:
inline
;
--dv
:
inline
;
}
}
.mobile-container
{
.mobile-container
{
display
:
block
!important
;
display
:
block
!important
;
}
}
.login-container
{
.login-container
{
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
-
56px
);
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
-
56px
);
position
:
relative
;
position
:
relative
;
display
:
flex
;
display
:
flex
;
justify-content
:
center
;
justify-content
:
center
;
overflow
:
scroll
;
overflow
:
scroll
;
}
}
.login-box
{
.login-box
{
width
:
20em
;
width
:
20em
;
padding
:
1em
;
padding
:
1em
;
margin
:
5em
auto
;
margin
:
5em
auto
;
height
:
23em
;
height
:
23em
;
background
:
#fcfcfc
;
background
:
#fcfcfc
;
}
}
.login-box
.connect
{
.login-box
.connect
{
width
:
100%
;
width
:
100%
;
text-align
:
center
;
text-align
:
center
;
}
}
.login-box
h2
{
.login-box
h2
{
text-align
:
center
;
text-align
:
center
;
margin-bottom
:
40px
;
margin-bottom
:
40px
;
}
}
.label-fallback
{
.label-fallback
{
opacity
:
0.5
;
opacity
:
0.5
;
}
}
.label
{
.label
{
left
:
0
;
left
:
0
;
position
:
absolute
;
position
:
absolute
;
bottom
:
0
;
bottom
:
0
;
width
:
100%
;
width
:
100%
;
z-index
:
1
;
z-index
:
1
;
text-align
:
center
;
text-align
:
center
;
line-height
:
24px
;
line-height
:
24px
;
color
:
#ffffff
;
color
:
#ffffff
;
}
}
.nav-link
{
.nav-link
{
padding
:
0
;
padding
:
0
;
color
:
#dbd9d9
;
color
:
#dbd9d9
;
min-width
:
30px
;
min-width
:
30px
;
display
:
block
;
display
:
block
;
text-align
:
center
;
text-align
:
center
;
margin
:
0
10px
;
margin
:
0
10px
;
position
:
relative
;
position
:
relative
;
line-height
:
1.1
;
line-height
:
1.1
;
}
}
.nav-link
span
{
.nav-link
span
{
display
:
block
;
display
:
block
;
}
}
.nav-link
label
{
.nav-link
label
{
display
:
block
;
display
:
block
;
cursor
:
pointer
;
cursor
:
pointer
;
color
:
#fff
;
color
:
#fff
;
font-size
:
55%
;
font-size
:
55%
;
}
}
.nav-link
:hover
{
.nav-link
:hover
{
color
:
#c2a4e0
;
color
:
#c2a4e0
;
}
}
.nav-link
label
:hover
{
.nav-link
label
:hover
{
color
:
#c2a4e0
;
color
:
#c2a4e0
;
}
}
.nav-cancel
,
.muted
,
.nav-cancel
label
,
.muted
label
{
.nav-cancel
,
.muted
,
.nav-cancel
label
,
.muted
label
{
color
:
#d03e3e
color
:
#d03e3e
}
}
.nav-cancel
:hover
,
.muted
:hover
,
.nav-cancel
label
:hover
,
.muted
label
:hover
{
.nav-cancel
:hover
,
.muted
:hover
,
.nav-cancel
label
:hover
,
.muted
label
:hover
{
color
:
#d03e3e
color
:
#d03e3e
}
}
.nav-button
{
.nav-button
{
cursor
:
pointer
;
cursor
:
pointer
;
font-size
:
25px
;
font-size
:
25px
;
}
}
.nav-more
{
.nav-more
{
padding-top
:
5px
;
padding-top
:
5px
;
margin-left
:
0
;
margin-left
:
0
;
}
}
.header-title
{
.header-title
{
float
:
left
;
float
:
left
;
margin
:
0
;
margin
:
0
;
font-size
:
1rem
;
font-size
:
1rem
;
font-weight
:
700
;
font-weight
:
700
;
color
:
#ebebeb
;
color
:
#ebebeb
;
line-height
:
2em
;
line-height
:
2em
;
}
}
#title
{
#title
{
text-align
:
center
;
text-align
:
center
;
}
}
h1
{
h1
{
white-space
:
nowrap
;
white-space
:
nowrap
;
}
}
#statdiv
{
#statdiv
{
white-space
:
nowrap
;
white-space
:
nowrap
;
margin-bottom
:
16px
;
margin-bottom
:
16px
;
}
}
#errspan
{
#errspan
{
margin-left
:
1em
;
margin-left
:
1em
;
}
}
.connected
{
.connected
{
color
:
green
;
color
:
green
;
}
}
.disconnected
{
.disconnected
{
color
:
red
;
color
:
red
;
font-weight
:
bold
;
font-weight
:
bold
;
}
}
.userform
{
.userform
{
display
:
inline
display
:
inline
}
}
.userform
label
{
.userform
label
{
min-width
:
3em
;
min-width
:
3em
;
display
:
inline-block
;
display
:
inline-block
;
padding-top
:
10px
;
padding-top
:
10px
;
}
}
.userform
input
[
type
=
"text"
],
.userform
input
[
type
=
"password"
]
{
.userform
input
[
type
=
"text"
],
.userform
input
[
type
=
"password"
]
{
width
:
100%
;
width
:
100%
;
}
}
.switch-radio
{
.switch-radio
{
margin
:
0
;
margin
:
0
;
}
}
.invisible
{
.invisible
{
display
:
none
;
display
:
none
!important
;
}
}
.error
{
.error
{
color
:
red
;
color
:
red
;
font-weight
:
bold
;
font-weight
:
bold
;
}
}
.noerror
{
.noerror
{
display
:
none
;
display
:
none
;
}
}
.clear
{
.clear
{
clear
:
both
;
clear
:
both
;
content
:
""
;
content
:
""
;
}
}
#optionsdiv
{
#optionsdiv
{
margin-bottom
:
4px
;
margin-bottom
:
4px
;
}
}
#optionsdiv
input
[
type
=
"checkbox"
]
{
#optionsdiv
input
[
type
=
"checkbox"
]
{
vertical-align
:
middle
;
vertical-align
:
middle
;
}
}
#presentbutton
,
#unpresentbutton
{
#presentbutton
,
#unpresentbutton
{
white-space
:
nowrap
;
white-space
:
nowrap
;
margin-right
:
0.4em
;
margin-right
:
0.4em
;
margin-top
:
.1em
;
margin-top
:
.1em
;
font-size
:
1.1em
;
font-size
:
1.1em
;
text-align
:
left
;
text-align
:
left
;
width
:
5.8em
;
width
:
5.8em
;
}
#pushtalk
{
position
:
fixed
;
bottom
:
70px
;
right
:
30px
;
z-index
:
1002
;
}
}
#videoselect
{
#videoselect
{
text-align-last
:
center
;
text-align-last
:
center
;
margin-right
:
0.4em
;
margin-right
:
0.4em
;
}
}
#audioselect
{
#audioselect
{
text-align-last
:
center
;
text-align-last
:
center
;
}
}
#sharebutton
,
#unsharebutton
{
#sharebutton
,
#unsharebutton
{
white-space
:
nowrap
;
white-space
:
nowrap
;
}
}
#unsharebutton
{
#unsharebutton
{
margin-right
:
0.4em
;
margin-right
:
0.4em
;
}
}
#filterselect
{
#filterselect
{
width
:
8em
;
width
:
8em
;
text-align-last
:
center
;
text-align-last
:
center
;
margin-right
:
0.4em
;
margin-right
:
0.4em
;
}
}
#sendselect
{
#sendselect
{
width
:
8em
;
width
:
8em
;
text-align-last
:
center
;
text-align-last
:
center
;
margin-right
:
0.4em
;
margin-right
:
0.4em
;
}
}
#simulcastselect
{
#simulcastselect
{
width
:
8em
;
width
:
8em
;
text-align-last
:
center
;
text-align-last
:
center
;
margin-right
:
0.4em
;
margin-right
:
0.4em
;
}
}
#requestselect
{
#requestselect
{
width
:
8em
;
width
:
8em
;
text-align-last
:
center
;
text-align-last
:
center
;
}
}
#chatbox
{
#chatbox
{
height
:
100%
;
height
:
100%
;
position
:
relative
;
position
:
relative
;
}
}
#chat
{
#chat
{
padding
:
0
;
padding
:
0
;
margin
:
0
;
margin
:
0
;
background-color
:
#f8f8f8
;
background-color
:
#f8f8f8
;
background-size
:
cover
;
background-size
:
cover
;
overflow-y
:
scroll
;
overflow-y
:
scroll
;
border
:
none
;
border
:
none
;
border-right
:
4px
solid
#e6e6e6
;
border-right
:
4px
solid
#e6e6e6
;
/* force to fill height */
/* force to fill height */
height
:
100%
!important
;
height
:
100%
!important
;
width
:
100%
;
width
:
100%
;
min-width
:
300px
;
min-width
:
300px
;
overflow
:
hidden
;
overflow
:
hidden
;
}
}
#inputform
{
#inputform
{
display
:
flex
;
display
:
flex
;
}
}
#box
{
#box
{
overflow
:
auto
;
overflow
:
auto
;
height
:
calc
(
100%
-
53px
);
height
:
calc
(
100%
-
53px
);
padding
:
10px
;
padding
:
10px
;
}
}
.close-chat
{
.close-chat
{
position
:
absolute
;
position
:
absolute
;
top
:
2px
;
top
:
2px
;
right
:
14px
;
right
:
14px
;
width
:
25px
;
width
:
25px
;
font-size
:
1em
;
font-size
:
1em
;
text-align
:
center
;
text-align
:
center
;
font-weight
:
700
;
font-weight
:
700
;
color
:
#8f8f8f
;
color
:
#8f8f8f
;
cursor
:
pointer
;
cursor
:
pointer
;
border
:
1px
solid
transparent
;
border
:
1px
solid
transparent
;
}
}
.close-chat
:hover
,
.close-chat
:active
{
.close-chat
:hover
,
.close-chat
:active
{
border
:
1px
solid
#dfdfdf
;
border
:
1px
solid
#dfdfdf
;
border-radius
:
4px
;
border-radius
:
4px
;
}
}
#connectbutton
{
#connectbutton
{
margin-top
:
1em
;
margin-top
:
1em
;
padding
:
0.37rem
1.5rem
;
padding
:
0.37rem
1.5rem
;
}
}
#input
{
#input
{
width
:
100%
;
width
:
100%
;
border
:
none
;
border
:
none
;
resize
:
none
;
resize
:
none
;
overflow-y
:
hidden
;
overflow-y
:
hidden
;
}
}
#input
:focus
{
#input
:focus
{
outline
:
none
;
outline
:
none
;
}
}
#inputbutton
:focus
{
#inputbutton
:focus
{
outline
:
none
;
outline
:
none
;
}
}
#resizer
{
#resizer
{
width
:
4px
;
width
:
4px
;
margin-left
:
-4px
;
margin-left
:
-4px
;
z-index
:
1000
;
z-index
:
1000
;
}
}
#resizer
:hover
{
#resizer
:hover
{
cursor
:
ew-resize
;
cursor
:
ew-resize
;
}
}
#peers
{
#peers
,
#mypeer
{
padding
:
10px
;
padding
:
10px
;
display
:
grid
;
display
:
grid
;
grid-template-columns
:
repeat
(
1
,
1
fr
);
grid-template-columns
:
repeat
(
1
,
1
fr
);
grid-template-rows
:
repeat
(
1
,
auto
);
grid-template-rows
:
repeat
(
1
,
auto
);
row-gap
:
5px
;
row-gap
:
5px
;
column-gap
:
10px
;
column-gap
:
10px
;
position
:
absolute
;
position
:
absolute
;
top
:
0
;
top
:
0
;
right
:
0
;
right
:
0
;
bottom
:
0
;
bottom
:
0
;
min-width
:
100%
;
min-width
:
100%
;
min-height
:
100%
;
min-height
:
100%
;
width
:
auto
;
width
:
auto
;
height
:
auto
;
height
:
auto
;
z-index
:
1000
;
z-index
:
1000
;
background-size
:
cover
;
background-size
:
cover
;
overflow
:
hidden
;
overflow
:
hidden
;
vertical-align
:
top
!important
;
vertical-align
:
top
!important
;
}
}
.peer
{
.peer
{
margin-top
:
auto
;
margin-top
:
auto
;
margin-bottom
:
auto
;
margin-bottom
:
auto
;
position
:
relative
;
position
:
relative
;
border
:
2px
solid
rgba
(
0
,
0
,
0
,
0
);
border
:
2px
solid
rgba
(
0
,
0
,
0
,
0
);
background
:
#80808014
;
background
:
#80808014
;
}
}
.peer-active
{
.peer-active
{
border
:
2px
solid
#610a86
;
border
:
2px
solid
#610a86
;
}
}
.media
{
.media
{
width
:
100%
;
width
:
100%
;
max-height
:
calc
(
var
(
--vh
,
1vh
)
*
100
-
76px
);
max-height
:
calc
(
var
(
--vh
,
1vh
)
*
100
-
76px
);
padding-bottom
:
20px
;
padding-bottom
:
20px
;
object-fit
:
contain
;
object-fit
:
contain
;
}
}
.media-failed
{
.media-failed
{
filter
:
grayscale
(
0.5
)
contrast
(
0.5
);
filter
:
grayscale
(
0.5
)
contrast
(
0.5
);
}
}
.mirror
{
.mirror
{
transform
:
scaleX
(
-1
);
transform
:
scaleX
(
-1
);
}
}
#inputform
{
#inputform
{
width
:
100%
;
width
:
100%
;
}
}
.sidenav
{
.sidenav
{
background-color
:
#4d076b
;
background-color
:
#4d076b
;
box-shadow
:
0
0
24px
0
rgba
(
71
,
77
,
86
,
.1
),
0
1px
0
0
rgba
(
71
,
77
,
86
,
.08
);
box-shadow
:
0
0
24px
0
rgba
(
71
,
77
,
86
,
.1
),
0
1px
0
0
rgba
(
71
,
77
,
86
,
.08
);
display
:
block
;
display
:
block
;
position
:
fixed
;
position
:
fixed
;
-webkit-transition
:
all
.2s
ease-out
;
-webkit-transition
:
all
.2s
ease-out
;
transition
:
all
.2s
ease-out
;
transition
:
all
.2s
ease-out
;
width
:
0px
;
width
:
0px
;
/* on top of everything */
/* on top of everything */
z-index
:
2999
;
z-index
:
2999
;
top
:
0
;
top
:
0
;
right
:
0
;
right
:
0
;
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
);
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
);
overflow-x
:
hidden
;
overflow-x
:
hidden
;
overflow-y
:
hidden
;
overflow-y
:
hidden
;
}
}
.sidenav
a
{
.sidenav
a
{
padding
:
10px
20px
;
padding
:
10px
20px
;
text-decoration
:
none
;
text-decoration
:
none
;
font-size
:
30px
;
font-size
:
30px
;
color
:
#dbd9d9
;
color
:
#dbd9d9
;
display
:
block
;
display
:
block
;
transition
:
0.3s
;
transition
:
0.3s
;
line-height
:
1.0
;
line-height
:
1.0
;
}
}
.sidenav
a
:hover
{
.sidenav
a
:hover
{
color
:
#c2a4e0
;
color
:
#c2a4e0
;
}
}
.sidenav
.closebtn
{
.sidenav
.closebtn
{
cursor
:
pointer
;
cursor
:
pointer
;
position
:
absolute
;
position
:
absolute
;
top
:
0
;
top
:
0
;
right
:
0
;
right
:
0
;
height
:
56px
;
height
:
56px
;
}
}
.sidenav-label
{
.sidenav-label
{
display
:
block
;
display
:
block
;
margin-top
:
15px
;
margin-top
:
15px
;
}
}
.sidenav-label-first
{
.sidenav-label-first
{
display
:
block
;
display
:
block
;
margin-top
:
0
;
margin-top
:
0
;
}
}
.sidenav
form
{
.sidenav
form
{
margin-top
:
15px
;
margin-top
:
15px
;
}
}
.sidenav-header
{
.sidenav-header
{
height
:
56px
;
height
:
56px
;
}
}
.sidenav-header
h2
{
.sidenav-header
h2
{
color
:
#fff
;
color
:
#fff
;
padding
:
10px
;
padding
:
10px
;
margin
:
0
;
margin
:
0
;
max-width
:
70%
;
max-width
:
70%
;
line-height
:
36px
;
line-height
:
36px
;
}
}
.sidenav-content
{
.sidenav-content
{
padding
:
10px
;
padding
:
10px
;
background
:
#fff
;
background
:
#fff
;
height
:
calc
(
100%
-
56px
);
height
:
calc
(
100%
-
56px
);
overflow-y
:
auto
;
overflow-y
:
auto
;
overflow-x
:
hidden
;
overflow-x
:
hidden
;
}
}
.sidenav-content
h2
{
.sidenav-content
h2
{
margin
:
0
;
margin
:
0
;
}
}
fieldset
{
fieldset
{
margin
:
0
;
margin
:
0
;
margin-top
:
20px
;
margin-top
:
20px
;
border
:
1px
solid
#e9e8e8
;
border
:
1px
solid
#e9e8e8
;
padding
:
8px
;
padding
:
8px
;
border-radius
:
4px
;
border-radius
:
4px
;
}
}
legend
{
legend
{
padding
:
2px
;
padding
:
2px
;
color
:
#4d4f51
;
color
:
#4d4f51
;
}
}
.nav-menu
{
.nav-menu
{
margin
:
0
;
margin
:
0
;
padding
:
0
;
padding
:
0
;
}
}
.nav-menu
li
{
.nav-menu
li
{
float
:
left
;
float
:
left
;
max-height
:
70px
;
max-height
:
70px
;
list-style
:
none
;
list-style
:
none
;
}
}
.show-video
{
.show-video
{
position
:
absolute
;
position
:
absolute
;
right
:
30px
;
right
:
30px
;
bottom
:
12
0px
;
top
:
1
0px
;
color
:
white
;
color
:
white
;
width
:
50px
;
width
:
50px
;
height
:
50px
;
height
:
50px
;
text-align
:
center
;
text-align
:
center
;
line-height
:
50px
;
line-height
:
50px
;
font-size
:
150%
;
font-size
:
150%
;
border-radius
:
30px
;
border-radius
:
30px
;
background
:
#600aa0
;
background
:
#600aa0
;
box-shadow
:
4px
4px
7px
1px
rgba
(
0
,
0
,
0
,
0.16
);
box-shadow
:
4px
4px
7px
1px
rgba
(
0
,
0
,
0
,
0.16
);
}
}
.blink
{
.blink
{
-ms-animation
:
blink
1.0s
linear
infinite
;
-ms-animation
:
blink
1.0s
linear
infinite
;
-o-animation
:
blink
1.0s
linear
infinite
;
-o-animation
:
blink
1.0s
linear
infinite
;
animation
:
blink
1.0s
linear
infinite
;
animation
:
blink
1.0s
linear
infinite
;
}
}
@keyframes
blink
{
@keyframes
blink
{
0
%
{
box-shadow
:
0
0
15px
#600aa0
;
}
0
%
{
box-shadow
:
0
0
15px
#600aa0
;
}
50
%
{
box-shadow
:
none
;
}
50
%
{
box-shadow
:
none
;
}
100
%
{
box-shadow
:
0
0
15px
#600aa0
;
}
100
%
{
box-shadow
:
0
0
15px
#600aa0
;
}
}
}
@-webkit-keyframes
blink
{
@-webkit-keyframes
blink
{
0
%
{
box-shadow
:
0
0
15px
#600aa0
;
}
0
%
{
box-shadow
:
0
0
15px
#600aa0
;
}
50
%
{
box-shadow
:
0
0
0
;
}
50
%
{
box-shadow
:
0
0
0
;
}
100
%
{
box-shadow
:
0
0
15px
#600aa0
;
}
100
%
{
box-shadow
:
0
0
15px
#600aa0
;
}
}
}
/* Dropdown Menu */
/* Dropdown Menu */
.dropbtn
{
.dropbtn
{
cursor
:
pointer
;
cursor
:
pointer
;
}
}
.dropdown
{
.dropdown
{
position
:
relative
;
position
:
relative
;
display
:
inline-block
;
display
:
inline-block
;
}
}
.dropdown-content
{
.dropdown-content
{
display
:
none
;
display
:
none
;
position
:
absolute
;
position
:
absolute
;
background-color
:
#fff
;
background-color
:
#fff
;
max-width
:
300px
;
max-width
:
300px
;
min-width
:
200px
;
min-width
:
200px
;
margin-top
:
7px
;
margin-top
:
7px
;
overflow
:
auto
;
overflow
:
auto
;
right
:
7px
;
right
:
7px
;
box-shadow
:
0
8px
16px
0
rgba
(
0
,
0
,
0
,
0.2
);
box-shadow
:
0
8px
16px
0
rgba
(
0
,
0
,
0
,
0.2
);
z-index
:
1
;
z-index
:
1
;
padding
:
15px
;
padding
:
15px
;
}
}
.dropdown-content
a
{
.dropdown-content
a
{
color
:
black
;
color
:
black
;
padding
:
12px
16px
;
padding
:
12px
16px
;
text-decoration
:
none
;
text-decoration
:
none
;
display
:
block
;
display
:
block
;
}
}
.dropdown
a
:hover
{
background-color
:
#ddd
;}
.dropdown
a
:hover
{
background-color
:
#ddd
;}
...
@@ -1093,8 +1124,8 @@ legend {
...
@@ -1093,8 +1124,8 @@ legend {
.show
{
display
:
block
;}
.show
{
display
:
block
;}
.dropdown-content
label
{
.dropdown-content
label
{
display
:
block
;
display
:
block
;
margin-top
:
15px
;
margin-top
:
15px
;
}
}
/* END Dropdown Menu */
/* END Dropdown Menu */
...
@@ -1102,105 +1133,118 @@ legend {
...
@@ -1102,105 +1133,118 @@ legend {
/* Sidebar left */
/* Sidebar left */
#left-sidebar
{
#left-sidebar
{
min-width
:
200px
;
min-width
:
200px
;
max-width
:
200px
;
max-width
:
200px
;
transition
:
all
0.3s
;
transition
:
all
0.3s
;
background
:
#ffffff
;
background
:
#ffffff
;
border-right
:
1px
solid
#dcdcdc
;
}
}
#left-sidebar
.galene-header
{
#left-sidebar
.galene-header
{
display
:
inline-block
;
display
:
inline-block
;
}
}
header
.collapse
{
header
.collapse
{
float
:
left
;
float
:
left
;
text-align
:
center
;
text-align
:
center
;
cursor
:
pointer
;
cursor
:
pointer
;
font-size
:
20px
;
font-size
:
20px
;
color
:
#dbd9d9
;
color
:
#dbd9d9
;
margin-right
:
20px
;
margin-right
:
20px
;
margin-left
:
5px
;
margin-left
:
5px
;
}
}
header
.collapse
:hover
{
header
.collapse
:hover
{
color
:
#c2a4e0
;
color
:
#c2a4e0
;
}
}
.galene-header
{
.galene-header
{
font-size
:
1.3rem
;
font-size
:
1.3rem
;
font-weight
:
900
;
font-weight
:
900
;
color
:
#dbd9d9
;
color
:
#dbd9d9
;
line-height
:
34px
;
line-height
:
34px
;
}
}
.header-sep
{
.header-sep
{
height
:
20px
;
height
:
20px
;
}
}
/* Shrinking the sidebar from 200px to 0px */
/* Shrinking the sidebar from 200px to 0px */
#left-sidebar
.active
{
#left-sidebar
.active
{
min-width
:
0
;
min-width
:
0
;
max-width
:
0
;
max-width
:
0
;
}
}
#left-sidebar
.sidebar-header
strong
{
#left-sidebar
.sidebar-header
strong
{
display
:
none
;
display
:
none
;
}
}
#left-sidebar
.active
.sidebar-header
h3
{
#left-sidebar
.active
.sidebar-header
h3
{
display
:
none
;
display
:
none
;
}
}
#left-sidebar
.active
.sidebar-header
strong
{
#left-sidebar
.active
.sidebar-header
strong
{
display
:
block
;
display
:
block
;
}
}
#users
{
#users
{
padding
:
0
;
padding
:
0
;
margin
:
0
;
margin
:
0
;
height
:
calc
(
100%
-
84
px
);
height
:
calc
(
100%
-
60
px
);
width
:
100%
;
width
:
100%
;
position
:
relative
;
position
:
relative
;
display
:
block
;
display
:
block
;
background-color
:
#fff
;
background-color
:
#fff
;
overflow-y
:
auto
;
overflow-y
:
auto
;
border
:
1px
solid
#f7f7f7
;
border
:
1px
solid
#f7f7f7
;
}
}
#users
.user-p
{
#users
.user-p
{
position
:
relative
;
position
:
relative
;
padding
:
10px
!important
;
padding
:
10px
!important
;
border-bottom
:
1px
solid
#f0f0f0
;
border-bottom
:
1px
solid
#f0f0f0
;
height
:
40px
;
height
:
40px
;
line-height
:
18px
;
line-height
:
18px
;
margin
:
0
!important
;
margin
:
0
!important
;
cursor
:
pointer
;
cursor
:
pointer
;
overflow
:
hidden
;
overflow
:
hidden
;
white-space
:
pre
;
white-space
:
pre
;
}
#users
.user-p
div
{
display
:
inline-flex
;
justify-content
:
space-between
;
width
:
calc
(
100%
-
25px
);
}
#users
.user-p
span
{
text-align
:
left
;
}
#users
.user-p
span
:last-child
{
padding
:
1px
5px
;
}
}
#left-sidebar
.active
#users
>
div
{
#left-sidebar
.active
#users
>
div
{
padding
:
10px
5px
!important
;
padding
:
10px
5px
!important
;
}
}
#users
>
div
:hover
{
#users
>
div
:hover
{
background-color
:
#f2f2f2
;
background-color
:
#f2f2f2
;
}
}
#users
>
div
::before
{
#users
>
div
::before
{
content
:
"\f111"
;
content
:
"\f111"
;
font-family
:
'Font Awesome 6 Free'
;
font-family
:
'Font Awesome 6 Free'
;
color
:
#20b91e
;
color
:
#20b91e
;
margin-right
:
5px
;
margin-right
:
5px
;
font-weight
:
900
;
font-weight
:
900
;
}
}
#users
>
div
.user-status-raisehand
::before
{
#users
>
div
.user-status-raisehand
::before
{
content
:
"\f256"
;
content
:
"\f256"
;
}
}
.close-icon
{
.close-icon
{
font
:
normal
1em
/
1
Arial
,
sans-serif
;
font
:
normal
1em
/
1
Arial
,
sans-serif
;
display
:
inline-block
;
display
:
inline-block
;
}
}
.close-icon
:before
{
content
:
"\2715"
;
}
.close-icon
:before
{
content
:
"\2715"
;
}
...
@@ -1208,144 +1252,166 @@ header .collapse:hover {
...
@@ -1208,144 +1252,166 @@ header .collapse:hover {
/* END Sidebar Left */
/* END Sidebar Left */
@media
only
screen
and
(
min-width
:
1025px
)
{
@media
only
screen
and
(
min-width
:
1025px
)
{
.coln-right
.collapse-video
,
.coln-right
.show-video
{
.coln-right
.collapse-video
,
.coln-right
.show-video
{
display
:
none
;
display
:
none
;
}
}
}
}
@media
only
screen
and
(
max-width
:
1024px
)
{
@media
only
screen
and
(
max-width
:
1024px
)
{
#presentbutton
,
#unpresentbutton
{
#presentbutton
,
#unpresentbutton
{
width
:
auto
;
width
:
auto
;
}
}
.nav-link
{
.nav-link
{
margin
:
0
4px
;
margin
:
0
4px
;
line-height
:
1.5
;
line-height
:
1.5
;
}
}
.nav-link
label
{
.nav-link
label
{
display
:
none
;
display
:
none
;
}
}
.nav-text
{
.nav-text
{
display
:
none
;
display
:
none
;
}
}
.nav-more
{
.nav-more
{
padding-top
:
0
;
padding-top
:
0
;
margin-left
:
inherit
;
margin-left
:
inherit
;
}
}
.full-width
{
.full-width
{
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
-
56px
);
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
-
40px
);
}
}
.close-chat
,
.show-chat
{
.close-chat
,
.show-chat
{
display
:
none
;
display
:
none
;
}
}
.video-container
{
#pushtalk
{
position
:
fixed
;
cursor
:
default
;
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
-
56px
);
}
top
:
56px
;
right
:
0
;
.video-container
{
left
:
0
;
/*position: fixed;
margin-bottom
:
60px
;
height: calc(var(--vh, 1vh) * 100 - 40px);
}
top: 56px;
right: 0;
.top-video-controls
{
left: 0;
opacity
:
1
;
margin-bottom: 60px;*/
}
height
:
100%
;
}
.login-container
{
.media
{
position
:
fixed
;
max-height
:
calc
(
var
(
--vh
,
1vh
)
*
50
-
36px
);
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
-
56px
);
}
top
:
56px
;
right
:
0
;
#peers
{
left
:
0
;
display
:
block
;
background
:
#eff3f9
;
}
}
.top-video-controls
{
.login-box
{
opacity
:
1
;
background
:
transparent
;
}
}
.login-container
{
.coln-left
{
position
:
fixed
;
flex
:
100%
;
height
:
calc
(
var
(
--vh
,
1vh
)
*
100
-
56px
);
width
:
100vw
;
top
:
56px
;
/* chat is always visible here */
right
:
0
;
display
:
block
!important
;
left
:
0
;
}
background
:
#eff3f9
;
}
.coln-right
{
flex
:
none
;
.login-box
{
position
:
relative
;
background
:
transparent
;
}
}
.full-width
{
.coln-left
{
width
:
100vw
;
flex
:
50%
;
}
width
:
100vw
;
/* chat is always visible here */
#left-sidebar
.active
{
display
:
block
!important
;
min-width
:
200px
;
}
max-width
:
200px
;
}
.coln-right
{
flex
:
50%
;
#left-sidebar
{
position
:
relative
;
min-width
:
0
;
}
max-width
:
0
;
}
.full-width
{
width
:
100vw
;
/* Reappearing the sidebar on toggle button click */
flex-wrap
:
wrap
;
#left-sidebar
{
flex-direction
:
column-reverse
;
margin-left
:
0
;
}
}
#left-sidebar
.active
{
#left-sidebar
.sidebar-header
strong
{
min-width
:
200px
;
display
:
none
;
max-width
:
200px
;
}
border-right
:
1px
solid
#dcdcdc
;
}
#left-sidebar
.active
.sidebar-header
h3
{
display
:
none
;
#left-sidebar
{
}
min-width
:
0
;
max-width
:
0
;
#left-sidebar
.active
.sidebar-header
strong
{
}
display
:
block
;
}
/* Reappearing the sidebar on toggle button click */
#left-sidebar
{
.sidenav
a
{
padding
:
10px
10px
;}
margin-left
:
0
;
}
.sidenav-header
h2
{
line-height
:
36px
;
#left-sidebar
.sidebar-header
strong
{
}
display
:
none
;
}
#peers
{
padding
:
3px
;
#left-sidebar
.active
.sidebar-header
h3
{
}
display
:
none
;
}
#resizer
{
display
:
none
;
#left-sidebar
.active
.sidebar-header
strong
{
}
display
:
block
;
}
#chat
{
border-right
:
none
;
.sidenav
a
{
padding
:
10px
10px
;}
}
.sidenav-header
h2
{
.dropdown-content
{
line-height
:
36px
;
margin-top
:
10px
;
}
}
#peers
{
padding
:
3px
;
}
#resizer
{
display
:
none
;
}
#chat
{
border-right
:
none
;
}
#box
{
/* 40px header height
53px reply box height
*/
height
:
calc
((
var
(
--vh
,
1vh
)
*
100
-
40px
)
/
2
-
53px
);
}
.dropdown-content
{
margin-top
:
10px
;
}
}
}
:root
{
:root
{
--contextualMenuBg
:
#eee
;
--contextualMenuBg
:
#eee
;
--contextualMenuShadow
:
1px
1px
1px
#444
;
*/
--contextualMenuShadow
:
1px
1px
1px
#444
;
--contextualMenuRadius
:
0px
;
*/
--contextualMenuRadius
:
0px
;
--contextualMenuText
:
black
;
--contextualMenuText
:
black
;
--contextualSubMenuBg
:
#eee
;
--contextualSubMenuBg
:
#eee
;
--contextualHover
:
#ddd
;
--contextualHover
:
#ddd
;
--contextualOverflowIcon
:
#999
;
--contextualOverflowIcon
:
#999
;
--contextualSeperator
:
#999
;
--contextualSeperator
:
#999
;
}
}
static/galene.html
View file @
84948418
...
@@ -47,11 +47,17 @@
...
@@ -47,11 +47,17 @@
</button>
</button>
</li>
</li>
<li>
<li>
<div
id=
"mutebutton"
class=
"nav-link nav-button"
>
<div
id=
"mutebutton"
class=
"nav-link nav-button
invisible
"
>
<span><i
class=
"fas fa-microphone-slash"
aria-hidden=
"true"
></i></span>
<span><i
class=
"fas fa-microphone-slash"
aria-hidden=
"true"
></i></span>
<label>
Mute
</label>
<label>
Mute
</label>
</div>
</div>
</li>
</li>
<li>
<div
id=
"videoon"
class=
"nav-link nav-button invisible"
>
<span><i
class=
"fas fa-video-camera"
aria-hidden=
"true"
></i></span>
<label>
Camera
</label>
</div>
</li>
<li>
<li>
<div
id=
"sharebutton"
class=
"invisible nav-link nav-button"
>
<div
id=
"sharebutton"
class=
"invisible nav-link nav-button"
>
<span><i
class=
"fas fa-share-square"
aria-hidden=
"true"
></i></span>
<span><i
class=
"fas fa-share-square"
aria-hidden=
"true"
></i></span>
...
@@ -69,10 +75,24 @@
...
@@ -69,10 +75,24 @@
<div
class=
"row full-width"
id=
"mainrow"
>
<div
class=
"row full-width"
id=
"mainrow"
>
<div
class=
"coln-left"
id=
"left"
>
<div
class=
"coln-left"
id=
"left"
>
<div
id=
"chat"
>
<div
id=
"chat"
>
<div
class=
"video-container invisible"
id=
"myvideo-container"
>
<div
class=
"chat-btn collapse-video invisible"
id=
"collapse-video"
>
<i
class=
"far fa-comment-alt icon-chat"
title=
"Hide video and show chat"
></i>
</div>
<div
id=
"mypeer"
></div>
</div>
<div
id=
"chatbox"
>
<div
id=
"chatbox"
>
<div
class=
"close-chat"
id=
"close-chat"
title=
"Hide chat"
>
<div
class=
"close-chat"
id=
"close-chat"
title=
"Hide chat"
>
<span
class=
"close-icon"
></span>
<span
class=
"close-icon"
></span>
</div>
</div>
<span
class=
"show-video blink invisible"
id=
"show-video"
>
<i
class=
"fas fa-exchange-alt"
aria-hidden=
"true"
></i>
</span>
<button
id=
"pushtalk"
class=
"btn btn-big btn-success invisible"
>
<i
id=
"pushvideo"
class=
"fas fa-play invisible"
aria-hidden=
"true"
></i>
<i
id=
"pushmic"
class=
"fas fa-microphone invisible"
aria-hidden=
"true"
></i>
</button>
<div
id=
"box"
></div>
<div
id=
"box"
></div>
<div
class=
"reply"
>
<div
class=
"reply"
>
<form
id=
"inputform"
>
<form
id=
"inputform"
>
...
@@ -85,19 +105,11 @@
...
@@ -85,19 +105,11 @@
</div>
</div>
<div
id=
"resizer"
></div>
<div
id=
"resizer"
></div>
<div
class=
"coln-right"
id=
"right"
>
<div
class=
"coln-right"
id=
"right"
>
<span
class=
"show-video blink invisible"
id=
"show-video"
>
<i
class=
"fas fa-exchange-alt"
aria-hidden=
"true"
></i>
</span>
<div
class=
"chat-btn show-chat invisible"
id=
"show-chat"
>
<div
class=
"chat-btn show-chat invisible"
id=
"show-chat"
>
<i
class=
"far fa-comment-alt icon-chat"
title=
"Show chat"
></i>
<i
class=
"far fa-comment-alt icon-chat"
title=
"Show chat"
></i>
</div>
</div>
<div
class=
"chat-btn collapse-video invisible"
id=
"collapse-video"
>
<i
class=
"far fa-comment-alt icon-chat"
title=
"Hide video and show chat"
></i>
</div>
<div
class=
"video-container invisible"
id=
"video-container"
>
<div
class=
"video-container invisible"
id=
"video-container"
>
<div
id=
"expand-video"
class=
"expand-video"
>
<div
id=
"peers"
></div>
<div
id=
"peers"
></div>
</div>
</div>
</div>
<div
class=
"login-container invisible"
id=
"login-container"
>
<div
class=
"login-container invisible"
id=
"login-container"
>
<div
class=
"login-box"
>
<div
class=
"login-box"
>
...
@@ -110,17 +122,17 @@
...
@@ -110,17 +122,17 @@
autocomplete=
"current-password"
class=
"form-control"
/>
autocomplete=
"current-password"
class=
"form-control"
/>
<label>
Enable at start:
</label>
<label>
Enable at start:
</label>
<div
class=
"present-switch"
>
<div
class=
"present-switch"
>
<p
class=
"switch-radio"
>
<
!--<
p class="switch-radio">
<input
id=
"presentoff"
type=
"radio"
name=
"presentradio"
value=
""
checked
/>
<input id="presentoff" type="radio" name="presentradio" value=""/>
<label for="presentoff">Nothing</label>
<label for="presentoff">Nothing</label>
</p>
</p>
-->
<p
class=
"switch-radio"
>
<p
class=
"switch-radio"
>
<input
id=
"presentmike"
type=
"radio"
name=
"presentradio"
value=
"mike"
/>
<input
id=
"presentmike"
type=
"radio"
name=
"presentradio"
value=
"mike"
/>
<label
for=
"presentmike"
>
Microphone
</label>
<label
for=
"presentmike"
>
Audio only
</label>
</p>
</p>
<p
class=
"switch-radio"
>
<p
class=
"switch-radio"
>
<input
id=
"present
both"
type=
"radio"
name=
"presentradio"
value=
"both"
/>
<input
id=
"present
video"
type=
"radio"
name=
"presentradio"
value=
"camera"
checked
/>
<label
for=
"present
both"
>
Camera and microphone
</label>
<label
for=
"present
video"
>
Audio and Camera
</label>
</p>
</p>
</div>
</div>
<div
class=
"clear"
></div>
<div
class=
"clear"
></div>
...
@@ -209,9 +221,9 @@
...
@@ -209,9 +221,9 @@
<form
id=
"sendform"
>
<form
id=
"sendform"
>
<label
for=
"sendselect"
class=
"sidenav-label-first"
>
Send:
</label>
<label
for=
"sendselect"
class=
"sidenav-label-first"
>
Send:
</label>
<select
id=
"sendselect"
class=
"select select-inline"
>
<select
id=
"sendselect"
class=
"select select-inline"
>
<option
value=
"lowest"
>
lowest
</option>
<option
value=
"lowest"
selected
>
lowest
</option>
<option
value=
"low"
>
low
</option>
<option
value=
"low"
>
low
</option>
<option
value=
"normal"
selected
>
normal
</option>
<option
value=
"normal"
>
normal
</option>
<option
value=
"unlimited"
>
unlimited
</option>
<option
value=
"unlimited"
>
unlimited
</option>
</select>
</select>
</form>
</form>
...
@@ -258,7 +270,7 @@
...
@@ -258,7 +270,7 @@
</span>
</span>
</div>
</div>
<div
class=
"controls-button controls-right"
>
<div
class=
"controls-button controls-right"
>
<span
class=
"pip"
title=
"Picture In Picture"
>
<span
class=
"pip
invisible
"
title=
"Picture In Picture"
>
<i
class=
"far fa-clone"
aria-hidden=
"true"
></i>
<i
class=
"far fa-clone"
aria-hidden=
"true"
></i>
</span>
</span>
<span
class=
"fullscreen"
title=
"Fullscreen"
>
<span
class=
"fullscreen"
title=
"Fullscreen"
>
...
@@ -272,6 +284,10 @@
...
@@ -272,6 +284,10 @@
<div
class=
"controls-button controls-right"
>
<div
class=
"controls-button controls-right"
>
<span
class=
"close-icon video-stop"
title=
"Stop video"
>
<span
class=
"close-icon video-stop"
title=
"Stop video"
>
</span>
</span>
<span
class=
"change-camera"
><i
class=
'fas fa-camera-rotate'
></i></span>
</div>
<div
class=
"controls-button controls-left"
>
<span
class=
"video-off"
><i
class=
'fas fa-video-camera'
></i></span>
</div>
</div>
</div>
</div>
</div>
</div>
...
...
static/galene.js
View file @
84948418
...
@@ -32,6 +32,12 @@ let groupStatus = {};
...
@@ -32,6 +32,12 @@ let groupStatus = {};
/** @type {string} */
/** @type {string} */
let
token
=
null
;
let
token
=
null
;
/** @type {Array} */
let
videoDevices
=
[];
/** @type {HTMLAudioElement} */
let
pushAudio
=
new
Audio
(
'
/audio/button-124476.mp3
'
);
/**
/**
* @typedef {Object} settings
* @typedef {Object} settings
* @property {boolean} [localMute]
* @property {boolean} [localMute]
...
@@ -247,20 +253,20 @@ function isMobileLayout() {
...
@@ -247,20 +253,20 @@ function isMobileLayout() {
* @param {boolean} [force]
* @param {boolean} [force]
*/
*/
function
hideVideo
(
force
)
{
function
hideVideo
(
force
)
{
let
mediadiv
=
document
.
getElementById
(
'
peers
'
);
let
mediadiv
=
document
.
getElementById
(
'
mypeer
'
);
if
(
mediadiv
.
childElementCount
>
0
&&
!
force
)
if
(
mediadiv
.
childElementCount
>
0
&&
!
force
)
return
;
return
;
setVisibility
(
'
video-container
'
,
false
);
setVisibility
(
'
my
video-container
'
,
false
);
scheduleReconsiderDownRate
();
scheduleReconsiderDownRate
();
}
}
function
showVideo
()
{
function
showVideo
()
{
let
hasmedia
=
document
.
getElementById
(
'
peers
'
).
childElementCount
>
0
;
let
hasmedia
=
document
.
getElementById
(
'
mypeer
'
).
childElementCount
>
0
;
if
(
isMobileLayout
())
{
if
(
isMobileLayout
())
{
setVisibility
(
'
show-video
'
,
false
);
setVisibility
(
'
show-video
'
,
false
);
setVisibility
(
'
collapse-video
'
,
hasmedia
);
setVisibility
(
'
collapse-video
'
,
hasmedia
);
}
}
setVisibility
(
'
video-container
'
,
hasmedia
);
//setVisibility('my
video-container', hasmedia);
scheduleReconsiderDownRate
();
scheduleReconsiderDownRate
();
}
}
...
@@ -301,6 +307,9 @@ async function gotConnected(username) {
...
@@ -301,6 +307,9 @@ async function gotConnected(username) {
token
=
null
;
token
=
null
;
}
else
{
}
else
{
setConnected
(
true
);
setConnected
(
true
);
// Set stream quality to lowest
updateSettings
({
send
:
'
lowest
'
});
pushAudio
.
volume
=
0.3
;
username
=
getInputElement
(
'
username
'
).
value
.
trim
();
username
=
getInputElement
(
'
username
'
).
value
.
trim
();
let
pw
=
getInputElement
(
'
password
'
).
value
;
let
pw
=
getInputElement
(
'
password
'
).
value
;
...
@@ -396,7 +405,7 @@ function setViewportHeight() {
...
@@ -396,7 +405,7 @@ function setViewportHeight() {
addEventListener
(
'
resize
'
,
setViewportHeight
);
addEventListener
(
'
resize
'
,
setViewportHeight
);
addEventListener
(
'
orientationchange
'
,
setViewportHeight
);
addEventListener
(
'
orientationchange
'
,
setViewportHeight
);
getButtonElement
(
'
p
resentbutton
'
).
onclick
=
async
function
(
e
)
{
getButtonElement
(
'
p
ushtalk
'
).
onclick
=
async
function
(
e
)
{
e
.
preventDefault
();
e
.
preventDefault
();
let
button
=
this
;
let
button
=
this
;
if
(
!
(
button
instanceof
HTMLButtonElement
))
if
(
!
(
button
instanceof
HTMLButtonElement
))
...
@@ -432,23 +441,30 @@ function setVisibility(id, visible) {
...
@@ -432,23 +441,30 @@ function setVisibility(id, visible) {
}
}
function
setButtonsVisibility
()
{
function
setButtonsVisibility
()
{
let
settings
=
getSettings
();
let
connected
=
serverConnection
&&
serverConnection
.
socket
;
let
connected
=
serverConnection
&&
serverConnection
.
socket
;
let
permissions
=
serverConnection
.
permissions
;
let
permissions
=
serverConnection
.
permissions
;
let
present
=
permissions
.
indexOf
(
'
present
'
)
>=
0
;
let
present
=
permissions
.
indexOf
(
'
present
'
)
>=
0
;
let
local
=
!!
findUpMedia
(
'
camera
'
);
let
local
=
!!
findUpMedia
(
'
camera
'
);
let
canWebrtc
=
!
(
typeof
RTCPeerConnection
===
'
undefined
'
);
let
canWebrtc
=
!
(
typeof
RTCPeerConnection
===
'
undefined
'
);
let
mediacount
=
document
.
getElementById
(
'
peers
'
).
childElementCount
;
let
mediacount
=
document
.
getElementById
(
'
mypeer
'
).
childElementCount
;
let
mobilelayout
=
isMobileLayout
();
let
mobilelayout
=
isMobileLayout
();
let
cameraEnabed
=
settings
.
video
?
true
:
false
;
// don't allow multiple presentations
// don't allow multiple presentations
setVisibility
(
'
presentbutton
'
,
canWebrtc
&&
present
&&
!
local
);
setVisibility
(
'
presentbutton
'
,
canWebrtc
&&
present
&&
!
mobilelayout
);
setVisibility
(
'
unpresentbutton
'
,
local
);
setVisibility
(
'
pushtalk
'
,
mobilelayout
&&
canWebrtc
&&
present
);
setVisibility
(
'
unpresentbutton
'
,
local
&&
!
mobilelayout
);
setVisibility
(
'
pushvideo
'
,
!
local
&&
mobilelayout
);
setVisibility
(
'
pushmic
'
,
local
&&
mobilelayout
);
setVisibility
(
'
videoon
'
,
local
&&
mobilelayout
&&
!
cameraEnabed
);
setVisibility
(
'
mutebutton
'
,
!
connected
||
present
);
setVisibility
(
'
mutebutton
'
,
false
);
// allow multiple shared documents
// allow multiple shared documents
setVisibility
(
'
sharebutton
'
,
canWebrtc
&&
present
&&
//setVisibility('sharebutton', canWebrtc && present &&
(
'
getDisplayMedia
'
in
navigator
.
mediaDevices
));
// ('getDisplayMedia' in navigator.mediaDevices));
setVisibility
(
'
sharebutton
'
,
false
);
setVisibility
(
'
mediaoptions
'
,
present
);
setVisibility
(
'
mediaoptions
'
,
present
);
setVisibility
(
'
sendform
'
,
present
);
setVisibility
(
'
sendform
'
,
present
);
...
@@ -539,6 +555,17 @@ document.getElementById('sharebutton').onclick = function(e) {
...
@@ -539,6 +555,17 @@ document.getElementById('sharebutton').onclick = function(e) {
addShareMedia
();
addShareMedia
();
};
};
document
.
getElementById
(
'
videoon
'
).
onclick
=
function
(
e
)
{
e
.
preventDefault
();
if
(
!
videoDevices
.
length
)
return
;
let
select
=
/** @type{HTMLSelectElement} */
document
.
getElementById
(
'
videoselect
'
);
select
.
value
=
videoDevices
[
0
];
updateSettings
({
video
:
videoDevices
[
0
]});
replaceCameraStream
();
};
getSelectElement
(
'
filterselect
'
).
onchange
=
async
function
(
e
)
{
getSelectElement
(
'
filterselect
'
).
onchange
=
async
function
(
e
)
{
if
(
!
(
this
instanceof
HTMLSelectElement
))
if
(
!
(
this
instanceof
HTMLSelectElement
))
throw
new
Error
(
'
Unexpected type for this
'
);
throw
new
Error
(
'
Unexpected type for this
'
);
...
@@ -826,6 +853,8 @@ async function setMediaChoices(done) {
...
@@ -826,6 +853,8 @@ async function setMediaChoices(done) {
label
=
`Camera
${
cn
}
`
;
label
=
`Camera
${
cn
}
`
;
addSelectOption
(
getSelectElement
(
'
videoselect
'
),
addSelectOption
(
getSelectElement
(
'
videoselect
'
),
label
,
d
.
deviceId
);
label
,
d
.
deviceId
);
if
(
videoDevices
.
indexOf
(
d
.
deviceId
)
===
-
1
)
videoDevices
.
push
(
d
.
deviceId
);
cn
++
;
cn
++
;
}
else
if
(
d
.
kind
===
'
audioinput
'
)
{
}
else
if
(
d
.
kind
===
'
audioinput
'
)
{
if
(
!
label
)
if
(
!
label
)
...
@@ -1187,7 +1216,9 @@ function setUpStream(c, stream) {
...
@@ -1187,7 +1216,9 @@ function setUpStream(c, stream) {
let
settings
=
getSettings
();
let
settings
=
getSettings
();
if
(
c
.
label
===
'
camera
'
)
{
if
(
c
.
label
===
'
camera
'
)
{
if
(
t
.
kind
==
'
audio
'
)
{
if
(
t
.
kind
==
'
audio
'
)
{
if
(
settings
.
localMute
)
//if(settings.localMute)
// always mute on mobile layout
if
(
isMobileLayout
)
t
.
enabled
=
false
;
t
.
enabled
=
false
;
}
else
if
(
t
.
kind
==
'
video
'
)
{
}
else
if
(
t
.
kind
==
'
video
'
)
{
if
(
settings
.
blackboardMode
)
{
if
(
settings
.
blackboardMode
)
{
...
@@ -1361,7 +1392,10 @@ async function addLocalMedia(localId) {
...
@@ -1361,7 +1392,10 @@ async function addLocalMedia(localId) {
video
.
width
=
{
min
:
640
,
ideal
:
1920
};
video
.
width
=
{
min
:
640
,
ideal
:
1920
};
video
.
height
=
{
min
:
400
,
ideal
:
1080
};
video
.
height
=
{
min
:
400
,
ideal
:
1080
};
}
}
setVisibility
(
'
myvideo-container
'
,
true
);
}
}
else
setVisibility
(
'
myvideo-container
'
,
false
);
if
(
audio
)
{
if
(
audio
)
{
if
(
!
settings
.
preprocessing
)
{
if
(
!
settings
.
preprocessing
)
{
...
@@ -1674,12 +1708,16 @@ function scheduleReconsiderDownRate() {
...
@@ -1674,12 +1708,16 @@ function scheduleReconsiderDownRate() {
*/
*/
async
function
setMedia
(
c
,
isUp
,
mirror
,
video
)
{
async
function
setMedia
(
c
,
isUp
,
mirror
,
video
)
{
let
peersdiv
=
document
.
getElementById
(
'
peers
'
);
let
peersdiv
=
document
.
getElementById
(
'
peers
'
);
let
div
=
document
.
getElementById
(
'
peer-
'
+
c
.
localId
);
let
div
=
document
.
getElementById
(
'
peer-
'
+
c
.
localId
);
if
(
isUp
)
{
//let container = document.getElementById("myvideo-container");
//container.classList.remove('invisible');
peersdiv
=
document
.
getElementById
(
'
mypeer
'
);
}
if
(
!
div
)
{
if
(
!
div
)
{
div
=
document
.
createElement
(
'
div
'
);
div
=
document
.
createElement
(
'
div
'
);
div
.
id
=
'
peer-
'
+
c
.
localId
;
div
.
id
=
'
peer-
'
+
c
.
localId
;
div
.
classList
.
add
(
'
peer
'
);
div
.
classList
.
add
(
'
peer
'
,
'
invisible
'
);
peersdiv
.
appendChild
(
div
);
peersdiv
.
appendChild
(
div
);
}
}
...
@@ -1701,7 +1739,13 @@ async function setMedia(c, isUp, mirror, video) {
...
@@ -1701,7 +1739,13 @@ async function setMedia(c, isUp, mirror, video) {
div
.
appendChild
(
media
);
div
.
appendChild
(
media
);
addCustomControls
(
media
,
div
,
c
,
!!
video
);
addCustomControls
(
media
,
div
,
c
,
!!
video
);
}
}
if
(
peersdiv
.
childElementCount
===
1
)
{
if
(
!
isUp
)
{
let
container
=
document
.
getElementById
(
"
video-container
"
);
container
.
classList
.
remove
(
'
invisible
'
);
}
div
.
classList
.
remove
(
'
invisible
'
);
}
if
(
mirror
)
if
(
mirror
)
media
.
classList
.
add
(
'
mirror
'
);
media
.
classList
.
add
(
'
mirror
'
);
else
else
...
@@ -1857,6 +1901,34 @@ function registerControlHandlers(localId, media, container) {
...
@@ -1857,6 +1901,34 @@ function registerControlHandlers(localId, media, container) {
}
}
};
};
}
}
let
camera
=
getVideoButton
(
container
,
'
change-camera
'
);
if
(
camera
)
{
camera
.
onclick
=
function
(
event
)
{
event
.
preventDefault
();
if
(
videoDevices
.
length
===
1
)
return
;
let
select
=
/** @type{HTMLSelectElement} */
document
.
getElementById
(
'
videoselect
'
);
let
pos
=
videoDevices
.
indexOf
(
select
.
value
)
+
1
;
if
(
pos
===
0
||
pos
>=
videoDevices
.
length
)
pos
=
0
;
select
.
value
=
videoDevices
[
pos
];
updateSettings
({
video
:
videoDevices
[
pos
]});
replaceCameraStream
();
};
}
let
videooff
=
getVideoButton
(
container
,
'
video-off
'
);
if
(
videooff
)
{
videooff
.
onclick
=
function
(
event
)
{
event
.
preventDefault
();
let
select
=
/** @type{HTMLSelectElement} */
document
.
getElementById
(
'
videoselect
'
);
select
.
value
=
''
;
updateSettings
({
video
:
''
});
replaceCameraStream
();
}
}
let
volume
=
getVideoButton
(
container
,
'
volume
'
);
let
volume
=
getVideoButton
(
container
,
'
volume
'
);
if
(
volume
)
{
if
(
volume
)
{
...
@@ -1916,11 +1988,25 @@ function registerControlHandlers(localId, media, container) {
...
@@ -1916,11 +1988,25 @@ function registerControlHandlers(localId, media, container) {
}
}
}
}
function
setDownStreamVisibility
()
{
let
peers
=
document
.
getElementById
(
'
peers
'
);
let
visiblemedia
=
peers
.
querySelector
(
'
.peer:not(.invisible)
'
);
if
(
visiblemedia
)
return
;
else
if
(
peers
.
childElementCount
===
0
)
setVisibility
(
"
video-container
"
,
false
);
else
{
let
lastChild
=
/** @type{HTMLElement} */
peers
.
lastChild
;
lastChild
.
classList
.
remove
(
'
invisible
'
);
}
}
/**
/**
* @param {string} localId
* @param {string} localId
*/
*/
function
delMedia
(
localId
)
{
function
delMedia
(
localId
)
{
let
mediadiv
=
document
.
getElementById
(
'
peers
'
);
let
mediadiv
=
document
.
getElementById
(
'
peers
'
);
let
mymediadiv
=
document
.
getElementById
(
'
mypeer
'
);
let
peer
=
document
.
getElementById
(
'
peer-
'
+
localId
);
let
peer
=
document
.
getElementById
(
'
peer-
'
+
localId
);
if
(
!
peer
)
if
(
!
peer
)
throw
new
Error
(
'
Removing unknown media
'
);
throw
new
Error
(
'
Removing unknown media
'
);
...
@@ -1929,9 +2015,12 @@ function delMedia(localId) {
...
@@ -1929,9 +2015,12 @@ function delMedia(localId) {
(
document
.
getElementById
(
'
media-
'
+
localId
));
(
document
.
getElementById
(
'
media-
'
+
localId
));
media
.
srcObject
=
null
;
media
.
srcObject
=
null
;
mediadiv
.
removeChild
(
peer
);
if
(
peer
.
parentElement
.
id
===
"
peers
"
)
mediadiv
.
removeChild
(
peer
);
else
mymediadiv
.
removeChild
(
peer
);
setButtonsVisibility
();
setButtonsVisibility
();
setDownStreamVisibility
();
resizePeers
();
resizePeers
();
hideVideo
();
hideVideo
();
}
}
...
@@ -1989,9 +2078,11 @@ function resizePeers() {
...
@@ -1989,9 +2078,11 @@ function resizePeers() {
// Window resize can call this method too early
// Window resize can call this method too early
if
(
!
serverConnection
)
if
(
!
serverConnection
)
return
;
return
;
let
count
=
//let count =
Object
.
keys
(
serverConnection
.
up
).
length
+
// Object.keys(serverConnection.up).length +
Object
.
keys
(
serverConnection
.
down
).
length
;
// Object.keys(serverConnection.down).length;
// always disply one video
let
count
=
1
;
let
peers
=
document
.
getElementById
(
'
peers
'
);
let
peers
=
document
.
getElementById
(
'
peers
'
);
let
columns
=
Math
.
ceil
(
Math
.
sqrt
(
count
));
let
columns
=
Math
.
ceil
(
Math
.
sqrt
(
count
));
if
(
!
count
)
if
(
!
count
)
...
@@ -2105,15 +2196,52 @@ function userMenu(elt) {
...
@@ -2105,15 +2196,52 @@ function userMenu(elt) {
function
addUser
(
id
,
userinfo
)
{
function
addUser
(
id
,
userinfo
)
{
let
div
=
document
.
getElementById
(
'
users
'
);
let
div
=
document
.
getElementById
(
'
users
'
);
let
user
=
document
.
createElement
(
'
div
'
);
let
user
=
document
.
createElement
(
'
div
'
);
let
usercontent
=
document
.
createElement
(
'
div
'
);
let
spantext
=
document
.
createElement
(
'
span
'
);
user
.
id
=
'
user-
'
+
id
;
user
.
id
=
'
user-
'
+
id
;
user
.
classList
.
add
(
"
user-p
"
);
user
.
classList
.
add
(
"
user-p
"
);
usercontent
.
appendChild
(
spantext
);
spantext
.
textContent
=
userinfo
.
username
?
userinfo
.
username
:
'
(anon)
'
;
if
(
spantext
.
textContent
!==
serverConnection
.
username
)
{
let
span
=
document
.
createElement
(
'
span
'
);
let
i
=
document
.
createElement
(
'
i
'
);
i
.
classList
.
add
(
'
fas
'
,
'
fa-eye
'
);
i
.
setAttribute
(
'
aria-hidden
'
,
'
true
'
)
span
.
appendChild
(
i
);
span
.
classList
.
add
(
'
activate
'
);
usercontent
.
appendChild
(
span
);
span
.
addEventListener
(
'
click
'
,
function
(
e
)
{
console
.
log
(
'
Swith video
'
);
let
divp
=
/** @type{HTMLElement} */
e
.
target
.
parentElement
.
parentElement
.
parentElement
;
if
(
!
divp
)
throw
new
Error
(
"
Couldn't find user ID
"
);
let
userid
=
divp
.
id
.
split
(
'
-
'
)[
1
];
let
mediadiv
=
null
;
for
(
let
id
in
serverConnection
.
down
)
{
if
(
serverConnection
.
down
[
id
].
source
===
userid
)
{
mediadiv
=
document
.
getElementById
(
'
peer-
'
+
serverConnection
.
down
[
id
].
localId
);
console
.
log
(
mediadiv
);
}
}
if
(
!
mediadiv
)
throw
new
Error
(
"
Couldn't find media
"
);
let
peers
=
document
.
getElementById
(
'
peers
'
);
let
visiblemedia
=
peers
.
querySelector
(
'
div:not(.invisible)
'
);
if
(
visiblemedia
)
visiblemedia
.
classList
.
add
(
'
invisible
'
);
mediadiv
.
classList
.
remove
(
'
invisible
'
);
console
.
log
(
e
);
});
}
user
.
appendChild
(
usercontent
);
setUserStatus
(
id
,
user
,
userinfo
);
setUserStatus
(
id
,
user
,
userinfo
);
user
.
addEventListener
(
'
click
'
,
function
(
e
)
{
/*
user.addEventListener('click', function(e) {
let elt = e.target;
let elt = e.target;
if(!elt || !(elt instanceof HTMLElement))
if(!elt || !(elt instanceof HTMLElement))
throw new Error("Couldn't find user div");
throw new Error("Couldn't find user div");
userMenu(elt);
userMenu(elt);
});
});
*/
let
us
=
div
.
children
;
let
us
=
div
.
children
;
...
@@ -2162,6 +2290,7 @@ function changeUser(id, userinfo) {
...
@@ -2162,6 +2290,7 @@ function changeUser(id, userinfo) {
* @param {user} userinfo
* @param {user} userinfo
*/
*/
function
setUserStatus
(
id
,
elt
,
userinfo
)
{
function
setUserStatus
(
id
,
elt
,
userinfo
)
{
return
false
;
elt
.
textContent
=
userinfo
.
username
?
userinfo
.
username
:
'
(anon)
'
;
elt
.
textContent
=
userinfo
.
username
?
userinfo
.
username
:
'
(anon)
'
;
if
(
userinfo
.
data
.
raisehand
)
if
(
userinfo
.
data
.
raisehand
)
elt
.
classList
.
add
(
'
user-status-raisehand
'
);
elt
.
classList
.
add
(
'
user-status-raisehand
'
);
...
@@ -2306,7 +2435,7 @@ async function gotJoined(kind, group, perms, status, data, message) {
...
@@ -2306,7 +2435,7 @@ async function gotJoined(kind, group, perms, status, data, message) {
delSetting
(
'
video
'
);
delSetting
(
'
video
'
);
reflectSettings
();
reflectSettings
();
let
button
=
getButtonElement
(
'
p
resentbutton
'
);
let
button
=
getButtonElement
(
'
p
ushtalk
'
);
button
.
disabled
=
true
;
button
.
disabled
=
true
;
try
{
try
{
await
addLocalMedia
();
await
addLocalMedia
();
...
@@ -3711,7 +3840,7 @@ function displayError(message, level) {
...
@@ -3711,7 +3840,7 @@ function displayError(message, level) {
case
"
info
"
:
case
"
info
"
:
background
=
'
linear-gradient(to right, #529518, #96c93d)
'
;
background
=
'
linear-gradient(to right, #529518, #96c93d)
'
;
position
=
'
right
'
;
position
=
'
right
'
;
gravity
=
'
bottom
'
;
gravity
=
'
top
'
;
break
;
break
;
case
"
warning
"
:
case
"
warning
"
:
background
=
"
linear-gradient(to right, #bdc511, #c2cf01)
"
;
background
=
"
linear-gradient(to right, #bdc511, #c2cf01)
"
;
...
@@ -3762,14 +3891,14 @@ document.getElementById('userform').onsubmit = async function(e) {
...
@@ -3762,14 +3891,14 @@ document.getElementById('userform').onsubmit = async function(e) {
connecting
=
false
;
connecting
=
false
;
}
}
if
(
getInputElement
(
'
present
both
'
).
checked
)
if
(
getInputElement
(
'
present
video
'
).
checked
)
presentRequested
=
'
both
'
;
presentRequested
=
'
both
'
;
else
if
(
getInputElement
(
'
presentmike
'
).
checked
)
else
if
(
getInputElement
(
'
presentmike
'
).
checked
)
presentRequested
=
'
mike
'
;
presentRequested
=
'
mike
'
;
else
else
presentRequested
=
null
;
presentRequested
=
'
both
'
;
getInputElement
(
'
presentoff
'
).
checked
=
true
;
//
getInputElement('presentoff').checked = true;
};
};
document
.
getElementById
(
'
disconnectbutton
'
).
onclick
=
function
(
e
)
{
document
.
getElementById
(
'
disconnectbutton
'
).
onclick
=
function
(
e
)
{
...
@@ -3801,6 +3930,21 @@ document.getElementById('openside').onclick = function(e) {
...
@@ -3801,6 +3930,21 @@ document.getElementById('openside').onclick = function(e) {
}
}
};
};
document
.
getElementById
(
'
pushtalk
'
).
addEventListener
(
'
contextmenu
'
,
e
=>
e
.
preventDefault
());
document
.
getElementById
(
'
pushtalk
'
).
ontouchstart
=
function
(
e
)
{
if
(
!!
findUpMedia
(
'
camera
'
))
{
pushAudio
.
play
();
muteLocalTracks
(
false
);
}
};
document
.
getElementById
(
'
pushtalk
'
).
ontouchend
=
function
(
e
)
{
if
(
!!
findUpMedia
(
'
camera
'
))
{
muteLocalTracks
(
true
);
displayError
(
'
user mic off
'
,
'
info
'
);
}
};
document
.
getElementById
(
'
clodeside
'
).
onclick
=
function
(
e
)
{
document
.
getElementById
(
'
clodeside
'
).
onclick
=
function
(
e
)
{
e
.
preventDefault
();
e
.
preventDefault
();
...
@@ -3812,11 +3956,12 @@ document.getElementById('collapse-video').onclick = function(e) {
...
@@ -3812,11 +3956,12 @@ document.getElementById('collapse-video').onclick = function(e) {
setVisibility
(
'
collapse-video
'
,
false
);
setVisibility
(
'
collapse-video
'
,
false
);
setVisibility
(
'
show-video
'
,
true
);
setVisibility
(
'
show-video
'
,
true
);
hideVideo
(
true
);
hideVideo
(
true
);
displayMessage
(
"
Your video is still visible!
"
);
};
};
document
.
getElementById
(
'
show-video
'
).
onclick
=
function
(
e
)
{
document
.
getElementById
(
'
show-video
'
).
onclick
=
function
(
e
)
{
e
.
preventDefault
();
e
.
preventDefault
();
setVisibility
(
'
video-container
'
,
true
);
setVisibility
(
'
my
video-container
'
,
true
);
setVisibility
(
'
collapse-video
'
,
true
);
setVisibility
(
'
collapse-video
'
,
true
);
setVisibility
(
'
show-video
'
,
false
);
setVisibility
(
'
show-video
'
,
false
);
};
};
...
...
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