Compare commits

...

4 Commits

Author SHA1 Message Date
Kalitsune
5a8d1f146f
Merge ac8a325c37 into 6aaeeff9a4 2024-11-16 02:27:11 -03:00
Kalitsune
ac8a325c37 🌐 Make the popup overlay more generic and fixed the esc key not closing the overlay properly 2024-05-21 17:20:49 +02:00
Kalitsune
194f0365b2 👥 Fluid account selection
Edited the account selection menu so that it can be oppened in "popup" mode, allowing similar behavior to the fluid server selection without disturbing the account selection already in place in case of an account validation failure. This new popup menu also adds a "manage accounts" button to open the settings in the same way the old account selection menu did
2024-05-12 16:19:51 +02:00
Kalitsune
abc4690949 🧭 Fluid server selection
Removed the select and cancel buttons and made the buttons directly select the server
2024-05-12 15:10:48 +02:00
6 changed files with 101 additions and 82 deletions

View File

@ -3688,10 +3688,6 @@ input:checked + .toggleSwitchSlider:before {
position: relative; position: relative;
background: rgba(131, 131, 131, 0.25); background: rgba(131, 131, 131, 0.25);
} }
.serverListing[selected] {
cursor: default;
opacity: 1.0;
}
.serverListing:hover, .serverListing:hover,
.serverListing:focus { .serverListing:focus {
outline: none; outline: none;
@ -3854,7 +3850,8 @@ input:checked + .toggleSwitchSlider:before {
/* Server selection confirm button styles. */ /* Server selection confirm button styles. */
#serverSelectConfirm, #serverSelectConfirm,
#accountSelectConfirm { #accountSelectConfirm,
#accountSelectManage {
background: none; background: none;
border: 1px solid #ffffff; border: 1px solid #ffffff;
color: white; color: white;

View File

@ -133,14 +133,6 @@ document.getElementById('settingsMediaButton').onclick = async e => {
switchView(getCurrentView(), VIEWS.settings) switchView(getCurrentView(), VIEWS.settings)
} }
// Bind avatar overlay button.
document.getElementById('avatarOverlay').onclick = async e => {
await prepareSettings()
switchView(getCurrentView(), VIEWS.settings, 500, 500, () => {
settingsNavItemListener(document.getElementById('settingsNavAccount'), false)
})
}
// Bind selected account // Bind selected account
function updateSelectedAccount(authUser){ function updateSelectedAccount(authUser){
let username = Lang.queryJS('landing.selectedAccount.noAccountSelected') let username = Lang.queryJS('landing.selectedAccount.noAccountSelected')
@ -176,6 +168,12 @@ server_selection_button.onclick = async e => {
await toggleServerSelection(true) await toggleServerSelection(true)
} }
// Bind avatar overlay button.
document.getElementById('avatarOverlay').onclick = async e => {
e.target.blur()
await toggleAccountSelection(true, true)
}
// Update Mojang Status Color // Update Mojang Status Color
const refreshMojangStatuses = async function(){ const refreshMojangStatuses = async function(){
loggerLanding.info('Refreshing Mojang Statuses..') loggerLanding.info('Refreshing Mojang Statuses..')

View File

@ -15,6 +15,9 @@ function isOverlayVisible(){
let overlayHandlerContent let overlayHandlerContent
let overlayContainer = document.getElementById('overlayContainer')
let accountSelectContent = document.getElementById('accountSelectContent')
/** /**
* Overlay keydown handler for a non-dismissable overlay. * Overlay keydown handler for a non-dismissable overlay.
* *
@ -22,8 +25,12 @@ let overlayHandlerContent
*/ */
function overlayKeyHandler (e){ function overlayKeyHandler (e){
if(e.key === 'Enter' || e.key === 'Escape'){ if(e.key === 'Enter' || e.key === 'Escape'){
if (overlayContainer.hasAttribute('popup')) {
toggleOverlay(false)
} else {
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click() document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click()
} }
}
} }
/** /**
* Overlay keydown handler for a dismissable overlay. * Overlay keydown handler for a dismissable overlay.
@ -64,8 +71,9 @@ function bindOverlayKeys(state, content, dismissable){
* @param {boolean} toggleState True to display, false to hide. * @param {boolean} toggleState True to display, false to hide.
* @param {boolean} dismissable Optional. True to show the dismiss option, otherwise false. * @param {boolean} dismissable Optional. True to show the dismiss option, otherwise false.
* @param {string} content Optional. The content div to be shown. * @param {string} content Optional. The content div to be shown.
* @param {boolean} popup Optional. True to show the overlay as a popup that is easily dismissable and interactible.
*/ */
function toggleOverlay(toggleState, dismissable = false, content = 'overlayContent'){ function toggleOverlay(toggleState, dismissable = false, content = 'overlayContent', popup = false){
if(toggleState == null){ if(toggleState == null){
toggleState = !document.getElementById('main').hasAttribute('overlay') toggleState = !document.getElementById('main').hasAttribute('overlay')
} }
@ -76,6 +84,9 @@ function toggleOverlay(toggleState, dismissable = false, content = 'overlayConte
bindOverlayKeys(toggleState, content, dismissable) bindOverlayKeys(toggleState, content, dismissable)
if(toggleState){ if(toggleState){
document.getElementById('main').setAttribute('overlay', true) document.getElementById('main').setAttribute('overlay', true)
overlayContainer.setAttribute('content', content)
overlayContainer.setAttribute('popup', popup)
// Make things untabbable. // Make things untabbable.
$('#main *').attr('tabindex', '-1') $('#main *').attr('tabindex', '-1')
$('#' + content).parent().children().hide() $('#' + content).parent().children().hide()
@ -95,6 +106,8 @@ function toggleOverlay(toggleState, dismissable = false, content = 'overlayConte
}) })
} else { } else {
document.getElementById('main').removeAttribute('overlay') document.getElementById('main').removeAttribute('overlay')
overlayContainer.removeAttribute('content')
// Make things tabbable. // Make things tabbable.
$('#main *').removeAttr('tabindex') $('#main *').removeAttr('tabindex')
$('#overlayContainer').fadeOut({ $('#overlayContainer').fadeOut({
@ -119,7 +132,21 @@ function toggleOverlay(toggleState, dismissable = false, content = 'overlayConte
async function toggleServerSelection(toggleState){ async function toggleServerSelection(toggleState){
await prepareServerSelectionList() await prepareServerSelectionList()
toggleOverlay(toggleState, true, 'serverSelectContent') toggleOverlay(toggleState, false, 'serverSelectContent', true)
}
async function toggleAccountSelection(toggleState, popup = false){
if (popup) {
// set the accountSelectActions div to display: none to avoid colliding with the validateSelectedAccount function
document.getElementById('accountSelectActions').style.display = 'none'
} else {
// set the overlayContainer div to display: block, this is not done while closing the overlay because of the fadeOut effect
document.getElementById('accountSelectActions').style.display = 'block'
}
// show the overlay
await prepareAccountSelectionList()
toggleOverlay(toggleState, false, 'accountSelectContent', popup)
} }
/** /**
@ -169,27 +196,9 @@ function setDismissHandler(handler){
} }
} }
/* Server Select View */ /* Account Select button */
document.getElementById('serverSelectConfirm').addEventListener('click', async () => {
const listings = document.getElementsByClassName('serverListing')
for(let i=0; i<listings.length; i++){
if(listings[i].hasAttribute('selected')){
const serv = (await DistroAPI.getDistribution()).getServerById(listings[i].getAttribute('servid'))
updateSelectedServer(serv)
refreshServerStatus(true)
toggleOverlay(false)
return
}
}
// None are selected? Not possible right? Meh, handle it.
if(listings.length > 0){
const serv = (await DistroAPI.getDistribution()).getServerById(listings[i].getAttribute('servid'))
updateSelectedServer(serv)
toggleOverlay(false)
}
})
// Bind account select confirm button.
document.getElementById('accountSelectConfirm').addEventListener('click', async () => { document.getElementById('accountSelectConfirm').addEventListener('click', async () => {
const listings = document.getElementsByClassName('accountListing') const listings = document.getElementsByClassName('accountListing')
for(let i=0; i<listings.length; i++){ for(let i=0; i<listings.length; i++){
@ -218,40 +227,60 @@ document.getElementById('accountSelectConfirm').addEventListener('click', async
} }
}) })
// Bind server select cancel button. // Bind account select cancel button.
document.getElementById('serverSelectCancel').addEventListener('click', () => {
toggleOverlay(false)
})
document.getElementById('accountSelectCancel').addEventListener('click', () => { document.getElementById('accountSelectCancel').addEventListener('click', () => {
$('#accountSelectContent').fadeOut(250, () => { $('#accountSelectContent').fadeOut(250, () => {
$('#overlayContent').fadeIn(250) $('#overlayContent').fadeIn(250)
}) })
}) })
function setServerListingHandlers(){ // Bind account select manage button.
document.getElementById('accountSelectManage').addEventListener('click', async () => {
await prepareSettings()
switchView(getCurrentView(), VIEWS.settings, 500, 500, () => {
settingsNavItemListener(document.getElementById('settingsNavAccount'), false)
})
toggleOverlay(false)
})
// Make the Server Selection background clickable to close the overlay.
overlayContainer.addEventListener('click', e => {
if (e.target === overlayContainer) {
// This function only works if the overlay is a popup
if(overlayContainer.hasAttribute('popup')) {
toggleOverlay(false)
}
}
})
async function setServerListingHandlers(){
const listings = Array.from(document.getElementsByClassName('serverListing')) const listings = Array.from(document.getElementsByClassName('serverListing'))
listings.map((val) => { listings.map(async (val) => {
val.onclick = e => { val.onclick = async e => {
if(val.hasAttribute('selected')){ const serv = (await DistroAPI.getDistribution()).getServerById(val.getAttribute('servid'))
return updateSelectedServer(serv)
} refreshServerStatus(true)
const cListings = document.getElementsByClassName('serverListing') toggleOverlay(false)
for(let i=0; i<cListings.length; i++){
if(cListings[i].hasAttribute('selected')){
cListings[i].removeAttribute('selected')
}
}
val.setAttribute('selected', '')
document.activeElement.blur()
} }
}) })
} }
function setAccountListingHandlers(){ async function setAccountListingHandlers(){
const listings = Array.from(document.getElementsByClassName('accountListing')) const listings = Array.from(document.getElementsByClassName('accountListing'))
listings.map((val) => { listings.map(async (val) => {
val.onclick = e => { val.onclick = async e => {
// popup mode
if(overlayContainer.hasAttribute('popup')){
const authAcc = ConfigManager.setSelectedAccount(val.getAttribute('uuid'))
ConfigManager.save()
updateSelectedAccount(authAcc)
if(getCurrentView() === VIEWS.settings) {
await prepareSettings()
}
toggleOverlay(false)
validateSelectedAccount()
return
} else {
if(val.hasAttribute('selected')){ if(val.hasAttribute('selected')){
return return
} }
@ -264,6 +293,7 @@ function setAccountListingHandlers(){
val.setAttribute('selected', '') val.setAttribute('selected', '')
document.activeElement.blur() document.activeElement.blur()
} }
}
}) })
} }
@ -304,7 +334,7 @@ function populateAccountListings(){
const accounts = Array.from(Object.keys(accountsObj), v=>accountsObj[v]) const accounts = Array.from(Object.keys(accountsObj), v=>accountsObj[v])
let htmlString = '' let htmlString = ''
for(let i=0; i<accounts.length; i++){ for(let i=0; i<accounts.length; i++){
htmlString += `<button class="accountListing" uuid="${accounts[i].uuid}" ${i===0 ? 'selected' : ''}> htmlString += `<button class="accountListing" uuid="${accounts[i].uuid}" ${!i && !overlayContainer.hasAttribute("popup") ? 'selected' : ''}>
<img src="https://mc-heads.net/head/${accounts[i].uuid}/40"> <img src="https://mc-heads.net/head/${accounts[i].uuid}/40">
<div class="accountListingName">${accounts[i].displayName}</div> <div class="accountListingName">${accounts[i].displayName}</div>
</button>` </button>`
@ -315,10 +345,10 @@ function populateAccountListings(){
async function prepareServerSelectionList(){ async function prepareServerSelectionList(){
await populateServerListings() await populateServerListings()
setServerListingHandlers() await setServerListingHandlers()
} }
function prepareAccountSelectionList(){ async function prepareAccountSelectionList(){
populateAccountListings() populateAccountListings()
setAccountListingHandlers() await setAccountListingHandlers()
} }

View File

@ -381,9 +381,9 @@ async function validateSelectedAccount(){
toggleOverlay(false) toggleOverlay(false)
switchView(getCurrentView(), VIEWS.loginOptions) switchView(getCurrentView(), VIEWS.loginOptions)
}) })
setDismissHandler(() => { setDismissHandler(async () => {
if(accLen > 1){ if(accLen > 1){
prepareAccountSelectionList() await prepareAccountSelectionList()
$('#overlayContent').fadeOut(250, () => { $('#overlayContent').fadeOut(250, () => {
bindOverlayKeys(true, 'accountSelectContent', true) bindOverlayKeys(true, 'accountSelectContent', true)
$('#accountSelectContent').fadeIn(250) $('#accountSelectContent').fadeIn(250)

View File

@ -1,7 +1,7 @@
[ejs.landing] [ejs.landing]
updateAvailableTooltip = "Update Available" updateAvailableTooltip = "Update Available"
usernamePlaceholder = "Username" usernamePlaceholder = "Username"
usernameEditButton = "Edit" usernameEditButton = "Switch"
settingsTooltip = "Settings" settingsTooltip = "Settings"
serverStatus = "SERVER" serverStatus = "SERVER"
serverStatusPlaceholder = "OFFLINE" serverStatusPlaceholder = "OFFLINE"
@ -42,11 +42,10 @@ cancelButton = "Cancel"
[ejs.overlay] [ejs.overlay]
serverSelectHeader = "Available Servers" serverSelectHeader = "Available Servers"
serverSelectConfirm = "Select"
serverSelectCancel = "Cancel"
accountSelectHeader = "Select an Account" accountSelectHeader = "Select an Account"
accountSelectConfirm = "Select" accountSelectConfirm = "Select"
accountSelectCancel = "Cancel" accountSelectCancel = "Cancel"
accountSelectManage = "Manage Accounts"
[ejs.settings] [ejs.settings]
navHeaderText = "Settings" navHeaderText = "Settings"

View File

@ -6,12 +6,6 @@
<!-- Server listings populated here. --> <!-- Server listings populated here. -->
</div> </div>
</div> </div>
<div id="serverSelectActions">
<button id="serverSelectConfirm" class="overlayKeybindEnter" type="submit"><%- lang('overlay.serverSelectConfirm') %></button>
<div id="serverSelectCancelWrapper">
<button id="serverSelectCancel" class="overlayKeybindEsc"><%- lang('overlay.serverSelectCancel') %></button>
</div>
</div>
</div> </div>
<div id="accountSelectContent" style="display: none;"> <div id="accountSelectContent" style="display: none;">
<span id="accountSelectHeader"><%- lang('overlay.accountSelectHeader') %></span> <span id="accountSelectHeader"><%- lang('overlay.accountSelectHeader') %></span>
@ -26,6 +20,7 @@
<button id="accountSelectCancel" class="overlayKeybindEsc"><%- lang('overlay.accountSelectCancel') %></button> <button id="accountSelectCancel" class="overlayKeybindEsc"><%- lang('overlay.accountSelectCancel') %></button>
</div> </div>
</div> </div>
<button id="accountSelectManage" class="overlayKeybindEnter" type="submit"><%- lang('overlay.accountSelectManage') %></button>
</div> </div>
<div id="overlayContent"> <div id="overlayContent">
<span id="overlayTitle">Lorem Ipsum:<br>Finis Illud</span> <span id="overlayTitle">Lorem Ipsum:<br>Finis Illud</span>