mirror of
https://github.com/slynn1324/tinypin
synced 2025-11-03 11:57:25 +00:00
almost done
This commit is contained in:
26
args.js
Normal file
26
args.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const yargs = require('yargs');
|
||||
|
||||
const argv = yargs
|
||||
.option('slow', {
|
||||
alias: 's',
|
||||
description: 'delay each request this many milliseconds for testing',
|
||||
type: 'number'
|
||||
})
|
||||
.option('image-path', {
|
||||
alias: 'i',
|
||||
description: 'base path to store images',
|
||||
type: 'string',
|
||||
default: './images'
|
||||
})
|
||||
.option('port', {
|
||||
alias: 'p',
|
||||
description: 'http server port',
|
||||
type: 'number',
|
||||
default: 3000
|
||||
})
|
||||
.help().alias('help', 'h')
|
||||
.argv;
|
||||
|
||||
|
||||
|
||||
console.log(argv);
|
||||
@@ -4,14 +4,24 @@
|
||||
function getClickHandler() {
|
||||
return function(info, tab) {
|
||||
|
||||
if ( !info.srcUrl.startsWith('http') ){
|
||||
window.alert("Image source is not a URL.");
|
||||
return;
|
||||
}
|
||||
|
||||
var w = 700;
|
||||
var h = 800;
|
||||
var left = (screen.width/2)-(w/2);
|
||||
var top = (screen.height/2)-(h/2);
|
||||
|
||||
var q = "i=" + encodeURIComponent(info.srcUrl) + "&s=" + encodeURIComponent(tab.url);
|
||||
|
||||
// The srcUrl property is only available for image elements.
|
||||
var url = 'http://localhost:3000/popup.html#' + q;
|
||||
var url = 'http://localhost:3000/addpin.html#' + q;
|
||||
|
||||
// Create a new window to the info page.
|
||||
// chrome.windows.create({ url: url, width: 520, height: 660 });
|
||||
chrome.windows.create({ url: url, width: 500, height: 500, type: 'popup' });
|
||||
chrome.windows.create({ url: url, width: w, height: h, left: left, top: top, type: 'popup' });
|
||||
};
|
||||
};
|
||||
|
||||
@@ -19,7 +29,7 @@ function getClickHandler() {
|
||||
* Create a context menu which will only show up for images.
|
||||
*/
|
||||
chrome.contextMenus.create({
|
||||
"title" : "Get image info",
|
||||
"title" : "add to tinypin",
|
||||
"type" : "normal",
|
||||
"contexts" : ["image"],
|
||||
"onclick" : getClickHandler()
|
||||
|
||||
BIN
chrome-extension/icon128.png
Normal file
BIN
chrome-extension/icon128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
chrome-extension/icon16.png
Normal file
BIN
chrome-extension/icon16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 224 B |
BIN
chrome-extension/icon32.png
Normal file
BIN
chrome-extension/icon32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 329 B |
BIN
chrome-extension/icon48.png
Normal file
BIN
chrome-extension/icon48.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 536 B |
@@ -1,10 +1,16 @@
|
||||
{
|
||||
"name": "TinyPin Plugin",
|
||||
"name": "add to tinypin",
|
||||
"version": "1.0",
|
||||
"description": "TinyPin context plugin",
|
||||
"description": "add to tinypin context menu plugin",
|
||||
"manifest_version": 2,
|
||||
"background" : { "scripts": ["background.js"] },
|
||||
"permissions" : [
|
||||
"contextMenus"
|
||||
]
|
||||
],
|
||||
"icons": {
|
||||
"16" : "icon16.png",
|
||||
"32" : "icon32.png",
|
||||
"48" : "icon48.png",
|
||||
"128" : "icon128.png"
|
||||
}
|
||||
}
|
||||
418
package-lock.json
generated
418
package-lock.json
generated
@@ -12,7 +12,8 @@
|
||||
"body-parser": "^1.19.0",
|
||||
"express": "^4.17.1",
|
||||
"node-fetch": "^2.6.1",
|
||||
"sharp": "^0.27.0"
|
||||
"sharp": "^0.27.0",
|
||||
"yargs": "^16.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
@@ -35,6 +36,36 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles/node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles/node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"node_modules/aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
@@ -300,6 +331,56 @@
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/string-width": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
|
||||
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
@@ -445,6 +526,11 @@
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
@@ -461,6 +547,14 @@
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
@@ -585,6 +679,14 @@
|
||||
"wide-align": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
},
|
||||
"node_modules/github-from-package": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
|
||||
@@ -1022,6 +1124,14 @@
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
@@ -1338,15 +1448,144 @@
|
||||
"string-width": "^1.0.2 || 2"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi/node_modules/ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi/node_modules/string-width": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
|
||||
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi/node_modules/strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
|
||||
"integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"dependencies": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^20.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "20.2.4",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
|
||||
"integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/string-width": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
|
||||
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -1364,6 +1603,29 @@
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
@@ -1559,6 +1821,46 @@
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
|
||||
},
|
||||
"cliui": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
|
||||
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
@@ -1674,6 +1976,11 @@
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
@@ -1687,6 +1994,11 @@
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"escalade": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
|
||||
},
|
||||
"escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
@@ -1795,6 +2107,11 @@
|
||||
"wide-align": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
|
||||
},
|
||||
"github-from-package": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
|
||||
@@ -2134,6 +2451,11 @@
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
@@ -2371,15 +2693,109 @@
|
||||
"string-width": "^1.0.2 || 2"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
|
||||
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
|
||||
"integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg=="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"requires": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^20.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
|
||||
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "20.2.4",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
|
||||
"integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"body-parser": "^1.19.0",
|
||||
"express": "^4.17.1",
|
||||
"node-fetch": "^2.6.1",
|
||||
"sharp": "^0.27.0"
|
||||
"sharp": "^0.27.0",
|
||||
"yargs": "^16.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
87
server.js
87
server.js
@@ -1,31 +1,78 @@
|
||||
const yargs = require('yargs');
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const db = require('better-sqlite3')('data.db') //, {verbose:console.log});
|
||||
const betterSqlite3 = require('better-sqlite3');
|
||||
// const db = require('better-sqlite3') //, {verbose:console.log});
|
||||
const http = require('http');
|
||||
const https = require('https');
|
||||
const sharp = require('sharp');
|
||||
const fs = require('fs').promises;
|
||||
const path = require('path');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
const IMAGE_PATH = "./images";
|
||||
|
||||
const argv = yargs
|
||||
.option('slow', {
|
||||
alias: 's',
|
||||
description: 'delay each request this many milliseconds for testing',
|
||||
type: 'number'
|
||||
})
|
||||
.option('image-path', {
|
||||
alias: 'i',
|
||||
description: 'base path to store images',
|
||||
type: 'string',
|
||||
default: './images'
|
||||
})
|
||||
.option('db-path', {
|
||||
alias: 'd',
|
||||
description: 'path to sqlite database file',
|
||||
type: 'string',
|
||||
default: 'tinypin.db'
|
||||
})
|
||||
.option('port', {
|
||||
alias: 'p',
|
||||
description: 'http server port',
|
||||
type: 'number',
|
||||
default: 3000
|
||||
})
|
||||
.help().alias('help', 'h')
|
||||
.argv;
|
||||
|
||||
|
||||
const DB_PATH = path.resolve(argv['db-path']);
|
||||
const IMAGE_PATH = path.resolve(argv['image-path']);
|
||||
const PORT = argv.port;
|
||||
|
||||
console.log('tinypin starting...');
|
||||
console.log('');
|
||||
console.log('configuration:');
|
||||
console.log(` port: ${PORT}`);
|
||||
console.log(` database path: ${DB_PATH}`);
|
||||
console.log(` image path: ${IMAGE_PATH}`)
|
||||
if ( argv.slow ){
|
||||
console.log(` slow mode delay: ${argv.slow}`);
|
||||
}
|
||||
console.log('');
|
||||
|
||||
|
||||
const db = betterSqlite3(DB_PATH);
|
||||
// express config
|
||||
const app = express();
|
||||
const port = 3000;
|
||||
app.use(express.static('static'));
|
||||
app.use(express.static('images'));
|
||||
app.use(bodyParser.urlencoded({ extended: false }))
|
||||
app.use(bodyParser.json());
|
||||
app.set('json spaces', 2);
|
||||
|
||||
// emulate slow down
|
||||
// app.use( (req,res,next) => {
|
||||
// console.log("slow...");
|
||||
// setTimeout(() => {
|
||||
// next();
|
||||
// }, 2000);
|
||||
// });
|
||||
//emulate slow down
|
||||
if ( argv.slow ){
|
||||
app.use( (req,res,next) => {
|
||||
console.log("slow...");
|
||||
setTimeout(() => {
|
||||
next();
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
const OK = {status: "ok"};
|
||||
const NOT_FOUND = {status: "error", error: "not found"};
|
||||
@@ -59,7 +106,6 @@ app.get("/api/boards", async (req, res) => {
|
||||
app.get("/api/boards/:boardId", async (req, res) => {
|
||||
try{
|
||||
|
||||
|
||||
let board = db.prepare("SELECT * FROM boards WHERE id = ?").get(req.params.boardId);
|
||||
if ( board ){
|
||||
|
||||
@@ -264,12 +310,15 @@ app.delete("/api/pins/:pinId", async (req, res) => {
|
||||
|
||||
|
||||
// start listening
|
||||
app.listen(port, () => {
|
||||
console.log(`tinypin is running at http://localhost:${port}`)
|
||||
app.listen(PORT, () => {
|
||||
console.log(`tinypin is running at http://localhost:${PORT}`);
|
||||
console.log('');
|
||||
});
|
||||
|
||||
function initDb(){
|
||||
|
||||
console.log("initializing database...");
|
||||
|
||||
db.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS migrations (
|
||||
id INTEGER PRIMARY KEY,
|
||||
@@ -281,7 +330,7 @@ function initDb(){
|
||||
|
||||
if ( !schemaVersion || schemaVersion < 1 ){
|
||||
|
||||
console.log("Running migration to version 1");
|
||||
console.log(" running migration v1");
|
||||
|
||||
db.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS boards (
|
||||
@@ -308,16 +357,14 @@ function initDb(){
|
||||
)
|
||||
`).run();
|
||||
|
||||
db.prepare(`
|
||||
INSERT INTO boards (id, name, createDate) VALUES (0, 'Default Board', ?)
|
||||
`).run(new Date().toISOString());
|
||||
|
||||
db.prepare("INSERT INTO migrations (id, createDate) VALUES ( @id, @createDate )").run({id:1, createDate: new Date().toISOString()});
|
||||
|
||||
} else {
|
||||
console.log("Database schema v" + schemaVersion + " is up to date.");
|
||||
schemaVersion = 1;
|
||||
}
|
||||
|
||||
console.log(`database ready - schema version v${schemaVersion}`);
|
||||
console.log('');
|
||||
|
||||
}
|
||||
|
||||
async function downloadImage(imageUrl){
|
||||
|
||||
0
static/addpin-app.js
Normal file
0
static/addpin-app.js
Normal file
351
static/addpin.html
Normal file
351
static/addpin.html
Normal file
@@ -0,0 +1,351 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>tinypin</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png">
|
||||
<link rel="manifest" href="icons/site.webmanifest">
|
||||
<link rel="mask-icon" href="icons/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<link rel="shortcut icon" href="icons/favicon.ico">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="msapplication-config" content="icons/browserconfig.xml">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="stylesheet" href="bulma-custom.css" />
|
||||
<!--<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css" />-->
|
||||
<link rel="stylesheet" href="client.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
<!-- <script src="pulltorefresh.js"></script> -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/reefjs/dist/reef.min.js"></script>
|
||||
|
||||
|
||||
<script src="reef-bootstrap.js"></script>
|
||||
<script src="reef-databind.js"></script>
|
||||
|
||||
|
||||
<!-- <script src="utils.js"></script> -->
|
||||
|
||||
<!-- <script src="client.js"></script> -->
|
||||
<!-- <script src="components/addpin.js"></script>
|
||||
<script src="addpin-app.js"></script> -->
|
||||
|
||||
<script>
|
||||
Reef.debug(true);
|
||||
|
||||
app.addSetter("render", (data) => {
|
||||
appComponent.render();
|
||||
});
|
||||
|
||||
app.addSetter("loader.show", (data) => {
|
||||
data.loading++;
|
||||
});
|
||||
|
||||
app.addSetter("loader.hide", (data) => {
|
||||
data.loading--;
|
||||
});
|
||||
|
||||
app.addSetter("hash.parse", (data) => {
|
||||
|
||||
let qs = window.location.hash.substr(1);
|
||||
|
||||
let obj = {};
|
||||
let parts = qs.split("&");
|
||||
for ( let i = 0; i < parts.length; ++i ){
|
||||
let kv = parts[i].split("=");
|
||||
if ( kv.length == 2 ){
|
||||
let key = decodeURIComponent(kv[0]);
|
||||
let value = decodeURIComponent(kv[1]);
|
||||
obj[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
data.hash = obj;
|
||||
|
||||
if ( data.hash.i ){
|
||||
data.addPinModal.imageUrl = data.hash.i;
|
||||
data.addPinModal.previewImageUrl = data.hash.i;
|
||||
data.addPinModal.siteUrl = data.hash.s;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
app.addSetter("load.boards", async (data) => {
|
||||
|
||||
store.do("loader.show");
|
||||
|
||||
let res = await fetch("/api/boards");
|
||||
data.boards = await res.json();
|
||||
|
||||
data.initialized = true;
|
||||
|
||||
data.addPinModal.boardId = data.boards[0].id;
|
||||
|
||||
store.do("loader.hide");
|
||||
});
|
||||
|
||||
app.addSetter('addPinModal.updatePreview', (data) => {
|
||||
console.log("update preview");
|
||||
if ( data.addPinModal.imageUrl.startsWith("http") ){
|
||||
( async() => {
|
||||
let res = await fetch(data.addPinModal.imageUrl, {
|
||||
mode: 'no-cors',
|
||||
method: "HEAD"
|
||||
});
|
||||
if ( res.status = 200 ){
|
||||
data.addPinModal.previewImageUrl = data.addPinModal.imageUrl;
|
||||
}
|
||||
store.do("render");
|
||||
})();
|
||||
} else {
|
||||
data.addPinModal.previewImageUrl = null;
|
||||
}
|
||||
});
|
||||
|
||||
app.addGetter('addPinModal.isValid', (data) => {
|
||||
|
||||
if ( data.addPinModal.boardId == "new"){
|
||||
if ( !data.addPinModal.newBoardName ){
|
||||
return false;
|
||||
} else if ( data.addPinModal.newBoardName.trim().length < 1 ){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !data.addPinModal.previewImageUrl ){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
app.addSetter('addPinModal.save', async (data) => {
|
||||
|
||||
data.addPinModal.saveInProgress = true;
|
||||
|
||||
let boardId = data.addPinModal.boardId;
|
||||
|
||||
let newBoard = null;
|
||||
|
||||
if ( boardId == "new" ){
|
||||
let res = await fetch('api/boards', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
"name": data.addPinModal.newBoardName
|
||||
})
|
||||
});
|
||||
|
||||
if ( res.status == 200 ){
|
||||
newBoard = await res.json();
|
||||
boardId = newBoard.id;
|
||||
data.boards.push(newBoard);
|
||||
}
|
||||
}
|
||||
|
||||
let postData = {
|
||||
boardId: boardId,
|
||||
imageUrl: data.addPinModal.imageUrl,
|
||||
siteUrl: data.addPinModal.siteUrl,
|
||||
description: data.addPinModal.description
|
||||
};
|
||||
|
||||
let res = await fetch('api/pins', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': "application/json"
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
});
|
||||
|
||||
if ( res.status == 200 ){
|
||||
window.close();
|
||||
}
|
||||
|
||||
store.do("render");
|
||||
|
||||
});
|
||||
|
||||
|
||||
const store = new Reef.Store({
|
||||
data: {
|
||||
loading: 0,
|
||||
hash: null,
|
||||
boards: [],
|
||||
addPinModal: {
|
||||
pinId: null,
|
||||
active: false,
|
||||
boardId: "",
|
||||
newBoardName: null,
|
||||
imageUrl: "",
|
||||
previewImageUrl: null,
|
||||
siteUrl: "",
|
||||
description: "",
|
||||
saveInProgress: false
|
||||
},
|
||||
initialized: false
|
||||
},
|
||||
getters: app.getGetters(),
|
||||
setters: app.getSetters()
|
||||
});
|
||||
|
||||
app.freeze();
|
||||
|
||||
const appComponent = new Reef("#app", {
|
||||
store: store,
|
||||
template: (data) => {
|
||||
|
||||
if ( !data.initialized ){
|
||||
return `<div style="margin-top: 20px; margin-left: auto; margin-right: auto;">
|
||||
<div id="loader" class="button is-text is-loading"></div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
let imagePlaceholder = 'data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22300%22%20height%3D%22300%22%3E%3Crect%20x%3D%222%22%20y%3D%222%22%20width%3D%22300%22%20height%3D%22300%22%20style%3D%22fill%3A%23dedede%3B%22%2F%3E%3Ctext%20x%3D%2250%25%22%20y%3D%2250%25%22%20font-size%3D%2218%22%20text-anchor%3D%22middle%22%20alignment-baseline%3D%22middle%22%20font-family%3D%22monospace%2C%20sans-serif%22%20fill%3D%22%23555555%22%3Eimage%3C%2Ftext%3E%3C%2Fsvg%3E';
|
||||
|
||||
let options = "";
|
||||
for ( let i = 0; i < data.boards.length; ++i ){
|
||||
options += `<option value="${data.boards[i].id}">${data.boards[i].name}</option>`;
|
||||
}
|
||||
|
||||
let newBoardField = '';
|
||||
if ( data.addPinModal.boardId == "new" ){
|
||||
newBoardField = /*html*/`
|
||||
<div class="field">
|
||||
<label class="label">Board Name</label>
|
||||
<div class="control">
|
||||
<input class="input" type="text" data-bind="addPinModal.newBoardName" />
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
return /*html*/`
|
||||
<div id="addPinModal">
|
||||
<div class="modal is-active">
|
||||
<div class="modal-background"></div>
|
||||
<div class="modal-card">
|
||||
<header class="modal-card-head">
|
||||
<p class="modal-card-title">Add Pin</p>
|
||||
<div id="loader" class="button is-text ${data.loading ? 'is-loading' : ''}"></div>
|
||||
</header>
|
||||
<section class="modal-card-body">
|
||||
<div class="add-pin-flex">
|
||||
<div class="add-pin-flex-left">
|
||||
<img id="add-pin-modal-img" src="${data.addPinModal.previewImageUrl ? data.addPinModal.previewImageUrl : imagePlaceholder}" />
|
||||
</div>
|
||||
<div class="add-pin-flex-right">
|
||||
<form>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Board</label>
|
||||
<div class="select">
|
||||
<select data-bind="addPinModal.boardId">
|
||||
${options}
|
||||
<option value="new">Create New Board</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${newBoardField}
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Image Url</label>
|
||||
<div class="control">
|
||||
<input class="input" type="text" data-bind="addPinModal.imageUrl" data-onblur="addPinModal.updatePreview" ${data.hash.i ? 'disabled' : ''}/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Website Url</label>
|
||||
<div class="control">
|
||||
<input class="input" type="text" data-bind="addPinModal.siteUrl" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Description</label>
|
||||
<div class="control">
|
||||
<textarea class="textarea" data-bind="addPinModal.description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<footer class="modal-card-foot">
|
||||
<button class="button is-success ${data.addPinModal.saveInProgress ? 'is-loading' : ''}" ${!store.get('addPinModal.isValid') || data.addPinModal.saveInProgress ? 'disabled' : ''} data-onclick="addPinModal.save">Add Pin</button>
|
||||
<button class="button is-light" ${data.addPinModal.saveInProgress ? 'disabled' : '' } onclick="window.close()">Cancel</button>
|
||||
</footer>
|
||||
</div>
|
||||
</div></div>`;
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// attach all the child components
|
||||
for (const [name, f] of Object.entries(app.getComponents())) {
|
||||
let c = f(store);
|
||||
if ( !c ){
|
||||
throw(new Error(`component ${name} did not return a Reef component`));
|
||||
} else {
|
||||
appComponent.attach(c);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('click', (el) => {
|
||||
|
||||
let target = el.target.closest('[data-onclick]');
|
||||
if (target) {
|
||||
let action = target.getAttribute('data-onclick');
|
||||
if (action) {
|
||||
try{
|
||||
store.do(action, target);
|
||||
} catch (err){
|
||||
console.error(`Error invoking ${action}:`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// focusout bubbles while 'blur' does not.
|
||||
document.addEventListener('focusout', (el) => {
|
||||
let target = el.target.closest('[data-onblur]');
|
||||
if ( target ){
|
||||
let method = target.getAttribute('data-onblur');
|
||||
if ( method ) {
|
||||
store.do(method, target);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
store.do('hash.parse');
|
||||
|
||||
store.do('load.boards');
|
||||
|
||||
Reef.databind(appComponent);
|
||||
appComponent.render();
|
||||
|
||||
function parseHash(){
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
BIN
tinypin-icon.psd
Normal file
BIN
tinypin-icon.psd
Normal file
Binary file not shown.
Reference in New Issue
Block a user