Improve login ux on smaller screens

- Hide other UI elements when modal opens, to reduce clutter
- Hide login required modal if the server list is opened, to allow switching servers without overlapping the modal
- Use tel input for registration code
This commit is contained in:
James Lyne 2021-09-01 02:17:56 +01:00
parent 5350c2483f
commit fb53ad195c
3 changed files with 33 additions and 8 deletions

View File

@ -17,7 +17,7 @@
<template>
<Map></Map>
<ChatBox v-if="chatBoxEnabled" v-show="chatBoxEnabled && chatVisible"></ChatBox>
<LoginModal v-if="loginEnabled" :required="loginRequired"></LoginModal>
<LoginModal v-if="loginEnabled" v-show="loginModalVisible" :required="loginRequired"></LoginModal>
<Sidebar></Sidebar>
<notifications position="bottom center" :speed="250" :max="3" :ignoreDuplicates="true" classes="notification" />
</template>
@ -56,9 +56,14 @@ export default defineComponent({
chatBoxEnabled = computed(() => store.state.components.chatBox),
chatVisible = computed(() => store.state.ui.visibleElements.has('chat')),
loginEnabled = computed(() => store.state.components.login),
loggedIn = computed(() => store.state.loggedIn),
loginRequired = ref(false),
loginEnabled = computed(() => store.state.components.login), //Whether logging in is enabled for the current server
loggedIn = computed(() => store.state.loggedIn), //Whether the user is currently logged in
loginRequired = ref(false), //Whether logging is required to view the current server
//Hide the login modal if we are logged out on a login-required server, but the server list is open
//Allows switching servers without the modal overlapping
loginModalVisible = computed(() => store.state.ui.visibleModal === 'login'
&& (!loginRequired.value || !store.state.ui.visibleElements.has('maps'))),
loading = ref(false),
loadingAttempts = ref(0),
@ -91,14 +96,13 @@ export default defineComponent({
return;
}
//Show login screen if required
//Logging in is required, show login modal
if(e.message === 'login-required') {
loginRequired.value = true;
store.commit(MutationTypes.SHOW_UI_MODAL, 'login');
notify('Login required');
return;
}
//Any other errors
const error = `Failed to load server configuration for '${store.state.currentServer!.id}'`;
console.error(`${error}:`, e);
showSplashError(`${error}\n${e}`, false, ++loadingAttempts.value);
@ -141,6 +145,11 @@ export default defineComponent({
let element: LiveAtlasUIElement;
//Disable shortcuts if modal is open - except login required to allow server list toggling
if(store.state.ui.visibleModal && !loginRequired.value) {
return;
}
switch(e.key) {
case 'M':
element = 'maps';
@ -190,6 +199,17 @@ export default defineComponent({
console.log('Login state changed. Reloading configuration');
await loadConfiguration();
}
});
watch(loginRequired, (newValue) => {
if(newValue) {
store.commit(MutationTypes.SET_UI_ELEMENT_VISIBILITY, {
element: 'maps',
state: false,
});
store.commit(MutationTypes.SHOW_UI_MODAL, 'login');
notify('Login required');
showSplashError('Login required', true, 1);
}
})
onMounted(() => loadConfiguration());
@ -217,6 +237,7 @@ export default defineComponent({
chatVisible,
loginEnabled,
loginRequired,
loginModalVisible
}
},
});

View File

@ -40,7 +40,7 @@
<div class="form__group">
<label for="register-code" class="form__label">{{ messageRegisterCodeLabel }}</label>
<input id="register-code" type="text" name="code" v-model="valueCode" required />
<input id="register-code" type="tel" name="code" minlength="9" maxlength="9" v-model="valueCode" required />
</div>
<div v-if="error" role="alert" aria-live="assertive" class="form__group alert">{{ error }}</div>

View File

@ -595,6 +595,10 @@ export const mutations: MutationTree<State> & Mutations = {
},
[MutationTypes.SHOW_UI_MODAL](state: State, modal: LiveAtlasUIModal): void {
if(state.ui.smallScreen) {
state.ui.visibleElements.clear();
}
state.ui.visibleModal = modal;
},