Compare commits
2 Commits
7c9a29b16c
...
c617c63510
| Author | SHA1 | Date | |
|---|---|---|---|
| c617c63510 | |||
| 02ecda067f |
@ -2,14 +2,15 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
<script type="module" src="r.js"></script>
|
||||||
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
|
||||||
<title>Time Chain</title>
|
<title>Time Chain</title>
|
||||||
<link rel="stylesheet" href="src/css/main.css">
|
<link rel="stylesheet" href="src/css/main.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="node_modules/@yaireo/tagify/dist/tagify.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="loading" >
|
<div id="timechain"></div>
|
||||||
|
<div class="loading" id="main-loading">
|
||||||
<h1>Time Chain!</h1>
|
<h1>Time Chain!</h1>
|
||||||
<p>Time traveling your data! Comming soon...</p>
|
<p>Time traveling your data! Comming soon...</p>
|
||||||
<p id="timestamp"></p>
|
<p id="timestamp"></p>
|
||||||
|
|||||||
16
main.js
16
main.js
@ -1,18 +1,28 @@
|
|||||||
const { app, BrowserWindow } = require('electron')
|
const { app, BrowserWindow } = require('electron')
|
||||||
|
require('./src/data/sqlite-electron-ipc');
|
||||||
|
|
||||||
|
|
||||||
|
let mainWin;
|
||||||
|
|
||||||
function createWindow () {
|
function createWindow () {
|
||||||
const win = new BrowserWindow({
|
mainWin = new BrowserWindow({
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
icon: __dirname + '/src/img/chains.png'
|
icon: __dirname + '/src/img/chains.png',
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
contextIsolation: false
|
||||||
|
},
|
||||||
|
nodeIntegration: true
|
||||||
})
|
})
|
||||||
|
|
||||||
//win.autoHideMenuBar = true;
|
//win.autoHideMenuBar = true;
|
||||||
|
|
||||||
win.loadFile('index.html')
|
mainWin.loadFile('index.html')
|
||||||
}
|
}
|
||||||
|
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
createWindow()
|
createWindow()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
2670
package-lock.json
generated
2670
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
@ -13,7 +13,11 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "electron .",
|
"start": "electron .",
|
||||||
"build": "parcel build --dist-dir ./src/dist --target \"jason\" start.js"
|
"build": "parcel build --dist-dir ./src/dist --target \"jason\" start.js",
|
||||||
|
"watch": "parcel --dist-dir ./src/dist --target \"jason\" start.js",
|
||||||
|
"build-main": "parcel build --dist-dir ./src/dist --target \"jason\" main.js",
|
||||||
|
"rebuild": "electron-rebuild -f -w better-sqlite3",
|
||||||
|
"postinstall": "electron-builder install-app-deps"
|
||||||
},
|
},
|
||||||
"browserslist": "> 0.5%, last 2 versions, not dead",
|
"browserslist": "> 0.5%, last 2 versions, not dead",
|
||||||
"targets": {
|
"targets": {
|
||||||
@ -29,11 +33,16 @@
|
|||||||
"parcel": "^2.2.1"
|
"parcel": "^2.2.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@yaireo/tagify": "^4.9.5",
|
||||||
"better-sqlite3": "^7.5.0",
|
"better-sqlite3": "^7.5.0",
|
||||||
|
"conf": "^10.1.1",
|
||||||
"dayjs": "^1.10.7",
|
"dayjs": "^1.10.7",
|
||||||
|
"electron-rebuild": "^3.2.7",
|
||||||
|
"empty-lite": "^1.2.0",
|
||||||
"es6-interface": "^3.2.1",
|
"es6-interface": "^3.2.1",
|
||||||
"nanoid": "^3.2.0",
|
"nanoid": "^3.2.0",
|
||||||
"pubsub-js": "^1.9.4",
|
"pubsub-js": "^1.9.4",
|
||||||
"riot": "^6.1.2"
|
"riot": "^6.1.2",
|
||||||
|
"sanitize-html": "^2.6.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,3 +29,27 @@ body {
|
|||||||
transform: rotate(359deg);
|
transform: rotate(359deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timestamp {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.3em;
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pasteme {
|
||||||
|
border: 3px dashed #ccc;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
padding: 1em;
|
||||||
|
margin: 0.5em 2em;
|
||||||
|
color: whitesmoke;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paste-html {
|
||||||
|
font-size: 1em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timestamp-puase {
|
||||||
|
color: yellow !important;
|
||||||
|
}
|
||||||
@ -17,14 +17,18 @@ const InterfaceFile = {
|
|||||||
|
|
||||||
const InterfaceTag = {
|
const InterfaceTag = {
|
||||||
add(tag){},
|
add(tag){},
|
||||||
delete(tag){}
|
delete(tag){},
|
||||||
|
get(tag){},
|
||||||
|
has(tag){}
|
||||||
}
|
}
|
||||||
|
|
||||||
const InterfaceTagLink = {
|
const InterfaceTagLink = {
|
||||||
add(uuid,tag){},
|
add(uuid,tag){},
|
||||||
delete(uuid,tag){},
|
delete(uuid,tag){},
|
||||||
deleteTag(tag){},
|
deleteTag(tag){},
|
||||||
deleteRecord(uuid){}
|
deleteRecord(uuid){},
|
||||||
|
getRecords(tag){},
|
||||||
|
getTags(uuid){}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|||||||
@ -0,0 +1,157 @@
|
|||||||
|
/*const Interface = window.require("es6-interface");
|
||||||
|
const {InterfaceRecord,InterfaceFile,InterfaceTag,InterfaceTagLink} = require("./interfaces");*/
|
||||||
|
const { ipcRenderer } = window.require('electron')
|
||||||
|
|
||||||
|
///const { ipcRenderer } = window.require('electron')
|
||||||
|
|
||||||
|
class TimeChainDataSqliteTag //extends Interface(InterfaceTag)
|
||||||
|
{
|
||||||
|
|
||||||
|
constructor(){
|
||||||
|
this.cmd = "timechain-tag";
|
||||||
|
}
|
||||||
|
|
||||||
|
send(func, data){
|
||||||
|
data.func = func;
|
||||||
|
return ipcRenderer.invoke(this.cmd,data);
|
||||||
|
}
|
||||||
|
|
||||||
|
add(tag){
|
||||||
|
return this.send('add',{tag:tag})
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(tag){
|
||||||
|
return this.send('delete',{tag:tag})
|
||||||
|
}
|
||||||
|
|
||||||
|
get(tag){
|
||||||
|
return this.send('get',{tag:tag})
|
||||||
|
}
|
||||||
|
|
||||||
|
has(tag){
|
||||||
|
return this.send('has',{tag:tag})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimeChainDataSqliteTagLink //extends Interface(InterfaceTagLink)
|
||||||
|
{
|
||||||
|
|
||||||
|
constructor(){
|
||||||
|
this.cmd = 'timechain-taglink';
|
||||||
|
}
|
||||||
|
|
||||||
|
send(func, data){
|
||||||
|
data.func = func;
|
||||||
|
return ipcRenderer.invoke(this.cmd,data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
add(uuid,tag){
|
||||||
|
return this.send('add',{uuid:uuid,tag:tag});
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(uuid,tag){
|
||||||
|
return this.send('delete',{uuid:uuid,tag:tag});
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteTag(tag){
|
||||||
|
return this.send('delete-tag',{tag:tag});
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteRecord(uuid){
|
||||||
|
return this.send('delete-record',{uuid:uuid});
|
||||||
|
}
|
||||||
|
|
||||||
|
getRecords(tag){
|
||||||
|
return this.send('get-records',{tag:tag});
|
||||||
|
}
|
||||||
|
|
||||||
|
getTags(uuid){
|
||||||
|
return this.send('get-tags',{uuid:uuid});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimeChainDataSqliteFile //extends Interface(InterfaceFile)
|
||||||
|
{
|
||||||
|
|
||||||
|
constructor(){
|
||||||
|
this.cmd = 'timechain-file';
|
||||||
|
}
|
||||||
|
|
||||||
|
send(func, data){
|
||||||
|
data.func = func;
|
||||||
|
return ipcRenderer.invoke(this.cmd,data);
|
||||||
|
}
|
||||||
|
|
||||||
|
add(uuid_record,uuid,timestamp,content,mime,hash){
|
||||||
|
return this.send('add',{uuid_record:uuid_record,uuid:uuid,timestamp:timestamp,content:content,mime:mime,hash:hash});
|
||||||
|
}
|
||||||
|
|
||||||
|
getByRecord(uuid_record){
|
||||||
|
return this.send('get-record',{uuid_record:uuid_record});
|
||||||
|
}
|
||||||
|
|
||||||
|
get(uuid){
|
||||||
|
return this.send('get',{uuid:uuid});
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(uuid){
|
||||||
|
return this.send('delete',{uuid:uuid});
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteRecord(uuid_record){
|
||||||
|
return this.send('delete-record',{uuid_record:uuid_record});
|
||||||
|
}
|
||||||
|
|
||||||
|
update(uuid,timestamp,content,mime,hash){
|
||||||
|
return this.send('update',{uuid:uuid,timestamp:timestamp,content:content,mime:mime,hash:hash});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimeChainDataSqliteRecord //extends Interface(InterfaceRecord)
|
||||||
|
{
|
||||||
|
|
||||||
|
cmd = 'timechain-record'
|
||||||
|
|
||||||
|
send(func, data){
|
||||||
|
data.func = func;
|
||||||
|
return ipcRenderer.invoke(this.cmd,data);
|
||||||
|
}
|
||||||
|
|
||||||
|
add(uuid,timestamp,content,mime,hash){
|
||||||
|
return this.send('add',{uuid:uuid,timestamp:timestamp,content:content,mime:mime,hash:hash});
|
||||||
|
}
|
||||||
|
|
||||||
|
get(uuid){
|
||||||
|
return this.send('get',{uuid:uuid});
|
||||||
|
}
|
||||||
|
|
||||||
|
find(search,sort=null,limit=undefined,offset=0){
|
||||||
|
return this.send('find',{search:search,sort:sort,limit:limit,offset:offset});
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(uuid){
|
||||||
|
return this.sedn('delete',{uuid:uuid});
|
||||||
|
}
|
||||||
|
|
||||||
|
update(uuid,content,mime,hash){
|
||||||
|
return this.send('update',{uuid:uuid,content:content,mime:mime,hash:hash});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimeChainDataSqlite {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
TimeChainDataSqlite,
|
||||||
|
TimeChainDataSqliteRecord,
|
||||||
|
TimeChainDataSqliteFile,
|
||||||
|
TimeChainDataSqliteTagLink,
|
||||||
|
TimeChainDataSqliteTag
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,76 +1,146 @@
|
|||||||
const { ipcMain } = require('electron');
|
const { ipcMain } = require('electron');
|
||||||
|
|
||||||
const {app} = require('electron');
|
const {app} = require('electron');
|
||||||
const config = app.getPath('userData');
|
//const config = app.getPath('userData');
|
||||||
|
|
||||||
|
const {TimeChainDataSqliteRecord,ConnectToDatabase, TimeChainDataSqliteFile, TimeChainDataSqliteTag, TimeChainDataSqliteTagLink} = require('./sqlite');
|
||||||
|
|
||||||
|
|
||||||
|
const appPath = app.getPath('userData');
|
||||||
|
|
||||||
|
const DBPath = appPath+"/timechain.db";
|
||||||
|
console.log(DBPath);
|
||||||
|
|
||||||
|
const DB = ConnectToDatabase(DBPath);
|
||||||
|
|
||||||
|
const DbRecord = new TimeChainDataSqliteRecord();
|
||||||
|
const DbFile = new TimeChainDataSqliteFile();
|
||||||
|
const dbTag = new TimeChainDataSqliteTag();
|
||||||
|
const dbTagLink = new TimeChainDataSqliteTagLink();
|
||||||
|
//const configDir = app.getPath('userData');
|
||||||
|
//const appPath = app.getPath('exe');
|
||||||
|
|
||||||
|
|
||||||
const Conf = require('conf');
|
|
||||||
const config = new Conf();
|
|
||||||
|
|
||||||
|
|
||||||
// ** Extra Data
|
// ** Extra Data
|
||||||
ipcMain.on('timechain-config-dir', (event,arg) => {
|
ipcMain.handle('timechain-config-dir', (event,arg) => {
|
||||||
const configDir = app.getPath('userData');
|
return false;
|
||||||
event.reply('timechain-config-dir-reply', configDir);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// ** RECORD **
|
// ** RECORD **
|
||||||
|
console.log("Register timechain-record");
|
||||||
|
ipcMain.handle('timechain-record', async (event,arg) => {
|
||||||
|
|
||||||
ipcMain.on('timechain-record-add', (event, arg) => {
|
let res = null;
|
||||||
event.reply('timechain-record-add-reply', 'pong')
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on('timechain-record-delete', (event, arg) => {
|
switch(arg.func){
|
||||||
event.reply('timechain-record-delete-reply', 'pong')
|
case 'add':
|
||||||
});
|
res = await DbRecord.add(arg.uuid, arg.timestamp, arg.content, arg.mime, arg.hash);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
res = await DbRecord.delete(arg.uuid);
|
||||||
|
break;
|
||||||
|
case 'update':
|
||||||
|
res = await DbRecord.update(arg.uuid,arg.content,arg.mime,arg.hash);
|
||||||
|
break;
|
||||||
|
case 'find':
|
||||||
|
res = await DbRecord.find(arg.search,arg.sort,arg.limit,arg.offset);
|
||||||
|
break;
|
||||||
|
case 'get':
|
||||||
|
res = await DbRecord.get(arg.uuid);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = new Error('unknown command');
|
||||||
|
}
|
||||||
|
|
||||||
ipcMain.on('timechain-record-update', (event, arg) => {
|
return res;
|
||||||
event.reply('timechain-record-update-reply', 'pong')
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on('timechain-record-find', (event, arg) => {
|
})
|
||||||
event.reply('timechain-record-find-reply', 'pong')
|
|
||||||
});
|
|
||||||
|
|
||||||
// ** FILE **
|
// ** FILE **
|
||||||
|
|
||||||
ipcMain.on('timechain-file-find', (event, arg) => {
|
ipcMain.handle('timechain-file', async (event, arg) => {
|
||||||
event.reply('timechain-file-find-reply', 'pong')
|
let res = null;
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on('timechain-file-add', (event, arg) => {
|
switch(arg.func){
|
||||||
event.reply('timechain-file-add-reply', 'pong')
|
case 'add':
|
||||||
});
|
res = await DbFile.add(arg.uuid_record,arg.uuid,arg.timestamp,arg.content,arg.mime,arg.hash);
|
||||||
|
break;
|
||||||
|
case 'update':
|
||||||
|
res = await DbFile.update(arg.uuid,arg.timestamp,arg.content,arg.mime,arg.hash);
|
||||||
|
break;
|
||||||
|
case 'get-record':
|
||||||
|
res = await DbFile.getByRecord(arg.uuid_record);
|
||||||
|
break;
|
||||||
|
case 'delete-record':
|
||||||
|
res = await DbFile.deleteRecord(arg.uuid_record);
|
||||||
|
break;
|
||||||
|
case 'get':
|
||||||
|
res = await DbFile.get(arg.uuid);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
res = await DbFile.delete(arg.uuid);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = new Error('Unknow a command');
|
||||||
|
}
|
||||||
|
|
||||||
ipcMain.on('timechain-file-update', (event, arg) => {
|
return res;
|
||||||
event.reply('timechain-file-update-reply', 'pong')
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on('timechain-file-delete', (event, arg) => {
|
|
||||||
event.reply('timechain-file-delete-reply', 'pong')
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// ** TAG **
|
// ** TAG **
|
||||||
ipcMain.on('timechain-tag-add', (event, arg) => {
|
|
||||||
event.reply('timechain-tag-add-reply', 'pong')
|
ipcMain.handle('timechain-tag', async (event, arg) => {
|
||||||
|
|
||||||
|
let res = null;
|
||||||
|
|
||||||
|
switch(arg.func){
|
||||||
|
case 'add':
|
||||||
|
res = await DbTag.add(arg.tag);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
res = await DbTag.delete(arg.tag);
|
||||||
|
break;
|
||||||
|
case 'has':
|
||||||
|
res = await DbTag.delete(arg.tag);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = new Error('Command Unknown');
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('timechain-tag-delete', (event, arg) => {
|
// TAG LINK
|
||||||
event.reply('timechain-tag-delete-reply', 'pong')
|
|
||||||
});
|
|
||||||
|
|
||||||
// ** TAG LINK **
|
ipcMain.handle('timechain-taglink', async (event, arg) => {
|
||||||
ipcMain.on('timechain-taglink-add', (event, arg) => {
|
|
||||||
event.reply('timechain-taglink-add-reply', 'pong')
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on('timechain-taglink-delete', (event, arg) => {
|
let res = null;
|
||||||
event.reply('timechain-taglink-delete-reply', 'pong')
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on('timechain-taglink-deleteTag', (event, arg) => {
|
switch(arg.func){
|
||||||
event.reply('timechain-taglink-deleteTag-reply', 'pong')
|
case 'add':
|
||||||
});
|
res = await DbTagLink.add(arg.uuid,arg.tag)
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
res = await DbTagLink.delete(arg.uuid,arg.tag);
|
||||||
|
break;
|
||||||
|
case 'delete-tag':
|
||||||
|
res = await DbTagLink.deleteTag(arg.tag);
|
||||||
|
break;
|
||||||
|
case 'delete-record':
|
||||||
|
res = await DbTagLink.deleteRecord(arg.uuid);
|
||||||
|
break;
|
||||||
|
case 'get-records':
|
||||||
|
res = await DbTagLink.getRecords(atg.tag);
|
||||||
|
break;
|
||||||
|
case 'get-tags':
|
||||||
|
res = await DbTagLink.getTags(atg.uuid);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = Error("Commande not known");
|
||||||
|
}
|
||||||
|
|
||||||
ipcMain.on('timechain-taglink-deleteRecord', (event, arg) => {
|
return res;
|
||||||
event.reply('timechain-taglink-deleteRecord-reply', 'pong')
|
|
||||||
});
|
});
|
||||||
@ -34,7 +34,7 @@ class TimeChainDataSqliteTag extends Interface(InterfaceTag) {
|
|||||||
if(!this._table_add){
|
if(!this._table_add){
|
||||||
this._table_add = db.prepare("INSERT INTO tags (tag,created_at,updated_at) VALUES (?,?,?)");
|
this._table_add = db.prepare("INSERT INTO tags (tag,created_at,updated_at) VALUES (?,?,?)");
|
||||||
}
|
}
|
||||||
return this.table_add;
|
return this._table_add;
|
||||||
}
|
}
|
||||||
|
|
||||||
get table_delete(){
|
get table_delete(){
|
||||||
@ -44,6 +44,20 @@ class TimeChainDataSqliteTag extends Interface(InterfaceTag) {
|
|||||||
return this._table_delete;
|
return this._table_delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get table_get(){
|
||||||
|
if(!this._table_get){
|
||||||
|
this._table_get = db.prepare("SELECT * FROM tags WHERE tag = ?");
|
||||||
|
}
|
||||||
|
return this._table_get;
|
||||||
|
}
|
||||||
|
|
||||||
|
get table_count(){
|
||||||
|
if(!this._table_count){
|
||||||
|
this._table_count = db.prepare("SELECT count(tag) as cnt FROM tags WHERE tag = ?");
|
||||||
|
}
|
||||||
|
return this._table_count;
|
||||||
|
}
|
||||||
|
|
||||||
add(tag){
|
add(tag){
|
||||||
return new Promise(resolve=>{
|
return new Promise(resolve=>{
|
||||||
const dt = Math.floor(Date.now());
|
const dt = Math.floor(Date.now());
|
||||||
@ -60,6 +74,20 @@ class TimeChainDataSqliteTag extends Interface(InterfaceTag) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get(tag){
|
||||||
|
return new Promise(resolve=>{
|
||||||
|
const res = this.table_get.get(tag);
|
||||||
|
return resolve(res);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
has(tag){
|
||||||
|
return new Promise(resolve=>{
|
||||||
|
const res = this.table_count.get(tag);
|
||||||
|
return resolve(res && res.cnt>0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TimeChainDataSqliteTagLink extends Interface(InterfaceTagLink) {
|
class TimeChainDataSqliteTagLink extends Interface(InterfaceTagLink) {
|
||||||
@ -86,7 +114,7 @@ class TimeChainDataSqliteTagLink extends Interface(InterfaceTagLink) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get table_add(){
|
get table_add(){
|
||||||
if(!_table_add){
|
if(!this._table_add){
|
||||||
this._table_add = db.prepare('INSERT INTO taglink (uuid,tag,created_at) VALUES (?,?,?)');
|
this._table_add = db.prepare('INSERT INTO taglink (uuid,tag,created_at) VALUES (?,?,?)');
|
||||||
}
|
}
|
||||||
return this._table_add;
|
return this._table_add;
|
||||||
@ -110,6 +138,21 @@ class TimeChainDataSqliteTagLink extends Interface(InterfaceTagLink) {
|
|||||||
if(!this._table_delete_record){
|
if(!this._table_delete_record){
|
||||||
this._table_delete_record = db.prepare('DELETE FROM taglink WHERE uuid=?');
|
this._table_delete_record = db.prepare('DELETE FROM taglink WHERE uuid=?');
|
||||||
}
|
}
|
||||||
|
return this._table_delete_record;
|
||||||
|
}
|
||||||
|
|
||||||
|
get table_get_records(){
|
||||||
|
if(!this._table_get_records){
|
||||||
|
this._table_get_records = db.prepare("SELECT * FROM taglink WHERE tag=?");
|
||||||
|
}
|
||||||
|
return this._table_get_records;
|
||||||
|
}
|
||||||
|
|
||||||
|
get table_get_tags(){
|
||||||
|
if(!this._table_get_tags){
|
||||||
|
this._table_get_tags = db.prepare("SELECT * FROM taglink WHERE uuid=?");
|
||||||
|
}
|
||||||
|
return this._table_get_tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
add(uuid,tag){
|
add(uuid,tag){
|
||||||
@ -144,6 +187,22 @@ class TimeChainDataSqliteTagLink extends Interface(InterfaceTagLink) {
|
|||||||
return resolve(res?.changes);
|
return resolve(res?.changes);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getRecords(tag){
|
||||||
|
return new Promise(resolve=>{
|
||||||
|
const prepare = this.table_get_records;
|
||||||
|
const res = prepare.all(tag);
|
||||||
|
return resolve(res);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getTags(uuid){
|
||||||
|
return new Promise(resolve=>{
|
||||||
|
const prepare = this.table_get_tags;
|
||||||
|
const res = prepare.all(uuid);
|
||||||
|
return resolve(res);
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TimeChainDataSqliteFile extends Interface(InterfaceFile) {
|
class TimeChainDataSqliteFile extends Interface(InterfaceFile) {
|
||||||
@ -238,7 +297,7 @@ class TimeChainDataSqliteFile extends Interface(InterfaceFile) {
|
|||||||
|
|
||||||
get(uuid){
|
get(uuid){
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const res = this.table_fine_one.get(uuid);
|
const res = this.table_find_one.get(uuid);
|
||||||
return resolve(res);
|
return resolve(res);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -246,7 +305,7 @@ class TimeChainDataSqliteFile extends Interface(InterfaceFile) {
|
|||||||
delete(uuid){
|
delete(uuid){
|
||||||
return new Promise(resolve=>{
|
return new Promise(resolve=>{
|
||||||
const prepare = this.table_delete;
|
const prepare = this.table_delete;
|
||||||
const res = prepare.exec(uuid);
|
const res = prepare.run(uuid);
|
||||||
return resolve(res?.changes);
|
return resolve(res?.changes);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
40
src/img/clock1-white.svg
Normal file
40
src/img/clock1-white.svg
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
version="1.1"
|
||||||
|
id="svg70"
|
||||||
|
sodipodi:docname="clock1-white.svg"
|
||||||
|
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs74" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview72"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#ffffff"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:pageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="27.291667"
|
||||||
|
inkscape:cx="12"
|
||||||
|
inkscape:cy="12"
|
||||||
|
inkscape:window-width="1552"
|
||||||
|
inkscape:window-height="864"
|
||||||
|
inkscape:window-x="48"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg70" />
|
||||||
|
<path
|
||||||
|
d="M 0,0 H 24 V 24 H 0 Z"
|
||||||
|
fill="none"
|
||||||
|
id="path64" />
|
||||||
|
<path
|
||||||
|
d="M 12,22 C 6.477,22 2,17.523 2,12 2,6.477 6.477,2 12,2 c 5.523,0 10,4.477 10,10 0,5.523 -4.477,10 -10,10 z m 0,-2 a 8,8 0 1 0 0,-16 8,8 0 0 0 0,16 z m 1,-8 h 4 v 2 H 11 V 7 h 2 z"
|
||||||
|
id="path66"
|
||||||
|
style="fill:#e6e6e6" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
2
src/main/ipc.js
Normal file
2
src/main/ipc.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
//IPC STUFF
|
||||||
|
|
||||||
48
src/ui/app-divider.riot
Normal file
48
src/ui/app-divider.riot
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<app-divider>
|
||||||
|
|
||||||
|
<div class="divider"><span></span><span>{props.label}</span><span></span></div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.divider { /* minor cosmetics */
|
||||||
|
display: table;
|
||||||
|
font-size: 24px;
|
||||||
|
text-align: center;
|
||||||
|
width: 75%; /* divider width */
|
||||||
|
margin: 40px auto; /* spacing above/below */
|
||||||
|
}
|
||||||
|
.divider span { display: table-cell; position: relative; }
|
||||||
|
.divider span:first-child, .divider span:last-child {
|
||||||
|
width: 50%;
|
||||||
|
top: 13px; /* adjust vertical align */
|
||||||
|
-moz-background-size: 100% 2px; /* line width */
|
||||||
|
background-size: 100% 2px; /* line width */
|
||||||
|
background-position: 0 0, 0 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
.divider span:first-child { /* color changes in here */
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(transparent), to(#000));
|
||||||
|
background-image: -webkit-linear-gradient(180deg, transparent, #000);
|
||||||
|
background-image: -moz-linear-gradient(180deg, transparent, #000);
|
||||||
|
background-image: -o-linear-gradient(180deg, transparent, #000);
|
||||||
|
background-image: linear-gradient(90deg, transparent, #000);
|
||||||
|
}
|
||||||
|
.divider span:nth-child(2) {
|
||||||
|
color: #000; padding: 0px 5px; width: auto; white-space: nowrap;
|
||||||
|
}
|
||||||
|
.divider span:last-child { /* color changes in here */
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#000), to(transparent));
|
||||||
|
background-image: -webkit-linear-gradient(180deg, #000, transparent);
|
||||||
|
background-image: -moz-linear-gradient(180deg, #000, transparent);
|
||||||
|
background-image: -o-linear-gradient(180deg, #000, transparent);
|
||||||
|
background-image: linear-gradient(90deg, #000, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</app-divider>
|
||||||
@ -1,3 +1,28 @@
|
|||||||
<app>
|
<app>
|
||||||
|
<timestamp />
|
||||||
|
|
||||||
|
<timechain-input />
|
||||||
|
|
||||||
|
<app-divider label="LIFO" />
|
||||||
|
|
||||||
|
<timechain-list />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import Timestamp from './timestamp.riot'
|
||||||
|
import TimechainInput from './timechain-input.riot'
|
||||||
|
import TimechainList from './timechain-list.riot'
|
||||||
|
import AppDivider from './app-divider.riot'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Timestamp,
|
||||||
|
TimechainInput,
|
||||||
|
TimechainList,
|
||||||
|
AppDivider
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
</app>
|
</app>
|
||||||
43
src/ui/timechain-input-buttons.riot
Normal file
43
src/ui/timechain-input-buttons.riot
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<timechain-input-buttons>
|
||||||
|
|
||||||
|
<div class="timechain-intput-buttons">
|
||||||
|
<button onclick="{onCancel}" class="cancel">cancel</button>
|
||||||
|
<button onclick="{onSave}" class="save">save</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.timechain-intput-buttons .cancel {
|
||||||
|
background-color: #ecaec0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timechain-intput-buttons .save {
|
||||||
|
background-color: #aeecda;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
onMounted(){
|
||||||
|
this.sendOnSave = this.props.onsave;
|
||||||
|
this.sendOnCancel = this.props.oncancel;
|
||||||
|
},
|
||||||
|
onCancel(e){
|
||||||
|
if(this.sendOnCancel){
|
||||||
|
this.sendOnCancel(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSave(e){
|
||||||
|
if(this.sendOnSave){
|
||||||
|
this.sendOnSave(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</timechain-input-buttons>
|
||||||
@ -0,0 +1,136 @@
|
|||||||
|
<timechain-input>
|
||||||
|
|
||||||
|
<div class="timechain-input-tempate" if={state.show_tagging}>
|
||||||
|
<timechain-tag if={state.show_tagging} onchange="{onTags}"/>
|
||||||
|
<timechain-input-buttons if={state.show_tagging} onsave="{onSave}" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="pasteme" ondblclick="{onSwap}">
|
||||||
|
<p>{state.message}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.paste-html {
|
||||||
|
background: white !important;
|
||||||
|
color: black !important;
|
||||||
|
text-align: left !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timechain-input-tempate {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: 0 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timechain-input-tempate timechain-tag {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timechain-input-tempate button {
|
||||||
|
height: 3em;
|
||||||
|
line-height: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
const pubsub = require('pubsub-js');
|
||||||
|
const empty = require('empty-lite');
|
||||||
|
import sanitizeHtml from 'sanitize-html';
|
||||||
|
import TimechainTag from './timechain-tag.riot'
|
||||||
|
import TimechainInputButtons from './timechain-input-buttons.riot';
|
||||||
|
|
||||||
|
const {TimeChainDataSqliteRecord} = require('../data/sqlite-client');
|
||||||
|
|
||||||
|
export default {
|
||||||
|
state: {
|
||||||
|
message:"Paste something in this window.",
|
||||||
|
show_tagging: false
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
TimechainTag,
|
||||||
|
TimechainInputButtons
|
||||||
|
},
|
||||||
|
onMounted(){
|
||||||
|
document.addEventListener('paste', this.pasteEvent.bind(this));
|
||||||
|
},
|
||||||
|
pasteEvent(e){
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
console.log("Bla");
|
||||||
|
console.log(e.clipboardData.items[0]);
|
||||||
|
console.log(e.clipboardData.items[1]);
|
||||||
|
|
||||||
|
if (e.clipboardData.types.indexOf('text/html') > -1) {
|
||||||
|
const newData = e.clipboardData.getData('text/html');
|
||||||
|
const newDataText = e.clipboardData.getData('text/plain');
|
||||||
|
const el = this.$('#pasteme');
|
||||||
|
pubsub.publish('timestamp-puase',true);
|
||||||
|
this.timestamp = Math.floor(new Date().getTime());
|
||||||
|
pubsub.publish('timestamp-settime',this.timestamp);
|
||||||
|
el.innerHTML = this.content = newData;
|
||||||
|
this.content_text = e.clipboardData.getData('text/plain');
|
||||||
|
this.content_mime = 'text/html';
|
||||||
|
el.classList.add('paste-html');
|
||||||
|
|
||||||
|
this.content_type = "html";
|
||||||
|
this.content_swap = 0;
|
||||||
|
this.content_orig = this.content;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!empty(this.content)){
|
||||||
|
this.update({show_tagging:true});
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
onSwap(){
|
||||||
|
console.log("Here we can swap to text");
|
||||||
|
|
||||||
|
if(this.content_type=='html'){
|
||||||
|
const el = this.$('#pasteme');
|
||||||
|
if(this.content_swap==0){
|
||||||
|
this.content_mime = "text/plain";
|
||||||
|
this.content = this.content_text;
|
||||||
|
el.innerText = this.content;
|
||||||
|
this.content_swap = 1;
|
||||||
|
}else if(this.content_swap==1){
|
||||||
|
this.content_mime = "text/html";
|
||||||
|
this.content = sanitizeHtml(this.content_orig);
|
||||||
|
el.innerHTML = this.content;
|
||||||
|
this.content_swap = 2;
|
||||||
|
}else{
|
||||||
|
this.content_mime = "text/html";
|
||||||
|
const temp = this.content;
|
||||||
|
this.content = this.content_orig;
|
||||||
|
this.content_swap = 0;
|
||||||
|
el.innerHTML = this.content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.getSelection().empty) { // Chrome
|
||||||
|
window.getSelection().empty();
|
||||||
|
} else if (window.getSelection().removeAllRanges) { // Firefox
|
||||||
|
window.getSelection().removeAllRanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
onTags(tags){
|
||||||
|
console.log(tags);
|
||||||
|
this.tags = tags;
|
||||||
|
},
|
||||||
|
onSave(){
|
||||||
|
console.log("Save button pressed");
|
||||||
|
const TR = new TimeChainDataSqliteRecord();
|
||||||
|
|
||||||
|
TR.add("iueyriweusdfsd8w",Math.floor(new Date().getTime()),this.content,this.content_mime,"Comming SOon").then(res=>{
|
||||||
|
console.log(res);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</timechain-input>
|
||||||
12
src/ui/timechain-list.riot
Normal file
12
src/ui/timechain-list.riot
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<timechain-list>
|
||||||
|
|
||||||
|
<div class="timechain-list-title">
|
||||||
|
List of shit
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timechain-list">
|
||||||
|
bla bla
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</timechain-list>
|
||||||
33
src/ui/timechain-tag.riot
Normal file
33
src/ui/timechain-tag.riot
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<timechain-tag>
|
||||||
|
<div class="timechain-tagging">
|
||||||
|
<input id="tagging" placeholder="tag your paste">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.tagify--focus {
|
||||||
|
border-color: yellow !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tagify--empty .tagify__input::before {
|
||||||
|
color: whitesmoke !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Tagify from '@yaireo/tagify'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
onMounted(){
|
||||||
|
const inputElm = this.$('#tagging');
|
||||||
|
this.tagify = new Tagify(inputElm);
|
||||||
|
inputElm.addEventListener('change', this.onChange.bind(this));
|
||||||
|
},
|
||||||
|
onChange(e){
|
||||||
|
this.props.onchange(e.target.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</timechain-tag>
|
||||||
@ -1,8 +1,10 @@
|
|||||||
<timestamp>
|
<timestamp>
|
||||||
|
|
||||||
<div class="timestamp">
|
<div class="timestamp">
|
||||||
<div class="timestamp-icon">
|
<div class="timestamp-text">
|
||||||
<div class="timestamp-text">{ state.time_text }</div>
|
<img src="src/img/clock1-white.svg" align="absmiddle" style="width:1em;margin-right:0.3em;">
|
||||||
|
{ state.time_text }
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -12,14 +14,23 @@
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
state: {
|
state: {
|
||||||
time_text: "",
|
time_text: "Comming Soon",
|
||||||
format: "long"
|
format: "long"
|
||||||
},
|
},
|
||||||
onMounted(){
|
onMounted(){
|
||||||
this.start();
|
this.start();
|
||||||
|
|
||||||
|
pubsub.subscribe("timestamp-puase", (event)=>{
|
||||||
|
clearTimeout(this.event_handle);
|
||||||
|
this.$('.timestamp-text').classList.add('timestamp-puase');
|
||||||
|
});
|
||||||
|
|
||||||
|
pubsub.subscribe("timestamp-settime",(event,arg)=>{
|
||||||
|
this.update({time_text:dayjs(new Date(arg)).format("MMMM D, YYYY h:mm:ss A")});
|
||||||
|
})
|
||||||
},
|
},
|
||||||
start(){
|
start(){
|
||||||
setTimeout(()=>{
|
this.event_handle = setTimeout(()=>{
|
||||||
this.makeString();
|
this.makeString();
|
||||||
this.start();
|
this.start();
|
||||||
},200);
|
},200);
|
||||||
|
|||||||
10
start.js
10
start.js
@ -1,7 +1,11 @@
|
|||||||
import Timestamp from './src/ui/timestamp.riot'
|
import App from './src/ui/app.riot'
|
||||||
|
|
||||||
import { component } from 'riot'
|
import { component } from 'riot'
|
||||||
|
|
||||||
|
|
||||||
component(Timestamp)(document.getElementById('timestamp'))
|
setTimeout(()=>{
|
||||||
|
document.getElementById('main-loading').remove();
|
||||||
|
component(App)(document.getElementById('timechain'));
|
||||||
|
},0)
|
||||||
|
|
||||||
|
|
||||||
console.log("yes!");
|
|
||||||
@ -74,4 +74,141 @@ test("Should create a record in the database and then remove it",async ()=>{
|
|||||||
return rec.delete(id);
|
return rec.delete(id);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should create a record, attach a file, and then remove it",async ()=>{
|
||||||
|
const rec = new TimeChainDataSqliteRecord();
|
||||||
|
const filerec = new TimeChainDataSqliteFile();
|
||||||
|
|
||||||
|
const record = {
|
||||||
|
id: nanoid(),
|
||||||
|
hash: "fakehash",
|
||||||
|
content: "This is a test",
|
||||||
|
mime: "text/plain",
|
||||||
|
ts: Math.floor(Date.now())
|
||||||
|
};
|
||||||
|
|
||||||
|
const attached = {
|
||||||
|
id: nanoid(),
|
||||||
|
hash: "faskhash",
|
||||||
|
ts: Math.floor(Date.now()),
|
||||||
|
content: "this is fake data that would normally be binary file data",
|
||||||
|
mime: "application/octet-stream"
|
||||||
|
}
|
||||||
|
|
||||||
|
return rec.add(record.id,record.ts,record.content,record.mime,record.hash).then(res=>{
|
||||||
|
expect(res).toEqual(1);
|
||||||
|
return rec.get(record.id).then(res=>{
|
||||||
|
expect(res.uuid).toEqual(record.id);
|
||||||
|
expect(res.timestamp).toEqual(record.ts);
|
||||||
|
expect(res.mime).toEqual(record.mime);
|
||||||
|
expect(res.content).toEqual(record.content);
|
||||||
|
expect(res.hash).toEqual(record.hash);
|
||||||
|
|
||||||
|
return filerec.add(record.id,attached.id,attached.ts,attached.content,attached.mime,attached.hash).then(res=>{
|
||||||
|
expect(res).toEqual(1);
|
||||||
|
|
||||||
|
return filerec.get(attached.id).then(afile=>{
|
||||||
|
expect(afile.uuid).toEqual(attached.id);
|
||||||
|
expect(afile.hash).toEqual(attached.hash);
|
||||||
|
expect(afile.timestamp).toEqual(attached.ts);
|
||||||
|
expect(afile.content).toEqual(attached.content);
|
||||||
|
expect(afile.mime).toEqual(attached.mime);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
}).then(()=>{
|
||||||
|
return rec.delete(record.id).then(res=>{
|
||||||
|
expect(res).toEqual(1);
|
||||||
|
})
|
||||||
|
}).then(()=>{
|
||||||
|
return filerec.delete(attached.id).then(res=>{
|
||||||
|
expect(res).toEqual(1);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should add, check that it exist, remove tags to tag table', async ()=>{
|
||||||
|
const tags = new TimeChainDataSqliteTag();
|
||||||
|
const tag = "test";
|
||||||
|
|
||||||
|
return tags.add(tag).then(res=>{
|
||||||
|
expect(res).toEqual(1);
|
||||||
|
return tags.get(tag).then(res=>{
|
||||||
|
expect(res).not.toBeNull();
|
||||||
|
expect(res.create_at).not.toBeNull();
|
||||||
|
expect(res.tag).toEqual(tag);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(()=>{
|
||||||
|
return tags.has(tag).then(res=>{
|
||||||
|
expect(res).toBe(true);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(()=>{
|
||||||
|
return tags.delete(tag).then(res=>{
|
||||||
|
expect(res).toEqual(1);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should create a record and tag the record", async ()=>{
|
||||||
|
const records = new TimeChainDataSqliteRecord();
|
||||||
|
const tags = new TimeChainDataSqliteTag();
|
||||||
|
const links = new TimeChainDataSqliteTagLink();
|
||||||
|
|
||||||
|
const rec = {
|
||||||
|
id: nanoid(),
|
||||||
|
hash: "fakehash",
|
||||||
|
content: "This is a test",
|
||||||
|
mime: "text/plain",
|
||||||
|
ts: Math.floor(Date.now())
|
||||||
|
};
|
||||||
|
|
||||||
|
const tag = "testing";
|
||||||
|
|
||||||
|
return records.add(rec.id,rec.ts,rec.content,rec.mime,rec.hash).then(res=>{
|
||||||
|
expect(res).toBe(1);
|
||||||
|
}).then(()=>{
|
||||||
|
return tags.add(tag).then(res=>{
|
||||||
|
expect(res).toBe(1);
|
||||||
|
});
|
||||||
|
}).then(()=>{
|
||||||
|
return links.add(rec.id,tag).then(res=>{
|
||||||
|
expect(res).toBe(1);
|
||||||
|
});
|
||||||
|
}).then(()=>{
|
||||||
|
return records.get(rec.id).then(res=>{
|
||||||
|
expect(res).not.toBeNull();
|
||||||
|
expect(res.uuid).toBe(rec.id);
|
||||||
|
});
|
||||||
|
}).then(()=>{
|
||||||
|
return links.getRecords(tag).then(res=>{
|
||||||
|
expect(res).not.toBeNull();
|
||||||
|
expect(res.length).toBeTruthy();
|
||||||
|
expect(res[0].uuid).toBe(rec.id);
|
||||||
|
});
|
||||||
|
}).then(()=>{
|
||||||
|
return links.getTags(rec.id).then(res=>{
|
||||||
|
expect(res).not.toBeNull();
|
||||||
|
expect(res.length).toBeTruthy();
|
||||||
|
expect(res[0].tag).toBe(tag);
|
||||||
|
});
|
||||||
|
}).then(()=>{
|
||||||
|
return links.deleteRecord(rec.id).then(res=>{
|
||||||
|
expect(res).toBe(1);
|
||||||
|
})
|
||||||
|
}).then(()=>{
|
||||||
|
return tags.delete(tag).then(res=>{
|
||||||
|
expect(res).toBe(1);
|
||||||
|
})
|
||||||
|
}).then(()=>{
|
||||||
|
return records.delete(rec.id).then(res=>{
|
||||||
|
expect(res).toBe(1);
|
||||||
|
})
|
||||||
|
});
|
||||||
})
|
})
|
||||||
BIN
test/test.db
BIN
test/test.db
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user