Update to include initial alpha code

This commit is contained in:
William Moore 2023-06-06 06:57:40 -05:00
parent ac4d614c82
commit a7ebf0794d
16 changed files with 2442 additions and 0 deletions

137
.gitignore vendored Normal file
View File

@ -0,0 +1,137 @@
# ---> Node
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
certs/
build/
public/js/
node-modules/
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

View File

@ -0,0 +1,3 @@
# Lavender
Lavendar is a full-featured widget dashboard that is configurable. Right now, it does not have the capability to share across different browsers and devices the configuration. This is planned! Until then, happily plug in your widgets into Lavender for a wonderful experience.

BIN
images/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
images/logo192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
images/logo512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 KiB

7
js/serviceworker.js Normal file
View File

@ -0,0 +1,7 @@
// This code executes in its own worker or thread
self.addEventListener("install", event => {
});
self.addEventListener("fetch", (e) => {
console.log(`[Service Worker] Fetched resource ${e.request.url}`);
});

1949
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

28
package.json Normal file
View File

@ -0,0 +1,28 @@
{
"name": "lavender",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "npx tsc && npx rollup -c",
"clean": "rm -rf build",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"lit": "^2.7.5",
"typescript": "^5.1.3"
},
"devDependencies": {
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-node-resolve": "^15.1.0",
"@rollup/plugin-terser": "^0.4.3",
"@web/rollup-plugin-copy": "^0.4.0",
"@web/rollup-plugin-html": "^2.0.0",
"@web/rollup-plugin-polyfills-loader": "^2.0.0",
"rollup": "^2.79.1",
"rollup-plugin-minify-html-literals": "^1.2.6",
"rollup-plugin-summary": "^2.0.0"
}
}

17
public/css/app.css Normal file
View File

@ -0,0 +1,17 @@
body {
background-color: #967BB6;
}
.edit-link {
position: absolute;
bottom: .5em;
color: black;
}
.edit-link:visited {
color: black;
}
.edit-link:hover {
color: white;
}

12
public/edit.html Normal file
View File

@ -0,0 +1,12 @@
<html>
<head>
<link rel="stylesheet" href="./css/app.css">
<script type="module" src="./js/edit.js"></script>
</head>
<body>
<lavender-configure></lavender-configure>
</body>
</html>

19
public/index.html Normal file
View File

@ -0,0 +1,19 @@
<html>
<head>
<link rel="stylesheet" href="./css/app.css">
<link rel="manifest" href="./manifest.json" />
<script type="module" src="./js/index.js"></script>
</head>
<body>
<lavender-widgets></lavender-widgets>
<a href="./edit.html" class="edit-link" target="_blank">Edit Widgets</a>
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register("./js/serviceworker.js", {scope: '.'});
}
</script>
</body>
</html>

25
public/manifest.json Normal file
View File

@ -0,0 +1,25 @@
{
"short_name": "Lavender",
"name": "Lavender Dashboard",
"icons": [
{
"src": "../images/favicon.png",
"sizes": "32x32",
"type": "image/png"
},
{
"src": "../images/logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "../images/logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

30
rollup.config.mjs Normal file
View File

@ -0,0 +1,30 @@
// Import rollup plugins
import { rollupPluginHTML as html } from "@web/rollup-plugin-html";
import {copy} from '@web/rollup-plugin-copy';
import resolve from '@rollup/plugin-node-resolve';
import * as terser from '@rollup/plugin-terser';
import * as minifyHTML from 'rollup-plugin-minify-html-literals';
import summary from 'rollup-plugin-summary';
export default {
plugins: [
// Entry point for application build; can specify a glob to build multiple
// HTML files for non-SPA app
html({
input: 'public/**.html',
}),
// Resolve bare module specifiers to relative paths
resolve(),
// Print bundle summary
summary(),
// Optional: copy any static assets to build directory
copy({
patterns: ['images/**/*', 'manifest.json', 'js/**/*'],
}),
],
output: {
dir: 'build',
},
experimentalCodeSplitting: true,
preserveEntrySignatures: 'strict',
};

107
src/edit.ts Normal file
View File

@ -0,0 +1,107 @@
import { LitElement, css, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('lavender-configure')
export class LavenderConfigure extends LitElement {
static override styles = [
css`
.centerit {
text-align: center;
}
@media (max-width: 601px) {
.widgets {
display: display !important;
}
.widgets >* {
margin: .6em !important;
}
}
@media (max-width: 501px) and (display-mode: standalone) {
.widgets {
display: block !important;
}
}
.widgets {
width: 100%;
display: flex;
flex-direction: column;
}
.widgets >* {
margin: .2em;
padding: .5em;
width: 100%;
}
input {
width: 50%;
padding: .5em;
border-radius: .5em;
}
.button {
padding: .5em;
padding-left: 1.2em;
padding-right: 1.2em;
border-radius: .5em;
}
`
];
save() {
const elems = this.shadowRoot?.children ?? null;
const widgets = elems ? elems?.item(1)?.children : null;
const widgetsLen = widgets ? widgets?.length : 0
const lavenderWidgets = [];
for (let widgetI = 0; widgetI < widgetsLen; widgetI++) {
const elem = widgets?.item(widgetI);
const titleEditElem = elem?.children.item(0)?.children.item(1) as HTMLInputElement;
const urlEditElem = elem?.children.item(1)?.children.item(1) as HTMLInputElement;
const title = titleEditElem.value;
const url = urlEditElem.value;
if (title && title.trim() !== '' && url && url.trim() !== '') {
lavenderWidgets.push({
title,
url,
});
}
}
localStorage.setItem('lavender-widgets', JSON.stringify(lavenderWidgets));
window.location.reload();
}
override render() {
const widgetJSON = localStorage.getItem('lavender-widgets') ?? '[]';
const widgets = JSON.parse(widgetJSON);
return html`
<h1 class="centerit">Lavender Widget Editor</h1>
<div class="widgets">
${widgets.map((widget: any) => {
return html`
<div name="widget-edit">
<div><span>Title</span><input type="text" name="titleEdit" value="${widget.title}"></div>
<div><span>Href</span><input type="text" name="urlEdit" value="${widget.url}"></div>
</div>
`;
})}
<div name="widget-edit">
<div><span>Title </span><input type="text" name="titleEdit"></div >
<div><span>Href </span><input type="text" name="urlEdit"></div >
</div>
</div>
<button class="button" @click="${() => this.save()}">Save</button>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'lavender-configure': LavenderConfigure;
}
}

74
src/index.ts Normal file
View File

@ -0,0 +1,74 @@
import { LitElement, css, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('lavender-widgets')
export class LavenderWidgets extends LitElement {
static override styles = [
css`
.centerit {
text-align: center;
}
@media (max-width: 601px) {
.widgets {
display: display !important;
}
.widgets >* {
margin: .6em !important;
}
}
@media (max-width: 501px) and (display-mode: standalone) {
.widgets {
display: block !important;
}
}
.header {
background-color: #146b37;
color: white;
text-align: center;
border: .01em solid black;
padding: .5em;
}
.widgets {
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: space-between;
align-content: space-between;
}
.widget-col {
flex: 1;
}
.widgets >* {
align-self: center;
flex: 1 1 160px;
margin: .2em;
}
`
];
override render() {
const widgetJSON = localStorage.getItem('lavender-widgets') ?? '[]';
const widgets = JSON.parse(widgetJSON);
return html`
<h1 class="centerit">Lavender</h1>
<div class="widgets">
${widgets.map((widget: any) => {
return html`<iframe width="100%" framespacing="0" frameborder="no" src="${widget.url}" title="${widget.title}">${widget.title}</iframe>`;
})}
</div>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'lavender-widgets': LavenderWidgets;
}
}

34
tsconfig.json Normal file
View File

@ -0,0 +1,34 @@
{
"compilerOptions": {
"target": "ES2019",
"module": "ES2020",
"lib": ["ES2019", "DOM", "DOM.Iterable"],
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"inlineSources": true,
"outDir": "./public/js",
"rootDir": "./src",
"strict": true,
"isolatedModules": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitThis": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"noImplicitOverride": true,
"useDefineForClassFields": false,
"plugins": [
{
"name": "ts-lit-plugin",
"strict": true
}
]
},
"compileOnSave": true
}