overlay.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /**
  2. * Script for overlay.ejs
  3. */
  4. /* Overlay Wrapper Functions */
  5. /**
  6. * Check to see if the overlay is visible.
  7. *
  8. * @returns {boolean} Whether or not the overlay is visible.
  9. */
  10. function isOverlayVisible(){
  11. return document.getElementById('main').hasAttribute('overlay')
  12. }
  13. let overlayHandlerContent
  14. /**
  15. * Overlay keydown handler for a non-dismissable overlay.
  16. *
  17. * @param {KeyboardEvent} e The keydown event.
  18. */
  19. function overlayKeyHandler (e){
  20. if(e.key === 'Enter' || e.key === 'Escape'){
  21. document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click()
  22. }
  23. }
  24. /**
  25. * Overlay keydown handler for a dismissable overlay.
  26. *
  27. * @param {KeyboardEvent} e The keydown event.
  28. */
  29. function overlayKeyDismissableHandler (e){
  30. if(e.key === 'Enter'){
  31. document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click()
  32. } else if(e.key === 'Escape'){
  33. document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEsc')[0].click()
  34. }
  35. }
  36. /**
  37. * Bind overlay keydown listeners for escape and exit.
  38. *
  39. * @param {boolean} state Whether or not to add new event listeners.
  40. * @param {string} content The overlay content which will be shown.
  41. * @param {boolean} dismissable Whether or not the overlay is dismissable
  42. */
  43. function bindOverlayKeys(state, content, dismissable){
  44. overlayHandlerContent = content
  45. document.removeEventListener('keydown', overlayKeyHandler)
  46. document.removeEventListener('keydown', overlayKeyDismissableHandler)
  47. if(state){
  48. if(dismissable){
  49. document.addEventListener('keydown', overlayKeyDismissableHandler)
  50. } else {
  51. document.addEventListener('keydown', overlayKeyHandler)
  52. }
  53. }
  54. }
  55. /**
  56. * Toggle the visibility of the overlay.
  57. *
  58. * @param {boolean} toggleState True to display, false to hide.
  59. * @param {boolean} dismissable Optional. True to show the dismiss option, otherwise false.
  60. * @param {string} content Optional. The content div to be shown.
  61. */
  62. function toggleOverlay(toggleState, dismissable = false, content = 'overlayContent'){
  63. if(toggleState == null){
  64. toggleState = !document.getElementById('main').hasAttribute('overlay')
  65. }
  66. if(typeof dismissable === 'string'){
  67. content = dismissable
  68. dismissable = false
  69. }
  70. bindOverlayKeys(toggleState, content, dismissable)
  71. if(toggleState){
  72. document.getElementById('main').setAttribute('overlay', true)
  73. // Make things untabbable.
  74. $('#main *').attr('tabindex', '-1')
  75. $('#' + content).parent().children().hide()
  76. $('#' + content).show()
  77. if(dismissable){
  78. $('#overlayDismiss').show()
  79. } else {
  80. $('#overlayDismiss').hide()
  81. }
  82. $('#overlayContainer').fadeIn({
  83. duration: 250,
  84. start: () => {
  85. if(getCurrentView() === VIEWS.settings){
  86. document.getElementById('settingsContainer').style.backgroundColor = 'transparent'
  87. }
  88. }
  89. })
  90. } else {
  91. document.getElementById('main').removeAttribute('overlay')
  92. // Make things tabbable.
  93. $('#main *').removeAttr('tabindex')
  94. $('#overlayContainer').fadeOut({
  95. duration: 250,
  96. start: () => {
  97. if(getCurrentView() === VIEWS.settings){
  98. document.getElementById('settingsContainer').style.backgroundColor = 'rgba(0, 0, 0, 0.50)'
  99. }
  100. },
  101. complete: () => {
  102. $('#' + content).parent().children().hide()
  103. $('#' + content).show()
  104. if(dismissable){
  105. $('#overlayDismiss').show()
  106. } else {
  107. $('#overlayDismiss').hide()
  108. }
  109. }
  110. })
  111. }
  112. }
  113. function toggleServerSelection(toggleState){
  114. prepareServerSelectionList()
  115. toggleOverlay(toggleState, true, 'serverSelectContent')
  116. }
  117. /**
  118. * Set the content of the overlay.
  119. *
  120. * @param {string} title Overlay title text.
  121. * @param {string} description Overlay description text.
  122. * @param {string} acknowledge Acknowledge button text.
  123. * @param {string} dismiss Dismiss button text.
  124. */
  125. function setOverlayContent(title, description, acknowledge, dismiss = 'Dismiss'){
  126. document.getElementById('overlayTitle').innerHTML = title
  127. document.getElementById('overlayDesc').innerHTML = description
  128. document.getElementById('overlayAcknowledge').innerHTML = acknowledge
  129. document.getElementById('overlayDismiss').innerHTML = dismiss
  130. }
  131. /**
  132. * Set the onclick handler of the overlay acknowledge button.
  133. * If the handler is null, a default handler will be added.
  134. *
  135. * @param {function} handler
  136. */
  137. function setOverlayHandler(handler){
  138. if(handler == null){
  139. document.getElementById('overlayAcknowledge').onclick = () => {
  140. toggleOverlay(false)
  141. }
  142. } else {
  143. document.getElementById('overlayAcknowledge').onclick = handler
  144. }
  145. }
  146. /**
  147. * Set the onclick handler of the overlay dismiss button.
  148. * If the handler is null, a default handler will be added.
  149. *
  150. * @param {function} handler
  151. */
  152. function setDismissHandler(handler){
  153. if(handler == null){
  154. document.getElementById('overlayDismiss').onclick = () => {
  155. toggleOverlay(false)
  156. }
  157. } else {
  158. document.getElementById('overlayDismiss').onclick = handler
  159. }
  160. }
  161. /* Server Select View */
  162. document.getElementById('serverSelectConfirm').addEventListener('click', () => {
  163. const listings = document.getElementsByClassName('serverListing')
  164. for(let i=0; i<listings.length; i++){
  165. if(listings[i].hasAttribute('selected')){
  166. const serv = DistroManager.getDistribution().getServer(listings[i].getAttribute('servid'))
  167. ConfigManager.setSelectedServer(serv != null ? serv.getID() : null)
  168. ConfigManager.save()
  169. updateSelectedServer(serv != null ? serv.getName() : null)
  170. setLaunchEnabled(serv != null)
  171. refreshServerStatus(true)
  172. toggleOverlay(false)
  173. return
  174. }
  175. }
  176. // None are selected? Not possible right? Meh, handle it.
  177. if(listings.length > 0){
  178. ConfigManager.setSelectedServer(listings[0].getAttribute('servid'))
  179. ConfigManager.save()
  180. updateSelectedServer()
  181. toggleOverlay(false)
  182. }
  183. })
  184. document.getElementById('accountSelectConfirm').addEventListener('click', () => {
  185. const listings = document.getElementsByClassName('accountListing')
  186. for(let i=0; i<listings.length; i++){
  187. if(listings[i].hasAttribute('selected')){
  188. const authAcc = ConfigManager.setSelectedAccount(listings[i].getAttribute('uuid'))
  189. ConfigManager.save()
  190. updateSelectedAccount(authAcc)
  191. toggleOverlay(false)
  192. validateSelectedAccount()
  193. return
  194. }
  195. }
  196. // None are selected? Not possible right? Meh, handle it.
  197. if(listings.length > 0){
  198. const authAcc = ConfigManager.setSelectedAccount(listings[0].getAttribute('uuid'))
  199. ConfigManager.save()
  200. updateSelectedAccount(authAcc)
  201. toggleOverlay(false)
  202. validateSelectedAccount()
  203. }
  204. })
  205. // Bind server select cancel button.
  206. document.getElementById('serverSelectCancel').addEventListener('click', () => {
  207. toggleOverlay(false)
  208. })
  209. document.getElementById('accountSelectCancel').addEventListener('click', () => {
  210. $('#accountSelectContent').fadeOut(250, () => {
  211. $('#overlayContent').fadeIn(250)
  212. })
  213. })
  214. function setServerListingHandlers(){
  215. const listings = Array.from(document.getElementsByClassName('serverListing'))
  216. listings.map((val) => {
  217. val.onclick = e => {
  218. if(val.hasAttribute('selected')){
  219. return
  220. }
  221. const cListings = document.getElementsByClassName('serverListing')
  222. for(let i=0; i<cListings.length; i++){
  223. if(cListings[i].hasAttribute('selected')){
  224. cListings[i].removeAttribute('selected')
  225. }
  226. }
  227. val.setAttribute('selected', '')
  228. document.activeElement.blur()
  229. }
  230. })
  231. }
  232. function setAccountListingHandlers(){
  233. const listings = Array.from(document.getElementsByClassName('accountListing'))
  234. listings.map((val) => {
  235. val.onclick = e => {
  236. if(val.hasAttribute('selected')){
  237. return
  238. }
  239. const cListings = document.getElementsByClassName('accountListing')
  240. for(let i=0; i<cListings.length; i++){
  241. if(cListings[i].hasAttribute('selected')){
  242. cListings[i].removeAttribute('selected')
  243. }
  244. }
  245. val.setAttribute('selected', '')
  246. document.activeElement.blur()
  247. }
  248. })
  249. }
  250. function populateServerListings(){
  251. const distro = DistroManager.getDistribution()
  252. const giaSel = ConfigManager.getSelectedServer()
  253. const servers = distro.getServers()
  254. let htmlString = ''
  255. for(const serv of servers){
  256. htmlString += `<button class="serverListing" servid="${serv.getID()}" ${serv.getID() === giaSel ? 'selected' : ''}>
  257. <img class="serverListingImg" src="${serv.getIcon()}"/>
  258. <div class="serverListingDetails">
  259. <span class="serverListingName">${serv.getName()}</span>
  260. <span class="serverListingDescription">${serv.getDescription()}</span>
  261. <div class="serverListingInfo">
  262. <div class="serverListingVersion">${serv.getMinecraftVersion()}</div>
  263. <div class="serverListingRevision">${serv.getVersion()}</div>
  264. ${serv.isMainServer() ? `<div class="serverListingStarWrapper">
  265. <svg id="Layer_1" viewBox="0 0 107.45 104.74" width="20px" height="20px">
  266. <defs>
  267. <style>.cls-1{fill:#fff;}.cls-2{fill:none;stroke:#fff;stroke-miterlimit:10;}</style>
  268. </defs>
  269. <path class="cls-1" d="M100.93,65.54C89,62,68.18,55.65,63.54,52.13c2.7-5.23,18.8-19.2,28-27.55C81.36,31.74,63.74,43.87,58.09,45.3c-2.41-5.37-3.61-26.52-4.37-39-.77,12.46-2,33.64-4.36,39-5.7-1.46-23.3-13.57-33.49-20.72,9.26,8.37,25.39,22.36,28,27.55C39.21,55.68,18.47,62,6.52,65.55c12.32-2,33.63-6.06,39.34-4.9-.16,5.87-8.41,26.16-13.11,37.69,6.1-10.89,16.52-30.16,21-33.9,4.5,3.79,14.93,23.09,21,34C70,86.84,61.73,66.48,61.59,60.65,67.36,59.49,88.64,63.52,100.93,65.54Z"/>
  270. <circle class="cls-2" cx="53.73" cy="53.9" r="38"/>
  271. </svg>
  272. <span class="serverListingStarTooltip">Main Server</span>
  273. </div>` : ''}
  274. </div>
  275. </div>
  276. </button>`
  277. }
  278. document.getElementById('serverSelectListScrollable').innerHTML = htmlString
  279. }
  280. function populateAccountListings(){
  281. const accountsObj = ConfigManager.getAuthAccounts()
  282. const accounts = Array.from(Object.keys(accountsObj), v=>accountsObj[v])
  283. let htmlString = ''
  284. for(let i=0; i<accounts.length; i++){
  285. htmlString += `<button class="accountListing" uuid="${accounts[i].uuid}" ${i===0 ? 'selected' : ''}>
  286. <img src="https://crafatar.com/renders/head/${accounts[i].uuid}?scale=2&default=MHF_Steve&overlay">
  287. <div class="accountListingName">${accounts[i].displayName}</div>
  288. </button>`
  289. }
  290. document.getElementById('accountSelectListScrollable').innerHTML = htmlString
  291. }
  292. function prepareServerSelectionList(){
  293. populateServerListings()
  294. setServerListingHandlers()
  295. }
  296. function prepareAccountSelectionList(){
  297. populateAccountListings()
  298. setAccountListingHandlers()
  299. }