Add the Theme setting and other functions for it

This commit is contained in:
KorbsStudio 2023-02-17 00:10:52 -05:00
parent 8a7703ddd5
commit be542c747c
No known key found for this signature in database
11 changed files with 269 additions and 19 deletions

View file

@ -31,5 +31,4 @@ import '../styles/splash.scss'
))} ))}
</div> </div>
</div> </div>
</div> </div>

View file

@ -5,6 +5,8 @@ A template replacement for FalixNodes Desktop.
___ ___
<button data-color-mode-switch>Toggle COLOR MODE 💡</button>
## What was FalixNodes Desktop? ## What was FalixNodes Desktop?
FalixNodes Desktop was developed by Korbs Studio, a FalixNodes Limited contractor. It was intended for its desktop customers to use FalixNodes more quickly and conveniently by allowing them to easily access both the client and game panels presented by FalixNodes. The capabilities of how the software works have progressed over time, and improved performance and security practices have been put in place to make the customer experience more efficient and trustworthy. FalixNodes Desktop was developed by Korbs Studio, a FalixNodes Limited contractor. It was intended for its desktop customers to use FalixNodes more quickly and conveniently by allowing them to easily access both the client and game panels presented by FalixNodes. The capabilities of how the software works have progressed over time, and improved performance and security practices have been put in place to make the customer experience more efficient and trustworthy.

View file

@ -0,0 +1,15 @@
---
import SettingCard from '../../components/settings/card.astro'
import Theme from '../../components/settings/appearance/theme.astro'
import '../../styles/settings.scss'
---
<div class="tab-header">
<h1>Settings</h1>
</div>
<SettingCard Title="Appearance">
<Theme />
</SettingCard>

View file

@ -0,0 +1,11 @@
<div class="option">
<div class="option-meta">
<h2>Theme</h2>
<p>Select how you would like the interface to look. You can either select a theme or choose the auto option to sync with your operating system's theme. </p>
</div>
<div class="theme">
<button id="auto" class="theme" onclick="Theme('Auto')"><p>Auto</p></button>
<button id="light" class="theme" onclick="Theme('Light')"><p>Light</p></button>
<button id="dark" class="theme" onclick="Theme('Dark')"><p>Dark</p></button>
</div>
</div>

View file

@ -0,0 +1,13 @@
---
const {Title, Description} = Astro.props
---
<div class="setting">
<div class="setting-header">
<h1>{Title}</h1>
<p>{Description}</p>
</div>
<div class="setting-content">
<slot />
</div>
</div>

View file

@ -1,6 +1,8 @@
--- ---
import Splash from '../components/Splash.astro' import Splash from '../components/Splash.astro'
import Sidebar from '../components/Sidebar.astro' import Sidebar from '../components/Sidebar.astro'
// Tabs
import Dashboard from '../components/pages/Dashboard.md' import Dashboard from '../components/pages/Dashboard.md'
import Tab2 from '../components/pages/Tab2.astro' import Tab2 from '../components/pages/Tab2.astro'
import Tab3 from '../components/pages/Tab3.astro' import Tab3 from '../components/pages/Tab3.astro'
@ -8,11 +10,12 @@ import Tab3A from '../components/pages/Tab3A.astro'
import Tab4 from '../components/pages/Tab4.astro' import Tab4 from '../components/pages/Tab4.astro'
import Settings from '../components/pages/Settings.astro' import Settings from '../components/pages/Settings.astro'
// Stylesheets
import '../styles/index.scss' import '../styles/index.scss'
import '../styles/notification.scss' import '../styles/notification.scss'
--- ---
<script src="./scripts/navigation.js" crossoarigin="anonymous"></script>
<script src="./navigation.js" crossoarigin="anonymous"></script> <script src="./scripts/theme.js" crossoarigin="anonymous"></script>
<script defer src="./font-awesome-6.3.0/js/all.js"></script> <script defer src="./font-awesome-6.3.0/js/all.js"></script>
<div class="content"> <div class="content">

View file

@ -7,13 +7,67 @@
--TabActiveText: black; --TabActiveText: black;
} }
///////////////////////////////////////////
// Theme: Auto | Light | Dark ///
///////////////////////////////////////////
// The "Auto" theme does appear to work
// on Linux, tested on GNOME 43 and KDE 2.27.
// The "Auto" option is disabled for Linux.
html.theme-auto { // Auto
@media (prefers-color-scheme: light) {
--SidebarBackground: rgb(239 240 241 / 75%);
--ContentBackground: #EFF0F1;
--TextColor: black;
--CardBackground: white;
--WebviewControlsColor: white;
--WebViewControlBackground: #EFF0F1;
}
@media (prefers-color-scheme: dark) {
--SidebarBackground: rgba(35, 35, 35, 0.75);
--ContentBackground: #232323;
--TextColor: white;
--CardBackground: #282828;
--WebviewControlsColor: white;
--WebViewControlBackground: #232323;
}
}
html.theme-light { // Light
--SidebarBackground: rgb(239 240 241 / 75%);
--ContentBackground: #EFF0F1;
--TextColor: black;
--CardBackground: white;
--WebviewControlsColor: white;
--WebViewControlBackground: #EFF0F1;
}
html.theme-dark { // Dark
--SidebarBackground: rgba(35, 35, 35, 0.75);
--ContentBackground: #232323;
--TextColor: white;
--CardBackground: #282828;
--WebviewControlsColor: white;
--WebViewControlBackground: #232323;
}
/////////////////////////////////////////// ///////////////////////////////////////////
* {outline: none} * {outline: none}
body { body {
background: transparent; background: transparent;
color: white; color: var(--TextColor);
font-family: arial; font-family: arial;
} }
@ -51,7 +105,7 @@ body {
padding: 0px 20px; padding: 0px 20px;
display: grid; display: grid;
grid-template-rows: 50px auto auto; grid-template-rows: 50px auto auto;
background: rgb(35 35 35 / 75%); background: var(--SidebarBackground);
.sidebar-header { .sidebar-header {
display: flex; display: flex;
align-items: center; align-items: center;
@ -74,7 +128,7 @@ body {
} }
li { li {
cursor: pointer; cursor: pointer;
color: white; color: var(--TextColor);
display: flex; display: flex;
width: 100%; width: 100%;
border-radius: 6px; border-radius: 6px;
@ -85,7 +139,7 @@ body {
svg {margin: 0px 16px} svg {margin: 0px 16px}
} }
li:hover { li:hover {
background: rgba(51, 51, 51, 0.5); background: rgb(255 255 255 / 10%);
} }
li.active { li.active {
background: var(--TabActiveBackground); background: var(--TabActiveBackground);
@ -101,11 +155,11 @@ body {
width: calc(100% - 280px); width: calc(100% - 280px);
max-width: calc(100% - 280px); max-width: calc(100% - 280px);
height: 100%; height: 100%;
background: #232323; background: var(--ContentBackground);
.page { .page {
display: none; display: none;
&.active {display: block} &.active {display: block}
background: #232323; background: var(--ContentBackground);
} }
} }
@ -114,12 +168,12 @@ body {
// Webview Navigation // Webview Navigation
/// Top Bar /// Top Bar
.webview-navigation#TopBar { .webview-navigation#TopBar {
background: black; background: var(--ContentBackground);
padding: 6px; padding: 6px;
cursor: default; cursor: default;
button { button {
color: white; fill: var(--WebviewControlsColor);
background: #202020; background: var(--WebViewControlBackground);
border: none; border: none;
aspect-ratio: 1; aspect-ratio: 1;
width: 32px; width: 32px;
@ -145,8 +199,8 @@ body {
aspect-ratio: 1; aspect-ratio: 1;
height: 32px; height: 32px;
width: 32px; width: 32px;
color: white; fill: var(--WebviewControlsColor);
background: #232323; background: var(--WebViewControlBackground);
border: none; border: none;
border-radius: 6px; border-radius: 6px;
margin-left: 6px; margin-left: 6px;
@ -156,6 +210,6 @@ body {
} }
} }
button:hover { button:hover {
background: #4b4b4b; background: var(--WebViewControlBackground);
} }
} }

View file

@ -0,0 +1,98 @@
// Settings
/// Global
.tab-header {
padding: 32px;
}
.setting {
background: var(--CardBackground);
border: 1px rgb(255 255 255 / 10%) solid;
border-radius: 6px;
padding: 12px 6px 12px 12px;
margin: 0px 32px 24px 32px;
h1, h2, p {
margin: 0px;
cursor: default;
}
h2 {
font-size: 18px;
}
.setting-header {
border-bottom: 1px rgba(255, 255, 255, 0.1) solid;
background: rgba(0, 0, 0, 0.25);
margin: -12px -6px 12px -12px;
padding: 14px 32px 6px 32px;
border-radius: 6px 6px 0px 0px;
h1 {
font-size: 24px;
margin-bottom: 6px;
}
p {
font-size: 14px;
margin-bottom: 12px;
}
}
.setting-content {
.option {
display: grid;
grid-template-columns: 360px auto;
grid-gap: 32px;
border-bottom: 1px rgb(255 255 255 / 10%) solid;
padding: 32px;
.option-meta {
h2 {
font-size: 16px;
margin-bottom: 12px;
margin-top: 6px;
}
p {
font-size: 14px;
color: rgb(145 145 145);
}
}
}
}
}
// Appearance
/// Theme
[os="Linux"] .theme #auto {display: none !important}
.theme {
button {
background: #181818;
border: 1px rgb(255 255 255 / 10%) solid;
color: white;
border-radius: 10px;
aspect-ratio: 1;
width: 84px;
cursor: pointer;
margin-right: 6px;
transition: 0.3s border;
p {
margin: 96px 0px -32px 0px;
color: gray;
transition: 0.3s color;
}
}
button:hover {
border: 1px white solid;
transition: 0.3s border;
p {
color: white;
transition: 0.3s color;
}
}
.theme-active::before {
content: "";
background: var(--TabActiveBackground);
width: 20px;
position: absolute;
margin: 50px 0px 0px 10px;
border-radius: 50px;
aspect-ratio: 1;
}
}
button#auto {background-image: url(/public/images/settings/theme/Auto.png)}
button#light {background-image: url(/public/images/settings/theme/Light.png)}
button#dark {background-image: url(/public/images/settings/theme/Dark.png)}

View file

@ -22,8 +22,8 @@ log.transports.console.format = '\x1b[34m[electron]:\x1b[37m'
console.log = log.log console.log = log.log
// Use the correct icon depending on the operating system // Use the correct icon depending on the operating system
if /* If macOS */ (process.platform == 'darwin') {global.AppIcon = 'public/images/icons/app/macOS.icns' } if /* If macOS */ (process.platform === 'darwin') {global.AppIcon = 'public/images/icons/app/macOS.icns' }
else if /* If Windows */ (process.platform == 'win32') {global.AppIcon = 'public/images/icons/app/Windows.png' } else if /* If Windows */ (process.platform === 'win32') {global.AppIcon = 'public/images/icons/app/Windows.png' }
else /* If Linux */ {global.AppIcon = 'public/images/icons/app/Linux.png' } else /* If Linux */ {global.AppIcon = 'public/images/icons/app/Linux.png' }
function createWindow () { function createWindow () {
@ -54,12 +54,18 @@ function createWindow () {
// Doc: https://www.electronjs.org/docs/latest/api/browser-window#showing-the-window-gracefully // Doc: https://www.electronjs.org/docs/latest/api/browser-window#showing-the-window-gracefully
mainWindow.once('ready-to-show', () => {mainWindow.show()}) mainWindow.once('ready-to-show', () => {mainWindow.show()})
// Set Platform Class
if /* If macOS */ (process.platform === 'darwin') { mainWindow.webContents.executeJavaScript(`document.querySelector('html').setAttribute('os', 'Mac')`) }
else if /* If Windows */ (process.platform === 'win32') { mainWindow.webContents.executeJavaScript(`document.querySelector('html').setAttribute('os', 'Windows')`) }
else /* If Linux */ { mainWindow.webContents.executeJavaScript(`document.querySelector('html').setAttribute('os', 'Linux')`) }
// Pushy - Pushy Notification System (PNS) // Pushy - Pushy Notification System (PNS)
mainWindow.webContents.on('did-finish-load', () => {Pushy.listen()}) mainWindow.webContents.on('did-finish-load', () => {Pushy.listen()})
Pushy.register({ appId: process.env.PushyAppId }).then((deviceToken) => {}).catch((error) => {console.log('Pushy registration error: ' + error.message)}) Pushy.register({ appId: process.env.PushyAppId }).then((deviceToken) => {}).catch((error) => {console.log('Pushy registration error: ' + error.message)})
setTimeout(() => { setTimeout(() => {
Pushy.setNotificationListener((data) => { Pushy.setNotificationListener((data) => {
new Notification({ title: data.title, body: data.message }).show()
if(process.env.NotificationType === 'Native') { if(process.env.NotificationType === 'Native') {
new Notification({ title: data.title, body: data.message }).show() new Notification({ title: data.title, body: data.message }).show()
} }
@ -69,7 +75,7 @@ function createWindow () {
`) `)
} }
}) })
}, 10000) // If this is triggered too soon, the notifications won't work. }, 5000) // If this is triggered too soon, the notifications won't work.
if (Pushy.isRegistered()) {Pushy.subscribe('AppName').then(() => {}).catch((error) => {console.error(error)})} if (Pushy.isRegistered()) {Pushy.subscribe('AppName').then(() => {}).catch((error) => {console.error(error)})}

0
public/navigation.js → public/scripts/navigation.js Executable file → Normal file
View file

49
public/scripts/theme.js Normal file
View file

@ -0,0 +1,49 @@
let AppTheme = localStorage.getItem('AppTheme')
if (AppTheme == null) {Theme('Dark')} else {Theme(AppTheme)}
function Theme(theme) {
if (theme === 'Auto') {
document.querySelector('html').setAttribute('class', 'theme-auto')
setTimeout(() => {ThemeIsAuto()}, 200)
} else if (theme === 'Light') {
document.querySelector('html').setAttribute('class', 'theme-light')
setTimeout(() => {ThemeIsLight()}, 200)
} else if (theme === 'Dark') {
document.querySelector('html').setAttribute('class', 'theme-dark')
setTimeout(() => {ThemeIsDark()}, 200)
}
localStorage.setItem('AppTheme', theme)
}
function ThemeIsReset() {
document.querySelector(".theme #auto").setAttribute('class', 'theme')
document.querySelector(".theme #auto").style.border = '1px rgba(255, 255, 255, 0.1) solid'
document.querySelector(".theme #auto > p").style.color = 'gray'
document.querySelector(".theme #light").setAttribute('class', 'theme')
document.querySelector(".theme #light").style.border = '1px rgba(255, 255, 255, 0.1) solid'
document.querySelector(".theme #light > p").style.color = 'gray'
document.querySelector(".theme #dark").setAttribute('class', 'theme')
document.querySelector(".theme #dark").style.border = '1px rgba(255, 255, 255, 0.1) solid'
document.querySelector(".theme #dark > p").style.color = 'gray'
}
function ThemeIsAuto() {
ThemeIsReset()
document.querySelector(".theme #auto").setAttribute('class', 'theme theme-active')
document.querySelector(".theme #auto").style.border = '1px var(--TabActiveBackground) solid'
document.querySelector(".theme #auto > p").style.color = 'var(--TabActiveBackground)'
}
function ThemeIsLight() {
ThemeIsReset()
document.querySelector(".theme #light").setAttribute('class', 'theme theme-active')
document.querySelector(".theme #light").style.border = '1px var(--TabActiveBackground) solid'
document.querySelector(".theme #light > p").style.color = 'var(--TabActiveBackground)'
}
function ThemeIsDark() {
ThemeIsReset()
document.querySelector(".theme #dark").setAttribute('class', 'theme theme-active')
document.querySelector(".theme #dark").style.border = '1px var(--TabActiveBackground) solid'
document.querySelector(".theme #dark > p").style.color = 'var(--TabActiveBackground)'
}