Latest updates

This commit is contained in:
CheddarCrisp 2020-02-06 12:27:58 -05:00
parent aace75679a
commit b2208a7e58
15 changed files with 1267 additions and 131 deletions

View file

@ -1,3 +1,8 @@
import App from './ncounter/App.svelte';
import runtime from 'serviceworker-webpack-plugin/lib/runtime';
if ('serviceWorker' in navigator) {
const registration = runtime.register();
}
new App({ target: document.body });

View file

@ -1,6 +1,6 @@
<div class="app">
{#each counters as counter}
<Counter counter={ counter } on:save={() => { save(counter); } }></Counter>
{#each $counters as counter}
<Counter counterId={ counter.id }></Counter>
{/each}
</div>
<button class="add" on:click="{ showAdd }"><i class="material-icons">add</i></button>
@ -12,38 +12,19 @@
<label>Target: <input type="number" bind:value={newCounter.max} /></label>
<label>Click counter: <input type="checkbox" bind:value={newCounter.isClickCounter} /></label>
<button on:click={ () => { showAddDialog = false; } }>Cancel</button>
<button class="ok" on:click={ addCounter }>OK</button>
<button class="ok" on:click={ add }>OK</button>
</div>
</div>
{/if}
<script>
import Counter from './Counter.svelte';
import { counters } from './db.js';
import './site.css';
let showAddDialog = false;
let newCounter = null;
let counters = [
{
title: 'Test 1',
value: 0
},
{
title: 'Test 2',
value: 10
},
{
title: 'Max Test',
value: 0,
max: 100
},
{
title: 'Click Test',
value: 0,
isClickCounter: true
}
];
function focus(node){
node.focus();
}
@ -56,7 +37,8 @@ function showAdd(){
newCounter = {
title: '',
value: 0,
isClickCounter: false
isClickCounter: false,
history: []
}
console.log({ newCounter });
@ -64,8 +46,8 @@ function showAdd(){
showAddDialog = true;
}
function addCounter(){
counters = [...counters, newCounter];
function add(){
counters.add(newCounter);
showAddDialog = false;
}

View file

@ -8,8 +8,10 @@
{#if !counter.isClickCounter}
<button on:click={ () => { showIncrement = true; } }><i class="material-icons">add</i></button>
{/if}
<span class="message">{ message }</span>
<button class="reset" on:click={ reset }><i class="material-icons">undo</i></button>
<button on:click={ save }><i class="material-icons">save</i></button>
<button on:click={ remove }><i class="material-icons">delete</i></button>
</div>
{#if showIncrement}
<div class="dialog">
@ -25,20 +27,43 @@
import MyProgress from './MyProgress.svelte';
import { tick } from 'svelte';
import { createEventDispatcher } from 'svelte';
import { counters } from './db.js';
const dispatch = createEventDispatcher();
export let counter;
export let counterId;
$: counter = $counters.find(x => x.id == counterId);
let incrementValue;
let showIncrement;
let message = '';
const formatter = new Intl.DateTimeFormat('en-US',
{
month: 'short',
day: 'numeric',
year: 'numeric',
hour: 'numeric',
minute: 'numeric'
});
function focus(node){
node.focus();
}
function update(newCounter){
counters.update(newCounter);
}
function increment(){
counter.value += incrementValue;
const newCounter = {
...counter,
value: counter.value + incrementValue
}
update(newCounter);
showIncrement = false;
incrementValue = null;
}
@ -46,22 +71,52 @@ function increment(){
function reset(e){
e.stopPropagation();
if(confirm(`Reset ${counter.title}?`))
counter.value = 0;
if(confirm(`Reset ${counter.title}?`)){
const newCounter = {
...counter,
value: 0
}
update(newCounter);
}
}
function save(e) {
e.stopPropagation();
dispatch('save');
counter.value = 0;
const time = new Date();
const data = {
time,
value: counter.value
}
const newCounter = {
...counter,
history: [...counter.history, data]
}
message = `Saved ${data.value} at ${formatter.format(data.time)}`;
setTimeout(() => message = '', 5000);
update(newCounter);
}
function remove(){
if(confirm(`Remove ${counter.title}?`))
counters.remove(counter);
}
function clickCount() {
if(!counter.isClickCounter)
return;
counter.value++;
const newCounter = {
...counter,
value: counter.value + 1
}
update(newCounter);
}
</script>
<style>
@ -79,8 +134,9 @@ function clickCount() {
display: flex;
}
.reset {
margin-left: auto;
.message {
flex: 1;
text-align: center;
}
header {

57
src/ncounter/db.js Normal file
View file

@ -0,0 +1,57 @@
import { set as setDb, get as getDb } from 'idb-keyval';
import { writable } from 'svelte/store';
import uuid from 'uuid/v4';
function createCounters(){
const {subscribe,set,update:updateVal} = writable([]);
getDb('counters').then(counters => {
if(counters)
set(counters);
});
function add(counter){
const newCounter = { id: uuid(), ...counter };
updateVal(counters => {
const newCounters = [...counters, newCounter];
setDb('counters', newCounters);
return newCounters;
});
}
function update(counter){
updateVal(counters => {
const counterIndex = counters.findIndex(x => x.id == counter.id);
const newCounters = [...counters.slice(0, counterIndex), counter, ...counters.slice(counterIndex + 1)];
setDb('counters', newCounters);
return newCounters;
});
}
function remove(counter){
updateVal(counters => {
const counterIndex = counters.findIndex(x => x.id == counter.id);
const newCounters = [...counters.slice(0, counterIndex), ...counters.slice(counterIndex + 1)];
setDb('counters', newCounters);
return newCounters;
})
}
return {
subscribe,
add,
update,
remove
};
}
export const counters = createCounters();

40
src/ncounter/site.css Normal file
View file

@ -0,0 +1,40 @@
body {
font-family: -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
button {
background: 0;
border: 0;
}
.dialog {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0,0,0,0.25);
z-index: 12;
pointer-events: none;
}
.dialog-content {
background-color: #E0E0E0;
pointer-events: all;
width: 250px;
border-radius: 5px;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
padding: 5px;
display: flex;
flex-wrap: wrap;
}

41
src/sw.js Normal file
View file

@ -0,0 +1,41 @@
import {registerRoute} from 'workbox-routing';
import {CacheFirst, StaleWhileRevalidate, NetworkFirst} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';
import {ExpirationPlugin} from 'workbox-expiration';
// Cache the Google Fonts stylesheets with a stale-while-revalidate strategy.
registerRoute(
/^https:\/\/fonts\.googleapis\.com/,
new StaleWhileRevalidate({
cacheName: 'google-fonts-stylesheets',
})
);
// Cache the underlying font files with a cache-first strategy for 1 year.
registerRoute(
/^https:\/\/fonts\.gstatic\.com/,
new CacheFirst({
cacheName: 'google-fonts-webfonts',
plugins: [
new CacheableResponsePlugin({
statuses: [0, 200],
}),
new ExpirationPlugin({
maxAgeSeconds: 60 * 60 * 24 * 365,
maxEntries: 30,
}),
],
})
);
registerRoute(
/\.(?:js|css)$/,
new StaleWhileRevalidate({
cacheName: 'static-resources',
})
);
registerRoute(
'/',
new NetworkFirst()
)