Skip to content

Commit e67c4ed

Browse files
committed
Fluid Selection
dscalzi#351
1 parent 08daebc commit e67c4ed

File tree

6 files changed

+100
-81
lines changed

6 files changed

+100
-81
lines changed

app/assets/css/launcher.css

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3702,10 +3702,7 @@ input:checked + .toggleSwitchSlider:before {
37023702
position: relative;
37033703
background: rgba(131, 131, 131, 0.25);
37043704
}
3705-
.serverListing[selected] {
3706-
cursor: default;
3707-
opacity: 1.0;
3708-
}
3705+
37093706
.serverListing:hover,
37103707
.serverListing:focus {
37113708
outline: none;
@@ -3858,7 +3855,8 @@ input:checked + .toggleSwitchSlider:before {
38583855

38593856
/* Content container which contains the server select actions. */
38603857
#serverSelectActions,
3861-
#accountSelectActions {
3858+
#accountSelectConfirm,
3859+
#accountSelectManage {
38623860
display: flex;
38633861
flex-direction: column;
38643862
justify-content: center;

app/assets/js/scripts/landing.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,6 @@ document.getElementById('settingsMediaButton').onclick = async e => {
133133
switchView(getCurrentView(), VIEWS.settings)
134134
}
135135

136-
// Bind avatar overlay button.
137-
document.getElementById('avatarOverlay').onclick = async e => {
138-
await prepareSettings()
139-
switchView(getCurrentView(), VIEWS.settings, 500, 500, () => {
140-
settingsNavItemListener(document.getElementById('settingsNavAccount'), false)
141-
})
142-
}
143-
144136
// Bind selected account
145137
function updateSelectedAccount(authUser){
146138
let username = Lang.queryJS('landing.selectedAccount.noAccountSelected')
@@ -176,6 +168,12 @@ server_selection_button.onclick = async e => {
176168
await toggleServerSelection(true)
177169
}
178170

171+
// Bind avatar overlay button.
172+
document.getElementById('avatarOverlay').onclick = async e => {
173+
e.target.blur()
174+
await toggleAccountSelection(true, true)
175+
}
176+
179177
// Update Mojang Status Color
180178
const refreshMojangStatuses = async function(){
181179
loggerLanding.info('Refreshing Mojang Statuses..')

app/assets/js/scripts/overlay.js

Lines changed: 86 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,21 @@ function isOverlayVisible(){
1515

1616
let overlayHandlerContent
1717

18+
let overlayContainer = document.getElementById('overlayContainer')
19+
let accountSelectContent = document.getElementById('accountSelectContent')
20+
1821
/**
1922
* Overlay keydown handler for a non-dismissable overlay.
2023
*
2124
* @param {KeyboardEvent} e The keydown event.
2225
*/
2326
function overlayKeyHandler (e){
2427
if(e.key === 'Enter' || e.key === 'Escape'){
25-
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click()
28+
if (overlayContainer.hasAttribute('popup')) {
29+
toggleOverlay(false)
30+
} else {
31+
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click()
32+
}
2633
}
2734
}
2835
/**
@@ -64,8 +71,9 @@ function bindOverlayKeys(state, content, dismissable){
6471
* @param {boolean} toggleState True to display, false to hide.
6572
* @param {boolean} dismissable Optional. True to show the dismiss option, otherwise false.
6673
* @param {string} content Optional. The content div to be shown.
74+
* @param {boolean} popup Optional. True to show the overlay as a popup that is easily dismissable and interactible.
6775
*/
68-
function toggleOverlay(toggleState, dismissable = false, content = 'overlayContent'){
76+
function toggleOverlay(toggleState, dismissable = false, content = 'overlayContent', popup = false){
6977
if(toggleState == null){
7078
toggleState = !document.getElementById('main').hasAttribute('overlay')
7179
}
@@ -75,6 +83,8 @@ function toggleOverlay(toggleState, dismissable = false, content = 'overlayConte
7583
}
7684
bindOverlayKeys(toggleState, content, dismissable)
7785
if(toggleState){
86+
overlayContainer.setAttribute('content', content)
87+
overlayContainer.setAttribute('popup', popup)
7888
document.getElementById('main').setAttribute('overlay', true)
7989
// Make things untabbable.
8090
$('#main *').attr('tabindex', '-1')
@@ -94,6 +104,7 @@ function toggleOverlay(toggleState, dismissable = false, content = 'overlayConte
94104
}
95105
})
96106
} else {
107+
overlayContainer.removeAttribute('content')
97108
document.getElementById('main').removeAttribute('overlay')
98109
// Make things tabbable.
99110
$('#main *').removeAttr('tabindex')
@@ -119,7 +130,21 @@ function toggleOverlay(toggleState, dismissable = false, content = 'overlayConte
119130

120131
async function toggleServerSelection(toggleState){
121132
await prepareServerSelectionList()
122-
toggleOverlay(toggleState, true, 'serverSelectContent')
133+
toggleOverlay(toggleState, false, 'serverSelectContent', true)
134+
}
135+
136+
async function toggleAccountSelection(toggleState, popup = false){
137+
if (popup) {
138+
// set the accountSelectActions div to display: none to avoid colliding with the validateSelectedAccount function
139+
document.getElementById('accountSelectActions').style.display = 'none'
140+
} else {
141+
// set the overlayContainer div to display: block, this is not done while closing the overlay because of the fadeOut effect
142+
document.getElementById('accountSelectActions').style.display = 'block'
143+
}
144+
145+
// show the overlay
146+
await prepareAccountSelectionList()
147+
toggleOverlay(toggleState, false, 'accountSelectContent', popup)
123148
}
124149

125150
/**
@@ -169,27 +194,9 @@ function setDismissHandler(handler){
169194
}
170195
}
171196

172-
/* Server Select View */
173-
174-
document.getElementById('serverSelectConfirm').addEventListener('click', async () => {
175-
const listings = document.getElementsByClassName('serverListing')
176-
for(let i=0; i<listings.length; i++){
177-
if(listings[i].hasAttribute('selected')){
178-
const serv = (await DistroAPI.getDistribution()).getServerById(listings[i].getAttribute('servid'))
179-
updateSelectedServer(serv)
180-
refreshServerStatus(true)
181-
toggleOverlay(false)
182-
return
183-
}
184-
}
185-
// None are selected? Not possible right? Meh, handle it.
186-
if(listings.length > 0){
187-
const serv = (await DistroAPI.getDistribution()).getServerById(listings[i].getAttribute('servid'))
188-
updateSelectedServer(serv)
189-
toggleOverlay(false)
190-
}
191-
})
197+
/* Account Select button */
192198

199+
// Bind account select confirm button.
193200
document.getElementById('accountSelectConfirm').addEventListener('click', async () => {
194201
const listings = document.getElementsByClassName('accountListing')
195202
for(let i=0; i<listings.length; i++){
@@ -218,51 +225,73 @@ document.getElementById('accountSelectConfirm').addEventListener('click', async
218225
}
219226
})
220227

221-
// Bind server select cancel button.
222-
document.getElementById('serverSelectCancel').addEventListener('click', () => {
223-
toggleOverlay(false)
224-
})
225-
228+
// Bind account select cancel button.
226229
document.getElementById('accountSelectCancel').addEventListener('click', () => {
227230
$('#accountSelectContent').fadeOut(250, () => {
228231
$('#overlayContent').fadeIn(250)
229232
})
230233
})
231234

232-
function setServerListingHandlers(){
235+
236+
// Bind account select manage button.
237+
document.getElementById('accountSelectManage').addEventListener('click', async () => {
238+
await prepareSettings()
239+
switchView(getCurrentView(), VIEWS.settings, 500, 500, () => {
240+
settingsNavItemListener(document.getElementById('settingsNavAccount'), false)
241+
})
242+
toggleOverlay(false)
243+
})
244+
245+
// Make the Server Selection background clickable to close the overlay.
246+
overlayContainer.addEventListener('click', e => {
247+
if (e.target === overlayContainer) {
248+
// This function only works if the overlay is a popup
249+
if(overlayContainer.hasAttribute('popup')) {
250+
toggleOverlay(false)
251+
}
252+
}
253+
})
254+
255+
async function setServerListingHandlers(){
233256
const listings = Array.from(document.getElementsByClassName('serverListing'))
234-
listings.map((val) => {
235-
val.onclick = e => {
236-
if(val.hasAttribute('selected')){
237-
return
238-
}
239-
const cListings = document.getElementsByClassName('serverListing')
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()
257+
listings.map(async (val) => {
258+
val.onclick = async e => {
259+
const serv = (await DistroAPI.getDistribution()).getServerById(val.getAttribute('servid'))
260+
updateSelectedServer(serv)
261+
refreshServerStatus(true)
262+
toggleOverlay(false)
247263
}
248264
})
249265
}
250266

251-
function setAccountListingHandlers(){
267+
async function setAccountListingHandlers(){
252268
const listings = Array.from(document.getElementsByClassName('accountListing'))
253-
listings.map((val) => {
254-
val.onclick = e => {
255-
if(val.hasAttribute('selected')){
269+
listings.map(async (val) => {
270+
val.onclick = async e => {
271+
// popup mode
272+
if(overlayContainer.hasAttribute('popup')){
273+
const authAcc = ConfigManager.setSelectedAccount(val.getAttribute('uuid'))
274+
ConfigManager.save()
275+
updateSelectedAccount(authAcc)
276+
if(getCurrentView() === VIEWS.settings) {
277+
await prepareSettings()
278+
}
279+
toggleOverlay(false)
280+
validateSelectedAccount()
256281
return
257-
}
258-
const cListings = document.getElementsByClassName('accountListing')
259-
for(let i=0; i<cListings.length; i++){
260-
if(cListings[i].hasAttribute('selected')){
261-
cListings[i].removeAttribute('selected')
282+
} else {
283+
if(val.hasAttribute('selected')){
284+
return
285+
}
286+
const cListings = document.getElementsByClassName('accountListing')
287+
for(let i=0; i<cListings.length; i++){
288+
if(cListings[i].hasAttribute('selected')){
289+
cListings[i].removeAttribute('selected')
290+
}
262291
}
292+
val.setAttribute('selected', '')
293+
document.activeElement.blur()
263294
}
264-
val.setAttribute('selected', '')
265-
document.activeElement.blur()
266295
}
267296
})
268297
}
@@ -304,7 +333,7 @@ function populateAccountListings(){
304333
const accounts = Array.from(Object.keys(accountsObj), v=>accountsObj[v])
305334
let htmlString = ''
306335
for(let i=0; i<accounts.length; i++){
307-
htmlString += `<button class="accountListing" uuid="${accounts[i].uuid}" ${i===0 ? 'selected' : ''}>
336+
htmlString += `<button class="accountListing" uuid="${accounts[i].uuid}" ${!i && !overlayContainer.hasAttribute("popup") ? 'selected' : ''}>
308337
<img src="https://mc-heads.net/head/${accounts[i].uuid}/40">
309338
<div class="accountListingName">${accounts[i].displayName}</div>
310339
</button>`
@@ -315,10 +344,10 @@ function populateAccountListings(){
315344

316345
async function prepareServerSelectionList(){
317346
await populateServerListings()
318-
setServerListingHandlers()
347+
await setServerListingHandlers()
319348
}
320349

321-
function prepareAccountSelectionList(){
350+
async function prepareAccountSelectionList(){
322351
populateAccountListings()
323-
setAccountListingHandlers()
352+
await setAccountListingHandlers()
324353
}

app/assets/js/scripts/uibinder.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,9 @@ async function validateSelectedAccount(){
381381
toggleOverlay(false)
382382
switchView(getCurrentView(), VIEWS.loginOptions)
383383
})
384-
setDismissHandler(() => {
384+
setDismissHandler(async () => {
385385
if(accLen > 1){
386-
prepareAccountSelectionList()
386+
await prepareAccountSelectionList()
387387
$('#overlayContent').fadeOut(250, () => {
388388
bindOverlayKeys(true, 'accountSelectContent', true)
389389
$('#accountSelectContent').fadeIn(250)

app/assets/lang/en_US.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[ejs.landing]
22
updateAvailableTooltip = "Update Available"
33
usernamePlaceholder = "Username"
4-
usernameEditButton = "Edit"
4+
usernameEditButton = "Switch"
55
settingsTooltip = "Settings"
66
serverStatus = "SERVER"
77
serverStatusPlaceholder = "OFFLINE"
@@ -42,11 +42,10 @@ cancelButton = "Cancel"
4242

4343
[ejs.overlay]
4444
serverSelectHeader = "Available Servers"
45-
serverSelectConfirm = "Select"
46-
serverSelectCancel = "Cancel"
4745
accountSelectHeader = "Select an Account"
4846
accountSelectConfirm = "Select"
4947
accountSelectCancel = "Cancel"
48+
accountSelectManage = "Manage Accounts"
5049

5150
[ejs.settings]
5251
closeLauncherOnLaunch = "Close the launcher when the game is launched."

app/overlay.ejs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@
66
<!-- Server listings populated here. -->
77
</div>
88
</div>
9-
<div id="serverSelectActions">
10-
<button id="serverSelectConfirm" class="overlayKeybindEnter" type="submit"><%- lang('overlay.serverSelectConfirm') %></button>
11-
<div id="serverSelectCancelWrapper">
12-
<button id="serverSelectCancel" class="overlayKeybindEsc"><%- lang('overlay.serverSelectCancel') %></button>
13-
</div>
14-
</div>
159
</div>
1610
<div id="accountSelectContent" style="display: none;">
1711
<span id="accountSelectHeader"><%- lang('overlay.accountSelectHeader') %></span>
@@ -26,6 +20,7 @@
2620
<button id="accountSelectCancel" class="overlayKeybindEsc"><%- lang('overlay.accountSelectCancel') %></button>
2721
</div>
2822
</div>
23+
<button id="accountSelectManage" class="overlayKeybindEnter" type="submit"><%- lang('overlay.accountSelectManage') %></button>
2924
</div>
3025
<div id="overlayContent">
3126
<span id="overlayTitle">Lorem Ipsum:<br>Finis Illud</span>

0 commit comments

Comments
 (0)