implemented basic theme changing support

build-validation
David Tookey 5 years ago
parent 6fb6f0b422
commit 907e13463c

@ -1,43 +1,39 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<!-- Required meta tags -->
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>ResourceFinder</title>
<!-- Bootstrap CSS -->
<!-- Custom CSS -->
<title>ResourceFinder</title>
</head>
<link rel="stylesheet" href="styles/theme.css">
<link rel="stylesheet" href="styles/ResourcesLandingPage.css"> <link rel="stylesheet" href="styles/ResourcesLandingPage.css">
<title>ResourceFinder</title> <script>let $ = require('jquery');</script>
<script>require('popper.js')</script>
<script>require('bootstrap')</script>
</head> </head>
<body> <body hidden ONLOAD="$('body').removeAttr('hidden');">
<header> <header>
<div class="collapse bg-primary" id="navbarHeader"> <div class="collapse bg-primary" id="navbarHeader">
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-sm-8 col-md-7 py-4"> <div class="col-sm-8 col-md-7 py-4">
<p class="text-success">You rely on a vast amount of resources to do your job. How can you keep track of them all? Explore ResourceFinder. From payroll to project-management, ResourceFinder can help you locate the tools you need.</p> <p class="text-success">You rely on a vast amount of resources to do your job. How can you keep
track of them all? Explore ResourceFinder. From payroll to project-management, ResourceFinder
can help you locate the tools you need.</p>
</div> </div>
<div class="col-sm-4 offset-md-1 py-4"> <div class="col-sm-4 offset-md-1 py-4">
<ul class="list-unstyled"> <ul class="list-unstyled">
<li><a href="#" class="text-success">Help</a></li> <li><a href="#" class="text-success">Help</a></li>
<li><a href="#" class="text-success">Feedback</a></li> <li><a href="#" class="text-success">Feedback</a></li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="navbar navbar-dark bg-secondary shadow-sm"> <div class="navbar navbar-dark bg-secondary shadow-sm">
<div class="container d-flex justify-content-between"> <div class="container d-flex justify-content-between">
<a href="#" class="navbar-brand d-flex align-items-left"> <a href="#" class="navbar-brand d-flex align-items-left">
<strong>ResourceFinder</strong> <strong>ResourceFinder</strong>
</a> </a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarHeader" <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarHeader"
@ -48,134 +44,145 @@
</div> </div>
</header> </header>
<main role="main bg-primary"> <main>
<div class="album py-5 bg-primary"> <div class="album py-5 bg-primary">
<button id="theme-toggle" class="btn btn-light mb-2">Push to change theme</button>
<div class="container"> <div class="container">
<input class="form-control form-control-dark w-100 bg-warning border-0" placeholder="Search" aria-label="Search"> <input class="form-control form-control-dark w-100 bg-warning border-0" placeholder="Search"
</div> aria-label="Search">
</div>
<div class="album py-5"> <div class="album py-5">
<div class="container bg-primary"> <div class="container bg-primary">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
<div class="card mb-4 shadow-sm bg-secondary"> <div class="card mb-4 shadow-sm bg-secondary">
<div class="card-body"> <div class="card-body">
<h7 class="card-text text-white" style="text-align:center">Paycor</h7> <h7 class="card-text text-white" style="text-align:center">Paycor</h7>
<p class="card-text text-success">Clock in and out, request time off, review health benefits and access paystubs using the Paycor human-resources application. <p class="card-text text-success">Clock in and out, request time off, review health
</p> benefits and access paystubs using the Paycor human-resources application.
</p>
<div class="d-flex justify-content-between align-items-center"> <div class="d-flex justify-content-between align-items-center">
<img class="rounded-circle mx-auto d-block img-fluid" src="../images/PaycorLogo2-Circle_100x100.png" alt="Paycor logo" style="max-height:50px"> <img class="rounded-circle mx-auto d-block img-fluid"
</div> src="../images/PaycorLogo2-Circle_100x100.png" alt="Paycor logo"
style="max-height:50px">
<hr width="95%" align="center" color="#A79D9D"> </div>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group"> <hr width="95%" align="center" color="#A79D9D">
<button type="button" class="btn btn-outline-light">Go</button> <div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<button type="button" class="btn btn-outline-light">Go</button>
</div>
</div> </div>
</div>
</div>
</div> </div>
</div> </div>
</div>
<div class="col-md-4">
<div class="card mb-4 shadow-sm bg-secondary"> <div class="col-md-4">
<div class="card mb-4 shadow-sm bg-secondary">
<div class="card-body"> <div class="card-body">
<h7 class="card-text text-white" style="text-align:center">Gmail</h7> <h7 class="card-text text-white" style="text-align:center">Gmail</h7>
<p class="card-text text-success">Access your company e-mail and a suite of Google apps, including a calendar, instant messaging and cloud storage. <p class="card-text text-success">Access your company e-mail and a suite of Google apps,
</p> including a calendar, instant messaging and cloud storage.
</p>
<div class="d-flex justify-content-between align-items-center"> <div class="d-flex justify-content-between align-items-center">
<img class="rounded-circle mx-auto d-block img-fluid" src="../images/GmailCircle_100x100.png" alt="Gmail logo" style="max-height:50px"> <img class="rounded-circle mx-auto d-block img-fluid"
</div> src="../images/GmailCircle_100x100.png" alt="Gmail logo"
style="max-height:50px">
<hr width="95%" align="center" color="#A79D9D">
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<button type="button" class="btn btn-outline-light">Go</button>
</div> </div>
</div>
<hr width="95%" align="center" color="#A79D9D">
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<button type="button" class="btn btn-outline-light">Go</button>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div>
<div class="col-md-4">
<div class="card mb-4 shadow-sm bg-secondary"> <div class="col-md-4">
<div class="card mb-4 shadow-sm bg-secondary">
<div class="card-body"> <div class="card-body">
<h7 class="card-text text-white" style="text-align:center">Workplace</h7> <h7 class="card-text text-white" style="text-align:center">Workplace</h7>
<p class="card-text text-success">Get the latest news and connect with colleagues. JDSfaulkner uses Workplace by Facebook for posting and sharing. <p class="card-text text-success">Get the latest news and connect with colleagues.
</p> JDSfaulkner uses Workplace by Facebook for posting and sharing.
<div class="d-flex justify-content-between align-items-center"> </p>
<img class="rounded-circle mx-auto d-block img-fluid" src="../images/WorkplaceLogo-Circle_100x100.png" alt="Workplace logo" style="max-height:50px"> <div class="d-flex justify-content-between align-items-center">
</div> <img class="rounded-circle mx-auto d-block img-fluid"
<hr width="95%" align="center" color="#A79D9D"> src="../images/WorkplaceLogo-Circle_100x100.png" alt="Workplace logo"
<div class="d-flex justify-content-between align-items-center"> style="max-height:50px">
<div class="btn-group"> </div>
<button type="button" class="btn btn-outline-light">Go</button> <hr width="95%" align="center" color="#A79D9D">
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<button type="button" class="btn btn-outline-light">Go</button>
</div>
</div> </div>
</div>
</div>
</div> </div>
</div> </div>
</div>
<div class="col-md-4">
<div class="col-md-4"> <div class="card mb-4 shadow-sm bg-secondary">
<div class="card mb-4 shadow-sm bg-secondary"> <div class="card-body">
<div class="card-body"> <h7 class="card-text text-white" style="text-align:center">Design 2</h7>
<h7 class="card-text text-white" style="text-align:center">Design 2</h7> <p class="card-text text-success">Would you like to see an alternative design? Try
<p class="card-text text-success">Would you like to see an alternative design? Try Design 2.</p> Design 2.</p>
<div class="d-flex justify-content-between align-items-center"> <div class="d-flex justify-content-between align-items-center">
</div> </div>
<div class="btn-group"> <div class="btn-group">
<a class="btn btn-outline-light" href="Design2.html" role="button">Go</a> <a class="btn btn-outline-light" href="Design2.html" role="button">Go</a>
</div> </div>
</div>
</div> </div>
</div> </div>
</div>
<div class="col-md-4">
<div class="card mb-4 shadow-sm bg-secondary"> <div class="col-md-4">
<div class="card-body"> <div class="card mb-4 shadow-sm bg-secondary">
<h7 class="card-text text-white" style="text-align:center">Design 3</h7> <div class="card-body">
<p class="card-text text-success">Here is another alternative. Check out Design 3.</p> <h7 class="card-text text-white" style="text-align:center">Design 3</h7>
<p class="card-text text-success">Here is another alternative. Check out Design 3.</p>
<div class="d-flex justify-content-between align-items-center"> <div class="d-flex justify-content-between align-items-center">
</div> </div>
<div class="btn-group"> <div class="btn-group">
<a class="btn btn-outline-light" href="Design3.html" role="button">Go</a> <a class="btn btn-outline-light" href="Design3.html" role="button">Go</a>
</div> </div>
</div>
</div> </div>
</div> </div>
</div>
<main role="main" class="container"> <main role="main" class="container">
</main><!-- /.container --> </main><!-- /.container -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="/docs/4.5/assets/js/vendor/jquery.slim.min.js"><\/script>')</script><script src="/docs/4.5/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script></body>
<footer class="page-footer"> <footer class="page-footer">
<div class="container"> <div class="container">
<p class="float-right text-white"> <p class="float-right text-white">
<a href="#">Back to top</a> <a href="#">Back to top</a>
</p> </p>
</div>
</footer>
</div>
</div>
</div>
</div> </div>
</footer> </main>
</body> </body>
<script>let $ = require('jquery');</script> <script src="scripts/tsUtil.js"></script>
<script>require('popper.js')</script> <script>loadTSTarget("themes.js");</script>
<script>require('bootstrap')</script>
</html> </html>

@ -1,3 +1,3 @@
function loadTSTarget(name) { function loadTSTarget(name) {
require(`../../util/${name}`); return require(`../../util/${name}`);
} }

@ -1,3 +1,5 @@
.main { .main {
background-color: primary; background-color: primary;
} }
@ -35,4 +37,4 @@
.footer p { .footer p {
margin-bottom: .25rem; margin-bottom: .25rem;
} }

@ -0,0 +1,6 @@
$enable-rounded: true !default;
@import "node_modules/bootstrap/scss/bootstrap";
@import "node_modules/bootstrap/scss/functions";
@import "node_modules/bootstrap/scss/variables";
@import "node_modules/bootstrap/scss/mixins";

@ -0,0 +1,8 @@
$theme-colors: (
"primary": #0B031C,
"secondary": #211F37,
"success": #A79D9D,
"info": #1C1CDE,
"warning": #303033
);
@import "theme-base";

@ -0,0 +1,11 @@
$theme-colors: (
"primary": #ffffff,
"secondary": #bbbbbb,
"success": #0B031C,
"info": #1C1CDE,
"warning": #700000
);
//$font-color: #000;
@import "theme-base";

@ -1,14 +0,0 @@
$theme-colors: (
"primary": #0B031C,
"secondary": #211F37,
"success": #A79D9D,
"info": #1C1CDE,
"warning": #303033
);
$enable-rounded: true !default;
@import "node_modules/bootstrap/scss/bootstrap";
@import "node_modules/bootstrap/scss/functions";
@import "node_modules/bootstrap/scss/variables";
@import "node_modules/bootstrap/scss/mixins";

@ -1,38 +1,42 @@
let path = require('path') let path = require('path')
let fs = require('fs'); let fs = require('fs');
const shell = require('electron').shell; const shell = require('electron').shell;
let fileExtensionToImage: object; let fileExtensionToImage: object;
import {Themes} from "./themes";
export enum ConfigPaths {
ApplicationConfigName = "dashboard.json",
UserConfigName = "user.json",
FileExtensionsName = "file-extensions.json"
}
export class Configurator { export module Configurator {
getFileExtensionToImageMap(): Object { export function getFileExtensionToImageMap(): Object {
if (!fileExtensionToImage) { if (!fileExtensionToImage) {
fileExtensionToImage = this.loadAppConfig("file-extensions.json"); fileExtensionToImage = this.loadAppConfig(ConfigPaths.FileExtensionsName);
} }
return fileExtensionToImage; return fileExtensionToImage;
}; }
loadAppConfig(fileName: string): object { export function loadAppConfig(fileName: string): object {
let filePath = FileUtils.getPathToConfig(fileName); let filePath = FileUtils.getPathToConfig(fileName);
let fileBuffer = fs.readFileSync(filePath); let fileBuffer = fs.readFileSync(filePath);
let content = fileBuffer.toString('utf8') let content = fileBuffer.toString('utf8')
return JSON.parse(content) return JSON.parse(content)
} }
loadUserConfig(fileName: string): object { export function loadUserConfig(fileName: string): object {
let userConfigPath = FileUtils.getPathToUserDir(fileName); let userConfigPath = FileUtils.getPathToUserDir(fileName);
if (!fs.existsSync(userConfigPath)) { if (!fs.existsSync(userConfigPath)) {
return {}; return buildDefaultConfig();
} else { } else {
let content = fs.readFileSync(userConfigPath); let content = fs.readFileSync(userConfigPath);
return JSON.parse(content); return JSON.parse(content);
} }
} }
saveUserConfig(fileName: string, obj: any) { export function saveUserConfig(fileName: string, obj: any) {
let userConfigPath = FileUtils.getPathToUserDir(fileName); let userConfigPath = FileUtils.getPathToUserDir(fileName);
let content = JSON.stringify(obj); let content = JSON.stringify(obj);
fs.writeFile(userConfigPath, content, (err) => { fs.writeFile(userConfigPath, content, (err) => {
@ -43,23 +47,30 @@ export class Configurator {
}); });
} }
function buildDefaultConfig(): object {
let userConfig = {};
userConfig['theme'] = Themes.AppTheme.Dark;
saveUserConfig(ConfigPaths.UserConfigName, userConfig)
return userConfig
}
} }
export module FileUtils { export module FileUtils {
export function getPathToView(templateName: string): string { export function getPathToView(templateName: string): string {
return path.join(this.getPathToAssets(), "views", templateName + ".mustache") return path.join(getPathToAssets(), "views", templateName + ".mustache")
} }
export function getPathToImage(imageName: string): string { export function getPathToImage(imageName: string): string {
return path.join(this.getPathToAssets(), "images", imageName) return path.join(getPathToAssets(), "images", imageName)
} }
export function getPathToDocument(documentName: string): string { export function getPathToDocument(documentName: string): string {
return path.join(this.getPathToAssets(), "documents", documentName) return path.join(getPathToAssets(), "documents", documentName)
} }
export function getPathToConfig(documentName: string): string { export function getPathToConfig(documentName: string): string {
return path.join(this.getPathToAssets(), "conf", documentName) return path.join(getPathToAssets(), "conf", documentName)
} }
export function getPathToAssets(): string { export function getPathToAssets(): string {
@ -73,7 +84,7 @@ export module FileUtils {
export function getPathToUserDir(fileName: string): string { export function getPathToUserDir(fileName: string): string {
let dirPath = path.join(__dirname, "..", "user"); let dirPath = path.join(__dirname, "..", "user");
let filePath = path.join(dirPath, fileName); let filePath = path.join(dirPath, fileName);
this.touchDir(dirPath); touchDir(dirPath);
return filePath; return filePath;
} }

@ -0,0 +1,80 @@
const $ = require('jquery');
import {ConfigPaths, Configurator} from "./fileutils";
export module Themes {
export enum AppTheme {
Light = "theme-light",
Dark = "theme-dark"
}
export function initTheme() {
let conf = Configurator.loadUserConfig(ConfigPaths.UserConfigName);
let initTheme = conf['theme'];
applyTheme(initTheme);
let initToggle = $('#theme-toggle');
let initThemeEnum = getThemeFromValue(initTheme);
initToggle.addClass(getButtonClassFromAppTheme(initThemeEnum));
initToggle.on("click", () => {
let conf = Configurator.loadUserConfig(ConfigPaths.UserConfigName);
let toggle = $("#theme-toggle");
let themeValue = conf['theme'];
let currTheme = getThemeFromValue(themeValue);
let opposite = getOppositeTheme(currTheme);
toggle.removeClass(getButtonClassFromAppTheme(currTheme));
toggle.addClass(getButtonClassFromAppTheme(opposite));
applyTheme(opposite);
conf['theme'] = opposite;
Configurator.saveUserConfig(ConfigPaths.UserConfigName, conf);
});
}
export function applyTheme(name: string) {
let head = $('head');
let newResource = `styles/${name}.css`;
let headLinks = head.children("link")
let themePattern = /theme-.*\.css/ig;
for (let i = 0, l = headLinks.length; i < l; i++) {
let link = headLinks[i];
if (themePattern.test(link.href)) {
console.log(`Found ${link}. Removing...`);
link.remove()
}
}
head.append(buildCSSLink(newResource));
}
function getButtonClassFromAppTheme(t: AppTheme): string {
switch (t) {
case Themes.AppTheme.Dark:
return "btn-light";
case Themes.AppTheme.Light:
return "btn-dark";
}
}
function getThemeFromValue(v: string): AppTheme {
switch (v) {
case AppTheme.Light:
return AppTheme.Light;
case AppTheme.Dark:
return AppTheme.Dark;
}
}
function getOppositeTheme(t: AppTheme): AppTheme {
switch (t) {
case Themes.AppTheme.Dark:
return Themes.AppTheme.Light;
case Themes.AppTheme.Light:
return Themes.AppTheme.Dark;
}
}
function buildCSSLink(resourceName: string): HTMLElement {
let link = $("<link>", {rel: "stylesheet", href: resourceName})
return link as HTMLElement
}
}
Themes.initTheme();

@ -1,10 +1,9 @@
import {Configurator, FileUtils} from './fileutils' import {Configurator, FileUtils, ConfigPaths} from './fileutils'
import {loadTemplateSingle} from "./templates" import {loadTemplateSingle} from "./templates"
import {WebUtils} from "./webutils" import {WebUtils} from "./webutils"
const shell = require('electron').shell; const shell = require('electron').shell;
const config = new Configurator();
export class CardModel { export class CardModel {
imagePath: string; imagePath: string;
@ -17,14 +16,6 @@ export class CardModel {
} }
export function buildFileCard(filePath: string, elem: Element, append: boolean = false, $: any = require('jquery')) { export function buildFileCard(filePath: string, elem: Element, append: boolean = false, $: any = require('jquery')) {
let conf = config.loadUserConfig("user.json");
console.log(conf);
let links = conf['links'];
if (!links) {
links = [];
}
links.push("www.fark.com");
config.saveUserConfig("user.json", conf);
let model = new CardModel(getImagePathFromDocumentName(filePath), fileNameToPrettyString(filePath)); let model = new CardModel(getImagePathFromDocumentName(filePath), fileNameToPrettyString(filePath));
loadTemplateSingle("file-card.mustache", model, (content: string, id: string) => { loadTemplateSingle("file-card.mustache", model, (content: string, id: string) => {
let snip = $(content); let snip = $(content);
@ -44,7 +35,7 @@ export function buildFileCard(filePath: string, elem: Element, append: boolean =
} }
export function buildDefaultWebCards(elem: Element) { export function buildDefaultWebCards(elem: Element) {
let userPrefs = config.loadAppConfig("user.json"); let userPrefs = Configurator.loadAppConfig(ConfigPaths.ApplicationConfigName);
let links = userPrefs['default-links']; let links = userPrefs['default-links'];
let $ = require('jquery') let $ = require('jquery')
for (let i = 0, l = links.length; i < l; i++) { for (let i = 0, l = links.length; i < l; i++) {
@ -107,7 +98,7 @@ function fileNameToPrettyString(fileName: string): string {
function getImagePathFromDocumentName(name: string): string { function getImagePathFromDocumentName(name: string): string {
let ext = FileUtils.getFileExtension(name); let ext = FileUtils.getFileExtension(name);
let thumbnail = config.getFileExtensionToImageMap()[ext]; let thumbnail = Configurator.getFileExtensionToImageMap()[ext];
return FileUtils.getPathToImage(thumbnail); return FileUtils.getPathToImage(thumbnail);
} }

Loading…
Cancel
Save