2024-11-25 15:45:53 +00:00
if ( window . PvInternals . services _client ) {
2024-11-26 15:30:33 +00:00
console . log ( "%c--> pv.me" , ` color:yellow;font-size:30pt; ` )
console . log ( "%cinternals available at window.PvInternals" , ` color:yellow;font-size:20pt; ` )
2024-11-25 15:45:53 +00:00
}
2024-11-26 15:30:33 +00:00
// Reimplement PopupManager.open
( ( ) => {
const pv = window . PvInternals ;
pv . popupMap = {
[ pv . Modal . BAN ] : pv . components _popups _pv _ban _pv _ban ,
[ pv . Modal . PROFILE ] : pv . components _popups _pv _profile _pv _profile ,
[ pv . Modal . SETTINGS ] : pv . components _popups _pv _settings _pv _settings ,
[ pv . Modal . MESSAGE ] : pv . components _popups _pv _message _pv _message ,
[ pv . Modal . NEW _ROOM ] : pv . components _popups _pv _new _room _pv _new _room ,
[ pv . Dialog . ROOMS ] : pv . components _popups _pv _rooms _pv _rooms ,
[ pv . Dialog . ACTIONS ] : pv . components _popups _pv _actions _pv _actions ,
[ pv . Dialog . DEVICES ] : pv . components _popups _pv _devices _pv _devices ,
[ pv . Dialog . SOUNDS ] : pv . components _popups _pv _sounds _pv _sounds ,
[ pv . Dialog . TRANSPOSE ] : pv . components _popups _pv _transpose _pv _transpose ,
[ pv . Dialog . VELOCITY ] : pv . components _popups _pv _velocity _pv _velocity ,
} ;
pv . PopupManager . open = ( popupName , ... args ) => {
let dialogElement = document . querySelector ( popupName )
if ( dialogElement && ! dialogElement . querySelector ( "dialog" ) . hasAttribute ( "closing" ) ) {
dialogElement . close ( ) ;
return dialogElement ;
}
const popupClass = pv . popupMap [ popupName ] ;
if ( ! popupClass ) {
throw new Error ( ` Popup ${ popupName } not found ` ) ;
}
dialogElement = new popupClass ( ) ;
document . body . append ( dialogElement ) ;
dialogElement . open ( ... args ) ;
return dialogElement ;
}
} ) ( ) ;
2024-11-25 15:32:52 +00:00
// custom rules
2024-11-25 15:25:15 +00:00
( ( ) => {
const pv = window . PvInternals ;
class PvmeRulesModal extends pv . components _pv _popup _pv _popup {
constructor ( ) {
2024-11-25 15:59:30 +00:00
super ( ) ;
this . innerHTML = ` <dialog blocking class=popup modal><div class=header><div class=title style=margin-right:20px><i class="fas fa-info-circle"></i> Rules</div><div class=x><i class="fas fa-xmark"></i></div></div><div class=content><div class=message><b>pianoverse.me rules are very simple.</b><ul><li>Don't be annoying<li>Don't be racist<li>Do not argue punishments</ul>That's it! :)</div></div></dialog> ` ;
2024-11-25 15:25:15 +00:00
}
}
customElements . define ( "pvme-rules-modal" , PvmeRulesModal ) ;
pv . Modal . RULES = "pvme-rules-modal" ;
2024-11-26 15:30:33 +00:00
pv . popupMap [ pv . Modal . RULES ] = PvmeRulesModal
2024-11-25 15:59:30 +00:00
2024-11-25 15:25:15 +00:00
class PvmeRules extends HTMLElement { }
customElements . define ( "pvme-rules" , PvmeRules ) ;
let g = document . querySelector ( "body > pv-header > div.left" ) ;
{ let a = document . createElement ( "div" ) ; a . className = "divider" ; a . style . marginLeft = "20px" ; g . appendChild ( a ) ; }
{
2024-11-25 15:59:30 +00:00
let a = document . createElement ( "pvme-rules" ) ;
a . innerHTML = ` <div class="icon" aria-label="Rules" data-tooltip="Rules"><i class="fas fa-scale-balanced"></i></div> ` ;
a . addEventListener ( "click" , ( ) => {
pv . PopupManager . open ( pv . Modal . RULES , null ) ;
} )
g . appendChild ( a ) ;
2024-11-25 15:25:15 +00:00
}
2024-11-25 15:45:53 +00:00
} ) ( ) ;
// change title
( ( ) => {
const pv = window . PvInternals ;
document . querySelector ( "pv-room" ) . updateBrowserTab = function ( ) {
if ( pv . services _client . room . id ) {
if ( pv . services _client . isConnected ( ) ) {
document . title = ` pv.me - ${ pv . services _client . room . id } ( ${ 1 + pv . services _client . users . length } ) `
} else {
document . title = ` pv.me - ${ pv . services _client . room . id } `
}
} else {
document . title = "pv.me"
}
}
document . querySelector ( "body > pv-header > div.left > div.pianoverse > span" ) . innerText = "pv.me"
2024-11-26 15:30:33 +00:00
} ) ( ) ;
( async ( ) => {
const style = document . createElement ( "style" ) ;
style . innerHTML = ` pv-chat>div button:nth-child(3){position:absolute;right:40px;z-index:26;cursor:url(88b4a467a18e813218f8.cur),auto;font-size:1em;border:none;height:46px;aspect-ratio:1;padding:0;border-radius:0;box-shadow:none;margin:0;flex:0;color:var(--color-text)}pv-chat>div button:nth-child(3)>img:hover{transform-origin:50% 50%;transform:scale(1.4);transition:.1s}pv-chat>div input[type=text]{padding:0 90px 0 14px}.emoji-container{display:grid;grid-template-columns:auto auto auto auto auto auto}.emoji-container>*{text-align:center;margin:2px} `
document . head . appendChild ( style ) ;
2024-11-26 16:07:33 +00:00
let shiftHeldDown = false ; // ShiftLeft/Right or False
document . addEventListener ( "keydown" , ( e ) => {
if ( ! shiftHeldDown ) shiftHeldDown = e . code ;
} )
document . addEventListener ( "keyup" , ( e ) => {
if ( e . code == shiftHeldDown ) shiftHeldDown = false ;
} )
2024-11-26 15:30:33 +00:00
const pv = window . PvInternals ;
const emojiRequest = await fetch ( "emojis.json" ) ;
let emojis = await emojiRequest . json ( )
const discordEmojis = [ '<:bratkanye:1271842184798273668>' , '<a:aniblobsweat:586029851870363660>' , '<:blobpensive:978314885337346089>' , '<:blobsip:978314935077597231>' , '<:blobheart:856700296302428170>' , '<:blobsaluteban:463464097137295392>' , '<:blobthinkban:812905997034061834>' , '<:blobreach:474817265339203584>' , '<a:blobReachAustralia:1247812442239795282>' , '<:nixos:1252753664397934646>' , '<:archlinux:1252754080640667658>' , '<:rust:1263598244588425388>' , '<:perfect:1243013970764370061>' , '<:True:811294080662896640>' , '<:froglove:1228043131430240407>' , '<a:frogpop:1228043129811374081>' , '<a:frogwave:1228043128871845979>' , '<:pianoverse:1218346119705133116>' , '<:restart:1257118826106064899>' , '<:tape:1274061265714811054>' , '<:what:1279839007714316392>' , '<:boof:1261047926088663161>' , '<:CHECK_CHECK_1:1075442774649872384>' , '<:CHECK_CROSS_1:1075442781708898414>' , '<a:pogg:947236908256362496>' , '<a:peeposhy:1052873747561971732>' , '<a:catfbi:1292722712212672582>' , '<:cat:1184105614994063410>' , '<:MBDTF:1263773146972946442>' , '<a:SpeedL:906979227939778580>' , '<a:SpeedR:906979227876864051>' , '<a:newports:1005206666792419458>' , '<a:myman:829624853845245953>' , '<a:skyperock:937848388685279262>' , '<:shut:714946339850420324>' , '<a:sponge:854419399871561800>' , '<a:weedwalker:855115903426625578>' , '<a:furret:791595456147750943>' , '<a:weewoo_red:706925335228317868>' ] ;
const discordEmojiRegex = /<(a?):.*?:(\d+)>/g ;
function renderEmoji ( emoji , size = "64" ) {
const id = emoji . replace ( discordEmojiRegex , "$2" ) ;
const isAnimated = ! ! emoji . replace ( discordEmojiRegex , "$1" )
const img = document . createElement ( "img" ) ;
img . src = ` https://cdn.discordapp.com/emojis/ ${ id } . ${ isAnimated ? "gif" : "png" } ?size= ${ size } ` ;
img . alt = "emoji" ;
img . width = size ;
img . height = size ;
return img ;
}
//#region Modal
class PvmeEmojiPicker extends pv . components _pv _popup _pv _popup {
2024-11-26 16:07:33 +00:00
2024-11-26 15:30:33 +00:00
constructor ( ) {
super ( ) ;
const dialog = document . createElement ( "dialog" ) ;
dialog . className = "popup"
dialog . setAttribute ( "modal" , "" )
dialog . setAttribute ( "blocking" , "" )
const header = document . createElement ( "div" ) ;
header . className = "header" ;
header . innerHTML = ` <div class="title"><i class="fas fa-info-circle" aria-hidden="true"></i>Emoji picker</div><div class="x"><i class="fas fa-xmark" aria-hidden="true"></i></div> `
dialog . appendChild ( header )
const content = document . createElement ( "div" )
content . className = "content"
// #region Modal search input
const input = document . createElement ( "input" )
input . type = "text"
input . value = pv . settingsmanager . get ( "latestEmojiLookup" ) || ""
input . addEventListener ( "keyup" , ( ) => {
pv . settingsmanager . set ( "latestEmojiLookup" , input . value ) ;
this . renderContainer ( document . querySelector ( ".emoji-container" ) , input . value )
} ) ;
content . appendChild ( input )
// #endregion
// #region Modal info
const info = document . createElement ( "p" )
2024-11-26 16:07:33 +00:00
info . innerText = "Write 'discord' for discord emoijs, anything else for normal ones.\nHold shift before opening emoji picker to spam emojis."
2024-11-26 15:30:33 +00:00
content . appendChild ( info ) ;
//#endregion
const container = document . createElement ( "div" )
container . className = "emoji-container"
this . renderContainer ( container , pv . settingsmanager . get ( "latestEmojiLookup" ) || "discord" )
content . append ( container ) ;
dialog . appendChild ( content )
this . appendChild ( dialog )
}
renderContainer ( container , value ) {
container . innerHTML = ""
if ( value !== "discord" ) {
emojis . filter ( z => z [ 0 ] . replace ( "_" , " " ) . includes ( value . toLowerCase ( ) ) || value . toLowerCase ( ) . includes ( z [ 0 ] . replace ( "_" , " " ) ) ) . slice ( 0 , 30 ) . forEach ( z => {
const div = document . createElement ( "div" )
div . innerText = z [ 1 ] ;
div . style . fontSize = "30px"
div . addEventListener ( "click" , ( ) => {
const chat = document . querySelector ( "pv-chat" ) ;
chat . input . value += z [ 1 ] + " " ;
2024-11-26 16:07:33 +00:00
console . log ( shiftHeldDown )
if ( ! shiftHeldDown ) pv . PopupManager . closeModals ( ) ;
2024-11-26 15:30:33 +00:00
setTimeout ( ( ) => {
document . querySelector ( "pv-chat" ) . input . scrollLeft = document . querySelector ( "pv-chat" ) . input . scrollWidth ;
} , 50 )
} )
container . appendChild ( div ) ;
} )
} else {
discordEmojis . forEach ( ( z ) => {
const img = renderEmoji ( z , "64" )
img . addEventListener ( "click" , ( ) => {
const chat = document . querySelector ( "pv-chat" ) ;
chat . input . value += z + " " ;
2024-11-26 16:07:33 +00:00
console . log ( shiftHeldDown )
if ( ! shiftHeldDown ) pv . PopupManager . closeModals ( ) ;
2024-11-26 15:30:33 +00:00
setTimeout ( ( ) => {
document . querySelector ( "pv-chat" ) . input . scrollLeft = document . querySelector ( "pv-chat" ) . input . scrollWidth ;
} , 50 )
} )
container . appendChild ( img ) ;
} )
}
}
}
customElements . define ( "pvme-emoji-picker" , PvmeEmojiPicker ) ;
pv . Modal . EMOJIS = "pvme-emoji-picker" ;
pv . popupMap [ pv . Modal . EMOJIS ] = PvmeEmojiPicker
//#endregion
//#region Button
const button = document . createElement ( "button" ) ;
button . className = "send" ;
button . type = "button"
button . ariaLabel = "Pick a emoji!"
function changeEmoji ( emoji ) {
button . firstElementChild ? . remove ( )
button . appendChild ( renderEmoji ( emoji , "32" ) ) ;
}
changeEmoji ( discordEmojis [ Math . floor ( Math . random ( ) * discordEmojis . length ) ] ) ;
button . addEventListener ( "click" , ( ) => {
pv . PopupManager . open ( pv . Modal . EMOJIS ) ;
changeEmoji ( discordEmojis [ Math . floor ( Math . random ( ) * discordEmojis . length ) ] ) ;
} )
document . querySelector ( "body > div > div.chat > pv-chat > div" ) . appendChild ( button )
//#endregion
2024-11-25 15:25:15 +00:00
} ) ( ) ;