2022-10-14 10:47:08 +00:00
function getMessageFromJsonData ( success , json ) {
let message = success ? "Success!" : "Error, please try again later" ;
let key = success ? "message" : "error" ;
if ( ! json || ! json [ key ] ) return message ;
message = json [ key ] ;
if ( ! success && json [ "details" ] ) {
message = json [ "details" ] ;
}
return message ;
}
function showToast ( success , message , isToastTwo = false ) {
let element = success ? "toast-post-success" : "toast-post-error" ;
2022-10-14 12:33:36 +00:00
let textElement = element + "-text" ;
2022-10-14 10:47:08 +00:00
if ( isToastTwo ) {
2022-10-14 12:33:36 +00:00
element = element + "2" ;
textElement = textElement + "2" ;
}
2022-10-14 09:49:58 +00:00
if ( ! message ) {
message = success ? "Success" : "Error, please try again later" ;
}
2022-10-14 10:47:08 +00:00
document . getElementById ( textElement ) . innerText = message ;
2022-10-14 09:49:58 +00:00
bootstrap . Toast . getOrCreateInstance ( document . getElementById ( element ) ) . show ( ) ;
2022-10-14 08:19:09 +00:00
}
2022-10-14 12:43:23 +00:00
function createXhrWithFormKey ( url , method = "POST" , form = new FormData ( ) ) {
2022-10-14 12:33:36 +00:00
const xhr = new XMLHttpRequest ( ) ;
xhr . open ( method , url ) ;
xhr . setRequestHeader ( 'xhr' , 'xhr' ) ;
2022-10-14 12:43:23 +00:00
if ( ! form ) form = new FormData ( ) ;
2022-10-14 12:33:36 +00:00
form . append ( "formkey" , formkey ( ) ) ;
return [ xhr , form ] ; // hacky but less stupid than what we were doing before
2022-10-14 11:31:02 +00:00
}
2022-10-14 07:58:05 +00:00
2022-11-03 19:08:22 +00:00
function postToast ( t , url , data , callback ) {
2022-11-03 19:07:08 +00:00
const isShopConfirm = t . id . startsWith ( 'buy1-' ) || t . id . startsWith ( 'buy2-' )
if ( ! isShopConfirm )
{
t . disabled = true ;
t . classList . add ( "disabled" ) ;
}
2022-10-14 07:58:05 +00:00
2022-10-14 12:33:36 +00:00
let form = new FormData ( ) ;
2022-10-14 07:58:05 +00:00
if ( typeof data === 'object' && data !== null ) {
for ( let k of Object . keys ( data ) ) {
form . append ( k , data [ k ] ) ;
}
}
2022-10-14 12:33:36 +00:00
const xhr = createXhrWithFormKey ( url , "POST" , form ) ;
2022-10-14 12:01:11 +00:00
xhr [ 0 ] . onload = function ( ) {
2022-10-14 07:58:05 +00:00
let result
2022-10-14 12:33:36 +00:00
let message ;
let success = xhr [ 0 ] . status >= 200 && xhr [ 0 ] . status < 300 ;
2022-11-03 19:07:08 +00:00
if ( success && callback ) result = callback ( xhr [ 0 ] ) ;
2022-10-14 12:33:36 +00:00
if ( typeof result == "string" ) {
message = result ;
} else {
message = getMessageFromJsonData ( success , JSON . parse ( xhr [ 0 ] . response ) ) ;
}
let oldToast = bootstrap . Toast . getOrCreateInstance ( document . getElementById ( 'toast-post-' + ( success ? 'error' : 'success' ) ) ) ; // intentionally reversed here: this is the old toast
oldToast . hide ( ) ;
showToast ( success , message ) ;
2022-11-03 19:07:08 +00:00
if ( ! isShopConfirm ) {
t . disabled = false ;
t . classList . remove ( "disabled" ) ;
}
2022-10-14 12:33:36 +00:00
return success ;
2022-10-14 07:58:05 +00:00
} ;
2022-10-14 12:01:11 +00:00
xhr [ 0 ] . send ( xhr [ 1 ] ) ;
2022-11-03 19:07:08 +00:00
if ( ! isShopConfirm )
{
setTimeout ( ( ) => {
t . disabled = false ;
t . classList . remove ( "disabled" ) ;
} , 2000 ) ;
}
}
2022-11-03 19:08:22 +00:00
function postToastSwitch ( t , url , button1 , button2 , cls , callback ) {
postToast ( t , url ,
2022-11-03 19:07:08 +00:00
{
} ,
( xhr ) => {
document . getElementById ( button1 ) . classList . toggle ( cls ) ;
document . getElementById ( button2 ) . classList . toggle ( cls ) ;
if ( callback ) callback ( xhr ) ;
}
) ;
2022-10-14 07:58:05 +00:00
}
if ( window . location . pathname != '/submit' )
{
document . addEventListener ( 'keydown' , ( e ) => {
if ( ! ( ( e . ctrlKey || e . metaKey ) && e . key === "Enter" ) ) return ;
const targetDOM = document . activeElement ;
if ( ! ( targetDOM instanceof HTMLTextAreaElement || targetDOM instanceof HTMLInputElement ) ) return ;
const formDOM = targetDOM . parentElement ;
const submitButtonDOMs = formDOM . querySelectorAll ( 'input[type=submit], .btn-primary' ) ;
if ( submitButtonDOMs . length === 0 )
throw new TypeError ( "I am unable to find the submit button :(. Contact the head custodian immediately." )
const btn = submitButtonDOMs [ 0 ]
btn . click ( ) ;
} ) ;
}
addEventListener ( 'show.bs.modal' , function ( e ) {
location . hash = "modal" ;
} ) ;
addEventListener ( 'hide.bs.modal' , function ( e ) {
if ( location . hash == "#modal" ) {
history . back ( ) ;
}
} ) ;
addEventListener ( 'hashchange' , function ( e ) {
if ( location . hash != "#modal" ) {
const curr _modal = bootstrap . Modal . getInstance ( document . getElementsByClassName ( 'show' ) [ 0 ] )
if ( curr _modal ) curr _modal . hide ( )
}
} ) ;
function disable ( t ) {
t . classList . add ( 'disabled' ) ;
setTimeout ( ( ) => {
t . classList . remove ( "disabled" ) ;
} , 2000 ) ;
}
function autoExpand ( field ) {
xpos = window . scrollX ;
ypos = window . scrollY ;
field . style . height = 'inherit' ;
var computed = window . getComputedStyle ( field ) ;
var height = parseInt ( computed . getPropertyValue ( 'border-top-width' ) , 10 )
+ parseInt ( computed . getPropertyValue ( 'padding-top' ) , 10 )
+ field . scrollHeight
+ parseInt ( computed . getPropertyValue ( 'padding-bottom' ) , 10 )
+ parseInt ( computed . getPropertyValue ( 'border-bottom-width' ) , 10 ) ;
field . style . height = height + 'px' ;
if ( Math . abs ( window . scrollX - xpos ) < 1 && Math . abs ( window . scrollY - ypos ) < 1 ) return ;
window . scrollTo ( xpos , ypos ) ;
} ;
document . addEventListener ( 'input' , function ( event ) {
if ( event . target . tagName . toLowerCase ( ) !== 'textarea' ) return ;
autoExpand ( event . target ) ;
} , false ) ;
function smoothScrollTop ( )
{
window . scrollTo ( { top : 0 , behavior : 'smooth' } ) ;
}
// Click navbar to scroll back to top
( ( ) => {
let toplisteners = [
document . querySelector ( 'nav' )
] ;
for ( let i of toplisteners )
{
i . addEventListener ( 'click' , ( e ) => {
if ( e . target . id === "navbar" ||
e . target . classList . contains ( "container-fluid" ) ||
e . target . id == "navbarResponsive" ||
e . target . id == "logo-container" ||
e . target . classList . contains ( "srd" ) )
smoothScrollTop ( ) ;
} , false ) ;
}
} ) ( ) ;
// Dynamic shadow when the user scrolls
document . addEventListener ( 'scroll' , function ( event ) {
let nav = document . querySelector ( "nav" ) ;
let i = ( Math . min ( 20 , window . scrollY / 4 ) + 1 ) / 21 ;
nav . style . boxShadow = "0px 2px " + i * 21 + "px rgba(15,15,15," + i * . 3 + ")" ;
if ( window . scrollY <= 0 )
{
// nav.classList.remove("shadow");
nav . classList . remove ( "navbar-active" ) ;
nav . style . boxShadow = "unset" ;
}
else
{
// nav.classList.add("shadow");
nav . classList . add ( "navbar-active" ) ;
}
} , false ) ;
function formkey ( ) {
let formkey = document . getElementById ( "formkey" )
if ( formkey ) return formkey . innerHTML ;
else return null ;
}
function expandDesktopImage ( url ) {
const e = this . event
if ( e . ctrlKey || e . metaKey || e . shiftKey || e . altKey )
return true ;
e . preventDefault ( ) ;
if ( ! url )
{
url = e . target . dataset . src
if ( ! url ) url = e . target . src
}
document . getElementById ( "desktop-expanded-image" ) . src = url . replace ( "200w_d.webp" , "giphy.webp" ) ;
document . getElementById ( "desktop-expanded-image-wrap-link" ) . href = url ;
bootstrap . Modal . getOrCreateInstance ( document . getElementById ( 'expandImageModal' ) ) . show ( ) ;
} ;
document . addEventListener ( "click" , function ( e ) {
const element = e . target
if ( element instanceof HTMLImageElement && element . alt . startsWith ( '![](' ) )
expandDesktopImage ( )
} ) ;
function bs _trigger ( e ) {
let tooltipTriggerList = [ ] . slice . call ( e . querySelectorAll ( '[data-bs-toggle="tooltip"]' ) ) ;
tooltipTriggerList . map ( function ( element ) {
return bootstrap . Tooltip . getOrCreateInstance ( element ) ;
} ) ;
const popoverTriggerList = [ ] . slice . call ( e . querySelectorAll ( '[data-bs-toggle="popover"]' ) ) ;
popoverTriggerList . map ( function ( popoverTriggerEl ) {
const popoverId = popoverTriggerEl . getAttribute ( 'data-content-id' ) ;
let contentEl ;
try { contentEl = e . getElementById ( popoverId ) ; }
catch ( t ) { contentEl = document . getElementById ( popoverId ) ; }
if ( contentEl ) {
return bootstrap . Popover . getOrCreateInstance ( popoverTriggerEl , {
content : contentEl . innerHTML ,
html : true ,
} ) ;
}
} )
if ( typeof update _speed _emoji _modal != 'undefined' ) {
let forms = e . querySelectorAll ( "textarea, .allow-emojis" ) ;
forms . forEach ( i => {
let pseudo _div = document . createElement ( "div" ) ;
pseudo _div . className = "ghostdiv" ;
pseudo _div . style . display = "none" ;
i . after ( pseudo _div ) ;
i . addEventListener ( 'input' , update _speed _emoji _modal , false ) ;
i . addEventListener ( 'keydown' , speed _carot _navigate , false ) ;
} ) ;
}
}
var bsTriggerOnReady = function ( ) {
bs _trigger ( document ) ;
}
if ( document . readyState === "complete" ||
( document . readyState !== "loading" && ! document . documentElement . doScroll ) ) {
bsTriggerOnReady ( ) ;
} else {
document . addEventListener ( "DOMContentLoaded" , bsTriggerOnReady ) ;
}
function escapeHTML ( unsafe ) {
return unsafe . replace ( /&/g , "&" ) . replace ( /</g , "<" ) . replace ( />/g , ">" ) . replace ( /"/g , """ ) . replace ( /'/g , "'" ) ;
}
function changename ( s1 , s2 ) {
const files = document . getElementById ( s2 ) . files ;
if ( files . length > 4 )
{
alert ( "You can't upload more than 4 files at one time!" )
document . getElementById ( s2 ) . files = null
return
}
let filename = '' ;
for ( const e of files ) {
filename += e . name . substr ( 0 , 20 ) + ', ' ;
}
document . getElementById ( s1 ) . innerHTML = escapeHTML ( filename . slice ( 0 , - 2 ) ) ;
}
function showmore ( ) {
const btn = this . event . target
const div = btn . parentElement . nextElementSibling
div . classList . toggle ( 'd-none' )
if ( div . classList . contains ( 'd-none' ) )
btn . innerHTML = 'SHOW MORE'
else
btn . innerHTML = 'SHOW LESS'
}
function formatDate ( d ) {
var year = d . getFullYear ( ) ;
var monthAbbr = d . toLocaleDateString ( 'en-us' , { month : 'short' } ) ;
var day = d . getDate ( ) ;
var hour = ( "0" + d . getHours ( ) ) . slice ( - 2 ) ;
var minute = ( "0" + d . getMinutes ( ) ) . slice ( - 2 ) ;
var second = ( "0" + d . getSeconds ( ) ) . slice ( - 2 ) ;
var tzAbbr = d . toLocaleTimeString ( 'en-us' , { timeZoneName : 'short' } ) . split ( ' ' ) [ 2 ] ;
return ( day + " " + monthAbbr + " " + year + " "
2022-10-14 09:49:58 +00:00
+ hour + ":" + minute + ":" + second + " " + tzAbbr ) ;
2022-10-14 07:58:05 +00:00
}
const timestamps = document . querySelectorAll ( '[data-time]' ) ;
for ( const e of timestamps ) {
const date = new Date ( e . dataset . time * 1000 ) ;
e . innerHTML = formatDate ( date ) ;
} ;
function timestamp ( str , ti ) {
const date = new Date ( ti * 1000 ) ;
document . getElementById ( str ) . setAttribute ( "data-bs-original-title" , formatDate ( date ) ) ;
} ;
function areyousure ( t ) {
if ( t . value )
t . value = 'Are you sure?'
else
t . innerHTML = t . innerHTML . replace ( t . textContent , 'Are you sure?' )
t . setAttribute ( "onclick" , t . dataset . click ) ;
if ( t . dataset . dismiss )
2022-10-14 09:49:58 +00:00
t . setAttribute ( "data-bs-dismiss" , t . dataset . dismiss ) ;
2022-10-14 18:20:23 +00:00
}
2022-10-24 22:36:51 +00:00
function prepare _to _pause ( audio ) {
for ( const e of document . querySelectorAll ( 'video,audio' ) )
{
e . addEventListener ( 'play' , ( ) => {
if ( ! audio . paused ) audio . pause ( ) ;
} ) ;
}
for ( const e of document . getElementsByTagName ( 'lite-youtube' ) )
{
e . addEventListener ( 'click' , ( event ) => {
if ( ! audio . paused ) audio . pause ( ) ;
} ) ;
}
}