Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Suggestion] Fluid Selection #351

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions app/assets/css/launcher.css
Original file line number Diff line number Diff line change
Expand Up @@ -3688,10 +3688,6 @@ input:checked + .toggleSwitchSlider:before {
position: relative;
background: rgba(131, 131, 131, 0.25);
}
.serverListing[selected] {
cursor: default;
opacity: 1.0;
}
.serverListing:hover,
.serverListing:focus {
outline: none;
Expand Down Expand Up @@ -3854,7 +3850,8 @@ input:checked + .toggleSwitchSlider:before {

/* Server selection confirm button styles. */
#serverSelectConfirm,
#accountSelectConfirm {
#accountSelectConfirm,
#accountSelectManage {
background: none;
border: 1px solid #ffffff;
color: white;
Expand Down
14 changes: 6 additions & 8 deletions app/assets/js/scripts/landing.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,6 @@ document.getElementById('settingsMediaButton').onclick = async e => {
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
function updateSelectedAccount(authUser){
let username = Lang.queryJS('landing.selectedAccount.noAccountSelected')
Expand Down Expand Up @@ -176,6 +168,12 @@ server_selection_button.onclick = async e => {
await toggleServerSelection(true)
}

// Bind avatar overlay button.
document.getElementById('avatarOverlay').onclick = async e => {
e.target.blur()
await toggleAccountSelection(true, true)
}

// Update Mojang Status Color
const refreshMojangStatuses = async function(){
loggerLanding.info('Refreshing Mojang Statuses..')
Expand Down
146 changes: 88 additions & 58 deletions app/assets/js/scripts/overlay.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,21 @@ function isOverlayVisible(){

let overlayHandlerContent

let overlayContainer = document.getElementById('overlayContainer')
let accountSelectContent = document.getElementById('accountSelectContent')

/**
* Overlay keydown handler for a non-dismissable overlay.
*
* @param {KeyboardEvent} e The keydown event.
*/
function overlayKeyHandler (e){
if(e.key === 'Enter' || e.key === 'Escape'){
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click()
if (overlayContainer.hasAttribute('popup')) {
toggleOverlay(false)
} else {
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click()
}
}
}
/**
Expand Down Expand Up @@ -64,8 +71,9 @@ function bindOverlayKeys(state, content, dismissable){
* @param {boolean} toggleState True to display, false to hide.
* @param {boolean} dismissable Optional. True to show the dismiss option, otherwise false.
* @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){
toggleState = !document.getElementById('main').hasAttribute('overlay')
}
Expand All @@ -76,6 +84,9 @@ function toggleOverlay(toggleState, dismissable = false, content = 'overlayConte
bindOverlayKeys(toggleState, content, dismissable)
if(toggleState){
document.getElementById('main').setAttribute('overlay', true)
overlayContainer.setAttribute('content', content)
overlayContainer.setAttribute('popup', popup)

// Make things untabbable.
$('#main *').attr('tabindex', '-1')
$('#' + content).parent().children().hide()
Expand All @@ -95,6 +106,8 @@ function toggleOverlay(toggleState, dismissable = false, content = 'overlayConte
})
} else {
document.getElementById('main').removeAttribute('overlay')
overlayContainer.removeAttribute('content')

// Make things tabbable.
$('#main *').removeAttr('tabindex')
$('#overlayContainer').fadeOut({
Expand All @@ -119,7 +132,21 @@ function toggleOverlay(toggleState, dismissable = false, content = 'overlayConte

async function toggleServerSelection(toggleState){
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)
}

/**
Expand Down Expand Up @@ -169,27 +196,9 @@ function setDismissHandler(handler){
}
}

/* Server Select View */

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)
}
})
/* Account Select button */

// Bind account select confirm button.
document.getElementById('accountSelectConfirm').addEventListener('click', async () => {
const listings = document.getElementsByClassName('accountListing')
for(let i=0; i<listings.length; i++){
Expand Down Expand Up @@ -218,51 +227,72 @@ document.getElementById('accountSelectConfirm').addEventListener('click', async
}
})

// Bind server select cancel button.
document.getElementById('serverSelectCancel').addEventListener('click', () => {
toggleOverlay(false)
})

// Bind account select cancel button.
document.getElementById('accountSelectCancel').addEventListener('click', () => {
$('#accountSelectContent').fadeOut(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'))
listings.map((val) => {
val.onclick = e => {
if(val.hasAttribute('selected')){
return
}
const cListings = document.getElementsByClassName('serverListing')
for(let i=0; i<cListings.length; i++){
if(cListings[i].hasAttribute('selected')){
cListings[i].removeAttribute('selected')
}
}
val.setAttribute('selected', '')
document.activeElement.blur()
listings.map(async (val) => {
val.onclick = async e => {
const serv = (await DistroAPI.getDistribution()).getServerById(val.getAttribute('servid'))
updateSelectedServer(serv)
refreshServerStatus(true)
toggleOverlay(false)
}
})
}

function setAccountListingHandlers(){
async function setAccountListingHandlers(){
const listings = Array.from(document.getElementsByClassName('accountListing'))
listings.map((val) => {
val.onclick = e => {
if(val.hasAttribute('selected')){
return
}
const cListings = document.getElementsByClassName('accountListing')
for(let i=0; i<cListings.length; i++){
if(cListings[i].hasAttribute('selected')){
cListings[i].removeAttribute('selected')
listings.map(async (val) => {
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')){
return
}
const cListings = document.getElementsByClassName('accountListing')
for(let i=0; i<cListings.length; i++){
if(cListings[i].hasAttribute('selected')){
cListings[i].removeAttribute('selected')
}
}
val.setAttribute('selected', '')
document.activeElement.blur()
}
val.setAttribute('selected', '')
document.activeElement.blur()
}
})
}
Expand Down Expand Up @@ -304,7 +334,7 @@ function populateAccountListings(){
const accounts = Array.from(Object.keys(accountsObj), v=>accountsObj[v])
let htmlString = ''
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">
<div class="accountListingName">${accounts[i].displayName}</div>
</button>`
Expand All @@ -315,10 +345,10 @@ function populateAccountListings(){

async function prepareServerSelectionList(){
await populateServerListings()
setServerListingHandlers()
await setServerListingHandlers()
}

function prepareAccountSelectionList(){
async function prepareAccountSelectionList(){
populateAccountListings()
setAccountListingHandlers()
await setAccountListingHandlers()
}
4 changes: 2 additions & 2 deletions app/assets/js/scripts/uibinder.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,9 +381,9 @@ async function validateSelectedAccount(){
toggleOverlay(false)
switchView(getCurrentView(), VIEWS.loginOptions)
})
setDismissHandler(() => {
setDismissHandler(async () => {
if(accLen > 1){
prepareAccountSelectionList()
await prepareAccountSelectionList()
$('#overlayContent').fadeOut(250, () => {
bindOverlayKeys(true, 'accountSelectContent', true)
$('#accountSelectContent').fadeIn(250)
Expand Down
5 changes: 2 additions & 3 deletions app/assets/lang/en_US.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[ejs.landing]
updateAvailableTooltip = "Update Available"
usernamePlaceholder = "Username"
usernameEditButton = "Edit"
usernameEditButton = "Switch"
settingsTooltip = "Settings"
serverStatus = "SERVER"
serverStatusPlaceholder = "OFFLINE"
Expand Down Expand Up @@ -42,11 +42,10 @@ cancelButton = "Cancel"

[ejs.overlay]
serverSelectHeader = "Available Servers"
serverSelectConfirm = "Select"
serverSelectCancel = "Cancel"
accountSelectHeader = "Select an Account"
accountSelectConfirm = "Select"
accountSelectCancel = "Cancel"
accountSelectManage = "Manage Accounts"

[ejs.settings]
navHeaderText = "Settings"
Expand Down
7 changes: 1 addition & 6 deletions app/overlay.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@
<!-- Server listings populated here. -->
</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 id="accountSelectContent" style="display: none;">
<span id="accountSelectHeader"><%- lang('overlay.accountSelectHeader') %></span>
Expand All @@ -26,6 +20,7 @@
<button id="accountSelectCancel" class="overlayKeybindEsc"><%- lang('overlay.accountSelectCancel') %></button>
</div>
</div>
<button id="accountSelectManage" class="overlayKeybindEnter" type="submit"><%- lang('overlay.accountSelectManage') %></button>
</div>
<div id="overlayContent">
<span id="overlayTitle">Lorem Ipsum:<br>Finis Illud</span>
Expand Down