mirror of
https://github.com/Elvanos/fantasia-archive.git
synced 2024-06-17 17:54:54 +12:00
added app splash screen, fixed multi-instance bug
This commit is contained in:
parent
2e722bd8af
commit
565bf34bde
36
index.html
36
index.html
|
@ -14,8 +14,44 @@
|
|||
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png">
|
||||
<link rel="icon" type="image/ico" href="favicon.ico">
|
||||
<style>
|
||||
.splashLoadingWrapper{
|
||||
background-color: #18303a;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
transition: 0.5s opacity ease-in;
|
||||
transition-delay: 2s;
|
||||
z-index: 9999999999999999999;
|
||||
}
|
||||
|
||||
.splashLoading{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.splashLoading path{
|
||||
fill: #d7ac47;
|
||||
}
|
||||
|
||||
#q-app[data-v-app] ~ .splashLoadingWrapper{
|
||||
opacity: 0 !important;
|
||||
user-select: none !important;
|
||||
pointer-events: none !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- quasar:entry-point -->
|
||||
<div class="splashLoadingWrapper">
|
||||
<svg class="splashLoading" width="500px" height="500px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-20,-20)"><path d="M79.9,52.6C80,51.8,80,50.9,80,50s0-1.8-0.1-2.6l-5.1-0.4c-0.3-2.4-0.9-4.6-1.8-6.7l4.2-2.9c-0.7-1.6-1.6-3.1-2.6-4.5 L70,35c-1.4-1.9-3.1-3.5-4.9-4.9l2.2-4.6c-1.4-1-2.9-1.9-4.5-2.6L59.8,27c-2.1-0.9-4.4-1.5-6.7-1.8l-0.4-5.1C51.8,20,50.9,20,50,20 s-1.8,0-2.6,0.1l-0.4,5.1c-2.4,0.3-4.6,0.9-6.7,1.8l-2.9-4.1c-1.6,0.7-3.1,1.6-4.5,2.6l2.1,4.6c-1.9,1.4-3.5,3.1-5,4.9l-4.5-2.1 c-1,1.4-1.9,2.9-2.6,4.5l4.1,2.9c-0.9,2.1-1.5,4.4-1.8,6.8l-5,0.4C20,48.2,20,49.1,20,50s0,1.8,0.1,2.6l5,0.4 c0.3,2.4,0.9,4.7,1.8,6.8l-4.1,2.9c0.7,1.6,1.6,3.1,2.6,4.5l4.5-2.1c1.4,1.9,3.1,3.5,5,4.9l-2.1,4.6c1.4,1,2.9,1.9,4.5,2.6l2.9-4.1 c2.1,0.9,4.4,1.5,6.7,1.8l0.4,5.1C48.2,80,49.1,80,50,80s1.8,0,2.6-0.1l0.4-5.1c2.3-0.3,4.6-0.9,6.7-1.8l2.9,4.2 c1.6-0.7,3.1-1.6,4.5-2.6L65,69.9c1.9-1.4,3.5-3,4.9-4.9l4.6,2.2c1-1.4,1.9-2.9,2.6-4.5L73,59.8c0.9-2.1,1.5-4.4,1.8-6.7L79.9,52.6 z M50,65c-8.3,0-15-6.7-15-15c0-8.3,6.7-15,15-15s15,6.7,15,15C65,58.3,58.3,65,50,65z" fill="currentColor"><animateTransform attributeName="transform" type="rotate" from="90 50 50" to="0 50 50" dur="1s" repeatCount="indefinite"></animateTransform></path></g><g transform="translate(20,20) rotate(15 50 50)"><path d="M79.9,52.6C80,51.8,80,50.9,80,50s0-1.8-0.1-2.6l-5.1-0.4c-0.3-2.4-0.9-4.6-1.8-6.7l4.2-2.9c-0.7-1.6-1.6-3.1-2.6-4.5 L70,35c-1.4-1.9-3.1-3.5-4.9-4.9l2.2-4.6c-1.4-1-2.9-1.9-4.5-2.6L59.8,27c-2.1-0.9-4.4-1.5-6.7-1.8l-0.4-5.1C51.8,20,50.9,20,50,20 s-1.8,0-2.6,0.1l-0.4,5.1c-2.4,0.3-4.6,0.9-6.7,1.8l-2.9-4.1c-1.6,0.7-3.1,1.6-4.5,2.6l2.1,4.6c-1.9,1.4-3.5,3.1-5,4.9l-4.5-2.1 c-1,1.4-1.9,2.9-2.6,4.5l4.1,2.9c-0.9,2.1-1.5,4.4-1.8,6.8l-5,0.4C20,48.2,20,49.1,20,50s0,1.8,0.1,2.6l5,0.4 c0.3,2.4,0.9,4.7,1.8,6.8l-4.1,2.9c0.7,1.6,1.6,3.1,2.6,4.5l4.5-2.1c1.4,1.9,3.1,3.5,5,4.9l-2.1,4.6c1.4,1,2.9,1.9,4.5,2.6l2.9-4.1 c2.1,0.9,4.4,1.5,6.7,1.8l0.4,5.1C48.2,80,49.1,80,50,80s1.8,0,2.6-0.1l0.4-5.1c2.3-0.3,4.6-0.9,6.7-1.8l2.9,4.2 c1.6-0.7,3.1-1.6,4.5-2.6L65,69.9c1.9-1.4,3.5-3,4.9-4.9l4.6,2.2c1-1.4,1.9-2.9,2.6-4.5L73,59.8c0.9-2.1,1.5-4.4,1.8-6.7L79.9,52.6 z M50,65c-8.3,0-15-6.7-15-15c0-8.3,6.7-15,15-15s15,6.7,15,15C65,58.3,58.3,65,50,65z" fill="currentColor"><animateTransform attributeName="transform" type="rotate" from="0 50 50" to="90 50 50" dur="1s" repeatCount="indefinite"></animateTransform></path></g></svg>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -10,6 +10,11 @@ export interface I_faWindowControlAPI {
|
|||
*/
|
||||
minimizeWindow: () => void
|
||||
|
||||
/**
|
||||
* Mazimizes the current window
|
||||
*/
|
||||
maximizeWindow: () => void
|
||||
|
||||
/**
|
||||
* Resizes the current window.
|
||||
* - If the window is maximized, smallifies it
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
"scripts": {
|
||||
"lint": "eslint --ext .js,.ts,.vue ./",
|
||||
"dev:electron": "quasar dev -m electron",
|
||||
"build": "quasar build -m electron --publish never --debug",
|
||||
"build": "quasar build -m electron --publish never",
|
||||
"test:unit:ui": "vitest --ui",
|
||||
"test:unit:ci": "vitest run --reporter verbose",
|
||||
"test:component": "node \"node_modules/@playwright/test/cli.js\" test src/components/",
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
// Configuration for your app
|
||||
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js
|
||||
|
||||
const { configure } = require('quasar/wrappers')
|
||||
const path = require('path')
|
||||
const { configure } = require("quasar/wrappers");
|
||||
const path = require("path");
|
||||
|
||||
module.exports = configure(function (/* ctx */) {
|
||||
return {
|
||||
|
@ -19,7 +19,7 @@ module.exports = configure(function (/* ctx */) {
|
|||
// exclude: [],
|
||||
// rawOptions: {},
|
||||
warnings: true,
|
||||
errors: true
|
||||
errors: true,
|
||||
},
|
||||
|
||||
// https://v2.quasar.dev/quasar-cli-vite/prefetch-feature
|
||||
|
@ -28,38 +28,33 @@ module.exports = configure(function (/* ctx */) {
|
|||
// app boot file (/src/boot)
|
||||
// --> boot files are part of "main.js"
|
||||
// https://v2.quasar.dev/quasar-cli-vite/boot-files
|
||||
boot: [
|
||||
'i18n',
|
||||
'axios'
|
||||
],
|
||||
boot: ["i18n", "axios"],
|
||||
|
||||
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
|
||||
css: [
|
||||
'app.scss'
|
||||
],
|
||||
css: ["app.scss"],
|
||||
|
||||
// https://github.com/quasarframework/quasar/tree/dev/extras
|
||||
extras: [
|
||||
// 'ionicons-v4',
|
||||
'mdi-v5',
|
||||
'fontawesome-v6',
|
||||
"mdi-v5",
|
||||
"fontawesome-v6",
|
||||
// 'eva-icons',
|
||||
// 'themify',
|
||||
// 'line-awesome',
|
||||
|
||||
// 'roboto-font', // optional, you are not bound to it
|
||||
'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!
|
||||
'material-icons' // optional, you are not bound to it
|
||||
"roboto-font-latin-ext", // this or either 'roboto-font', NEVER both!
|
||||
"material-icons", // optional, you are not bound to it
|
||||
],
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
|
||||
build: {
|
||||
target: {
|
||||
browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
|
||||
node: 'node16'
|
||||
browser: ["es2019", "edge88", "firefox78", "chrome87", "safari13.1"],
|
||||
node: "node16",
|
||||
},
|
||||
|
||||
vueRouterMode: 'history', // available values: 'hash', 'history'
|
||||
vueRouterMode: "history", // available values: 'hash', 'history'
|
||||
// vueRouterBase,
|
||||
// vueDevtools,
|
||||
// vueOptionsAPI: false,
|
||||
|
@ -79,24 +74,27 @@ module.exports = configure(function (/* ctx */) {
|
|||
// viteVuePluginOptions: {},
|
||||
|
||||
vitePlugins: [
|
||||
['@intlify/vite-plugin-vue-i18n', {
|
||||
// if you want to use Vue I18n Legacy API, you need to set `compositionOnly: false`
|
||||
// compositionOnly: false,
|
||||
[
|
||||
"@intlify/vite-plugin-vue-i18n",
|
||||
{
|
||||
// if you want to use Vue I18n Legacy API, you need to set `compositionOnly: false`
|
||||
// compositionOnly: false,
|
||||
|
||||
// if you want to use named tokens in your Vue I18n messages, such as 'Hello {name}',
|
||||
// you need to set `runtimeOnly: false`
|
||||
// runtimeOnly: false,
|
||||
// if you want to use named tokens in your Vue I18n messages, such as 'Hello {name}',
|
||||
// you need to set `runtimeOnly: false`
|
||||
// runtimeOnly: false,
|
||||
|
||||
// you need to set i18n resource including paths !
|
||||
include: path.resolve(__dirname, './src/i18n/**')
|
||||
}]
|
||||
]
|
||||
// you need to set i18n resource including paths !
|
||||
include: path.resolve(__dirname, "./src/i18n/**"),
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer
|
||||
devServer: {
|
||||
// https: true
|
||||
open: true // opens browser window automatically
|
||||
open: true, // opens browser window automatically
|
||||
},
|
||||
|
||||
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework
|
||||
|
@ -114,12 +112,12 @@ module.exports = configure(function (/* ctx */) {
|
|||
// directives: [],
|
||||
|
||||
// Quasar plugins
|
||||
plugins: []
|
||||
plugins: [],
|
||||
},
|
||||
|
||||
// animations: 'all', // --- includes all animations
|
||||
// https://v2.quasar.dev/options/animations
|
||||
animations: [],
|
||||
animations: "all",
|
||||
|
||||
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#sourcefiles
|
||||
// sourceFiles: {
|
||||
|
@ -150,17 +148,17 @@ module.exports = configure(function (/* ctx */) {
|
|||
// (gets superseded if process.env.PORT is specified at runtime)
|
||||
|
||||
middlewares: [
|
||||
'render' // keep this as last one
|
||||
]
|
||||
"render", // keep this as last one
|
||||
],
|
||||
},
|
||||
|
||||
// https://v2.quasar.dev/quasar-cli-vite/developing-pwa/configuring-pwa
|
||||
pwa: {
|
||||
workboxMode: 'generateSW', // or 'injectManifest'
|
||||
workboxMode: "generateSW", // or 'injectManifest'
|
||||
injectPwaMetaTags: true,
|
||||
swFilename: 'sw.js',
|
||||
manifestFilename: 'manifest.json',
|
||||
useCredentialsForManifestTag: false
|
||||
swFilename: "sw.js",
|
||||
manifestFilename: "manifest.json",
|
||||
useCredentialsForManifestTag: false,
|
||||
// useFilenameHashes: true,
|
||||
// extendGenerateSWOptions (cfg) {}
|
||||
// extendInjectManifestOptions (cfg) {},
|
||||
|
@ -175,7 +173,7 @@ module.exports = configure(function (/* ctx */) {
|
|||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-capacitor-apps/configuring-capacitor
|
||||
capacitor: {
|
||||
hideSplashscreen: true
|
||||
hideSplashscreen: true,
|
||||
},
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/configuring-electron
|
||||
|
@ -185,17 +183,15 @@ module.exports = configure(function (/* ctx */) {
|
|||
|
||||
inspectPort: 5858,
|
||||
|
||||
bundler: 'builder', // 'packager' or 'builder'
|
||||
bundler: "builder", // 'packager' or 'builder'
|
||||
|
||||
packager: {
|
||||
// https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options
|
||||
|
||||
// OS X / Mac App Store
|
||||
// appBundleId: '',
|
||||
// appCategoryType: '',
|
||||
// osxSign: '',
|
||||
// protocol: 'myapp://path',
|
||||
|
||||
// Windows only
|
||||
// win32metadata: { ... }
|
||||
},
|
||||
|
@ -203,21 +199,19 @@ module.exports = configure(function (/* ctx */) {
|
|||
builder: {
|
||||
// https://www.electron.build/configuration/configuration
|
||||
|
||||
appId: 'fantasia-archive',
|
||||
appId: "fantasia-archive",
|
||||
win: {
|
||||
icon: 'src-electron/icons/icon.ico'
|
||||
}
|
||||
}
|
||||
icon: "src-electron/icons/icon.ico",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex
|
||||
bex: {
|
||||
contentScripts: [
|
||||
'my-content-script'
|
||||
]
|
||||
contentScripts: ["my-content-script"],
|
||||
|
||||
// extendBexScriptsConf (esbuildConf) {}
|
||||
// extendBexManifestJson (json) {}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
|
@ -19,6 +19,14 @@ export const faWindowControlAPI: I_faWindowControlAPI = {
|
|||
}
|
||||
},
|
||||
|
||||
maximizeWindow () {
|
||||
const currentWindow = BrowserWindow.getFocusedWindow()
|
||||
|
||||
if (currentWindow !== null) {
|
||||
currentWindow.maximize()
|
||||
}
|
||||
},
|
||||
|
||||
resizeWindow () {
|
||||
const currentWindow = BrowserWindow.getFocusedWindow()
|
||||
|
||||
|
|
|
@ -16,11 +16,9 @@ export const openAppWindowManager = () => {
|
|||
// Create the app window in the normal way
|
||||
app.whenReady().then(mainWindowCreation)
|
||||
|
||||
// Create the app window, if it still doesn't exist yet
|
||||
// Create the app window
|
||||
app.on('activate', () => {
|
||||
if (app.requestSingleInstanceLock()) {
|
||||
mainWindowCreation()
|
||||
}
|
||||
mainWindowCreation()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,34 @@
|
|||
import { BrowserWindow } from 'electron'
|
||||
import { BrowserWindow, app } from 'electron'
|
||||
import { enable } from '@electron/remote/main'
|
||||
import path from 'path'
|
||||
|
||||
/**
|
||||
* Prevent app to launch a secondary instance
|
||||
*/
|
||||
const preventSecondaryAppInstance = (appWindow: BrowserWindow | undefined) => {
|
||||
/**
|
||||
* Determines if the app is the primary instance
|
||||
* - This exists as a variable due to the app bugging out if used directly from "app"
|
||||
*/
|
||||
const isPrimaryInstance = app.requestSingleInstanceLock()
|
||||
|
||||
// Check this is NOT the primary app instance
|
||||
if (!isPrimaryInstance) {
|
||||
app.quit()
|
||||
} else {
|
||||
/*
|
||||
Someone tried to start a second instance. That one is closed already.
|
||||
Our instance here (the first instance) maximizes it's own window and refocuses it.
|
||||
*/
|
||||
app.on('second-instance', () => {
|
||||
if (appWindow) {
|
||||
if (appWindow.isMinimized()) appWindow.restore()
|
||||
appWindow.focus()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the main app window
|
||||
*/
|
||||
|
@ -12,6 +39,7 @@ export const mainWindowCreation = () => {
|
|||
let appWindow: BrowserWindow | undefined = new BrowserWindow({
|
||||
useContentSize: true,
|
||||
frame: false,
|
||||
show: false,
|
||||
icon: path.resolve(__dirname, '../icons/icon.png'),
|
||||
webPreferences: {
|
||||
sandbox: false,
|
||||
|
@ -23,9 +51,15 @@ export const mainWindowCreation = () => {
|
|||
// Enable actual webContents inside the created window
|
||||
enable(appWindow.webContents)
|
||||
|
||||
// Set the current window as empty and maximize it
|
||||
appWindow.once('ready-to-show', () => {
|
||||
if (appWindow) {
|
||||
appWindow.maximize()
|
||||
appWindow.focus()
|
||||
}
|
||||
})
|
||||
|
||||
// Set the current window's menu as empty
|
||||
appWindow.setMenu(null)
|
||||
appWindow.maximize()
|
||||
|
||||
// Load the basic app URL
|
||||
appWindow.loadURL(process.env.APP_URL)
|
||||
|
@ -39,4 +73,7 @@ export const mainWindowCreation = () => {
|
|||
appWindow.on('closed', () => {
|
||||
appWindow = undefined
|
||||
})
|
||||
|
||||
// Check if we are on the primary or secondary instance of the app
|
||||
preventSecondaryAppInstance(appWindow)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue