First Comment. Parcel setup. Electron Set Up. First working verion (just an intro). Data interfaces.
40
.gitignore
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
.npm
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# IDEs
|
||||
|
||||
.vscode
|
||||
.idea
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# build directory
|
||||
dist/
|
||||
6
.parcelrc
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "@parcel/config-default",
|
||||
"transformers": {
|
||||
"*.riot": ["@riotjs/parcel-transformer-riot"]
|
||||
}
|
||||
}
|
||||
21
index.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||
<title>Time Chain</title>
|
||||
<link rel="stylesheet" href="src/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="loading" >
|
||||
<h1>Time Chain!</h1>
|
||||
<p>Time traveling your data! Comming soon...</p>
|
||||
<p id="timestamp"></p>
|
||||
<img src="src/img/chain2.svg" class="rotate">
|
||||
</div>
|
||||
|
||||
<script type="module" src="src/dist/start.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
18
main.js
Normal file
@ -0,0 +1,18 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
autoHideMenuBar: true,
|
||||
width: 800,
|
||||
height: 600,
|
||||
icon: __dirname + '/src/img/chains.png'
|
||||
})
|
||||
|
||||
//win.autoHideMenuBar = true;
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
13329
package-lock.json
generated
Normal file
37
package.json
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "time-chain",
|
||||
"version": "1.0.0",
|
||||
"description": "timechain",
|
||||
"author": "Jaosn Tudisco",
|
||||
"license": "UNLICENSED",
|
||||
"main": "main.js",
|
||||
"build": {
|
||||
"appId": "com.duker.timechain",
|
||||
"win": {
|
||||
"icon": "src/img/chains.png"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"start": "electron .",
|
||||
"compile": "parcel build --dist-dir ./src/dist --target \"jason\" start.js"
|
||||
},
|
||||
"browserslist": "> 0.5%, last 2 versions, not dead",
|
||||
"targets": {
|
||||
"jason": {
|
||||
"distDir": "./src/dist"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@riotjs/compiler": "^6.1.3",
|
||||
"@riotjs/parcel-transformer-riot": "^7.0.3",
|
||||
"electron": "^16.0.7",
|
||||
"parcel": "^2.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"better-sqlite3": "^7.5.0",
|
||||
"dayjs": "^1.10.7",
|
||||
"es6-interface": "^3.2.1",
|
||||
"pubsub-js": "^1.9.4",
|
||||
"riot": "^6.1.2"
|
||||
}
|
||||
}
|
||||
31
src/css/main.css
Normal file
@ -0,0 +1,31 @@
|
||||
body {
|
||||
background-color: #333;
|
||||
color: whitesmoke;
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
padding: 5em;
|
||||
}
|
||||
|
||||
.loading img {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.loading p {
|
||||
font-weight: 700;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.rotate {
|
||||
animation: rotation 2s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes rotation {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
35
src/data/interfaces.js
Normal file
@ -0,0 +1,35 @@
|
||||
const InterfaceRecord = {
|
||||
find(search,limit,offset){},
|
||||
get(uuid){},
|
||||
add(uuid,timestamp,content,mime,hash){},
|
||||
update(uuid,timestamp,content,mime,hash){},
|
||||
delete(uuid){},
|
||||
}
|
||||
|
||||
const InterfaceFile = {
|
||||
add(uuid_record,uuid,timestamp,content,mime,hash){},
|
||||
getByRecord(uuid_record){},
|
||||
get(uuid){},
|
||||
delete(uuid){},
|
||||
deleteRecord(uuid_record){},
|
||||
update(uuid,timestamp,content,mime,hash){}
|
||||
}
|
||||
|
||||
const InterfaceTag = {
|
||||
add(uuid,word){},
|
||||
delete(uuid){}
|
||||
}
|
||||
|
||||
const InterfaceTagLink = {
|
||||
add(uuid_record,uuid_tag){},
|
||||
delete(uuid_record,uuid_tag){},
|
||||
deleteTag(uuid){},
|
||||
deleteRecord(uuid){}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
InterfaceTagLink,
|
||||
InterfaceTag,
|
||||
InterfaceFile,
|
||||
InterfaceRecord
|
||||
}
|
||||
0
src/data/sqlite-client.js
Normal file
76
src/data/sqlite-electron-ipc.js
Normal file
@ -0,0 +1,76 @@
|
||||
const { ipcMain } = require('electron');
|
||||
|
||||
const {app} = require('electron');
|
||||
const config = app.getPath('userData');
|
||||
|
||||
const Conf = require('conf');
|
||||
const config = new Conf();
|
||||
|
||||
|
||||
// ** Extra Data
|
||||
ipcMain.on('timechain-config-dir', (event,arg) => {
|
||||
const configDir = app.getPath('userData');
|
||||
event.reply('timechain-config-dir-reply', configDir);
|
||||
});
|
||||
|
||||
// ** RECORD **
|
||||
|
||||
ipcMain.on('timechain-record-add', (event, arg) => {
|
||||
event.reply('timechain-record-add-reply', 'pong')
|
||||
});
|
||||
|
||||
ipcMain.on('timechain-record-delete', (event, arg) => {
|
||||
event.reply('timechain-record-delete-reply', 'pong')
|
||||
});
|
||||
|
||||
ipcMain.on('timechain-record-update', (event, arg) => {
|
||||
event.reply('timechain-record-update-reply', 'pong')
|
||||
});
|
||||
|
||||
ipcMain.on('timechain-record-find', (event, arg) => {
|
||||
event.reply('timechain-record-find-reply', 'pong')
|
||||
});
|
||||
|
||||
// ** FILE **
|
||||
|
||||
ipcMain.on('timechain-file-find', (event, arg) => {
|
||||
event.reply('timechain-file-find-reply', 'pong')
|
||||
});
|
||||
|
||||
ipcMain.on('timechain-file-add', (event, arg) => {
|
||||
event.reply('timechain-file-add-reply', 'pong')
|
||||
});
|
||||
|
||||
ipcMain.on('timechain-file-update', (event, arg) => {
|
||||
event.reply('timechain-file-update-reply', 'pong')
|
||||
});
|
||||
|
||||
ipcMain.on('timechain-file-delete', (event, arg) => {
|
||||
event.reply('timechain-file-delete-reply', 'pong')
|
||||
});
|
||||
|
||||
// ** TAG **
|
||||
ipcMain.on('timechain-tag-add', (event, arg) => {
|
||||
event.reply('timechain-tag-add-reply', 'pong')
|
||||
});
|
||||
|
||||
ipcMain.on('timechain-tag-delete', (event, arg) => {
|
||||
event.reply('timechain-tag-delete-reply', 'pong')
|
||||
});
|
||||
|
||||
// ** TAG LINK **
|
||||
ipcMain.on('timechain-taglink-add', (event, arg) => {
|
||||
event.reply('timechain-taglink-add-reply', 'pong')
|
||||
});
|
||||
|
||||
ipcMain.on('timechain-taglink-delete', (event, arg) => {
|
||||
event.reply('timechain-taglink-delete-reply', 'pong')
|
||||
});
|
||||
|
||||
ipcMain.on('timechain-taglink-deleteTag', (event, arg) => {
|
||||
event.reply('timechain-taglink-deleteTag-reply', 'pong')
|
||||
});
|
||||
|
||||
ipcMain.on('timechain-taglink-deleteRecord', (event, arg) => {
|
||||
event.reply('timechain-taglink-deleteRecord-reply', 'pong')
|
||||
});
|
||||
264
src/data/sqlite.js
Normal file
@ -0,0 +1,264 @@
|
||||
const Interface = require("es6-interface");
|
||||
const {InterfaceRecord,InterfaceFile,InterfaceTag,InterfaceTagLink} = require("./interfaces");
|
||||
|
||||
let db = null;
|
||||
|
||||
const connectToDatabase = (path)=>{
|
||||
db = require('better-sqlite3')(path, {});
|
||||
}
|
||||
|
||||
class TimeChainDataSqliteTag extends Interface(InterfaceTag) {
|
||||
|
||||
constructor(){
|
||||
|
||||
}
|
||||
|
||||
add(uuid,word){
|
||||
|
||||
}
|
||||
|
||||
delete(uuid){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TimeChainDataSqliteTagLink extends Interface(InterfaceTagLink) {
|
||||
|
||||
constructor(){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TimeChainDataSqliteFile extends Interface(InterfaceFile) {
|
||||
|
||||
constructor(){
|
||||
const table = `CREATE TABLE IF NOT EXISTS "files" (
|
||||
"uuid" TEXT UNIQUE,
|
||||
"uuid_record" TEXT NOT NULL,
|
||||
"timestamp" INTEGER NOT NULL,
|
||||
"content" BLOB NOT NULL,
|
||||
"mime" TEXT NOT NULL,
|
||||
"hash" TEXT,
|
||||
"created_at" INTEGER NOT NULL,
|
||||
"updated_at" INTEGER NOT NULL,
|
||||
PRIMARY KEY("uuid")
|
||||
);`;
|
||||
const table_idx = `
|
||||
CREATE INDEX IF NOT EXISTS "files_idx_record" ON "files" (
|
||||
"uuid_record"
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS "files_idx_time" ON "files" (
|
||||
"timestamp" DESC
|
||||
);`;
|
||||
|
||||
if(!db){
|
||||
throw new Error("Database is not connected");
|
||||
}
|
||||
|
||||
db.exec(table + "\n" + table_idx);
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
get table_insert() {
|
||||
if(!this._table_insert){
|
||||
this._table_insert = db.prepare(`INSERT INTO files (uuid,uuid_record,timestamp,content,mime,hash,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?)`);
|
||||
}
|
||||
return this._table_insert;
|
||||
}
|
||||
|
||||
get table_update() {
|
||||
if(!this._table_update){
|
||||
this._table_update = db.prepare(`UPDATE files SET timestamp = ?, content = ?, mime = ? hash = ?, updated_at = ? WHERE uuid = ?`);
|
||||
}
|
||||
return this._table_update;
|
||||
}
|
||||
|
||||
get table_delete() {
|
||||
if(!this._table_delete){
|
||||
this._table_delete = db.prepare(`DELETE FROM files WHERE uuid = ?`);
|
||||
}
|
||||
return this._table_delete;
|
||||
}
|
||||
|
||||
get table_delete_record() {
|
||||
|
||||
if(!this._table_delete_record){
|
||||
this._table_delete_record = db.prepare(`DELETE FROM files WHERE uuid_record = ?`);
|
||||
}
|
||||
|
||||
return this._table_delete_record;
|
||||
}
|
||||
|
||||
get table_find_one() {
|
||||
if(!this._table_find_one){
|
||||
this._table_find_one = db.prepare(`SELECT * FROM files WHERE uuid = ?`);
|
||||
}
|
||||
return this._table_find_one;
|
||||
}
|
||||
|
||||
get table_find_record(){
|
||||
if(!this._table_find_record){
|
||||
this._table_find_record = db.prepare(`SELECT * FROM files WHERE uuid_record = ?`);
|
||||
}
|
||||
return this._table_find_record;
|
||||
}
|
||||
|
||||
add(uuid_record,uuid,timestamp,content,mime,hash){
|
||||
return new Promise(resolve=>{
|
||||
const dt = Math.floor(Date.now());
|
||||
const res = this.table_insert.exec(uuid,uuid_record,timestamp,content,mime,hash,dt,dt);
|
||||
return resolve(res?.changes);
|
||||
});
|
||||
}
|
||||
|
||||
getByRecord(uuid_record){
|
||||
return new Promise(resolve => {
|
||||
const res = this.table_find_record.get(uuid_record);
|
||||
return resolve(res);
|
||||
});
|
||||
}
|
||||
|
||||
get(uuid){
|
||||
return new Promise(resolve => {
|
||||
const res = this.table_fine_one.get(uuid);
|
||||
return resolve(res);
|
||||
});
|
||||
}
|
||||
|
||||
delete(uuid){
|
||||
return new Promise(resolve=>{
|
||||
const res = this.table_delete.exec(uuid);
|
||||
return resolve(res?.changes);
|
||||
})
|
||||
}
|
||||
|
||||
deleteRecord(){
|
||||
return new Promise(resolve=>{
|
||||
const res = this.table_delete_record.exec(uuid_record);
|
||||
return resolve(res?.changes);
|
||||
})
|
||||
}
|
||||
|
||||
update(uuid,timestamp,content,mime,hash){
|
||||
return new Promise(resolve=>{
|
||||
const res = this.table_update.exec(timestamp,content,mime,hash,uuid);
|
||||
return resolve(res?.changes);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
class TimeChainDataSqliteRecord extends Interface(InterfaceRecord) {
|
||||
|
||||
constructor(){
|
||||
//TODO: Create Tables Here if not exist
|
||||
const table = `CREATE TABLE IF NOT EXISTS "records" (
|
||||
"uuid" TEXT NOT NULL UNIQUE,
|
||||
"timestamp" INTEGER NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"mime" TEXT NOT NULL,
|
||||
"hash" TEXT,
|
||||
"created_at" INTEGER NOT NULL,
|
||||
"updated_at" INTEGER NOT NULL,
|
||||
PRIMARY KEY("uuid")
|
||||
);`;
|
||||
const table_idx = `CREATE INDEX IF NOT EXISTS "records_idx_timestamp" ON "records" (
|
||||
"timestamp" DESC
|
||||
);`
|
||||
|
||||
if(!db){
|
||||
throw new Error("Database is not connected");
|
||||
}
|
||||
|
||||
db.exec(table + "\n" + table_idx);
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
get table_insert() {
|
||||
if(!this._table_insert){
|
||||
this._table_insert = db.prepare(`INSERT INTO records (uuid,timestamp,content,mime,hash,created_at,updated_at) VALUES (?,?,?,?,?,?,?)`);
|
||||
}
|
||||
return this._table_insert;
|
||||
}
|
||||
|
||||
get table_update(){
|
||||
if(!this._table_update){
|
||||
this._table_update = db.prepare(`UPDATE records SET timestamp = ?, content = ?, mime = ?, hash = ? updated_at = ? WHERE uuid = ?`);
|
||||
}
|
||||
return this._table_update;
|
||||
}
|
||||
|
||||
get table_delete(){
|
||||
if(!this._table_delete){
|
||||
this._table_delete = db.prepare(`DELETE FROM records WHERE uuid = ?`);
|
||||
}
|
||||
return this._table_delete;
|
||||
}
|
||||
|
||||
get table_fine_one(){
|
||||
if(!this._table_fine_one){
|
||||
this._table_fine_one = db.prepare(`SELECT * FROM records WHERE uuid = ?`);
|
||||
}
|
||||
return this._table_fine_one;
|
||||
}
|
||||
|
||||
add(uuid,timestamp,content,mime,hash){
|
||||
return new Promise(resolve=>{
|
||||
const dt = Math.floor(Date.now());
|
||||
const res = this.table_insert.run(uuid,timestamp,content,mime,hash,dt,dt);
|
||||
return resolve(res?.changes);
|
||||
});
|
||||
}
|
||||
|
||||
get(uuid){
|
||||
return new Promise(resolve=>{
|
||||
const rec = this.table_fine_one.get(uuid);
|
||||
return resolve(rec);
|
||||
});
|
||||
}
|
||||
|
||||
find(search,sort=null,limit=undefined,offset=0){
|
||||
//TODO: add logic for seach and sort (Currently does nothing)
|
||||
return new Promise(resolve=>{
|
||||
const rescount = this.db.prepare("SELECT count(*) as cnt FROM records").get();
|
||||
|
||||
if(limit){
|
||||
const res = this.db.prepare("SELECT * FROM records ORDER BY timestamp DESC LIMIT ? OFFSET ?").all(limit,offset);
|
||||
}else{
|
||||
const res = this.db.prepare("SELECT * FROM records ORDER BY timestamp DESC").all();
|
||||
}
|
||||
|
||||
return resolve({
|
||||
data: res,
|
||||
count: rescount?.cnt,
|
||||
limit: limit,
|
||||
offset: offset
|
||||
});
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
delete(uuid){
|
||||
return new Promise(resolve=>{
|
||||
const res = this.table_delete.exec(uuid);
|
||||
return resolve(res?.changes);
|
||||
});
|
||||
}
|
||||
|
||||
update(uuid,content,mime,hash){
|
||||
return new Promise(resolve=>{
|
||||
const dt = Math.floor(Date.now());
|
||||
const res = this.table_update.exec(content,mime,hash,dt,uuid);
|
||||
return resolve(res?.changes);
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TimeChainDataSqlite {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
1
src/img/calendar.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs><style>.cls-1{fill:#141f38;}</style></defs><title>calendar-outline</title><path class="cls-1" d="M102.4,332.8a12.8,12.8,0,0,0,0,25.6H128V384a12.8,12.8,0,1,0,25.6,0V358.4h51.2V384a12.8,12.8,0,0,0,25.6,0V358.4h51.2V384a12.8,12.8,0,0,0,25.6,0V358.4h51.2V384a12.8,12.8,0,0,0,25.6,0V358.4h25.6a12.8,12.8,0,0,0,0-25.6H384V281.6h25.6a12.8,12.8,0,0,0,0-25.6H384V230.4a12.8,12.8,0,0,0-25.6,0V256H307.2V230.4a12.8,12.8,0,1,0-25.6,0V256H230.4V230.4a12.8,12.8,0,0,0-25.6,0V256H153.6V230.4a12.8,12.8,0,1,0-25.6,0V256H102.4a12.8,12.8,0,0,0,0,25.6H128v51.2Zm256-51.2v51.2H307.2V281.6Zm-76.8,0v51.2H230.4V281.6Zm-128,0h51.2v51.2H153.6ZM448,38.4H409.6a38.4,38.4,0,0,0-76.8,0H179.2a38.4,38.4,0,1,0-76.8,0H64a64,64,0,0,0-64,64V428.8A83.2,83.2,0,0,0,83.2,512H428.8A83.2,83.2,0,0,0,512,428.8V102.4A64,64,0,0,0,448,38.4Zm-89.6,0a12.8,12.8,0,0,1,25.6,0V64a12.8,12.8,0,0,1-25.6,0ZM128,38.4a12.8,12.8,0,1,1,25.6,0V64A12.8,12.8,0,1,1,128,64Zm-102.4,64A38.33,38.33,0,0,1,42.54,70.57,38.18,38.18,0,0,1,64,64h38.4a38.4,38.4,0,1,0,76.8,0H332.8a38.4,38.4,0,0,0,76.8,0H448a38.44,38.44,0,0,1,38.2,34.48,38.69,38.69,0,0,1,.2,3.92v51.2H25.6Zm403.2,384H83.2a57.56,57.56,0,0,1-53-35.33A63.61,63.61,0,0,0,64,460.8H448a63.61,63.61,0,0,0,33.8-9.73A57.56,57.56,0,0,1,428.8,486.4Zm57.6-89.6A38.44,38.44,0,0,1,448,435.2H64a38.44,38.44,0,0,1-38.4-38.4V179.2H486.4Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
1
src/img/chain1.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 24 24" height="24px" id="Layer_1" version="1.1" viewBox="0 0 24 24" width="24px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g><path d="M16.9,7.1c-0.4-0.4-1-0.4-1.4,0l-8.4,8.4c-0.4,0.4-0.4,1,0,1.4c0.4,0.4,1,0.4,1.4,0l8.4-8.4C17.3,8.1,17.3,7.5,16.9,7.1z"/><path d="M8.5,22.5L12,19c1.4-1.4,1.8-3.5,1.1-5.3l-1.7,1.7c0,0.8-0.2,1.6-0.9,2.3l-3.5,3.5c-1.2,1.2-3.1,1.2-4.2,0 c-1.2-1.2-1.2-3.1,0-4.2l3.5-3.5c0.6-0.6,1.5-0.9,2.3-0.9l1.7-1.7C8.5,10.2,6.4,10.5,5,12l-3.5,3.5c-1.9,1.9-1.9,5.1,0,7 C3.4,24.5,6.6,24.5,8.5,22.5z"/><path d="M13.4,6.4l3.5-3.5c1.2-1.2,3.1-1.2,4.2,0s1.2,3.1,0,4.2l-3.5,3.5c-0.6,0.6-1.5,0.9-2.3,0.9l-1.7,1.7 c1.8,0.7,3.9,0.3,5.3-1.1l3.5-3.5c1.9-1.9,1.9-5.1,0-7c-1.9-1.9-5.1-1.9-7,0L12,5c-1.4,1.4-1.8,3.5-1.1,5.3l1.7-1.7 C12.5,7.8,12.8,7,13.4,6.4z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 990 B |
1
src/img/chain2.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" ?><svg data-name="Layer 1" id="Layer_1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:none;stroke:#1d1d1b;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style></defs><title/><g data-name="<Group>" id="_Group_"><path class="cls-1" d="M13.38,10.79h0a3.5,3.5,0,0,1,0,5L10.52,18.6a3.5,3.5,0,0,1-5,0h0a3.5,3.5,0,0,1,0-5l.86-.86" data-name="<Path>" id="_Path_"/><path class="cls-1" d="M11,13.21h0a3.5,3.5,0,0,1,0-5L13.81,5.4a3.5,3.5,0,0,1,5,0h0a3.5,3.5,0,0,1,0,5l-.86.86" data-name="<Path>" id="_Path_2"/></g></svg>
|
||||
|
After Width: | Height: | Size: 597 B |
BIN
src/img/chains.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
1
src/img/clock1.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" ?><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g><path d="M0 0h24v24H0z" fill="none"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm1-8h4v2h-6V7h2v5z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 270 B |
1
src/img/clock2.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" ?><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g><path d="M0 0h24v24H0z" fill="none"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm1-10V7h-2v7h6v-2h-4z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 238 B |
1
src/img/link1.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><title>link</title><path d="M512,256c0,141.38-114.62,256-256,256S0,397.39,0,256,114.62,0,256,0,512,114.62,512,256Z" fill="#404041"/><path d="M28,139.52,139.52,28A257.1,257.1,0,0,0,28,139.52Z" fill="#4d4d4f"/><path d="M179.06,11.77,11.77,179.06a254.14,254.14,0,0,0-6.43,24.69L203.75,5.34A253.94,253.94,0,0,0,179.06,11.77Z" fill="#4d4d4f"/><path d="M231.24,1.2l-230,230Q.27,240.84.07,250.64L250.63.07Q240.84.27,231.24,1.2Z" fill="#4d4d4f"/><path d="M273.44.6.6,273.43q.56,8.39,1.66,16.63L290.05,2.26Q281.83,1.17,273.44.6Z" fill="#4d4d4f"/><path d="M309.94,5.71,5.71,309.95q1.59,7.41,3.6,14.66L324.6,9.31Q317.35,7.3,309.94,5.71Z" fill="#4d4d4f"/><path d="M342.32,14.93,14.94,342.33Q17.32,349,20,355.47L355.46,20Q349,17.31,342.32,14.93Z" fill="#4d4d4f"/><path d="M371.41,27.44l-344,344q3,6,6.39,11.86L383.28,33.83Q377.44,30.48,371.41,27.44Z" fill="#4d4d4f"/><path d="M397.69,42.77,42.77,397.69q3.63,5.46,7.53,10.72L408.42,50.31Q403.16,46.4,397.69,42.77Z" fill="#4d4d4f"/><path d="M421.43,60.64,60.65,421.43q4.18,4.93,8.6,9.65L431.08,69.25Q426.36,64.82,421.43,60.64Z" fill="#4d4d4f"/><path d="M442.75,80.91,80.92,442.75q4.72,4.42,9.65,8.6L451.37,90.58Q447.18,85.64,442.75,80.91Z" fill="#4d4d4f"/><path d="M461.69,103.58,103.58,461.69q5.26,3.91,10.73,7.54L469.23,114.31Q465.59,108.85,461.69,103.58Z" fill="#4d4d4f"/><path d="M478.17,128.72,128.71,478.16q5.84,3.35,11.88,6.4l344-344Q481.51,134.56,478.17,128.72Z" fill="#4d4d4f"/><path d="M492,156.53,156.53,492q6.48,2.73,13.14,5.11L497.06,169.67Q494.68,163,492,156.53Z" fill="#4d4d4f"/><path d="M502.69,187.41,187.4,502.69q7.24,2,14.66,3.6L506.29,202.06Q504.7,194.65,502.69,187.41Z" fill="#4d4d4f"/><path d="M509.74,222,221.94,509.74q8.23,1.09,16.62,1.66L511.4,238.56Q510.83,230.18,509.74,222Z" fill="#4d4d4f"/><path d="M510.81,280.75q.92-9.59,1.13-19.38L261.37,511.93q9.79-.2,19.39-1.13Z" fill="#4d4d4f"/><path d="M332.92,500.23,500.23,332.92a254,254,0,0,0,6.42-24.68L308.23,506.66A254.22,254.22,0,0,0,332.92,500.23Z" fill="#4d4d4f"/><path d="M484,372.49,372.48,484A257.12,257.12,0,0,0,484,372.49Z" fill="#4d4d4f"/><path d="M176.21,316.33l19.45,19.47a16,16,0,0,0,22.66,0l36.39-36.37h0s0-.06.07-.08l3.72-3.73a12.84,12.84,0,0,1,18.12,0l4.51,4.5a12.85,12.85,0,0,1,0,18.13L277.4,322l-.07.06h0L241,358.44a48.09,48.09,0,0,1-67.93,0L153.56,339a48.1,48.1,0,0,1,0-67.93l36.39-36.38h0l.07-.08,3.73-3.73a12.84,12.84,0,0,1,18.11,0l4.51,4.51a12.81,12.81,0,0,1,0,18.11l-3.71,3.73-.08.07,0,0-36.38,36.38A16,16,0,0,0,176.21,316.33Zm159.58-98L299.41,254.7l0,0s-.06,0-.08.07l-3.71,3.72a12.84,12.84,0,0,0,0,18.12l4.51,4.52a12.84,12.84,0,0,0,18.1,0l3.74-3.71a.19.19,0,0,1,.07-.09h0L358.44,241a48.14,48.14,0,0,0,0-67.94L339,153.57a48.07,48.07,0,0,0-67.92,0L234.65,190h0l-.07.06-3.72,3.73a12.84,12.84,0,0,0,0,18.12l4.51,4.51a12.86,12.86,0,0,0,18.13,0l3.71-3.73a.46.46,0,0,1,.07-.08l0,0,36.39-36.37a16,16,0,0,1,22.64,0l19.46,19.46A16,16,0,0,1,335.79,218.32ZM294.14,211a12.82,12.82,0,0,0-18.1,0l-63.71,63.72a12.82,12.82,0,0,0,0,18.1l6.81,6.82a12.86,12.86,0,0,0,18.11,0L301,236a12.86,12.86,0,0,0,0-18.12Z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
1
src/img/link2.svg
Normal file
|
After Width: | Height: | Size: 503 KiB |
1
src/img/stopwatch.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs><style>.cls-1{fill:#141f38;}</style></defs><title>pocket-clock-glyph</title><path class="cls-1" d="M242.53,336.84A13.47,13.47,0,1,1,256,350.32,13.49,13.49,0,0,1,242.53,336.84ZM207.18,140.69a67.37,67.37,0,1,1,97.63,0,200.53,200.53,0,0,1,27.54,9,94.32,94.32,0,1,0-152.71,0A200.53,200.53,0,0,1,207.18,140.69Zm48.82,21c96.58,0,175.16,78.58,175.16,175.16S352.58,512,256,512,80.84,433.42,80.84,336.84,159.42,161.68,256,161.68ZM215.58,336.84a40.42,40.42,0,1,0,53.89-38.11v-56.2a13.47,13.47,0,0,0-26.95,0v56.2A40.43,40.43,0,0,0,215.58,336.84Zm53.89-256H242.53a27,27,0,0,0-26.95,26.95v31a203.9,203.9,0,0,1,80.84,0v-31A27,27,0,0,0,269.47,80.84Z"/></svg>
|
||||
|
After Width: | Height: | Size: 744 B |
1
src/img/stopwatch2.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" ?><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g><path d="M0 0h24v24H0z" fill="none"/><path d="M12 22a9 9 0 1 1 0-18 9 9 0 0 1 0 18zm0-2a7 7 0 1 0 0-14 7 7 0 0 0 0 14zm1-7h3v2h-5V8h2v5zM1.747 6.282l3.535-3.535 1.415 1.414L3.16 7.697 1.747 6.282zm16.97-3.535l3.536 3.535-1.414 1.415-3.536-3.536 1.415-1.414z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 355 B |
1
src/img/stopwatch3.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs><style>.cls-1{fill:#141f38;}</style></defs><title>stopwatch-glyph</title><path class="cls-1" d="M407,106.62a242.14,242.14,0,0,0-67.3-37.9L353,45.6a20.21,20.21,0,0,1,27.61-7.4L412.5,56.61a20.21,20.21,0,0,1,7.4,27.61Zm64.61,189.8C471.58,415.29,374.87,512,256,512S40.42,415.29,40.42,296.42,137.13,80.84,256,80.84,471.58,177.55,471.58,296.42Zm-175.16,0a40.43,40.43,0,0,0-26.95-38.11V175.16a13.47,13.47,0,0,0-26.95,0v83.15a40.42,40.42,0,1,0,53.89,38.11ZM256,282.95a13.47,13.47,0,1,0,13.47,13.47A13.49,13.49,0,0,0,256,282.95ZM105,106.62a242.14,242.14,0,0,1,67.3-37.9L159,45.6a20.21,20.21,0,0,0-27.61-7.4L99.5,56.61a20.21,20.21,0,0,0-7.4,27.61Zm204.86-46.7v-33A27,27,0,0,0,282.95,0H229.05a27,27,0,0,0-26.95,26.95v33a244.28,244.28,0,0,1,107.79,0Z"/></svg>
|
||||
|
After Width: | Height: | Size: 848 B |
BIN
src/img/supply-chain.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
1
src/img/wallclock.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs><style>.cls-1{fill:#141f38;}</style></defs><title>cuckoo-clock-glyph</title><path class="cls-1" d="M435.16,307.24H409.57v-107a40.06,40.06,0,0,0,41.57-11.43,37.79,37.79,0,0,0-4.28-54.45L306.33,18.1a79,79,0,0,0-100.65,0L65.14,134.39a37.79,37.79,0,0,0-4.29,54.45A39.67,39.67,0,0,0,90.6,202a40.4,40.4,0,0,0,11.83-1.77v107H76.84a38.39,38.39,0,0,0,0,76.78H192v53.39a38.39,38.39,0,1,0,25.59,0V384h76.78v27.8a38.39,38.39,0,1,0,25.59,0V384H435.16a38.39,38.39,0,0,0,0-76.78ZM256,140.87a64,64,0,1,1-64,64A64,64,0,0,1,256,140.87Zm-9,73a12.8,12.8,0,0,1-3.75-9v-12.8a12.8,12.8,0,1,1,25.59,0v7.5l9,9a12.8,12.8,0,1,1-18.1,18.1Z"/></svg>
|
||||
|
After Width: | Height: | Size: 721 B |
7
start.js
Normal file
@ -0,0 +1,7 @@
|
||||
import Timestamp from './timestamp.riot'
|
||||
import { component } from 'riot'
|
||||
|
||||
|
||||
component(Timestamp)(document.getElementById('timestamp'))
|
||||
|
||||
console.log("yes!");
|
||||
34
timestamp.riot
Normal file
@ -0,0 +1,34 @@
|
||||
<timestamp>
|
||||
|
||||
<div class="timestamp">
|
||||
<div class="timestamp-icon">
|
||||
<div class="timestamp-text">{ state.time_text }</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
const pubsub = require('pubsub-js');
|
||||
const dayjs = require('dayjs');
|
||||
|
||||
export default {
|
||||
state: {
|
||||
time_text: "",
|
||||
format: "long"
|
||||
},
|
||||
onMounted(){
|
||||
this.start();
|
||||
},
|
||||
start(){
|
||||
setTimeout(()=>{
|
||||
this.makeString();
|
||||
this.start();
|
||||
},200);
|
||||
},
|
||||
makeString(){
|
||||
if(this.state.format=="long"){
|
||||
this.update({time_text:dayjs().format("MMMM D, YYYY h:mm:ss A")});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</timestamp>
|
||||