diff --git a/.gitignore b/.gitignore index f69b05c3..36aa96e3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /release # compiled output +/release /dist /dist-server /tmp diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..19239df3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,47 @@ +sudo: required +dist: trusty + +language: c + +matrix: + include: + - os: osx + - os: linux + env: CC=clang CXX=clang++ npm_config_clang=1 + compiler: clang + +node_js: + - 10.9.0 + +cache: + directories: + - node_modules + +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - g++-4.8 + - icnsutils + - graphicsmagick + - libgnome-keyring-dev + - xz-utils + - xorriso + - xvfb + +install: + - nvm install 10.9.0 + - npm install electron-builder@next + - npm install + - npm rebuild node-sass + - export DISPLAY=':99.0' + - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & + +before_script: + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start & + - sleep 3 + +script: +- npm run dist \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..5e1b8a8d --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,45 @@ +os: unstable +cache: + - node_modules +environment: + GH_TOKEN: + secure: wRRBU0GXTmTBgZBs2PGSaEJWOflynAyvp3Nc/7e9xmciPfkUCQAXcpOn0jIYmzpb + matrix: + - nodejs_version: 10.9.0 +install: + - ps: Install-Product node $env:nodejs_version + - set CI=true + - npm install -g npm@latest + - set PATH=%APPDATA%\npm;%PATH% + - npm install +matrix: + fast_finish: true +build: off +version: '{build}' +shallow_clone: true +clone_depth: 1 +test_script: +- ps: >- + npm run test-nowatch + + $wc = New-Object 'System.Net.WebClient' + + Get-ChildItem . -Name -Recurse 'TESTS-*.xml' | + + Foreach-Object { + $wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $_)) + } +- npm run dist +artifacts: +- path: dist +deploy: +- provider: FTP + host: home205977321.1and1-data.host + protocol: sftp + username: u45308485-sengi + password: + secure: Sk3NZwuaYK9hTIQ3kgIIQEc8SmaPDVGvGpgsZzFEzoVLuy4WxVfvKQtegW9oXaj7 + folder: / + application: dist.zip + on: + branch: master \ No newline at end of file diff --git a/assets/icons/mac/icon.icns b/assets/icons/mac/icon.icns new file mode 100644 index 00000000..f344dcb8 Binary files /dev/null and b/assets/icons/mac/icon.icns differ diff --git a/assets/icons/png/1024x1024.png b/assets/icons/png/1024x1024.png new file mode 100644 index 00000000..28856177 Binary files /dev/null and b/assets/icons/png/1024x1024.png differ diff --git a/assets/icons/png/128x128.png b/assets/icons/png/128x128.png new file mode 100644 index 00000000..15fb413d Binary files /dev/null and b/assets/icons/png/128x128.png differ diff --git a/assets/icons/png/16x16.png b/assets/icons/png/16x16.png new file mode 100644 index 00000000..dcfb4673 Binary files /dev/null and b/assets/icons/png/16x16.png differ diff --git a/assets/icons/png/24x24.png b/assets/icons/png/24x24.png new file mode 100644 index 00000000..2b7cd90d Binary files /dev/null and b/assets/icons/png/24x24.png differ diff --git a/assets/icons/png/256x256.png b/assets/icons/png/256x256.png new file mode 100644 index 00000000..b135deed Binary files /dev/null and b/assets/icons/png/256x256.png differ diff --git a/assets/icons/png/32x32.png b/assets/icons/png/32x32.png new file mode 100644 index 00000000..dfe7e66d Binary files /dev/null and b/assets/icons/png/32x32.png differ diff --git a/assets/icons/png/48x48.png b/assets/icons/png/48x48.png new file mode 100644 index 00000000..75e400e5 Binary files /dev/null and b/assets/icons/png/48x48.png differ diff --git a/assets/icons/png/512x512.png b/assets/icons/png/512x512.png new file mode 100644 index 00000000..e3127fd1 Binary files /dev/null and b/assets/icons/png/512x512.png differ diff --git a/assets/icons/png/64x64.png b/assets/icons/png/64x64.png new file mode 100644 index 00000000..60194416 Binary files /dev/null and b/assets/icons/png/64x64.png differ diff --git a/assets/icons/png/96x96.png b/assets/icons/png/96x96.png new file mode 100644 index 00000000..49a0674a Binary files /dev/null and b/assets/icons/png/96x96.png differ diff --git a/assets/icons/win/icon.ico b/assets/icons/win/icon.ico new file mode 100644 index 00000000..8105bdc2 Binary files /dev/null and b/assets/icons/win/icon.ico differ diff --git a/main-electron.js b/main-electron.js index b216d6eb..5a633912 100644 --- a/main-electron.js +++ b/main-electron.js @@ -10,7 +10,7 @@ let win function createWindow() { // Create the browser window. - win = new BrowserWindow({ width: 393, height: 800, title: "Sengi", backgroundColor: '#FFF' }); + win = new BrowserWindow({ width: 377, height: 800, title: "Sengi", backgroundColor: '#FFF', 'useContentSize': true }); var server = http.createServer(requestHandler).listen(9527); win.loadURL('http://localhost:9527'); diff --git a/package-lock.json b/package-lock.json index 16410455..6708c459 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,12 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "7zip-bin": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-4.1.0.tgz", + "integrity": "sha512-AsnBZN3a8/JcNt+KPkGGODaA4c7l3W5+WpeKgGSbstSLxqWtTXqd1ieJGBQ8IFCtRg8DmmKUcSkIkUc0A4p3YA==", + "dev": true + }, "@angular-devkit/architect": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.4.tgz", @@ -1157,6 +1163,48 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true, + "requires": { + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "ansi-colors": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", @@ -1199,6 +1247,61 @@ "normalize-path": "^2.1.1" } }, + "app-builder-bin": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-2.6.4.tgz", + "integrity": "sha512-wC9HYqiC1XqpunT/9y2VuF90KbarnIHL90Tv8BD3TITTgbVIdRTXAsvWvmaR/ImvAX0+l5Z3jZtXjdJ7Pw3bLQ==", + "dev": true + }, + "app-builder-lib": { + "version": "20.39.0", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-20.39.0.tgz", + "integrity": "sha512-lkxGyBrQwueYb3ViqHt5WjyzVVBQqXMXc7TF+JqkuuUWp5DF7SXAYZYd+rsR3gmCbdNxw4SPIEmWmm+I9LK2gw==", + "dev": true, + "requires": { + "7zip-bin": "~4.1.0", + "app-builder-bin": "2.6.4", + "async-exit-hook": "^2.0.1", + "bluebird-lst": "^1.0.7", + "builder-util": "9.7.0", + "builder-util-runtime": "8.2.0", + "chromium-pickle-js": "^0.2.0", + "debug": "^4.1.1", + "ejs": "^2.6.1", + "electron-osx-sign": "0.4.11", + "electron-publish": "20.39.0", + "fs-extra-p": "^7.0.1", + "hosted-git-info": "^2.7.1", + "is-ci": "^2.0.0", + "isbinaryfile": "^4.0.0", + "js-yaml": "^3.12.1", + "lazy-val": "^1.0.4", + "minimatch": "^3.0.4", + "normalize-package-data": "^2.5.0", + "plist": "^3.0.1", + "read-config-file": "3.2.2", + "sanitize-filename": "^1.6.1", + "semver": "^5.6.0", + "temp-file": "^3.3.2" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "isbinaryfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.0.tgz", + "integrity": "sha512-RBtmso6l2mCaEsUvXngMTIjg3oheXo0MgYzzfT6sk44RYggPnm9fT+cQJAmzRnJIxPHXg9FZglqDJGW28dvcqA==", + "dev": true + } + } + }, "app-root-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.1.0.tgz", @@ -1421,6 +1524,12 @@ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", "dev": true }, + "async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "dev": true + }, "async-foreach": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", @@ -1760,6 +1869,15 @@ "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", "dev": true }, + "bluebird-lst": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.7.tgz", + "integrity": "sha512-5ix04IbXVIZ6nSRM4aZnwQfk40Td0D57WAl8LfhnICF6XwT4efCZYh0veOHvfDmgpbqE4ju5L5XEAMIcAe13Kw==", + "dev": true, + "requires": { + "bluebird": "^3.5.3" + } + }, "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", @@ -1820,6 +1938,60 @@ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz", "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag==" }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "dev": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2005,6 +2177,66 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, + "builder-util": { + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-9.7.0.tgz", + "integrity": "sha512-QA2RxbaSKvaFVNGcYsjmlkTn03tcdPxgIxHCOgw38G7NK91QWc76RBY9+T1sU8BLVEZJ4qNRWx+pd5rG9tTi+Q==", + "dev": true, + "requires": { + "7zip-bin": "~4.1.0", + "app-builder-bin": "2.6.4", + "bluebird-lst": "^1.0.7", + "builder-util-runtime": "^8.2.0", + "chalk": "^2.4.2", + "debug": "^4.1.1", + "fs-extra-p": "^7.0.1", + "is-ci": "^2.0.0", + "js-yaml": "^3.12.1", + "source-map-support": "^0.5.10", + "stat-mode": "^0.2.2", + "temp-file": "^3.3.2" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "builder-util-runtime": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.2.0.tgz", + "integrity": "sha512-2Q3YrxANTrDs2NjSG5mbNGLPuUhPnSNYF9w5i4jWfHcNfQ3TgRrGXq4UfnkCiZVX8Axp4eAOSscaLLScKp/XLg==", + "dev": true, + "requires": { + "bluebird-lst": "^1.0.7", + "debug": "^4.1.1", + "fs-extra-p": "^7.0.1", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + } + } + }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -2099,6 +2331,12 @@ "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", "dev": true }, + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", + "dev": true + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -2168,6 +2406,18 @@ "tslib": "^1.9.0" } }, + "chromium-pickle-js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -2224,6 +2474,12 @@ } } }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "dev": true + }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", @@ -2361,6 +2617,12 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "compare-version": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", + "integrity": "sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA=", + "dev": true + }, "compare-versions": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.4.0.tgz", @@ -2472,6 +2734,20 @@ } } }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, "connect": { "version": "3.6.6", "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", @@ -2663,6 +2939,15 @@ "elliptic": "^6.0.0" } }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, "create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -2720,6 +3005,12 @@ "randomfill": "^1.0.3" } }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, "css-parse": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", @@ -3031,6 +3322,33 @@ } } }, + "dmg-builder": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-6.6.0.tgz", + "integrity": "sha512-voodd3qdpdRiaciFZTfrFq/e82UPmUqSJq6R3Wc2Ql6XqXYLQcKo1h9rSZiivwls8PqE4Mk1IHTIOwmvJaq+MA==", + "dev": true, + "requires": { + "app-builder-lib": "~20.39.0", + "bluebird-lst": "^1.0.7", + "builder-util": "~9.7.0", + "fs-extra-p": "^7.0.1", + "iconv-lite": "^0.4.24", + "js-yaml": "^3.12.1", + "parse-color": "^1.0.0", + "sanitize-filename": "^1.6.1" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -3074,6 +3392,33 @@ "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", "dev": true }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "dotenv": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", + "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==", + "dev": true + }, + "dotenv-expand": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-4.2.0.tgz", + "integrity": "sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU=", + "dev": true + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, "duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", @@ -3133,6 +3478,12 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, + "ejs": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", + "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==", + "dev": true + }, "electron": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/electron/-/electron-4.0.6.tgz", @@ -3150,6 +3501,270 @@ } } }, + "electron-builder": { + "version": "20.39.0", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-20.39.0.tgz", + "integrity": "sha512-50SNZ/G+iE9MpTwxzeHt1Cqg8jZKeFLuJ9wubR4e/8VIzAe0ERUmwAQw+77UrlwXZD/PKKoYblc0Sr08Vm4exg==", + "dev": true, + "requires": { + "app-builder-lib": "20.39.0", + "bluebird-lst": "^1.0.7", + "builder-util": "9.7.0", + "builder-util-runtime": "8.2.0", + "chalk": "^2.4.2", + "dmg-builder": "6.6.0", + "fs-extra-p": "^7.0.1", + "is-ci": "^2.0.0", + "lazy-val": "^1.0.4", + "read-config-file": "3.2.2", + "sanitize-filename": "^1.6.1", + "update-notifier": "^2.5.0", + "yargs": "^13.2.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + } + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.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==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "yargs": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", + "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.0.0" + } + }, + "yargs-parser": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", + "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "electron-download": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-4.1.1.tgz", @@ -3166,6 +3781,60 @@ "sumchecker": "^2.0.2" } }, + "electron-osx-sign": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.11.tgz", + "integrity": "sha512-VVd40nrnVqymvFrY9ZkOYgHJOvexHHYTR3di/SN+mjJ0OWhR1I8BRVj3U+Yamw6hnkZZNKZp52rqL5EFAAPFkQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.0", + "compare-version": "^0.1.2", + "debug": "^2.6.8", + "isbinaryfile": "^3.0.2", + "minimist": "^1.2.0", + "plist": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "electron-publish": { + "version": "20.39.0", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-20.39.0.tgz", + "integrity": "sha512-PWrGUru994CSmtsA56GnjyLB3EnIS3zyEmrW0hDXtwuctZLGMnrxjK/7WEORYkgTQ/GufD5b/8T05Q2Kr42nqQ==", + "dev": true, + "requires": { + "bluebird-lst": "^1.0.7", + "builder-util": "~9.7.0", + "builder-util-runtime": "^8.2.0", + "chalk": "^2.4.2", + "fs-extra-p": "^7.0.1", + "lazy-val": "^1.0.4", + "mime": "^2.4.0" + }, + "dependencies": { + "mime": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.1.tgz", + "integrity": "sha512-VRUfmQO0rCd3hKwBymAn3kxYzBHr3I/wdVMywgG3HhXOwrCQgN84ZagpdTm2tZ4TNtwsSmyJWYO88mb5XvzGqQ==", + "dev": true + } + } + }, "electron-to-chromium": { "version": "1.3.113", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz", @@ -3187,6 +3856,12 @@ "minimalistic-crypto-utils": "^1.0.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", @@ -4175,6 +4850,29 @@ "universalify": "^0.1.0" } }, + "fs-extra-p": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-7.0.1.tgz", + "integrity": "sha512-yhd2OV0HnHt2oitlp+X9hl2ReX4X/7kQeL7/72qzPHTZj5eUPGzAKOvEglU02Fa1OeG2rSy/aKB4WGVaLiF8tw==", + "dev": true, + "requires": { + "bluebird-lst": "^1.0.7", + "fs-extra": "^7.0.1" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } + } + }, "fs-minipass": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", @@ -4898,6 +5596,15 @@ } } }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, "globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", @@ -4938,6 +5645,25 @@ "minimatch": "~3.0.2" } }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + } + }, "graceful-fs": { "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", @@ -5320,6 +6046,12 @@ "resolve-from": "^3.0.0" } }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, "import-local": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", @@ -5598,6 +6330,15 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -5695,6 +6436,22 @@ "is-extglob": "^2.1.1" } }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -5715,6 +6472,12 @@ } } }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, "is-path-cwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", @@ -5766,6 +6529,18 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "dev": true + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -6438,6 +7213,21 @@ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, + "lazy-val": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.4.tgz", + "integrity": "sha512-u93kb2fPbIrfzBuLjZE+w+fJbUUMhNDXxNmMfaqNgpfQf1CO5ZSe2LfsnBqVAk7i/2NF48OSoRj+Xe2VT+lE8Q==", + "dev": true + }, "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", @@ -6642,6 +7432,12 @@ "signal-exit": "^3.0.0" } }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -7895,6 +8691,18 @@ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + } + }, "pacote": { "version": "9.4.0", "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.4.0.tgz", @@ -8139,6 +8947,23 @@ "safe-buffer": "^5.1.1" } }, + "parse-color": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz", + "integrity": "sha1-e3SLlag/A/FqlPU15S1/PZRlhhk=", + "dev": true, + "requires": { + "color-convert": "~0.5.0" + }, + "dependencies": { + "color-convert": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", + "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=", + "dev": true + } + } + }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", @@ -8338,6 +9163,25 @@ } } }, + "plist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", + "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", + "dev": true, + "requires": { + "base64-js": "^1.2.3", + "xmlbuilder": "^9.0.7", + "xmldom": "0.1.x" + }, + "dependencies": { + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "dev": true + } + } + }, "portfinder": { "version": "1.0.20", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", @@ -8437,6 +9281,12 @@ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, "preserve": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", @@ -8820,6 +9670,34 @@ "pify": "^2.3.0" } }, + "read-config-file": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-3.2.2.tgz", + "integrity": "sha512-PuFpMgZF01VB0ydH1dfitAxCP/fh+qnfbA9cYNIPoxPbz0SMngsrafCtaHDWfER7MwlDz4fmrNBhPkakxxFpTg==", + "dev": true, + "requires": { + "ajv": "^6.9.2", + "ajv-keywords": "^3.4.0", + "bluebird-lst": "^1.0.7", + "dotenv": "^6.2.0", + "dotenv-expand": "^4.2.0", + "fs-extra-p": "^7.0.1", + "js-yaml": "^3.12.1", + "json5": "^2.1.0", + "lazy-val": "^1.0.4" + }, + "dependencies": { + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -8959,6 +9837,25 @@ "regjsparser": "^0.1.4" } }, + "registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, "regjsgen": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", @@ -9174,6 +10071,15 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "sanitize-filename": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.1.tgz", + "integrity": "sha1-YS2hyWRz+gLczaktzVtKsWSmdyo=", + "dev": true, + "requires": { + "truncate-utf8-bytes": "^1.0.0" + } + }, "sass-graph": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", @@ -9301,6 +10207,15 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, "semver-dsl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz", @@ -10075,6 +10990,12 @@ "safe-buffer": "^5.1.1" } }, + "stat-mode": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz", + "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=", + "dev": true + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -10431,6 +11352,54 @@ "inherits": "2" } }, + "temp-file": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.3.2.tgz", + "integrity": "sha512-FGKccAW0Mux9hC/2bdUIe4bJRv4OyVo4RpVcuplFird1V/YoplIFbnPZjfzbJSf/qNvRZIRB9/4n/RkI0GziuQ==", + "dev": true, + "requires": { + "async-exit-hook": "^2.0.1", + "bluebird-lst": "^1.0.6", + "fs-extra-p": "^7.0.0" + } + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "^0.7.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + } + } + }, "terser": { "version": "3.16.1", "resolved": "https://registry.npmjs.org/terser/-/terser-3.16.1.tgz", @@ -10683,6 +11652,12 @@ "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", "dev": true }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, "timers-browserify": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", @@ -10804,6 +11779,15 @@ "glob": "^7.1.2" } }, + "truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "dev": true, + "requires": { + "utf8-byte-length": "^1.0.1" + } + }, "ts-node": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-5.0.1.tgz", @@ -10973,6 +11957,15 @@ "imurmurhash": "^0.1.4" } }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -11030,12 +12023,53 @@ } } }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, "upath": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", "dev": true }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + } + } + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -11078,6 +12112,15 @@ "requires-port": "^1.0.0" } }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", @@ -11094,6 +12137,12 @@ "tmp": "0.0.x" } }, + "utf8-byte-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", + "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=", + "dev": true + }, "util": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", @@ -11708,6 +12757,48 @@ "string-width": "^1.0.2 || 2" } }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dev": true, + "requires": { + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", @@ -11739,6 +12830,17 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write-file-atomic": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", + "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, "ws": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", @@ -11755,6 +12857,12 @@ "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=", "dev": true }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, "xml2js": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", @@ -11785,6 +12893,12 @@ "integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=", "dev": true }, + "xmldom": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", + "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=", + "dev": true + }, "xmlhttprequest-ssl": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", diff --git a/package.json b/package.json index 2204c7ba..c63da331 100644 --- a/package.json +++ b/package.json @@ -1,65 +1,128 @@ { - "name": "sengi", - "version": "0.0.0", - "license": "AGPL-3.0-or-later", - "main": "main-electron.js", - "scripts": { - "ng": "ng", - "start": "ng serve", - "build": "ng build --prod", - "test": "ng test", - "test-nowatch": "ng test --watch=false", - "lint": "ng lint", - "e2e": "ng e2e", - "electron": "ng build --prod && electron .", - "electron-debug": "ng build && electron ." - }, - "private": true, - "dependencies": { - "@angular/animations": "^7.2.7", - "@angular/common": "^7.2.7", - "@angular/compiler": "^7.2.7", - "@angular/core": "^7.2.7", - "@angular/forms": "^7.2.7", - "@angular/http": "^7.2.7", - "@angular/platform-browser": "^7.2.7", - "@angular/platform-browser-dynamic": "^7.2.7", - "@angular/router": "^7.2.7", - "@fortawesome/angular-fontawesome": "^0.3.0", - "@fortawesome/fontawesome-svg-core": "^1.2.13", - "@fortawesome/free-brands-svg-icons": "^5.7.0", - "@fortawesome/free-regular-svg-icons": "^5.7.0", - "@fortawesome/free-solid-svg-icons": "^5.7.0", - "@ngxs/storage-plugin": "^3.2.0", - "@ngxs/store": "^3.2.0", - "bootstrap": "^4.1.3", - "core-js": "^2.5.4", - "electron": "^4.0.6", - "ionicons": "^4.4.3", - "rxjs": "^6.4.0", - "tslib": "^1.9.0", - "zone.js": "^0.8.29" - }, - "devDependencies": { - "@angular-devkit/build-angular": "~0.13.0", - "@angular/cli": "~7.3.3", - "@angular/compiler-cli": "^7.2.7", - "@angular/language-service": "^7.2.7", - "@types/jasmine": "~2.8.6", - "@types/jasminewd2": "~2.0.3", - "@types/node": "~8.9.4", - "codelyzer": "~4.2.1", - "jasmine-core": "~2.99.1", - "jasmine-spec-reporter": "~4.2.1", - "karma": "~1.7.1", - "karma-chrome-launcher": "~2.2.0", - "karma-coverage-istanbul-reporter": "~2.0.0", - "karma-jasmine": "~1.1.0", - "karma-jasmine-html-reporter": "^0.2.2", - "karma-junit-reporter": "^1.2.0", - "protractor": "~5.3.0", - "ts-node": "~5.0.1", - "tslint": "~5.9.1", - "typescript": "~3.2.4" - } + "name": "sengi", + "version": "0.6.0", + "license": "AGPL-3.0-or-later", + "main": "main-electron.js", + "description": "A multi-account desktop client for Mastodon and Pleroma", + "author": { + "name": "Nicolas Constant", + "email": "github@nicolas-constant.com" + }, + "repository": { + "type": "git", + "url": "https://github.com/NicolasConstant/sengi.git" + }, + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build --prod", + "test": "ng test", + "test-nowatch": "ng test --watch=false", + "lint": "ng lint", + "e2e": "ng e2e", + "electron": "ng build --prod && electron .", + "electron-debug": "ng build && electron .", + "dist": "npm run build && build --publish onTagOrDraft" + }, + "private": true, + "dependencies": { + "@angular/animations": "^7.2.7", + "@angular/common": "^7.2.7", + "@angular/compiler": "^7.2.7", + "@angular/core": "^7.2.7", + "@angular/forms": "^7.2.7", + "@angular/http": "^7.2.7", + "@angular/platform-browser": "^7.2.7", + "@angular/platform-browser-dynamic": "^7.2.7", + "@angular/router": "^7.2.7", + "@fortawesome/angular-fontawesome": "^0.3.0", + "@fortawesome/fontawesome-svg-core": "^1.2.13", + "@fortawesome/free-brands-svg-icons": "^5.7.0", + "@fortawesome/free-regular-svg-icons": "^5.7.0", + "@fortawesome/free-solid-svg-icons": "^5.7.0", + "@ngxs/storage-plugin": "^3.2.0", + "@ngxs/store": "^3.2.0", + "bootstrap": "^4.1.3", + "core-js": "^2.5.4", + "ionicons": "^4.4.3", + "rxjs": "^6.4.0", + "tslib": "^1.9.0", + "zone.js": "^0.8.29" + }, + "devDependencies": { + "@angular-devkit/build-angular": "~0.13.0", + "@angular/cli": "~7.3.3", + "@angular/compiler-cli": "^7.2.7", + "@angular/language-service": "^7.2.7", + "@types/jasmine": "~2.8.6", + "@types/jasminewd2": "~2.0.3", + "@types/node": "~8.9.4", + "codelyzer": "~4.2.1", + "electron": "^4.0.6", + "electron-builder": "^20.39.0", + "jasmine-core": "~2.99.1", + "jasmine-spec-reporter": "~4.2.1", + "karma": "~1.7.1", + "karma-chrome-launcher": "~2.2.0", + "karma-coverage-istanbul-reporter": "~2.0.0", + "karma-jasmine": "~1.1.0", + "karma-jasmine-html-reporter": "^0.2.2", + "karma-junit-reporter": "^1.2.0", + "protractor": "~5.3.0", + "ts-node": "~5.0.1", + "tslint": "~5.9.1", + "typescript": "~3.2.4" + }, + "optionalDependencies": { + "jquery": "1.9.1 - 3", + "popper.js": "^1.14.7" + }, + "build": { + "productName": "Sengi", + "appId": "org.sengi.desktop", + "artifactName": "${productName}-${version}-${os}.${ext}", + "directories": { + "output": "release" + }, + "files": [ + "dist/", + "node_modules/", + "main-electron.js", + "package.json" + ], + "dmg": { + "contents": [ + { + "x": 130, + "y": 220 + }, + { + "x": 410, + "y": 220, + "type": "link", + "path": "/Applications" + } + ] + }, + "mac": { + "icon": "assets/icons/mac/icon.icns", + "target": [ + "dmg" + ], + "category": "public.app-category.social-networking" + }, + "win": { + "icon": "assets/icons/win/icon.ico", + "target": "nsis" + }, + "linux": { + "icon": "assets/icons/png", + "target": [ + "AppImage", + "deb", + "snap" + ], + "category": "Network" + } + } } diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 68bce313..1e1ab5cb 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -63,10 +63,9 @@ export class AppComponent implements OnInit, OnDestroy { this.dragoverSub = this.dragoverSubject .pipe( - debounceTime(150) + debounceTime(1500) ) - .subscribe(() => { - console.warn('disable drag'); + .subscribe(() => { this.drag = false; }) } diff --git a/src/app/components/create-status/create-status.component.ts b/src/app/components/create-status/create-status.component.ts index e0d2194b..6390180d 100644 --- a/src/app/components/create-status/create-status.component.ts +++ b/src/app/components/create-status/create-status.component.ts @@ -34,8 +34,8 @@ export class CreateStatusComponent implements OnInit, OnDestroy { private maxCharLength: number; charCountLeft: number; postCounts: number = 1; - isSending: boolean; + mentionTooFarAwayError: boolean; @Input() statusReplyingToWrapper: StatusWrapper; @Output() onClose = new EventEmitter(); @@ -76,6 +76,21 @@ export class CreateStatusComponent implements OnInit, OnDestroy { this.status += `@${mention} `; } + switch (this.statusReplyingTo.visibility) { + case 'unlisted': + this.setVisibility(VisibilityEnum.Unlisted); + break; + case 'public': + this.setVisibility(VisibilityEnum.Public); + break; + case 'private': + this.setVisibility(VisibilityEnum.Private); + break; + case 'direct': + this.setVisibility(VisibilityEnum.Direct); + break; + } + this.title = this.statusReplyingTo.spoiler_text; } @@ -100,60 +115,54 @@ export class CreateStatusComponent implements OnInit, OnDestroy { this.notificationService.notifyHttpError(err); }); - this.instancesInfoService.getDefaultPrivacy(selectedAccount) - .then((defaultPrivacy: VisibilityEnum) => { - switch (defaultPrivacy) { - case VisibilityEnum.Public: - this.selectedPrivacy = 'Public'; - break; - case VisibilityEnum.Unlisted: - this.selectedPrivacy = 'Unlisted'; - break; - case VisibilityEnum.Private: - this.selectedPrivacy = 'Follows-only'; - break; - case VisibilityEnum.Direct: - this.selectedPrivacy = 'DM'; - break; - } - }) - .catch((err: HttpErrorResponse) => { - this.notificationService.notifyHttpError(err); - }); + if (!this.statusReplyingToWrapper) { + this.instancesInfoService.getDefaultPrivacy(selectedAccount) + .then((defaultPrivacy: VisibilityEnum) => { + this.setVisibility(defaultPrivacy); + }) + .catch((err: HttpErrorResponse) => { + this.notificationService.notifyHttpError(err); + }); + } } } - mentionTooFarAwayError: boolean; + private setVisibility(defaultPrivacy: VisibilityEnum) { + switch (defaultPrivacy) { + case VisibilityEnum.Public: + this.selectedPrivacy = 'Public'; + break; + case VisibilityEnum.Unlisted: + this.selectedPrivacy = 'Unlisted'; + break; + case VisibilityEnum.Private: + this.selectedPrivacy = 'Follows-only'; + break; + case VisibilityEnum.Direct: + this.selectedPrivacy = 'DM'; + break; + } + } private countStatusChar(status: string) { this.mentionTooFarAwayError = false; const parseStatus = this.parseStatus(status); const mentions = this.getMentionsFromStatus(status); - if(mentions.length > 0){ + if (mentions.length > 0) { let containAllMention = true; mentions.forEach(m => { - if(!parseStatus[0].includes(m)){ + if (!parseStatus[0].includes(m)) { containAllMention = false; } }); - if(!containAllMention){ + if (!containAllMention) { this.mentionTooFarAwayError = true; this.charCountLeft = this.maxCharLength - status.length; this.postCounts = 1; return; } - - // const lastMention = mentions[mentions.length - 1]; - // const lastMentionPosition = status.lastIndexOf(lastMention); - // console.warn(`lastMentionPosition ${lastMentionPosition}`); - // if(lastMentionPosition > (this.maxCharLength - lastMention.length * 2 + 10)){ - // this.mentionTooFarAwayError = true; - // this.charCountLeft = this.maxCharLength - status.length; - // this.postCounts = 1; - // return; - // } } const currentStatus = parseStatus[parseStatus.length - 1]; @@ -182,6 +191,9 @@ export class CreateStatusComponent implements OnInit, OnDestroy { globalUniqueMentions.push(mention); } + const selectedUser = this.toolsService.getSelectedAccounts()[0]; + globalUniqueMentions = globalUniqueMentions.filter(x => x.toLowerCase() !== `${selectedUser.username}@${selectedUser.instance}`.toLowerCase()); + return globalUniqueMentions; } @@ -196,7 +208,7 @@ export class CreateStatusComponent implements OnInit, OnDestroy { this.isSending = true; let visibility: VisibilityEnum = VisibilityEnum.Unknown; - switch (this.selectedPrivacy) { //FIXME: in case of responding, set the visibility to original + switch (this.selectedPrivacy) { case 'Public': visibility = VisibilityEnum.Public; break; @@ -275,7 +287,7 @@ export class CreateStatusComponent implements OnInit, OnDestroy { let aggregateMention = ''; let mentions = this.getMentionsFromStatus(status); mentions.forEach(x => { - aggregateMention += `${x} `; + aggregateMention += `${x} `; }); const currentMaxCharLength = this.maxCharLength + mentionExtraChars; @@ -290,7 +302,7 @@ export class CreateStatusComponent implements OnInit, OnDestroy { return results; } - private getMentionExtraChars(status: string): number{ + private getMentionExtraChars(status: string): number { let mentionExtraChars = 0; let mentions = this.getMentionsFromStatus(status); @@ -305,7 +317,7 @@ export class CreateStatusComponent implements OnInit, OnDestroy { return mentionExtraChars; } - private getMentionsFromStatus(status: string): string[]{ + private getMentionsFromStatus(status: string): string[] { return status.split(' ').filter(x => x.indexOf('@') === 0 && x.length > 1); } } diff --git a/src/app/components/floating-column/floating-column.component.ts b/src/app/components/floating-column/floating-column.component.ts index df5ed180..47a66cf9 100644 --- a/src/app/components/floating-column/floating-column.component.ts +++ b/src/app/components/floating-column/floating-column.component.ts @@ -1,16 +1,18 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, OnDestroy } from '@angular/core'; import { faTimes } from "@fortawesome/free-solid-svg-icons"; import { NavigationService, LeftPanelType } from '../../services/navigation.service'; import { AccountWrapper } from '../../models/account.models'; import { OpenThreadEvent } from '../../services/tools.service'; +import { Subscription } from 'rxjs'; @Component({ selector: 'app-floating-column', templateUrl: './floating-column.component.html', styleUrls: ['./floating-column.component.scss'] }) -export class FloatingColumnComponent implements OnInit { +export class FloatingColumnComponent implements OnInit, OnDestroy { + faTimes = faTimes; overlayActive: boolean; overlayAccountToBrowse: string; @@ -19,31 +21,59 @@ export class FloatingColumnComponent implements OnInit { userAccountUsed: AccountWrapper; - openPanel: string; + openPanel: string = ''; + + private activatedPanelSub: Subscription; constructor(private readonly navigationService: NavigationService) { } ngOnInit() { - this.navigationService.activatedPanelSubject.subscribe((type: LeftPanelType) => { + this.activatedPanelSub = this.navigationService.activatedPanelSubject.subscribe((type: LeftPanelType) => { + this.overlayActive = false; switch (type) { case LeftPanelType.Closed: this.openPanel = ''; break; case LeftPanelType.AddNewAccount: - this.openPanel = 'addNewAccount'; + if (this.openPanel === 'addNewAccount') { + this.closePanel(); + } else { + this.openPanel = 'addNewAccount'; + } break; case LeftPanelType.CreateNewStatus: - this.openPanel = 'createNewStatus'; + if (this.openPanel === 'createNewStatus') { + this.closePanel(); + } else { + this.openPanel = 'createNewStatus'; + } break; case LeftPanelType.ManageAccount: - this.userAccountUsed = this.navigationService.getAccountToManage(); - this.openPanel = 'manageAccount'; + let lastUserAccountId = ''; + if (this.userAccountUsed && this.userAccountUsed.info) { + lastUserAccountId = this.userAccountUsed.info.id; + } + this.userAccountUsed = this.navigationService.getAccountToManage(); + + if (this.openPanel === 'manageAccount' && this.userAccountUsed.info.id === lastUserAccountId) { + this.closePanel(); + } else { + this.openPanel = 'manageAccount'; + } break; case LeftPanelType.Search: - this.openPanel = 'search'; + if (this.openPanel === 'search') { + this.closePanel(); + } else { + this.openPanel = 'search'; + } break; case LeftPanelType.Settings: - this.openPanel = 'settings'; + if (this.openPanel === 'settings') { + this.closePanel(); + } else { + this.openPanel = 'settings'; + } break; default: this.openPanel = ''; @@ -51,6 +81,12 @@ export class FloatingColumnComponent implements OnInit { }); } + ngOnDestroy(): void { + if(this.activatedPanelSub) { + this.activatedPanelSub.unsubscribe(); + } + } + closePanel(): boolean { this.navigationService.closePanel(); return false; @@ -60,21 +96,21 @@ export class FloatingColumnComponent implements OnInit { this.overlayAccountToBrowse = account; this.overlayHashtagToBrowse = null; this.overlayThreadToBrowse = null; - this.overlayActive = true; + this.overlayActive = true; } browseHashtag(hashtag: string): void { this.overlayAccountToBrowse = null; this.overlayHashtagToBrowse = hashtag; this.overlayThreadToBrowse = null; - this.overlayActive = true; + this.overlayActive = true; } browseThread(openThreadEvent: OpenThreadEvent): void { this.overlayAccountToBrowse = null; this.overlayHashtagToBrowse = null; this.overlayThreadToBrowse = openThreadEvent; - this.overlayActive = true; + this.overlayActive = true; } closeOverlay(): boolean { diff --git a/src/app/components/floating-column/manage-account/my-account/my-account.component.html b/src/app/components/floating-column/manage-account/my-account/my-account.component.html index 82d03bde..9404680e 100644 --- a/src/app/components/floating-column/manage-account/my-account/my-account.component.html +++ b/src/app/components/floating-column/manage-account/my-account/my-account.component.html @@ -1,7 +1,8 @@

add column:

- - {{ stream.name }} + + {{ stream.name }}

remove account from sengi:

diff --git a/src/app/components/floating-column/manage-account/my-account/my-account.component.scss b/src/app/components/floating-column/manage-account/my-account/my-account.component.scss index 4d7ba144..d31138d6 100644 --- a/src/app/components/floating-column/manage-account/my-account/my-account.component.scss +++ b/src/app/components/floating-column/manage-account/my-account/my-account.component.scss @@ -6,7 +6,6 @@ &__body { overflow: auto; height: calc(100%); - // width: calc(100%); padding-left: 10px; padding-right: 10px; font-size: $small-font-size; @@ -14,24 +13,11 @@ outline: 1px dotted greenyellow; } &__label { - // text-decoration: underline; font-size: $small-font-size; margin-top: 10px; margin-left: 5px; color: $font-color-secondary; } - &__link { - text-decoration: none; - display: block; // width: calc(100% - 20px); - width: 100%; // height: 30px; - padding: 5px 10px; // border: solid 1px black; - &:not(:last-child) { - margin-bottom: 5px; - } - } - &__margin-top { - margin-top: 25px; - } &__blue { background-color: $color-primary; color: #fff; @@ -47,4 +33,26 @@ background-color: lighten($red-button-color, 15); } } + &__link { + text-decoration: none; + display: block; // width: calc(100% - 20px); + width: 100%; // height: 30px; + padding: 5px 10px; // border: solid 1px black; + &:not(:last-child) { + margin-bottom: 5px; + } + &--icon { + float: right; + } + &--disabled { + cursor: default; + background-color: darken($color-primary, 4); + &:hover { + background-color: darken($color-primary, 4); + } + } + } + &__margin-top { + margin-top: 25px; + } } \ No newline at end of file diff --git a/src/app/components/floating-column/manage-account/my-account/my-account.component.ts b/src/app/components/floating-column/manage-account/my-account/my-account.component.ts index 67a52474..d4e0e9e9 100644 --- a/src/app/components/floating-column/manage-account/my-account/my-account.component.ts +++ b/src/app/components/floating-column/manage-account/my-account/my-account.component.ts @@ -1,5 +1,7 @@ -import { Component, OnInit, Input } from '@angular/core'; -import { Store } from '@ngxs/store'; +import { Component, OnInit, OnDestroy, Input } from '@angular/core'; +import { Observable, Subscription } from 'rxjs'; +import { Store, Select } from '@ngxs/store'; +import { faCheckSquare } from "@fortawesome/free-regular-svg-icons"; import { NotificationService } from '../../../../services/notification.service'; import { StreamElement, StreamTypeEnum, AddStream, RemoveAllStreams } from '../../../../states/streams.state'; @@ -12,11 +14,24 @@ import { NavigationService } from '../../../../services/navigation.service'; templateUrl: './my-account.component.html', styleUrls: ['./my-account.component.scss'] }) -export class MyAccountComponent implements OnInit { +export class MyAccountComponent implements OnInit, OnDestroy { + + faCheckSquare = faCheckSquare; - availableStreams: StreamElement[] = []; + availableStreams: StreamWrapper[] = []; - @Input() account: AccountWrapper; + private _account: AccountWrapper; + @Input('account') + set account(acc: AccountWrapper) { + this._account = acc; + this.loadStreams(acc); + } + get account(): AccountWrapper { + return this._account; + } + + @Select(state => state.streamsstatemodel.streams) streamElements$: Observable; + private streamChangedSub: Subscription; constructor( private readonly store: Store, @@ -24,19 +39,41 @@ export class MyAccountComponent implements OnInit { private notificationService: NotificationService) { } ngOnInit() { - const instance = this.account.info.instance; - this.availableStreams.length = 0; - this.availableStreams.push(new StreamElement(StreamTypeEnum.global, 'Federated Timeline', this.account.info.id, null, null, instance)); - this.availableStreams.push(new StreamElement(StreamTypeEnum.local, 'Local Timeline', this.account.info.id, null, null, instance)); - this.availableStreams.push(new StreamElement(StreamTypeEnum.personnal, 'Home', this.account.info.id, null, null, instance)); + this.streamChangedSub = this.streamElements$.subscribe((streams: StreamElement[]) => { + this.loadStreams(this.account); + }); } - addStream(stream: StreamElement): boolean { - if (stream) { + ngOnDestroy(): void { + if(this.streamChangedSub) { + this.streamChangedSub.unsubscribe(); + } + } + + private loadStreams(account: AccountWrapper){ + const instance = account.info.instance; + this.availableStreams.length = 0; + this.availableStreams.push(new StreamWrapper(new StreamElement(StreamTypeEnum.global, 'Federated Timeline', account.info.id, null, null, instance))); + this.availableStreams.push(new StreamWrapper(new StreamElement(StreamTypeEnum.local, 'Local Timeline', account.info.id, null, null, instance))); + this.availableStreams.push(new StreamWrapper(new StreamElement(StreamTypeEnum.personnal, 'Home', account.info.id, null, null, instance))); + + const loadedStreams = this.store.snapshot().streamsstatemodel.streams; + this.availableStreams.forEach(s => { + if(loadedStreams.find(x => x.id === s.id)){ + s.isAdded = true; + } else { + s.isAdded = false; + } + }); + } + + addStream(stream: StreamWrapper): boolean { + if (stream && !stream.isAdded) { this.store.dispatch([new AddStream(stream)]).toPromise() .then(() => { - this.notificationService.notify(`stream added`, false); - }); + stream.isAdded = true; + //this.notificationService.notify(`stream added`, false); + }); } return false; } @@ -48,3 +85,11 @@ export class MyAccountComponent implements OnInit { return false; } } + +class StreamWrapper extends StreamElement { + constructor(stream: StreamElement) { + super(stream.type, stream.name, stream.accountId, stream.tag, stream.list, stream.instance); + } + + isAdded: boolean; +} \ No newline at end of file diff --git a/src/app/components/left-side-bar/left-side-bar.component.html b/src/app/components/left-side-bar/left-side-bar.component.html index a5840902..ca85986f 100644 --- a/src/app/components/left-side-bar/left-side-bar.component.html +++ b/src/app/components/left-side-bar/left-side-bar.component.html @@ -1,9 +1,9 @@
+ - + @@ -12,11 +12,11 @@
- + - +
\ No newline at end of file diff --git a/src/app/components/stream/status/action-bar/action-bar.component.html b/src/app/components/stream/status/action-bar/action-bar.component.html index 58bcd5be..99b96d9b 100644 --- a/src/app/components/stream/status/action-bar/action-bar.component.html +++ b/src/app/components/stream/status/action-bar/action-bar.component.html @@ -4,7 +4,9 @@ - @@ -12,7 +14,9 @@ title="This post cannot be boosted"> - diff --git a/src/app/components/stream/status/action-bar/action-bar.component.scss b/src/app/components/stream/status/action-bar/action-bar.component.scss index 53a5143f..58739eda 100644 --- a/src/app/components/stream/status/action-bar/action-bar.component.scss +++ b/src/app/components/stream/status/action-bar/action-bar.component.scss @@ -1,4 +1,5 @@ @import "variables"; + .action-bar { // outline: 1px solid greenyellow; // height: 20px; margin: 5px 10px 5px $avatar-column-space; @@ -9,9 +10,11 @@ &__link { color: $status-secondary-color; + &:hover { color: $status-links-color; } + &:not(:last-child) { margin-right: 15px; } @@ -50,9 +53,9 @@ .boosted { color: $boost-color; - + &:hover { - color: darken($boost-color, 10); + color: darken($boost-color, 10); } } @@ -62,4 +65,70 @@ &:hover { color: darken($favorite-color, 10); } +} + + +@keyframes loadingAnimation { + 0% { + opacity: 0; + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +@-o-keyframes loadingAnimation { + 0% { + opacity: 0; + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +@-moz-keyframes loadingAnimation { + 0% { + opacity: 0; + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +@-webkit-keyframes loadingAnimation { + 0% { + opacity: 0; + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +.boosting, +.favoriting { + -webkit-animation: loadingAnimation 1s infinite; + -moz-animation: loadingAnimation 1s infinite; + -o-animation: loadingAnimation 1s infinite; + animation: loadingAnimation 1s infinite; + } \ No newline at end of file diff --git a/src/app/components/stream/status/action-bar/action-bar.component.ts b/src/app/components/stream/status/action-bar/action-bar.component.ts index db21919f..4336c31d 100644 --- a/src/app/components/stream/status/action-bar/action-bar.component.ts +++ b/src/app/components/stream/status/action-bar/action-bar.component.ts @@ -34,6 +34,9 @@ export class ActionBarComponent implements OnInit, OnDestroy { isBoostLocked: boolean; isLocked: boolean; + favoriteIsLoading: boolean; + boostIsLoading: boolean; + isContentWarningActive: boolean = false; private isProviderSelected: boolean; @@ -48,7 +51,7 @@ export class ActionBarComponent implements OnInit, OnDestroy { constructor( private readonly store: Store, private readonly toolsService: ToolsService, - private readonly mastodonService: MastodonService, + private readonly mastodonService: MastodonService, private readonly notificationService: NotificationService) { this.accounts$ = this.store.select(state => state.registeredaccounts.accounts); @@ -57,8 +60,14 @@ export class ActionBarComponent implements OnInit, OnDestroy { ngOnInit() { const status = this.statusWrapper.status; const account = this.statusWrapper.provider; - this.favoriteStatePerAccountId[account.id] = status.favourited; - this.bootedStatePerAccountId[account.id] = status.reblogged; + + if(status.reblog){ + this.favoriteStatePerAccountId[account.id] = status.reblog.favourited; + this.bootedStatePerAccountId[account.id] = status.reblog.reblogged; + } else { + this.favoriteStatePerAccountId[account.id] = status.favourited; + this.bootedStatePerAccountId[account.id] = status.reblogged; + } this.accountSub = this.accounts$.subscribe((accounts: AccountInfo[]) => { this.checkStatus(accounts); @@ -87,7 +96,7 @@ export class ActionBarComponent implements OnInit, OnDestroy { this.isLocked = false; } - if(status.sensitive || status.spoiler_text){ + if (status.sensitive || status.spoiler_text) { this.isContentWarningActive = true; } @@ -113,56 +122,63 @@ export class ActionBarComponent implements OnInit, OnDestroy { } boost(): boolean { - //TODO get rid of that - this.selectedAccounts.forEach((account: AccountInfo) => { + if(this.boostIsLoading) return; - const usableStatus = this.toolsService.getStatusUsableByAccount(account, this.statusWrapper); - usableStatus - .then((status: Status) => { - if (this.isBoosted && status.reblogged) { - return this.mastodonService.unreblog(account, status); - } else if(!this.isBoosted && !status.reblogged){ - return this.mastodonService.reblog(account, status); - } else { - return Promise.resolve(status); - } - }) - .then((boostedStatus: Status) => { - this.bootedStatePerAccountId[account.id] = boostedStatus.reblogged; - this.checkIfBoosted(); - // this.isBoosted = !this.isBoosted; - }) - .catch((err: HttpErrorResponse) => { - this.notificationService.notifyHttpError(err); - }); - }); + this.boostIsLoading = true; + const account = this.toolsService.getSelectedAccounts()[0]; + const usableStatus = this.toolsService.getStatusUsableByAccount(account, this.statusWrapper); + usableStatus + .then((status: Status) => { + if (this.isBoosted && status.reblogged) { + return this.mastodonService.unreblog(account, status); + } else if (!this.isBoosted && !status.reblogged) { + return this.mastodonService.reblog(account, status); + } else { + return Promise.resolve(status); + } + }) + .then((boostedStatus: Status) => { + this.bootedStatePerAccountId[account.id] = boostedStatus.reblogged; + this.checkIfBoosted(); + }) + .catch((err: HttpErrorResponse) => { + this.notificationService.notifyHttpError(err); + }) + .then(() => { + this.boostIsLoading = false; + }); return false; } favorite(): boolean { - this.selectedAccounts.forEach((account: AccountInfo) => { - - const usableStatus = this.toolsService.getStatusUsableByAccount(account, this.statusWrapper); - usableStatus - .then((status: Status) => { - if (this.isFavorited && status.favourited) { - return this.mastodonService.unfavorite(account, status); - } else if(!this.isFavorited && !status.favourited) { - return this.mastodonService.favorite(account, status); - } else { - return Promise.resolve(status); - } - }) - .then((favoritedStatus: Status) => { - this.favoriteStatePerAccountId[account.id] = favoritedStatus.favourited; - this.checkIfFavorited(); - // this.isFavorited = !this.isFavorited; - }) - .catch((err: HttpErrorResponse) => { - this.notificationService.notifyHttpError(err); - }); - }); + if(this.favoriteIsLoading) return; + + this.favoriteIsLoading = true; + const account = this.toolsService.getSelectedAccounts()[0]; + const usableStatus = this.toolsService.getStatusUsableByAccount(account, this.statusWrapper); + usableStatus + .then((status: Status) => { + if (this.isFavorited && status.favourited) { + return this.mastodonService.unfavorite(account, status); + } else if (!this.isFavorited && !status.favourited) { + return this.mastodonService.favorite(account, status); + } else { + return Promise.resolve(status); + } + }) + .then((favoritedStatus: Status) => { + this.favoriteStatePerAccountId[account.id] = favoritedStatus.favourited; + this.checkIfFavorited(); + // this.isFavorited = !this.isFavorited; + }) + .catch((err: HttpErrorResponse) => { + this.notificationService.notifyHttpError(err); + }) + .then(() => { + this.favoriteIsLoading = false; + }); + return false; } @@ -189,9 +205,4 @@ export class ActionBarComponent implements OnInit, OnDestroy { console.warn('more'); //TODO return false; } - - // private getSelectedAccounts(): AccountInfo[] { - // var regAccounts = this.store.snapshot().registeredaccounts.accounts; - // return regAccounts; - // } } diff --git a/src/app/components/stream/user-profile/user-profile.component.html b/src/app/components/stream/user-profile/user-profile.component.html index bf6a095d..2022a9dc 100644 --- a/src/app/components/stream/user-profile/user-profile.component.html +++ b/src/app/components/stream/user-profile/user-profile.component.html @@ -1,13 +1,12 @@ -
+
-
+
- - header -

{{account.display_name}}

-

@{{account.acct}}

+ header +

{{displayedAccount.display_name}}

+

@{{displayedAccount.acct}}

-
- - +
-
-
+
+
@@ -49,8 +47,6 @@
- -
no toots found
@@ -60,6 +56,9 @@ (browseAccountEvent)="browseAccount($event)" (browseThreadEvent)="browseThread($event)">
+ + +
\ No newline at end of file diff --git a/src/app/components/stream/user-profile/user-profile.component.ts b/src/app/components/stream/user-profile/user-profile.component.ts index ee1dc4fa..4ab69ece 100644 --- a/src/app/components/stream/user-profile/user-profile.component.ts +++ b/src/app/components/stream/user-profile/user-profile.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { Component, OnInit, Input, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core'; import { HttpErrorResponse } from '@angular/common/http'; import { faUser, faHourglassHalf, faUserCheck } from "@fortawesome/free-solid-svg-icons"; import { faUser as faUserRegular } from "@fortawesome/free-regular-svg-icons"; @@ -25,10 +25,13 @@ export class UserProfileComponent implements OnInit { faHourglassHalf = faHourglassHalf; faUserCheck = faUserCheck; - account: Account; + displayedAccount: Account; hasNote: boolean; isLoading: boolean; + + private maxReached = false; + private maxId: string; statusLoading: boolean; error: string; @@ -41,6 +44,8 @@ export class UserProfileComponent implements OnInit { private accounts$: Observable; private accountSub: Subscription; + @ViewChild('statusstream') public statustream: ElementRef; + @Output() browseAccountEvent = new EventEmitter(); @Output() browseHashtagEvent = new EventEmitter(); @Output() browseThreadEvent = new EventEmitter(); @@ -61,12 +66,12 @@ export class UserProfileComponent implements OnInit { ngOnInit() { this.accountSub = this.accounts$.subscribe((accounts: AccountInfo[]) => { - if (this.account) { - this.currentlyUsedAccount = accounts.filter(x => x.isSelected)[0]; + if (this.displayedAccount) { + const userAccount = accounts.filter(x => x.isSelected)[0]; - this.toolsService.findAccount(this.currentlyUsedAccount, this.lastAccountName) + this.toolsService.findAccount(userAccount, this.lastAccountName) .then((account: Account) => { - this.getFollowStatus(this.currentlyUsedAccount, account); + this.getFollowStatus(userAccount, account); }) .catch((err: HttpErrorResponse) => { this.notificationService.notifyHttpError(err); @@ -82,7 +87,7 @@ export class UserProfileComponent implements OnInit { private load(accountName: string) { this.statuses.length = 0; - this.account = null; + this.displayedAccount = null; this.isLoading = true; this.lastAccountName = accountName; @@ -93,11 +98,11 @@ export class UserProfileComponent implements OnInit { this.isLoading = false; this.statusLoading = true; - this.account = account; + this.displayedAccount = account; this.hasNote = account && account.note && account.note !== '

'; - const getFollowStatusPromise = this.getFollowStatus(this.currentlyUsedAccount, this.account); - const getStatusesPromise = this.getStatuses(this.currentlyUsedAccount, this.account); + const getFollowStatusPromise = this.getFollowStatus(this.currentlyUsedAccount, this.displayedAccount); + const getStatusesPromise = this.getStatuses(this.currentlyUsedAccount, this.displayedAccount); return Promise.all([getFollowStatusPromise, getStatusesPromise]); }) @@ -113,11 +118,25 @@ export class UserProfileComponent implements OnInit { private getStatuses(userAccount: AccountInfo, account: Account): Promise { this.statusLoading = true; return this.mastodonService.getAccountStatuses(userAccount, account.id, false, false, true, null, null, 40) - .then((result: Status[]) => { - for (const status of result) { - const wrapper = new StatusWrapper(status, userAccount); - this.statuses.push(wrapper); - } + .then((statuses: Status[]) => { + this.loadStatus(userAccount, statuses); + + // if (statuses.length === 0) { + // this.maxReached = true; + // return; + // } + + // for (const status of statuses) { + // const wrapper = new StatusWrapper(status, userAccount); + // this.statuses.push(wrapper); + // } + + // this.maxId = this.statuses[this.statuses.length - 1].status.id; + }) + .catch(err => { + this.notificationService.notifyHttpError(err); + }) + .then(() => { this.statusLoading = false; }); } @@ -147,10 +166,10 @@ export class UserProfileComponent implements OnInit { } follow(): boolean { - this.currentlyUsedAccount = this.toolsService.getSelectedAccounts()[0]; - this.toolsService.findAccount(this.currentlyUsedAccount, this.lastAccountName) + const userAccount = this.toolsService.getSelectedAccounts()[0]; + this.toolsService.findAccount(userAccount, this.lastAccountName) .then((account: Account) => { - return this.mastodonService.follow(this.currentlyUsedAccount, account); + return this.mastodonService.follow(userAccount, account); }) .then((relationship: Relationship) => { this.relationship = relationship; @@ -162,10 +181,10 @@ export class UserProfileComponent implements OnInit { } unfollow(): boolean { - this.currentlyUsedAccount = this.toolsService.getSelectedAccounts()[0]; - this.toolsService.findAccount(this.currentlyUsedAccount, this.lastAccountName) + const userAccount = this.toolsService.getSelectedAccounts()[0]; + this.toolsService.findAccount(userAccount, this.lastAccountName) .then((account: Account) => { - return this.mastodonService.unfollow(this.currentlyUsedAccount, account); + return this.mastodonService.unfollow(userAccount, account); }) .then((relationship: Relationship) => { this.relationship = relationship; @@ -175,4 +194,44 @@ export class UserProfileComponent implements OnInit { }); return false; } + + onScroll() { + var element = this.statustream.nativeElement as HTMLElement; + const atBottom = element.scrollHeight <= element.clientHeight + element.scrollTop + 1000; + + if (atBottom) { + this.scrolledToBottom(); + } + } + + private scrolledToBottom() { + if (this.statusLoading || this.maxReached) return; + + this.statusLoading = true; + const userAccount = this.currentlyUsedAccount; + this.mastodonService.getAccountStatuses(userAccount, this.displayedAccount.id, false, false, true, this.maxId, null, 40) + .then((statuses: Status[]) => { + this.loadStatus(userAccount, statuses); + }) + .catch(err => { + this.notificationService.notifyHttpError(err); + }) + .then(() => { + this.statusLoading = false; + }); + } + + private loadStatus(userAccount: AccountInfo, statuses: Status[]){ + if (statuses.length === 0) { + this.maxReached = true; + return; + } + + for (const status of statuses) { + const wrapper = new StatusWrapper(status, userAccount); + this.statuses.push(wrapper); + } + + this.maxId = this.statuses[this.statuses.length - 1].status.id; + } } diff --git a/src/app/services/media.service.ts b/src/app/services/media.service.ts index c577f97e..d2ecde37 100644 --- a/src/app/services/media.service.ts +++ b/src/app/services/media.service.ts @@ -29,6 +29,9 @@ export class MediaService { let medias = this.mediaSubject.value; medias.push(wrapper); + if(medias.length > 4){ + medias.splice(0, 1); + } this.mediaSubject.next(medias); this.mastodonService.uploadMediaAttachment(account, file, null) diff --git a/src/app/services/models/mastodon.interfaces.ts b/src/app/services/models/mastodon.interfaces.ts index bcbf001e..6ab6e417 100644 --- a/src/app/services/models/mastodon.interfaces.ts +++ b/src/app/services/models/mastodon.interfaces.ts @@ -157,7 +157,7 @@ export interface Status { favourited: boolean; sensitive: boolean; spoiler_text: string; - visibility: string; + visibility: 'public' | 'unlisted' | 'private' | 'direct'; media_attachments: Attachment[]; mentions: Mention[]; tags: Tag[]; diff --git a/src/app/services/tools.service.ts b/src/app/services/tools.service.ts index 0e444c68..f1a1ecb0 100644 --- a/src/app/services/tools.service.ts +++ b/src/app/services/tools.service.ts @@ -44,10 +44,10 @@ export class ToolsService { .then((result: Results) => { if(accountName[0] === '@') accountName = accountName.substr(1); - const foundAccount = result.accounts.filter( + const foundAccount = result.accounts.find( x => x.acct.toLowerCase() === accountName.toLowerCase() - || x.acct.toLowerCase() === accountName.toLowerCase().split('@')[0] - )[0]; + || x.acct.toLowerCase().split('@')[0] === accountName.toLowerCase().split('@')[0] + ); return foundAccount; }); }