diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e09093ae..2d9da504 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,4 +21,4 @@ For example: ## Pull Requests Pull Requests are maybe a bit early right now, since the project and code can change a lot, so it's not really adviced to open PR today. -I will notify explicitely when I'll be more opened to external contributions. +I will notify explicitly when I'll be more open to external contributions. diff --git a/DOCKER.md b/DOCKER.md new file mode 100644 index 00000000..344aed45 --- /dev/null +++ b/DOCKER.md @@ -0,0 +1,28 @@ +# Sengi's Docker documentation + +Here is some more detailed informations for Sengi's Docker users. + +## Deploy Sengi's + +Execute: + +``` +docker run -d -p 80:80 nicolasconstant/sengi +``` + +Sengi will then be available on port 80 + +## Landing page + +Sengi's docker contains a landing page so that you can open a pop-up easily.
+It's available in ```https://your-host/start/index.html``` + +## Personalize the Privacy Statement + +You can personalize the privacy statement by linking it as follow: + +``` +docker run -d -p 80:80 -v /Path/privacy.html:/app/assets/docs/privacy.html nicolasconstant/sengi +``` + + diff --git a/README.md b/README.md index ae1f3687..c0f4f6fb 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ Sengi is a **Mastodon** and **Pleroma** desktop focused client. It takes inspira It is strongly focused on the following points: * Heavily oriented on multi-accounts usage - * Desktop based interactions (right clic, left clic, etc) - * One column at a time display (leaves it on the side of your screen, and keep an eye on it while doing your other stuff) + * Desktop based interactions (right click, left click, etc) + * One column at a time display (leave it on the side of your screen, and keep an eye on it while doing your other stuff) It is released as a **browser webapp** and also packaged as an **cross-platform desktop application** (Mac, Windows, and Linux). @@ -18,7 +18,7 @@ It is released as a **browser webapp** and also packaged as an **cross-platform ## State of development -Sengi already supporting all the basics functionalities, but many minors enhancements are still needed before a 1.0.0 release. +Sengi already supports all the basics functionalities, but many minors enhancements are still needed before a 1.0.0 release. ## Screens @@ -32,6 +32,8 @@ A docker image is available for auto-hosting your own Sengi webapp! docker run -d -p 80:80 nicolasconstant/sengi ``` +Find more informations [here](https://github.com/NicolasConstant/sengi/blob/master/DOCKER.md). + The docker image also provide a landing page so that you can open a pop-up really easily.
It's available in ```https://your-host/start/index.html``` @@ -56,7 +58,7 @@ See [credits](https://github.com/NicolasConstant/sengi/blob/master/CREDITS.md) * [Angular 7](https://github.com/angular/angular) * [NGXS](https://github.com/ngxs/store) * [SASS](https://github.com/sass/dart-sass) - * [Electron 8](https://github.com/electron/electron) + * [Electron 10](https://github.com/electron/electron) ## What's a sengi?! diff --git a/main-electron.js b/main-electron.js index 6cb015e2..1249be75 100644 --- a/main-electron.js +++ b/main-electron.js @@ -1,4 +1,4 @@ -const { app, Menu, BrowserWindow, shell } = require("electron"); +const { app, Menu, MenuItem, BrowserWindow, shell } = require("electron"); // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. @@ -12,6 +12,9 @@ function createWindow() { title: "Sengi", backgroundColor: "#131925", useContentSize: true, + webPreferences: { + spellcheck: false + } // webPreferences: { // contextIsolation: true, // nodeIntegration: false, @@ -21,7 +24,7 @@ function createWindow() { win.setAutoHideMenuBar(true); win.setMenuBarVisibility(false); - + const sengiUrl = "https://sengi.nicolas-constant.com"; win.loadURL(sengiUrl); @@ -75,7 +78,7 @@ function createWindow() { Menu.buildFromTemplate([ { label: "Sengi", - submenu: [ + submenu: [ { role: "close" }, { role: 'quit' } ] @@ -114,7 +117,7 @@ function createWindow() { } }, { type: "separator" }, - { role: "reload" }, + { role: "reload" }, { role: "forcereload" }, { type: 'separator' }, { role: 'togglefullscreen' } @@ -156,6 +159,30 @@ function createWindow() { // when you should delete the corresponding element. win = null; }); + + + // win.webContents.on('context-menu', (event, params) => { + // const menu = new Menu(); + + // // Add each spelling suggestion + // for (const suggestion of params.dictionarySuggestions) { + // menu.append(new MenuItem({ + // label: suggestion, + // click: () => mainWindow.webContents.replaceMisspelling(suggestion) + // })); + // } + + // // Allow users to add the misspelled word to the dictionary + // if (params.misspelledWord) { + // menu.append( + // new MenuItem({ + // label: 'Add to dictionary', + // click: () => mainWindow.webContents.session.addWordToSpellCheckerDictionary(params.misspelledWord) + // })); + // } + + // menu.popup(); + // }); } app.commandLine.appendSwitch("force-color-profile", "srgb"); diff --git a/package-lock.json b/package-lock.json index f3e321f5..6dcee2e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,7 @@ { "name": "sengi", - "version": "0.20.1", + "version": "0.31.1", + "version": "0.27.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -797,9 +798,9 @@ } }, "@electron/get": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.8.0.tgz", - "integrity": "sha512-p9q2KNfN12lhLzcSJwjOKbHHZcPCP+DMHXWLE/nFzJfyFDiPFAvOgLdKwz8WvGfzn2Y8YtYk1BhqvaNRow78ag==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.12.2.tgz", + "integrity": "sha512-vAuHUbfvBQpYTJ5wB7uVIDq5c/Ry0fiTBMs7lnEYAo/qXXppIVcWdfBr57u6eRnKdVso7KSiH6p/LbQAG6Izrg==", "dev": true, "requires": { "debug": "^4.1.1", @@ -808,6 +809,7 @@ "global-agent": "^2.0.2", "global-tunnel-ng": "^2.7.1", "got": "^9.6.0", + "progress": "^2.0.3", "sanitize-filename": "^1.6.2", "sumchecker": "^3.0.1" }, @@ -2375,6 +2377,12 @@ "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", "dev": true }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, "buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", @@ -2536,18 +2544,18 @@ }, "dependencies": { "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" } }, "http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-Z2EICWNJou7Tr9Bd2M2UqDJq3A9F2ePG9w3lIpjoyuSyXFP9QbniJVu3XQYytuw5ebmG7dXSXO9PgAjJG8DDKA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", "dev": true }, "lowercase-keys": { @@ -3812,9 +3820,9 @@ "dev": true }, "electron": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/electron/-/electron-8.0.2.tgz", - "integrity": "sha512-hiQaFtFhd9X2Vjs01l3GXb8hPWSCa31o/kXydo+RC7vwcx9AGuzG7jWIq8vidzAWsF/YPM0LFVjFRZrfkqi03Q==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-10.1.1.tgz", + "integrity": "sha512-ZJtZHMr17AvvBosuA6XUmpehwAlGM4/n46Mw9BcyD8tpgdI6IQd0X5OU9meE3X3M8Y6Ja2Kr2udTMgtjvot2hA==", "dev": true, "requires": { "@electron/get": "^1.0.1", @@ -3823,9 +3831,9 @@ }, "dependencies": { "@types/node": { - "version": "12.12.28", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.28.tgz", - "integrity": "sha512-g73GJYJDXgf0jqg+P9S8h2acWbDXNkoCX8DLtJVu7Fkn788pzQ/oJsrdJz/2JejRf/SjfZaAhsw+3nd1D5EWGg==", + "version": "12.12.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.55.tgz", + "integrity": "sha512-Vd6xQUVvPCTm7Nx1N7XHcpX6t047ltm7TgcsOr4gFHjeYgwZevo+V7I1lfzHnj5BT5frztZ42+RTG4MwYw63dw==", "dev": true } } @@ -4813,15 +4821,15 @@ } }, "extract-zip": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", - "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", "dev": true, "requires": { - "concat-stream": "1.6.2", - "debug": "2.6.9", - "mkdirp": "0.5.1", - "yauzl": "2.4.1" + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" }, "dependencies": { "debug": { @@ -4833,6 +4841,21 @@ "ms": "2.0.0" } }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -4873,9 +4896,9 @@ } }, "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "dev": true, "requires": { "pend": "~1.2.0" @@ -5174,9 +5197,9 @@ }, "dependencies": { "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true } } @@ -5861,32 +5884,32 @@ } }, "global-agent": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.8.tgz", - "integrity": "sha512-VpBe/rhY6Rw2VDOTszAMNambg+4Qv8j0yiTNDYEXXXxkUNGWLHp8A3ztK4YDBbFNcWF4rgsec6/5gPyryya/+A==", + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.12.tgz", + "integrity": "sha512-caAljRMS/qcDo69X9BfkgrihGUgGx44Fb4QQToNQjsiWh+YlQ66uqYVAdA8Olqit+5Ng0nkz09je3ZzANMZcjg==", "dev": true, "optional": true, "requires": { - "boolean": "^3.0.0", - "core-js": "^3.6.4", + "boolean": "^3.0.1", + "core-js": "^3.6.5", "es6-error": "^4.1.1", - "matcher": "^2.1.0", - "roarr": "^2.15.2", - "semver": "^7.1.2", - "serialize-error": "^5.0.0" + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" }, "dependencies": { "core-js": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", - "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", "dev": true, "optional": true }, "semver": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", - "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true, "optional": true } @@ -7996,19 +8019,19 @@ } }, "matcher": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-2.1.0.tgz", - "integrity": "sha512-o+nZr+vtJtgPNklyeUKkkH42OsK8WAfdgaJE2FNxcjLPg+5QbeEoT6vRj8Xq/iv18JlQ9cmKsEu0b94ixWf1YQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", "dev": true, "optional": true, "requires": { - "escape-string-regexp": "^2.0.0" + "escape-string-regexp": "^4.0.0" }, "dependencies": { "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "optional": true } @@ -9739,6 +9762,12 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", @@ -10463,9 +10492,9 @@ } }, "roarr": { - "version": "2.15.2", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.2.tgz", - "integrity": "sha512-jmaDhK9CO4YbQAV8zzCnq9vjAqeO489MS5ehZ+rXmFiPFFE6B+S9KYO6prjmLJ5A0zY3QxVlQdrIya7E/azz/Q==", + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.3.tgz", + "integrity": "sha512-AEjYvmAhlyxOeB9OqPUzQCo3kuAkNfuDk/HqWbZdFsqDFpapkTjiw+p4svNEoRLvuqNTxqfL+s+gtD4eDgZ+CA==", "dev": true, "optional": true, "requires": { @@ -10755,13 +10784,13 @@ } }, "serialize-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz", - "integrity": "sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", "dev": true, "optional": true, "requires": { - "type-fest": "^0.8.0" + "type-fest": "^0.13.1" } }, "serialize-javascript": { @@ -12330,9 +12359,9 @@ "dev": true }, "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", "dev": true, "optional": true }, @@ -13454,12 +13483,13 @@ } }, "yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, "requires": { - "fd-slicer": "~1.0.1" + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" } }, "yeast": { diff --git a/package.json b/package.json index 380eece7..8a612428 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "sengi", - "version": "0.31.1", + "version": "0.32.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", + "name": "Nicolas Constant", "email": "github@nicolas-constant.com" }, "repository": { @@ -70,7 +70,7 @@ "@types/jasminewd2": "~2.0.3", "@types/node": "~8.9.4", "codelyzer": "~4.2.1", - "electron": "^8.0.2", + "electron": "^10.1.1", "electron-builder": "^20.39.0", "jasmine-core": "~2.99.1", "jasmine-spec-reporter": "~4.2.1", diff --git a/src/app/app.component.html b/src/app/app.component.html index fd202f74..929daad4 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -16,6 +16,11 @@ +
+ +
+ diff --git a/src/app/app.component.scss b/src/app/app.component.scss index aef18c8b..3aac2af3 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -171,4 +171,27 @@ app-streams-selection-footer { } } } +} + +.enhanced-tutorial { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0,0,0,0.9); + z-index: 9999999; + opacity: 0; + transition: all .4s; + + &__visible { + opacity: 1; + } + + &__content { + display: block; + padding: 25px; + width: calc(100%); + height: calc(100%); + } } \ No newline at end of file diff --git a/src/app/app.component.ts b/src/app/app.component.ts index dd3e8bad..777a2efd 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -62,9 +62,6 @@ export class AppComponent implements OnInit, OnDestroy { } ngOnInit(): void { - // disable tutorial for future update - localStorage.setItem('tutorial', JSON.stringify(true)); - this.paramsSub = this.activatedRoute.queryParams.subscribe(params => { const code = params['code']; if (!code) { @@ -130,6 +127,8 @@ export class AppComponent implements OnInit, OnDestroy { this.columnEditorSub = this.navigationService.activatedPanelSubject.subscribe((event: OpenLeftPanelEvent) => { if (event.type === LeftPanelType.Closed) { this.floatingColumnActive = false; + + this.checkEnhancedTutorial(); } else { this.floatingColumnActive = true; } @@ -158,6 +157,29 @@ export class AppComponent implements OnInit, OnDestroy { }); } + enhancedTutorialActive: boolean; + enhancedTutorialVisible: boolean; + private checkEnhancedTutorial() { + let enhancedTutorialDesactivated = JSON.parse(localStorage.getItem('tutorial')); + if (!this.floatingColumnActive && !this.tutorialActive && !enhancedTutorialDesactivated) { + setTimeout(() => { + this.enhancedTutorialActive = true; + setTimeout(() => { + this.enhancedTutorialVisible = true; + }, 100); + }, 500); + } + } + + closeTutorial(){ + localStorage.setItem('tutorial', JSON.stringify(true)); + + this.enhancedTutorialVisible = false; + setTimeout(() => { + this.enhancedTutorialActive = false; + }, 400); + } + ngOnDestroy(): void { this.streamSub.unsubscribe(); this.columnEditorSub.unsubscribe(); diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 20ea0dc1..582e1230 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -86,7 +86,10 @@ import { AttachementImageComponent } from './components/stream/status/attachemen import { EnsureHttpsPipe } from './pipes/ensure-https.pipe'; import { UserFollowsComponent } from './components/stream/user-follows/user-follows.component'; import { AccountComponent } from './components/common/account/account.component'; - +import { TutorialEnhancedComponent } from './components/tutorial-enhanced/tutorial-enhanced.component'; +import { NotificationsTutorialComponent } from './components/tutorial-enhanced/notifications-tutorial/notifications-tutorial.component'; +import { LabelsTutorialComponent } from './components/tutorial-enhanced/labels-tutorial/labels-tutorial.component'; +import { ThankyouTutorialComponent } from './components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component'; const routes: Routes = [ { path: "", component: StreamsMainDisplayComponent }, @@ -152,7 +155,11 @@ const routes: Routes = [ AttachementImageComponent, EnsureHttpsPipe, UserFollowsComponent, - AccountComponent + AccountComponent, + TutorialEnhancedComponent, + NotificationsTutorialComponent, + LabelsTutorialComponent, + ThankyouTutorialComponent ], entryComponents: [ EmojiPickerComponent diff --git a/src/app/components/floating-column/settings/settings.component.html b/src/app/components/floating-column/settings/settings.component.html index 8977c6a0..01df4b0f 100644 --- a/src/app/components/floating-column/settings/settings.component.html +++ b/src/app/components/floating-column/settings/settings.component.html @@ -148,7 +148,9 @@

About

Sengi version: {{version}}
- check for updates + open tutorial
+ imprint & privacy
+ check for updates

diff --git a/src/app/components/floating-column/settings/settings.component.ts b/src/app/components/floating-column/settings/settings.component.ts index 190a0c56..838135b3 100644 --- a/src/app/components/floating-column/settings/settings.component.ts +++ b/src/app/components/floating-column/settings/settings.component.ts @@ -8,6 +8,7 @@ import { UserNotificationService, NotificationSoundDefinition } from '../../../s import { ServiceWorkerService } from '../../../services/service-worker.service'; import { ContentWarningPolicy, ContentWarningPolicyEnum, TimeLineModeEnum, TimeLineHeaderEnum } from '../../../states/settings.state'; import { NotificationService } from '../../../services/notification.service'; +import { NavigationService } from '../../../services/navigation.service'; @Component({ selector: 'app-settings', @@ -60,6 +61,7 @@ export class SettingsComponent implements OnInit { } constructor( + private readonly navigationService: NavigationService, private formBuilder: FormBuilder, private serviceWorkersService: ServiceWorkerService, private readonly toolsService: ToolsService, @@ -250,6 +252,12 @@ export class SettingsComponent implements OnInit { notifyRestartNeeded(){ this.notificationService.notifyRestartNotification('Reload to apply changes'); } + + openTutorial(): boolean { + localStorage.setItem('tutorial', JSON.stringify(false)); + this.navigationService.closePanel(); + return false; + } } enum ColumnShortcut { diff --git a/src/app/components/stream/status/databinded-text/databinded-text.component.spec.ts b/src/app/components/stream/status/databinded-text/databinded-text.component.spec.ts index 9426d8eb..495dd8cd 100644 --- a/src/app/components/stream/status/databinded-text/databinded-text.component.spec.ts +++ b/src/app/components/stream/status/databinded-text/databinded-text.component.spec.ts @@ -156,6 +156,15 @@ describe('DatabindedTextComponent', () => { expect(component.processedText).toContain('

@sengi_app@mastodon.social Blabla

'); //FIXME: dont let domain appear in name }); + it('should parse mention - Misskey in Pleroma', () => { + const sample = `

@sengi@domain.xyz @sengi@domain.eu bla bla
bla bla bla

`; + + component.text = sample; + expect(component.processedText).toContain('@sengi'); + expect(component.processedText).toContain('@sengi'); + expect(component.processedText).toContain(' bla bla
bla bla bla
'); + }); + it('should parse mention - Misskey in Mastodon - 2', () => { const sample = `

Since @test@mastodon.technology mentioned

`; diff --git a/src/app/components/stream/status/databinded-text/databinded-text.component.ts b/src/app/components/stream/status/databinded-text/databinded-text.component.ts index 3c94b985..57902653 100644 --- a/src/app/components/stream/status/databinded-text/databinded-text.component.ts +++ b/src/app/components/stream/status/databinded-text/databinded-text.component.ts @@ -28,7 +28,7 @@ export class DatabindedTextComponent implements OnInit { @Input('text') set text(value: string) { - //console.log(value); + // console.log(value); let parser = new DOMParser(); var dom = parser.parseFromString(value, 'text/html') @@ -113,13 +113,18 @@ export class DatabindedTextComponent implements OnInit { extractedAccountAndNext = section.split('
'); extractedAccountName = extractedAccountAndNext[0].split('@')[1].replace('', '').replace('', ''); } else if (section.includes('class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@') && !section.includes('target="_blank">@<')) { //Misskey - //console.warn('misskey'); - extractedAccountAndNext = section.split(''); extractedAccountName = extractedAccountAndNext[0].split('class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@')[1]; if (extractedAccountName.includes('@')) extractedAccountName = extractedAccountName.split('@')[0]; + } else if(section.includes(' class="u-url mention">@') && !section.includes(' class="u-url mention">@<')) { //Misskey in pleroma + extractedAccountAndNext = section.split(''); + extractedAccountName = extractedAccountAndNext[0].split(' class="u-url mention">@')[1]; + + if (extractedAccountName.includes('@')) + extractedAccountName = extractedAccountName.split('@')[0]; + } else if (!section.includes('@')) { //GNU social extractedAccountAndNext = section.split(''); extractedAccountName = extractedAccountAndNext[0].split('>')[1]; diff --git a/src/app/components/tutorial-enhanced/labels-tutorial/labels-tutorial.component.html b/src/app/components/tutorial-enhanced/labels-tutorial/labels-tutorial.component.html new file mode 100644 index 00000000..956ccf98 --- /dev/null +++ b/src/app/components/tutorial-enhanced/labels-tutorial/labels-tutorial.component.html @@ -0,0 +1,69 @@ +
+

Labels

+

+ Sengi uses labels on statuses to describe them properly:
+
+
+

+ + +

Definitions

+
+
+
+ BOT +
+
+ The account is tagged as a bot +
+
+
+
+ REPLIES +
+
+ The status has replies +
+
+
+
+ THREAD +
+
+ The status is part of a thread +
+
+
+
+ X-POST +
+
+ The status was cross-posted using a software like MOA.
+ This functionality is limited to Local TL/Accounts due to API limitation. +
+
+
+
+ OLD +
+
+ The status was posted more than 3 months ago. +
+
+
+
+ REMOTE +
+
+ The status wasn't federated with your instance and was fetched remotely.
+ This functionality bypasses the blocking rules of your account/instance, you can disable it in the settings. +
+
+ + + + +

+ +

+
\ No newline at end of file diff --git a/src/app/components/tutorial-enhanced/labels-tutorial/labels-tutorial.component.scss b/src/app/components/tutorial-enhanced/labels-tutorial/labels-tutorial.component.scss new file mode 100644 index 00000000..506a0740 --- /dev/null +++ b/src/app/components/tutorial-enhanced/labels-tutorial/labels-tutorial.component.scss @@ -0,0 +1,60 @@ +.doc-label-wrapper { + margin-bottom: 15px; +} + +.doc-label { + width: 70px; + // height: 15px; + color: white; + text-align: center; + padding: 3px 0 2px 0; + font-size: 11px; + border-radius: 3px; + float: left; + + &__bot { + background-color: #017282; + } + + &__replies { + background-color: #59028f; + } + + &__thread { + background-color: #007233; + } + + &__xpost { + background-color: #9f5d00; + } + + &__old { + background-color: #960000; + } + + &__remote { + background-color: #264d94; + } +} + +.doc-label-definition { + margin-left: 85px; + position: relative; + // top: -1px; + + & a { + color: white; + text-decoration: underline; + + &:hover, &:active, &:focus { + color: rgb(218, 218, 218); + } + } + + &__gray { + display: inline-block; + margin-top: 5px; + color: #0f111a; + color: #9497a5; + } +} \ No newline at end of file diff --git a/src/app/components/tutorial-enhanced/labels-tutorial/labels-tutorial.component.spec.ts b/src/app/components/tutorial-enhanced/labels-tutorial/labels-tutorial.component.spec.ts new file mode 100644 index 00000000..d72f59e7 --- /dev/null +++ b/src/app/components/tutorial-enhanced/labels-tutorial/labels-tutorial.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LabelsTutorialComponent } from './labels-tutorial.component'; + +xdescribe('LabelsTutorialComponent', () => { + let component: LabelsTutorialComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ LabelsTutorialComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LabelsTutorialComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/tutorial-enhanced/labels-tutorial/labels-tutorial.component.ts b/src/app/components/tutorial-enhanced/labels-tutorial/labels-tutorial.component.ts new file mode 100644 index 00000000..e134f15e --- /dev/null +++ b/src/app/components/tutorial-enhanced/labels-tutorial/labels-tutorial.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-labels-tutorial', + templateUrl: './labels-tutorial.component.html', + styleUrls: ['../tutorial-enhanced.component.scss', 'labels-tutorial.component.scss'] +}) +export class LabelsTutorialComponent implements OnInit { + + constructor() { } + + ngOnInit() { + } + +} diff --git a/src/app/components/tutorial-enhanced/notifications-tutorial/notifications-tutorial.component.html b/src/app/components/tutorial-enhanced/notifications-tutorial/notifications-tutorial.component.html new file mode 100644 index 00000000..25960e8e --- /dev/null +++ b/src/app/components/tutorial-enhanced/notifications-tutorial/notifications-tutorial.component.html @@ -0,0 +1,33 @@ +
+

And... you're all set! 🎉

+

+ Please find below more information about Sengi.
+
+

+ +

Notifications

+

+ By default, Sengi doesn't need notification timelines: it has its own way to do it.
+
+ When your account will receive a new mention, follow, boost, favorite and other kind of notifications, your + avatar's icon will start flashing this way:
+
+ + +
+ If you right-click on your avatar, the account panel will automatically open and switch to the related + subsection (mentions or notifications) and show you the last entries.
+ The flashing animation will then automatically stop:
+
+ +
+ The aim of this mechanism is to prevent the flood of notification timelines (one per account) in the interface, + especially if you add a lot of accounts in Sengi.
+
+ Of course, you can disable various parts of this mechanism in the settings like "disable avatar notification", "disable account's panel autofocus", etc.
+

+
\ No newline at end of file diff --git a/src/app/components/tutorial-enhanced/notifications-tutorial/notifications-tutorial.component.scss b/src/app/components/tutorial-enhanced/notifications-tutorial/notifications-tutorial.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/tutorial-enhanced/notifications-tutorial/notifications-tutorial.component.spec.ts b/src/app/components/tutorial-enhanced/notifications-tutorial/notifications-tutorial.component.spec.ts new file mode 100644 index 00000000..4169c5fe --- /dev/null +++ b/src/app/components/tutorial-enhanced/notifications-tutorial/notifications-tutorial.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NotificationsTutorialComponent } from './notifications-tutorial.component'; + +xdescribe('NotificationsTutorialComponent', () => { + let component: NotificationsTutorialComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ NotificationsTutorialComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NotificationsTutorialComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/tutorial-enhanced/notifications-tutorial/notifications-tutorial.component.ts b/src/app/components/tutorial-enhanced/notifications-tutorial/notifications-tutorial.component.ts new file mode 100644 index 00000000..5eeb6fdc --- /dev/null +++ b/src/app/components/tutorial-enhanced/notifications-tutorial/notifications-tutorial.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-notifications-tutorial', + templateUrl: './notifications-tutorial.component.html', + styleUrls: ['../tutorial-enhanced.component.scss'] +}) +export class NotificationsTutorialComponent implements OnInit { + + constructor() { } + + ngOnInit() { + } + +} diff --git a/src/app/components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component.html b/src/app/components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component.html new file mode 100644 index 00000000..1e014e8b --- /dev/null +++ b/src/app/components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component.html @@ -0,0 +1,36 @@ +
+

Thank you!

+

+ Thank you for downloading Sengi, I hope you will enjoy using this app as much as I did when making it.
+
+ Please find below some useful informations and... that's it!
+
+

+

The app's account

+

+ +
+
+ + +

+

Alternative builds

+

+ Official Docker + build
+ Official Snap build
+
+

+

Other ressources

+

+ Official + page
+ Github + Repository
+ Maintainer's dev + blog
+
+

+
\ No newline at end of file diff --git a/src/app/components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component.scss b/src/app/components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component.scss new file mode 100644 index 00000000..43200572 --- /dev/null +++ b/src/app/components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component.scss @@ -0,0 +1,29 @@ +.follow { + color: white; + display: block; + border: 1px solid rgb(0, 84, 122); + border-radius: 5px; + width: 200px; + text-align: center; + padding: 10px 0; + margin: 0 auto 30px auto; + transition: all .2s; + box-shadow: inset 0 0 5px rgb(0, 84, 122); + + &:hover, + &:focus { + text-decoration: none; + background-color: rgb(0, 84, 122); + } + + &__disabled { + opacity: .15; + border: 1px solid gray; + + &:hover, + &:focus { + text-decoration: none; + background-color: gray; + } + } +} \ No newline at end of file diff --git a/src/app/components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component.spec.ts b/src/app/components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component.spec.ts new file mode 100644 index 00000000..6c481e4a --- /dev/null +++ b/src/app/components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ThankyouTutorialComponent } from './thankyou-tutorial.component'; + +xdescribe('ThankyouTutorialComponent', () => { + let component: ThankyouTutorialComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ThankyouTutorialComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ThankyouTutorialComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component.ts b/src/app/components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component.ts new file mode 100644 index 00000000..6f636013 --- /dev/null +++ b/src/app/components/tutorial-enhanced/thankyou-tutorial/thankyou-tutorial.component.ts @@ -0,0 +1,41 @@ +import { Component, OnInit } from '@angular/core'; + +import { ToolsService } from '../../../services/tools.service'; +import { MastodonWrapperService } from '../../../services/mastodon-wrapper.service'; +import { NotificationService } from '../../../services/notification.service'; + +@Component({ + selector: 'app-thankyou-tutorial', + templateUrl: './thankyou-tutorial.component.html', + styleUrls: ['../tutorial-enhanced.component.scss', './thankyou-tutorial.component.scss'] +}) +export class ThankyouTutorialComponent implements OnInit { + followingDisabled: boolean; + + constructor( + private readonly notificationService: NotificationService, + private readonly mastodonService: MastodonWrapperService, + private readonly toolsService: ToolsService) { } + + ngOnInit() { + } + + follow(): boolean { + if(this.followingDisabled) return; + this.followingDisabled = true; + + const accounts = this.toolsService.getAllAccounts(); + for (let acc of accounts) { + this.toolsService.findAccount(acc, "@sengi_app@mastodon.social") + .then(sengi => { + return this.mastodonService.follow(acc, sengi); + }) + .catch(err => { + this.followingDisabled = false; + this.notificationService.notifyHttpError(err, acc); + }); + } + + return false; + } +} diff --git a/src/app/components/tutorial-enhanced/tutorial-enhanced.component.html b/src/app/components/tutorial-enhanced/tutorial-enhanced.component.html new file mode 100644 index 00000000..54dfbb98 --- /dev/null +++ b/src/app/components/tutorial-enhanced/tutorial-enhanced.component.html @@ -0,0 +1,20 @@ +
+
+ + + +
+ +
\ No newline at end of file diff --git a/src/app/components/tutorial-enhanced/tutorial-enhanced.component.scss b/src/app/components/tutorial-enhanced/tutorial-enhanced.component.scss new file mode 100644 index 00000000..47fad1a3 --- /dev/null +++ b/src/app/components/tutorial-enhanced/tutorial-enhanced.component.scss @@ -0,0 +1,142 @@ +@import"variables"; +@import "commons"; +@import "panel"; + +$border-color: #1d2335; +$footer-height: 30px; + +.tutorial { + border: 1px solid $border-color; + background-color: $color-primary; + height: calc(100%); + border-radius: 2px; + + &__content { + height: calc(100% - #{$footer-height}); + } + + &__footer { + border-top: 1px solid $border-color; + height: $footer-height; + + &--button { + text-transform: uppercase; + font-size: 15px; + text-align: center; + display: inline-block; + height: $footer-height; + width: calc(33.33333% - 1px); + color: white; + padding-top: 4px; + transition: all .2s; + + &:not(:last-child) { + border-right: 1px solid $border-color; + } + + &--close { + &:hover { + text-decoration: none; + background-color: rgb(95, 0, 0); + } + } + + &--navigate { + &:hover { + text-decoration: none; + background-color: rgb(0, 117, 172); + } + } + + &--next { + background-color: rgb(230, 230, 230); + background-color: rgb(0, 74, 109); + background-color: rgb(0, 84, 122); + color: white; + + // font-weight: bold; + &:hover { + text-decoration: none; + background-color: rgb(0, 74, 109); + background-color: rgb(0, 117, 172); + } + } + + &--disabled { + color: #4e5672; + + &:hover { + cursor: default; + text-decoration: none; + background-color: rgba(0, 0, 0, 0); + } + } + } + } +} + +.tutorial-content { + font-size: 14px; + + padding: 5px 10px; + overflow-y: auto; + height: calc(100%); + + &__title { + font-size: 20px; + + } + + &__title-important { + font-size: 20px; + margin: 5px 0 15px 10px; + } + + &__subtitle { + font-size: 16px; + + } +} + +.content { + &__center { + margin: auto; + width: 48px; + display: block; + } + + &__expand { + margin: auto; + width: calc(100%); + max-width: 380px; + display: block; + + &--smaller { + max-width: 270px; + } + } +} + +.link { + color: white; + text-decoration: underline; + + &:hover, + &:active, + &:focus { + color: rgb(218, 218, 218); + } + + &__tab { + padding-left: 10px; + } +} + +.clean-outline{ + display: block; + &:focus { + background: none !important; + border: 0px !important; + outline: none !important; + } +} \ No newline at end of file diff --git a/src/app/components/tutorial-enhanced/tutorial-enhanced.component.spec.ts b/src/app/components/tutorial-enhanced/tutorial-enhanced.component.spec.ts new file mode 100644 index 00000000..e129ba7d --- /dev/null +++ b/src/app/components/tutorial-enhanced/tutorial-enhanced.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TutorialEnhancedComponent } from './tutorial-enhanced.component'; + +xdescribe('TutorialEnhancedComponent', () => { + let component: TutorialEnhancedComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ TutorialEnhancedComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TutorialEnhancedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/tutorial-enhanced/tutorial-enhanced.component.ts b/src/app/components/tutorial-enhanced/tutorial-enhanced.component.ts new file mode 100644 index 00000000..32bfd2d4 --- /dev/null +++ b/src/app/components/tutorial-enhanced/tutorial-enhanced.component.ts @@ -0,0 +1,58 @@ +import { Component, OnInit, Output, EventEmitter } from '@angular/core'; + +@Component({ + selector: 'app-tutorial-enhanced', + templateUrl: './tutorial-enhanced.component.html', + styleUrls: ['./tutorial-enhanced.component.scss'] +}) +export class TutorialEnhancedComponent implements OnInit { + @Output() closeEvent = new EventEmitter(); + + previousAvailable = false; + nextAvailable = true; + index = 0; + tutorialEnded = false; + private maxIndex = 3; + + constructor() { } + + ngOnInit() { + } + + close(): boolean { + this.closeEvent.next(); + return false; + } + + previous(): boolean { + if (this.index > 0) { + this.index--; + this.checkState(); + } + return false; + } + + next(): boolean { + this.index++; + this.checkState(); + return false; + } + + private checkState() { + if(this.index >= this.maxIndex - 1){ + this.tutorialEnded = true; + } else { + this.tutorialEnded = false; + } + + if (this.index === 0) { + this.previousAvailable = false; + } else { + this.previousAvailable = true; + } + + if (this.index === this.maxIndex){ + this.close(); + } + } +} diff --git a/src/app/services/tools.service.ts b/src/app/services/tools.service.ts index 2e68a03f..001d9912 100644 --- a/src/app/services/tools.service.ts +++ b/src/app/services/tools.service.ts @@ -119,6 +119,11 @@ export class ToolsService { return regAccounts.filter(x => x.isSelected); } + getAllAccounts(): AccountInfo[] { + let regAccounts = this.store.snapshot().registeredaccounts.accounts; + return regAccounts; + } + getAccountById(accountId: string): AccountInfo { let regAccounts = this.store.snapshot().registeredaccounts.accounts; return regAccounts.find(x => x.id === accountId); diff --git a/src/assets/docs/privacy.html b/src/assets/docs/privacy.html new file mode 100644 index 00000000..c3597a8f --- /dev/null +++ b/src/assets/docs/privacy.html @@ -0,0 +1,20 @@ + + + + + + + Privacy Policy + + + +

Privacy Policy

+

Your privacy is important to us. It is Sengi's policy to respect your privacy regarding any information we may collect from you across our website, https://sengi.nicolas-constant.com, and other sites we own and operate.

+

We don't ask nor retain any personal information.

+

We don’t share any personally identifying information publicly or with third-parties, except when required to by law.

+

Our website may link to external sites that are not operated by us. Please be aware that we have no control over the content and practices of these sites, and cannot accept responsibility or liability for their respective privacy policies.

+

Your continued use of our website will be regarded as acceptance of our practices around privacy and personal information. If you have any questions about how we handle user data and personal information, feel free to contact us.

+

This policy is effective as of 1 September 2020.

+ + + \ No newline at end of file diff --git a/src/assets/img/account.png b/src/assets/img/account.png new file mode 100644 index 00000000..5a59a301 Binary files /dev/null and b/src/assets/img/account.png differ diff --git a/src/assets/img/labels.png b/src/assets/img/labels.png new file mode 100644 index 00000000..e55d89ff Binary files /dev/null and b/src/assets/img/labels.png differ diff --git a/src/assets/video/flashing.gif b/src/assets/video/flashing.gif new file mode 100644 index 00000000..132b9a86 Binary files /dev/null and b/src/assets/video/flashing.gif differ diff --git a/src/assets/video/flashing.mp4 b/src/assets/video/flashing.mp4 new file mode 100644 index 00000000..6b20318c Binary files /dev/null and b/src/assets/video/flashing.mp4 differ diff --git a/src/assets/video/notification.mp4 b/src/assets/video/notification.mp4 new file mode 100644 index 00000000..61b503c3 Binary files /dev/null and b/src/assets/video/notification.mp4 differ