2023-07-22 16:24:16 +00:00
const SITE _FULL _IMAGES = document . getElementById ( 'SITE_FULL_IMAGES' ) . value
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-06 12:04:00 +00:00
function postToast ( t , url , data , extraActionsOnSuccess , method = "POST" ) {
2023-04-24 15:08:40 +00:00
const isShopConfirm = t . id . startsWith ( 'buy-' ) || t . id . startsWith ( 'giveaward' )
2022-11-03 19:07:08 +00:00
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-11-06 12:04:00 +00:00
const xhr = createXhrWithFormKey ( url , method , form ) ;
2023-03-10 03:21:02 +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 ;
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 ;
2023-01-01 11:36:20 +00:00
t . classList . remove ( "disabled" ) ;
2022-11-03 19:07:08 +00:00
}
2023-03-12 17:36:35 +00:00
if ( success && extraActionsOnSuccess ) result = extraActionsOnSuccess ( xhr [ 0 ] ) ;
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
}
2022-11-06 12:04:00 +00:00
function postToastReload ( t , url , method = "POST" ) {
2022-11-04 21:44:37 +00:00
postToast ( t , url ,
{
} ,
( ) => {
location . reload ( )
}
2022-11-06 12:04:00 +00:00
, method ) ;
2022-11-04 21:44:37 +00:00
}
2022-11-06 12:04:00 +00:00
function postToastSwitch ( t , url , button1 , button2 , cls , extraActionsOnSuccess , method = "POST" ) {
2022-11-03 19:08:22 +00:00
postToast ( t , url ,
2022-11-03 19:07:08 +00:00
{
} ,
( xhr ) => {
2022-11-04 18:45:52 +00:00
if ( button1 )
{
if ( typeof ( button1 ) == 'boolean' ) {
location . reload ( )
} else {
2022-12-16 20:00:42 +00:00
try {
document . getElementById ( button1 ) . classList . toggle ( cls ) ;
2022-12-16 20:17:23 +00:00
}
catch ( e ) { }
try {
document . getElementById ( button2 ) . classList . toggle ( cls ) ;
2022-12-16 20:00:42 +00:00
}
catch ( e ) { }
2022-11-04 18:45:52 +00:00
}
}
2023-01-24 10:40:25 +00:00
if ( typeof extraActionsOnSuccess == 'function' )
extraActionsOnSuccess ( xhr ) ;
2022-11-03 19:07:08 +00:00
}
2022-11-06 12:04:00 +00:00
, method ) ;
2022-10-14 07:58:05 +00:00
}
2023-02-27 15:02:35 +00:00
if ( ! location . pathname . endsWith ( '/submit' ) )
2022-10-14 07:58:05 +00:00
{
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 ;
2023-07-22 17:43:32 +00:00
if ( formDOM . id == 'note_section' ) {
document . getElementById ( 'giveaward' ) . click ( ) ;
return
}
2022-10-14 07:58:05 +00:00
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 ( ) ;
} ) ;
}
2022-11-08 04:09:55 +00:00
function autoExpand ( field ) {
2022-10-14 07:58:05 +00:00
xpos = window . scrollX ;
ypos = window . scrollY ;
field . style . height = 'inherit' ;
2022-12-04 15:40:32 +00:00
let computed = window . getComputedStyle ( field ) ;
2022-10-14 07:58:05 +00:00
2022-12-04 15:40:32 +00:00
let height = parseInt ( computed . getPropertyValue ( 'border-top-width' ) , 10 )
2022-10-14 07:58:05 +00:00
+ 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 ) ;
} ;
function smoothScrollTop ( )
{
window . scrollTo ( { top : 0 , behavior : 'smooth' } ) ;
}
// Click navbar to scroll back to top
2022-11-26 05:34:50 +00:00
const nav = document . getElementsByTagName ( 'nav' )
2022-12-04 15:40:32 +00:00
if ( nav . length ) {
2022-11-26 05:34:50 +00:00
nav [ 0 ] . 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 ) ;
}
2022-10-14 07:58:05 +00:00
function formkey ( ) {
let formkey = document . getElementById ( "formkey" )
if ( formkey ) return formkey . innerHTML ;
else return null ;
}
2023-03-12 08:35:44 +00:00
const expandImageModal = document . getElementById ( 'expandImageModal' )
2022-12-25 01:56:19 +00:00
function expandImage ( url ) {
2022-10-14 07:58:05 +00:00
const e = this . event
if ( e . ctrlKey || e . metaKey || e . shiftKey || e . altKey )
2022-11-07 10:49:49 +00:00
return ;
2022-10-14 07:58:05 +00:00
e . preventDefault ( ) ;
2023-04-25 07:10:28 +00:00
document . getElementById ( "desktop-expanded-image" ) . src = '' ;
document . getElementById ( "desktop-expanded-image-wrap-link" ) . href = '' ;
2022-10-14 07:58:05 +00:00
if ( ! url )
{
url = e . target . dataset . src
if ( ! url ) url = e . target . src
}
2023-01-01 11:18:24 +00:00
document . getElementById ( "desktop-expanded-image" ) . src = url . replace ( "200w.webp" , "giphy.webp" ) ;
document . getElementById ( "desktop-expanded-image-wrap-link" ) . href = url . replace ( "200w.webp" , "giphy.webp" ) ;
2022-12-25 01:56:10 +00:00
2023-03-12 08:35:44 +00:00
bootstrap . Modal . getOrCreateInstance ( expandImageModal ) . show ( ) ;
2022-10-14 07:58:05 +00:00
} ;
function bs _trigger ( e ) {
let tooltipTriggerList = [ ] . slice . call ( e . querySelectorAll ( '[data-bs-toggle="tooltip"]' ) ) ;
tooltipTriggerList . map ( function ( element ) {
return bootstrap . Tooltip . getOrCreateInstance ( element ) ;
} ) ;
2022-11-21 15:14:26 +00:00
if ( typeof update _speed _emoji _modal == 'function' ) {
2022-10-14 07:58:05 +00:00
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 ) ;
} ) ;
}
}
function escapeHTML ( unsafe ) {
return unsafe . replace ( /&/g , "&" ) . replace ( /</g , "<" ) . replace ( />/g , ">" ) . replace ( /"/g , """ ) . replace ( /'/g , "'" ) ;
}
2023-01-01 12:31:40 +00:00
function showmore ( t ) {
2023-03-10 21:10:46 +00:00
div = t . parentElement . parentElement . parentElement
2023-02-24 07:31:12 +00:00
let text = div . getElementsByTagName ( 'd' ) [ 0 ]
if ( ! text ) text = div . getElementsByClassName ( 'showmore-text' ) [ 0 ]
2023-03-10 23:30:42 +00:00
if ( ! text ) text = div . querySelector ( 'div.d-none' )
2023-02-24 07:31:12 +00:00
2023-05-16 02:05:19 +00:00
text . classList . remove ( 'd-none' )
t . remove ( )
2022-10-14 07:58:05 +00:00
}
function formatDate ( d ) {
2022-12-04 15:40:32 +00:00
let year = d . getFullYear ( ) ;
let monthAbbr = d . toLocaleDateString ( 'en-us' , { month : 'short' } ) ;
let day = d . getDate ( ) ;
let hour = ( "0" + d . getHours ( ) ) . slice ( - 2 ) ;
let minute = ( "0" + d . getMinutes ( ) ) . slice ( - 2 ) ;
let second = ( "0" + d . getSeconds ( ) ) . slice ( - 2 ) ;
let tzAbbr = d . toLocaleTimeString ( 'en-us' , { timeZoneName : 'short' } ) . split ( ' ' ) [ 2 ] ;
2022-10-14 07:58:05 +00:00
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 ) {
2022-11-25 23:25:15 +00:00
e . innerHTML = formatDate ( new Date ( e . dataset . time * 1000 ) ) ;
2022-10-14 07:58:05 +00:00
} ;
2023-01-01 03:05:09 +00:00
function timestamp ( t , ti ) {
2022-11-25 23:25:15 +00:00
const date = formatDate ( new Date ( ti * 1000 ) ) ;
2023-01-01 03:05:09 +00:00
t . setAttribute ( "data-bs-original-title" , date ) ;
2022-10-14 07:58:05 +00:00
} ;
function areyousure ( t ) {
2023-03-21 19:11:02 +00:00
if ( t . value ) {
t . dataset . oldvalue = t . value
2022-10-14 07:58:05 +00:00
t . value = 'Are you sure?'
2023-03-21 19:11:02 +00:00
}
else {
t . dataset . oldhtml = t . innerHTML
2022-10-14 07:58:05 +00:00
t . innerHTML = t . innerHTML . replace ( t . textContent , 'Are you sure?' )
2023-03-21 19:11:02 +00:00
}
2022-10-14 07:58:05 +00:00
2022-12-30 12:14:18 +00:00
t . setAttribute ( "data-onclick" , t . dataset . areyousure ) ;
2022-10-14 07:58:05 +00:00
if ( t . dataset . dismiss )
2022-10-14 09:49:58 +00:00
t . setAttribute ( "data-bs-dismiss" , t . dataset . dismiss ) ;
2023-03-21 19:11:02 +00:00
t . classList . add ( 'areyousure' )
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 ( ) ;
} ) ;
}
2022-12-27 02:19:19 +00:00
document . addEventListener ( 'click' , ( e ) => {
2023-01-28 10:38:06 +00:00
if ( ( e . target . tagName . toLowerCase ( ) == "lite-youtube" || e . target . classList . contains ( 'lty-playbtn' ) ) && ! audio . paused ) {
audio . pause ( ) ;
}
2022-11-18 19:41:03 +00:00
} ) ;
2022-10-24 22:36:51 +00:00
}
2022-11-07 06:08:50 +00:00
2022-12-30 12:52:59 +00:00
function sendFormXHR ( form , extraActionsOnSuccess ) {
2022-11-07 06:08:50 +00:00
const xhr = new XMLHttpRequest ( ) ;
formData = new FormData ( form ) ;
formData . append ( "formkey" , formkey ( ) ) ;
actionPath = form . getAttribute ( "action" ) ;
xhr . open ( "POST" , actionPath ) ;
xhr . setRequestHeader ( 'xhr' , 'xhr' ) ;
2023-03-10 03:21:02 +00:00
xhr . onload = function ( ) {
2022-11-07 06:08:50 +00:00
if ( xhr . status >= 200 && xhr . status < 300 ) {
let data = JSON . parse ( xhr . response ) ;
showToast ( true , getMessageFromJsonData ( true , data ) ) ;
if ( extraActionsOnSuccess ) extraActionsOnSuccess ( xhr ) ;
} else {
document . getElementById ( 'toast-post-error-text' ) . innerText = "Error, please try again later."
try {
let data = JSON . parse ( xhr . response ) ;
2022-12-04 15:40:32 +00:00
bootstrap . Toast . getOrCreateInstance ( document . getElementById ( 'toast-post-error' ) ) . show ( ) ;
2022-11-07 06:08:50 +00:00
document . getElementById ( 'toast-post-error-text' ) . innerText = data [ "error" ] ;
if ( data && data [ "details" ] ) document . getElementById ( 'toast-post-error-text' ) . innerText = data [ "details" ] ;
} catch ( e ) {
2022-12-04 15:40:32 +00:00
bootstrap . Toast . getOrCreateInstance ( document . getElementById ( 'toast-post-success' ) ) . hide ( ) ;
bootstrap . Toast . getOrCreateInstance ( document . getElementById ( 'toast-post-error' ) ) . show ( ) ;
2022-11-07 06:08:50 +00:00
}
}
} ;
xhr . send ( formData ) ;
}
2023-03-17 14:23:42 +00:00
function sendFormXHRSwitch ( form ) {
2022-12-30 12:52:59 +00:00
sendFormXHR ( form ,
2022-11-07 06:08:50 +00:00
( ) => {
2023-01-21 05:46:21 +00:00
form . previousElementSibling . classList . remove ( 'd-none' ) ;
2023-03-17 14:23:42 +00:00
const days = form . querySelector ( "input[name=days]" )
if ( ! days || ! days . value )
2023-02-19 13:23:08 +00:00
form . classList . add ( 'd-none' ) ;
2022-11-07 06:08:50 +00:00
}
)
}
2022-12-10 10:40:34 +00:00
2023-07-14 17:07:58 +00:00
function sendFormXHRReload ( form ) {
sendFormXHR ( form ,
( ) => {
location . reload ( ) ;
}
)
}
2022-12-10 10:40:34 +00:00
let sortAscending = { } ;
function sort _table ( t ) {
const n = Array . prototype . indexOf . call ( t . parentElement . children , t ) ;
const table = this . event . target . parentElement . parentElement . parentElement
const rows = table . rows ;
let items = [ ] ;
for ( let i = 1 ; i < rows . length ; i ++ ) {
const ele = rows [ i ] ;
let x = rows [ i ] . getElementsByTagName ( "TD" ) [ n ] ;
if ( ! ( 'sortKey' in x . dataset ) ) {
x = x . getElementsByTagName ( 'a' ) [ 0 ] || x ;
}
let attr ;
if ( 'sortKey' in x . dataset ) {
attr = x . dataset . sortKey ;
2023-03-07 05:38:55 +00:00
if ( /^[\d-,]+$/ . test ( attr ) ) {
2023-03-07 05:37:14 +00:00
attr = parseInt ( attr . replace ( /,/g , '' ) )
}
2022-12-10 10:40:34 +00:00
} else if ( 'time' in x . dataset ) {
attr = parseInt ( x . dataset . time ) ;
} else {
attr = x . innerText
2022-12-10 11:57:23 +00:00
if ( /^[\d-,]+$/ . test ( x . innerHTML ) ) {
2022-12-10 10:40:34 +00:00
attr = parseInt ( attr . replace ( /,/g , '' ) )
}
}
items . push ( { ele , attr } ) ;
}
if ( sortAscending [ n ] ) {
items . sort ( ( a , b ) => a . attr > b . attr ? 1 : - 1 ) ;
sortAscending [ n ] = false ;
} else {
items . sort ( ( a , b ) => a . attr < b . attr ? 1 : - 1 ) ;
sortAscending [ n ] = true ;
}
for ( let i = items . length - 1 ; i -- ; ) {
items [ i ] . ele . parentNode . insertBefore ( items [ i ] . ele , items [ i + 1 ] . ele ) ;
}
}
2023-07-25 18:47:20 +00:00
const is _pwa = window . matchMedia ( '(display-mode: standalone)' ) [ 'matches' ] || window . matchMedia ( '(display-mode: minimal-ui)' ) [ 'matches' ]
2023-06-29 19:05:24 +00:00
if ( is _pwa ) {
2022-12-29 14:20:27 +00:00
const links = document . querySelectorAll ( 'a[data-target="t"]' ) ;
for ( const link of links ) {
link . removeAttribute ( "target" ) ;
}
}
2023-06-29 19:05:24 +00:00
const gbrowser = document . getElementById ( 'gbrowser' ) . value
if ( gbrowser == 'iphone' || gbrowser == 'mac' ) {
2022-12-29 14:20:27 +00:00
const videos = document . querySelectorAll ( 'video' )
for ( const video of videos ) {
const link = video . src
const htmlString = `
< a rel = "nofollow noopener" href = "${link}" target = "_blank" >
< div class = "d-flex justify-content-between align-items-center border rounded p-2 mb-3 download-video" >
< span > $ { link } < / s p a n >
< i class = "fas fa-external-link-alt text-small" > < / i >
< / d i v >
< / a > `
const div = document . createElement ( 'div' ) ;
div . innerHTML = htmlString ;
video . after ( div )
}
}
2023-01-24 10:02:08 +00:00
function logout ( t ) {
postToast ( t , '/logout' ,
{
} ,
( ) => {
location . href = '/'
} ) ;
}
2023-02-18 18:58:07 +00:00
2023-06-26 11:40:36 +00:00
const screen _width = ( window . innerWidth > 0 ) ? window . innerWidth : screen . width ;
2023-02-18 18:58:07 +00:00
function focusSearchBar ( element )
{
2023-06-26 11:40:36 +00:00
if ( screen _width >= 768 ) {
2023-02-18 18:58:07 +00:00
element . focus ( ) ;
}
}
2023-02-27 15:02:35 +00:00
2023-06-26 11:40:36 +00:00
let MINFLIES ;
let MAXFLIES ;
2023-07-14 11:24:53 +00:00
let ACTUALMAXFILES ;
2023-02-27 15:02:35 +00:00
2023-06-26 11:40:36 +00:00
if ( screen _width < 768 ) {
MINFLIES = 5 ;
MAXFLIES = 10 ;
2023-07-14 11:24:53 +00:00
ACTUALMAXFILES = 50 ;
2023-06-26 11:40:36 +00:00
}
else {
MINFLIES = 10 ;
MAXFLIES = 20 ;
2023-07-14 11:24:53 +00:00
ACTUALMAXFILES = 150 ;
2023-06-26 11:40:36 +00:00
}
2023-02-27 15:02:35 +00:00
2023-03-18 14:27:12 +00:00
function insertText ( input , text ) {
const newPos = input . selectionStart + text . length ;
input . setRangeText ( text ) ;
if ( window . chrome !== undefined )
setTimeout ( function ( ) {
input . focus ( ) ;
for ( let i = 0 ; i < 2 ; i ++ )
input . setSelectionRange ( newPos , newPos ) ;
input . focus ( ) ;
for ( let i = 0 ; i < 2 ; i ++ )
input . setSelectionRange ( newPos , newPos ) ;
} , 1 ) ;
else
input . setSelectionRange ( newPos , newPos ) ;
2023-07-22 16:29:19 +00:00
input . selectionStart = newPos ;
2023-03-18 14:27:12 +00:00
}
2023-02-27 15:02:35 +00:00
//FILE SHIT
let oldfiles = { } ;
function handle _files ( input , newfiles ) {
if ( ! newfiles ) return ;
2023-05-05 21:45:25 +00:00
2023-02-27 15:02:35 +00:00
const ta = input . parentElement . parentElement . parentElement . parentElement . querySelector ( 'textarea.file-ta' ) ;
if ( oldfiles [ ta . id ] ) {
let list = new DataTransfer ( ) ;
for ( const file of oldfiles [ ta . id ] ) {
2023-07-22 23:59:45 +00:00
list . items . add ( file ) ;
2023-02-27 15:02:35 +00:00
}
for ( const file of newfiles ) {
list . items . add ( file ) ;
}
input . files = list . files ;
}
else {
input . files = newfiles ;
oldfiles [ ta . id ] = [ ]
}
2023-02-27 16:05:28 +00:00
if ( input . files . length > 20 )
2023-02-27 15:02:35 +00:00
{
2023-02-27 16:05:28 +00:00
alert ( "You can't upload more than 20 files at one time!" )
2023-02-27 15:02:35 +00:00
input . value = null
oldfiles [ ta . id ] = [ ]
return
}
for ( const file of newfiles ) {
oldfiles [ ta . id ] . push ( file )
2023-07-03 00:36:25 +00:00
if ( location . pathname != '/chat' && location . pathname != '/old_chat' )
2023-03-18 14:27:12 +00:00
insertText ( ta , ` [ ${ file . name } ] ` ) ;
2023-03-15 04:34:47 +00:00
}
2023-02-27 15:02:35 +00:00
autoExpand ( ta )
if ( typeof checkForRequired === "function" ) checkForRequired ( ) ;
}
2023-03-04 19:54:06 +00:00
file _upload = document . getElementById ( 'file-upload' ) ;
if ( file _upload ) {
function process _url _image ( ) {
if ( file _upload . files )
{
const filename = file _upload . files [ 0 ] . name
2023-03-06 18:02:12 +00:00
file _upload . previousElementSibling . textContent = filename . substr ( 0 , 50 ) ;
2023-03-10 21:41:43 +00:00
for ( const s of document . getElementById ( 'IMAGE_FORMATS' ) . value . split ( ',' ) )
2023-03-04 19:54:06 +00:00
{
2023-03-10 21:33:41 +00:00
if ( filename . toLowerCase ( ) . endsWith ( s ) ) {
const fileReader = new FileReader ( ) ;
fileReader . readAsDataURL ( file _upload . files [ 0 ] ) ;
fileReader . addEventListener ( "load" , function ( ) {
document . getElementById ( 'image-preview' ) . setAttribute ( 'src' , this . result ) ;
document . getElementById ( 'image-preview' ) . classList . remove ( 'd-none' ) ;
} ) ;
break ;
}
2023-03-04 19:54:06 +00:00
}
if ( typeof checkForRequired === "function" ) {
document . getElementById ( 'urlblock' ) . classList . add ( 'd-none' ) ;
checkForRequired ( ) ;
}
else {
document . getElementById ( 'submit-btn' ) . disabled = false ;
}
}
}
file _upload . onchange = process _url _image
}
2023-02-27 15:02:35 +00:00
document . onpaste = function ( event ) {
const files = structuredClone ( event . clipboardData . files ) ;
if ( ! files . length ) return
const focused = document . activeElement ;
let input ;
2023-03-04 19:54:06 +00:00
if ( file _upload ) {
if ( location . pathname . endsWith ( '/submit' ) && focused && focused . id == 'post-text' ) {
2023-02-27 15:02:35 +00:00
input = document . getElementById ( 'file-upload-submit' )
}
else {
2023-03-04 19:54:06 +00:00
file _upload . files = files ;
process _url _image ( ) ;
2023-02-27 15:02:35 +00:00
return ;
}
}
else if ( focused ) {
input = focused . parentElement . querySelector ( 'input[type="file"]' )
}
else {
input = document . querySelector ( 'input[type="file"]' )
}
2023-03-17 13:20:11 +00:00
event . preventDefault ( ) ;
2023-02-27 15:02:35 +00:00
handle _files ( input , files ) ;
}
2023-02-27 17:25:38 +00:00
function handleUploadProgress ( e , upload _prog ) {
const bar = upload _prog . firstElementChild ;
const percentIndicator = upload _prog . lastElementChild ;
2023-05-05 21:45:25 +00:00
2023-02-27 17:25:38 +00:00
upload _prog . classList . remove ( "d-none" )
if ( e . lengthComputable ) {
const progressPercent = Math . floor ( ( e . loaded / e . total ) * 100 ) ;
bar . value = progressPercent ;
percentIndicator . textContent = progressPercent + '%' ;
}
}
2023-03-10 01:51:45 +00:00
2023-07-30 07:22:33 +00:00
2023-08-03 20:59:50 +00:00
if ( screen _width <= 768 ) {
let object
if ( gbrowser == 'iphone' && expandImageModal )
object = expandImageModal
if ( gbrowser != 'iphone' )
object = document
2023-08-03 10:52:20 +00:00
2023-08-03 20:59:50 +00:00
if ( object ) {
object . addEventListener ( 'hide.bs.modal' , function ( ) {
if ( location . hash == "#modal" ) {
history . back ( ) ;
}
} ) ;
object . addEventListener ( 'shown.bs.modal' , function ( ) {
location . hash = "modal" ;
} ) ;
addEventListener ( 'hashchange' , function ( ) {
2023-08-04 16:28:34 +00:00
if ( location . hash == "#modal" ) {
const curr _modal = bootstrap . Modal . getInstance ( document . getElementsByClassName ( 'show' ) [ 0 ] )
if ( ! curr _modal ) history . back ( ) ;
}
else {
2023-08-03 20:59:50 +00:00
const curr _modal = bootstrap . Modal . getInstance ( document . getElementsByClassName ( 'show' ) [ 0 ] )
if ( curr _modal ) curr _modal . hide ( )
}
} ) ;
}
2023-07-30 07:22:33 +00:00
}
2023-03-21 19:03:28 +00:00
document . querySelectorAll ( 'form' ) . forEach ( form => {
2023-03-21 18:56:05 +00:00
form . addEventListener ( 'submit' , ( e ) => {
if ( form . classList . contains ( 'is-submitting' ) ) {
e . preventDefault ( ) ;
}
2023-05-05 21:45:25 +00:00
2023-03-21 18:56:05 +00:00
form . classList . add ( 'is-submitting' ) ;
} ) ;
} ) ;
2023-06-29 18:09:27 +00:00
function urlB64ToUint8Array ( base64String ) {
const padding = '=' . repeat ( ( 4 - base64String . length % 4 ) % 4 ) ;
const base64 = ( base64String + padding )
. replace ( /\-/g , '+' )
. replace ( /_/g , '/' ) ;
const rawData = window . atob ( base64 ) ;
const outputArray = new Uint8Array ( rawData . length ) ;
for ( let i = 0 ; i < rawData . length ; ++ i ) {
outputArray [ i ] = rawData . charCodeAt ( i ) ;
}
return outputArray ;
}
function updateSubscriptionOnServer ( subscription , apiEndpoint ) {
const formData = new FormData ( ) ;
formData . append ( "subscription_json" , JSON . stringify ( subscription ) ) ;
const xhr = createXhrWithFormKey (
apiEndpoint ,
'POST' ,
formData
) ;
xhr [ 0 ] . send ( xhr [ 1 ] ) ;
}
function enablePushNotifications ( ) {
if ( ! ( 'serviceWorker' in navigator && 'PushManager' in window ) ) return ;
let publicKeyElement = document . getElementById ( 'VAPID_PUBLIC_KEY' ) ;
if ( ! publicKeyElement ) return ;
let publicKey = urlB64ToUint8Array ( publicKeyElement . value ) ;
navigator . serviceWorker . getRegistration ( "/assets/js/service_worker.js" ) . then ( ( reg ) => {
return reg . pushManager . subscribe ( {
userVisibleOnly : true ,
applicationServerKey : publicKey ,
} )
} ) . then ( ( subscription ) => {
updateSubscriptionOnServer ( subscription , "/push_subscribe" )
alert ( "Push notifications are enabled!" )
} ) . catch ( ( e ) => {
alert ( "Please give the site access to notifications!" )
2023-07-22 23:44:00 +00:00
console . error ( e )
2023-06-29 18:09:27 +00:00
} )
}