🔀 Merge pull request #238 from Lissy93/FEATURE/improved-loading

[FEATURE] Improved Loading
This commit is contained in:
Alicia Sykes 2021-09-19 22:52:52 +01:00 committed by GitHub
commit e0d93659d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 73 additions and 19 deletions

View File

@ -1,5 +1,10 @@
# Changelog
## ⚡️ 1.8.3 - Improved UX for Initial Load [PR #238](https://github.com/Lissy93/dashy/pull/238)
- Removes the old splash screen
- Adds placeholder in the HTML index, which will usually be visible on initial load
- Show progress bar on route switcher
## ✨ 1.8.2 - Serverless Functions for Netlify Instances [PR #235](https://github.com/Lissy93/dashy/pull/235)
- Previously when Dashy was deployed as a static site to Netlify, it was not possible to use several features, which required server-side code
- This PR adds serverless cloud functions to provide most of this functionality

View File

@ -1,6 +1,6 @@
{
"name": "Dashy",
"version": "1.8.2",
"version": "1.8.3",
"license": "MIT",
"main": "server",
"scripts": {

View File

@ -1,27 +1,60 @@
<!DOCTYPE html>
<!-- Do not modify this file directly -->
<html lang="en">
<head>
<!-- Encoding and Viewport -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<!-- Favicon + App Icon -->
<link rel="icon" type="image/png" sizes="64x64" href="<%= BASE_URL %>/web-icons/favicon-64x64.png">
<link rel="icon" type="image/png" sizes="32x32" href="web-icons/favicon-32x32.png">
<link rel="icon" href="/favicon.ico" />
<link rel="icon" type="image/png" href="<%= BASE_URL %>favicon.ico" />
<!-- Default Page Title -->
<title>Dashy</title>
</head>
<body>
<!-- built files will be auto injected -->
<div id="app">
<!-- Loading screen, will be replaced when app loaded -->
<div class="loading-placeholder" id="loader"><h1>Dashy</h1><p>Loading...</p></div>
</div>
<!-- Devices without JS enabled -->
<noscript>
<strong>Sorry, JavaScript is required to run this app 😥</strong>
<strong>Sorry, JavaScript needs to be enabled to run Dashy 😥</strong>
</noscript>
<!-- built files will be auto injected -->
<div id="app"></div>
<!-- Styles for loading screen -->
<style type="text/css">
body { margin: 0; }
#app .loading-placeholder {
position: absolute;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
cursor: progress;
background: #121212;
}
#app .loading-placeholder h1 {
font-size: 20vh;
font-family: Tahoma, monospace;
cursor: progress;
color: #0c0c0c;
text-shadow: 0px 4px 4px #090909, 0 0 0 #000, 0px 2px 2px #000000;
}
#app .loading-placeholder p {
font-size: 2rem;
font-family: monospace;
cursor: progress;
color: #0c0c0c;
text-shadow: 0 1px 1px #090909, 0 0 0 #000, 0 1px 1px #000000;
}
::selection { background-color: #db78fc; color: #121212; }
</style>
</body>
</html>

View File

@ -53,8 +53,7 @@ export default {
},
/* Determine if splash screen should be shown */
shouldShowSplash() {
return (this.visibleComponents || defaultVisibleComponents).splashScreen
|| !localStorage[localStorageKeys.HIDE_WELCOME_BANNER];
return (this.visibleComponents || defaultVisibleComponents).splashScreen;
},
},
methods: {
@ -107,6 +106,10 @@ export default {
this.$i18n.locale = language;
document.getElementsByTagName('html')[0].setAttribute('lang', language);
},
hideLoader() {
const loader = document.getElementById('loader');
if (loader) loader.style.display = 'none';
},
},
/* When component mounted, hide splash and initiate the injection of custom styles */
mounted() {
@ -115,6 +118,7 @@ export default {
if (this.appConfig.customCss) {
const cleanedCss = this.appConfig.customCss.replace(/<\/?[^>]+(>|$)/g, '');
this.injectCustomStyles(cleanedCss);
this.hideLoader();
}
welcomeMsg();
},

View File

@ -66,7 +66,7 @@ import IconBackup from '@/assets/interface-icons/config-backup.svg';
import IconRestore from '@/assets/interface-icons/config-restore.svg';
import { backup, update, restore } from '@/utils/CloudBackup';
import { localStorageKeys } from '@/utils/defaults';
import ErrorHandler, { InfoHandler } from '@/utils/ErrorHandler';
import { InfoHandler, WarningInfoHandler } from '@/utils/ErrorHandler';
export default {
name: 'CloudBackupRestore',
@ -161,7 +161,7 @@ export default {
this.backupPassword = '';
},
showErrorMsg(errorMsg) {
ErrorHandler(errorMsg);
WarningInfoHandler(errorMsg, 'Cloud Backup');
this.$toasted.show(errorMsg, { className: 'toast-error' });
},
showSuccessMsg(msg) {

View File

@ -7,6 +7,7 @@
// Import Vue.js and vue router
import Vue from 'vue';
import Router from 'vue-router';
import ProgressBar from 'rsup-progress';
// Import views
import Home from '@/views/Home.vue';
@ -21,6 +22,7 @@ import { config } from '@/utils/ConfigHelpers';
import { metaTagData, startingView, routePaths } from '@/utils/defaults';
Vue.use(Router);
const progress = new ProgressBar({ color: 'var(--progress-bar)' });
/* Returns true if user is already authenticated, or if auth is not enabled */
const isAuthenticated = () => {
@ -119,12 +121,14 @@ const router = new Router({
* If not logged in, prevent all access and redirect them to login page
* */
router.beforeEach((to, from, next) => {
progress.start();
if (to.name !== 'login' && !isAuthenticated()) next({ name: 'login' });
else next();
});
/* If title is missing, then apply default page title */
router.afterEach((to) => {
progress.end();
Vue.nextTick(() => {
document.title = to.meta.title || 'Dashy';
});

View File

@ -28,7 +28,7 @@ export const statusMsg = (title, msg) => {
/* Prints status message, with a stack trace */
export const statusErrorMsg = (title, msg, errorLog) => {
console.log(
`%c${title || ''}\n%c${msg} \n%c${errorLog}`,
`%c${title || ''}\n%c${msg} \n%c${errorLog || ''}`,
'font-weight: bold; color: #0dd8d8; text-decoration: underline;',
'color: #ff025a',
'color: #ff025a80;',

View File

@ -1,5 +1,5 @@
import * as Sentry from '@sentry/vue';
import { warningMsg, statusMsg } from '@/utils/CoolConsole';
import { warningMsg, statusMsg, statusErrorMsg } from '@/utils/CoolConsole';
import { sessionStorageKeys } from '@/utils/defaults';
/* Makes the current time, like hh:mm:ss */
@ -33,4 +33,9 @@ export const InfoHandler = (msg, title) => {
statusMsg(title || 'Info', msg);
};
/* Outputs warnings caused by the user, such as missing field */
export const WarningInfoHandler = (msg, title, log) => {
statusErrorMsg(title || 'Warning', msg, log);
};
export default ErrorHandler;

View File

@ -71,8 +71,9 @@ module.exports = {
],
/* Which structural components should be visible by default */
visibleComponents: {
pageTitle: true,
splashScreen: false,
navigation: true,
pageTitle: true,
searchBar: true,
settings: true,
footer: true,

View File

@ -76,7 +76,7 @@ import router from '@/router';
import Button from '@/components/FormElements/Button';
import Input from '@/components/FormElements/Input';
import Defaults, { localStorageKeys } from '@/utils/defaults';
import { InfoHandler } from '@/utils/ErrorHandler';
import { InfoHandler, WarningInfoHandler } from '@/utils/ErrorHandler';
import {
checkCredentials,
login,
@ -160,7 +160,7 @@ export default {
this.goHome();
InfoHandler(`Succesfully signed in as ${this.username}`, 'Authentication');
} else {
InfoHandler(`Unable to Sign In - ${this.message}`, 'Authentication');
WarningInfoHandler('Unable to Sign In', 'Authentication', this.message);
}
},
/* Calls function to double-check guest access enabled, then log in as guest */
@ -168,9 +168,11 @@ export default {
const isAllowed = this.isGuestAccessEnabled;
if (isAllowed) {
this.$toasted.show('Logged in as Guest, Redirecting...', { className: 'toast-success' });
InfoHandler('Logged in as Guest', 'Authentication');
this.goHome();
} else {
this.$toasted.show('Guest access not allowed', { className: 'toast-error' });
this.$toasted.show('Guest Access Not Allowed', { className: 'toast-error' });
WarningInfoHandler('Guest Access Not Allowed', 'Authentication');
}
},
/* Calls logout, shows status message, and refreshed page */