2023-12-27 17:25:49 +00:00
chatComponent = {
html : `
< div id = "videos" style = "pointer-events:none" > < / d i v >
< div id = "messages" aria - live = "assertive" aria - relevant > < / d i v >
< div id = "chatfooter" >
< div id = "chatbar" >
< input id = "chatline" type = "text" placeholder = "type here" > < / i n p u t >
< / d i v >
< button id = "showchat" class = "btn" > show chat < / b u t t o n >
< / d i v >
< / d i v >
` ,
init : ( el ) => new Proxy ( {
scene : null ,
visible : true ,
messages : [ ] ,
$messages : $messages = el . querySelector ( "#messages" ) ,
$chatline : $chatline = el . querySelector ( "#chatline" ) ,
install ( opts ) {
this . opts = opts
this . scene = opts . scene
el . className = "xrf"
el . style . display = 'none' // start hidden
document . body . appendChild ( el )
document . dispatchEvent ( new CustomEvent ( "$chat:ready" , { detail : opts } ) )
2023-12-27 18:26:42 +00:00
$chat . send ( { message : ` Welcome to <b> ${ document . location . search . substr ( 1 ) } </b>, a 3D scene(file) which simply links to other ones.<br>You can start a solo offline exploration in XR right away.<br>Type /help below, or use the arrow- or WASD-keys on your keyboard, and mouse-drag to rotate.<br> ` , class : [ "info" , "multiline" ] } )
2023-12-27 17:25:49 +00:00
} ,
initListeners ( ) {
//opts.scene.addEventListener('meeting.peer.add', () => console.log("$chat.peer.add") )
//opts.scene.addEventListener('meeting.peer.remove', () => console.log("$chat.peer.remove") )
$chatline . addEventListener ( 'keydown' , ( e ) => {
if ( e . key == 'Enter' ) {
this . send ( { message : $chatline . value } )
$chatline . value = ''
}
} )
console . dir ( this . scene )
} ,
toggle ( ) {
this . visible = ! this . visible
if ( this . visible && window . meeting . status == 'offline' ) window . meeting . start ( this . opts )
} ,
send ( opts ) {
opts = { linebreak : true , message : "" , class : [ ] , ... opts }
let msg = document . createElement ( 'div' )
let br = document . createElement ( 'br' )
msg . className = "msg"
let html = ` ${ opts . message || '' } ${ opts . html ? opts . html ( opts ) : '' } `
if ( $messages . last == html ) return
msg . innerHTML = html
if ( opts . el ) msg . appendChild ( opts . el )
opts . id = Math . random ( )
if ( opts . class ) {
msg . classList . add . apply ( msg . classList , opts . class )
br . classList . add . apply ( br . classList , opts . class )
}
$messages . appendChild ( msg )
if ( opts . linebreak ) $messages . appendChild ( br )
$messages . scrollTop = $messages . scrollHeight // scroll down
document . dispatchEvent ( new CustomEvent ( "$chat:receive" , { detail : opts } ) )
$messages . last = msg . innerHTML
}
} , {
get ( data , k , v ) { return data [ k ] } ,
set ( data , k , v ) {
data [ k ] = v
switch ( k ) {
case "visible" : {
el . style . display = data . visible ? 'block' : 'none'
if ( ! el . inited && ( el . inited = true ) ) data . initListeners ( )
$menu . collapsed = ! data . visible
break ;
}
}
}
} )
}
// reactify component!
document . addEventListener ( '$menu:ready' , ( opts ) => {
opts = opts . detail
document . head . innerHTML += chatComponent . css
$chat = document . createElement ( 'div' )
$chat . innerHTML = chatComponent . html
$chat = chatComponent . init ( $chat )
$chat . install ( opts )
//$menu.buttons = ([`<a class="btn" aria-label="button" aria-description="toggle text" id="meeting" onclick="$chat.toggle()">📜 toggle text</a><br>`])
// .concat($menu.buttons)
} )
// alpine component for displaying meetings
chatComponent . css = `
< style type = "text/css" >
# videos {
display : grid - auto - columns ;
grid - column - gap : 5 px ;
margin - bottom : 15 px ;
position : fixed ;
top : 0 ;
left : 0 ;
bottom : 0 ;
right : 0 ;
margin : 15 px ;
z - index : 1500 ;
}
# videos > video {
border - radius : 7 px ;
display : inline - block ;
background : black ;
width : 80 px ;
height : 60 px ;
margin - right : 5 px ;
margin - bottom : 5 px ;
vertical - align : top ;
pointer - events : all ;
}
# videos > video : hover {
filter : brightness ( 1.8 ) ;
cursor : pointer ;
}
# chatbar ,
button # showchat {
z - index : 1500 ;
position : fixed ;
2023-12-27 21:31:42 +00:00
bottom : 24 px ;
height : 34 px ;
2023-12-27 17:25:49 +00:00
left : 20 px ;
width : 48 % ;
background : white ;
padding : 0 px 0 px 0 px 15 px ;
border - radius : 30 px ;
max - width : 500 px ;
box - sizing : border - box ;
box - shadow : 0 px 0 px 5 px 5 px # 0002 ;
}
button # showchat {
z - index : 1550 ;
color : white ;
border : 0 ;
display : none ;
height : 44 px ;
background : # 07 F ;
font - weight : bold ;
}
# chatbar input {
border : none ;
width : 90 % ;
box - sizing : border - box ;
2023-12-27 21:31:42 +00:00
height : 24 px ;
font - size : var ( -- xrf - font - size - 2 ) ;
2023-12-27 17:25:49 +00:00
}
# messages {
position : absolute ;
top : 100 px ;
left : 0 ;
right : 0 ;
bottom : 88 px ;
padding : 15 px ;
pointer - events : none ;
overflow - y : auto ;
}
# messages . msg {
background : # fff ;
display : inline - block ;
padding : 6 px 17 px ;
border - radius : 20 px ;
color : # 000 c ;
margin - bottom : 10 px ;
line - height : 23 px ;
pointer - events : visible ;
border : 1 px solid # ccc8 ;
line - height : 33 px ;
}
# messages . msg . info {
font - size : 14 px ;
padding : 3 px 16 px ;
}
2023-12-27 18:26:42 +00:00
# messages . guide , . guide {
2023-12-27 17:25:49 +00:00
display : unset ;
}
2023-12-27 18:26:42 +00:00
# messages . guide , . guide {
2023-12-27 17:25:49 +00:00
display : none ;
}
br . guide {
display : inline - block ;
}
# messages . msg . info a ,
# messages . msg . info a : visited {
color : var ( -- xrf - primary ) ;
text - decoration : underline ;
transition : 0.3 s ;
}
# messages . msg . info a : hover ,
# messages button : hover {
filter : brightness ( 1.4 ) ;
}
# messages . msg . multiline {
padding : 2 px 14 px ;
}
2023-12-27 21:31:42 +00:00
# messages . msg . config {
background : #
}
2023-12-27 17:25:49 +00:00
# messages button {
text - decoration : none ;
margin : 0 px 15 px 10 px 0 px ;
background : var ( -- xrf - primary ) ;
font - family : var ( -- xrf - font - sans - serif ) ;
color : # FFF ;
border - radius : 7 px ;
padding : 11 px 15 px ;
border : 0 ;
font - weight : bold ;
box - shadow : 0 px 0 px 5 px 5 px # 0002 ;
pointer - events : all ;
}
# messages , # chatbar , # chatbar * , # messages * {
}
2023-12-27 18:26:42 +00:00
# messages button . emoticon ,
# messages . btn . emoticon {
line - height : 2 px ;
width : 20 px ;
display : inline - block ;
padding : 0 px 0 px ;
margin : 0 ;
vertical - align : middle ;
background : none ;
border : none ;
min - width : 31 px ;
box - shadow : none ;
}
# messages button . emoticon : hover ,
# messages . btn . emoticon : hover {
border : 1 px solid # ccc ! important ;
background : # EEE ;
}
2023-12-27 21:31:42 +00:00
. nomargin {
2023-12-27 18:26:42 +00:00
margin : 0 ;
}
2023-12-27 17:25:49 +00:00
< / s t y l e > `