mirror of
https://github.com/standardnotes/app
synced 2026-09-19 18:13:48 -04:00
Compare commits
79
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29f2c18311 | ||
|
|
e37cd1d299 | ||
|
|
e0d48afbe2 | ||
|
|
7d9dabb818 | ||
|
|
991a7a521f | ||
|
|
a49549177c | ||
|
|
6097cb50d9 | ||
|
|
9d532e83e1 | ||
|
|
1bf3a99911 | ||
|
|
67494b647e | ||
|
|
54ba30ea1d | ||
|
|
e2c04b3576 | ||
|
|
9c06b6ae71 | ||
|
|
2d687d9786 | ||
|
|
6a7c5277f8 | ||
|
|
894167520d | ||
|
|
a1317b2bfd | ||
|
|
a6be2f0a9a | ||
|
|
6295f179a1 | ||
|
|
3bf670ece7 | ||
|
|
a3978f142b | ||
|
|
7a24ea3c25 | ||
|
|
56c522b5c3 | ||
|
|
ade6c8bb1e | ||
|
|
d55b2527d5 | ||
|
|
20354a926a | ||
|
|
3d794bb12e | ||
|
|
d9630c99c7 | ||
|
|
5ff795d636 | ||
|
|
86e9c90c10 | ||
|
|
0902580b79 | ||
|
|
202a132482 | ||
|
|
23331788f6 | ||
|
|
f95a4fe981 | ||
|
|
4be9b51481 | ||
|
|
6fdd8b3729 | ||
|
|
4260c1ec4a | ||
|
|
63281b9998 | ||
|
|
b97ed403bf | ||
|
|
af6ac568f0 | ||
|
|
de3836869d | ||
|
|
d28b20008c | ||
|
|
7bbe8d3842 | ||
|
|
8a40364c6c | ||
|
|
752448f9e6 | ||
|
|
79b47150d6 | ||
|
|
ed30fec2ba | ||
|
|
61cb95dc4a | ||
|
|
00317fda88 | ||
|
|
83a731b076 | ||
|
|
f4479feae7 | ||
|
|
f37bd487a2 | ||
|
|
9c43c87f14 | ||
|
|
61cdfc6030 | ||
|
|
f408950aa4 | ||
|
|
d1c295751d | ||
|
|
e42e2d6130 | ||
|
|
572c9b7dfa | ||
|
|
14ea00dc28 | ||
|
|
daaee89639 | ||
|
|
da37c421db | ||
|
|
85bd411d8f | ||
|
|
63f14d318d | ||
|
|
95cd682d49 | ||
|
|
941eeea4e3 | ||
|
|
991de1ddf5 | ||
|
|
044776d937 | ||
|
|
83fa6adbeb | ||
|
|
ce908c8ec4 | ||
|
|
98c61de501 | ||
|
|
198efdc41c | ||
|
|
cace6522f6 | ||
|
|
f3a9717883 | ||
|
|
00d30ca003 | ||
|
|
8574c42706 | ||
|
|
0f73ea8c4e | ||
|
|
12ccd22d78 | ||
|
|
d891ac7578 | ||
|
|
ce0db04646 |
@@ -13,6 +13,7 @@ jobs:
|
||||
env:
|
||||
CSC_LINK: ${{ secrets.MAC_CI_KEYS }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.MAC_CI_KEYS_PASSWORD }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
NOTARIZE_APPLE_ID: ${{ secrets.NOTARIZE_APPLE_ID }}
|
||||
NOTARIZE_APPLE_ID_PASSWORD: ${{ secrets.NOTARIZE_APPLE_ID_PASSWORD }}
|
||||
defaults:
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -26,6 +26,7 @@
|
||||
"build:snjs": "yarn workspaces foreach -p --topological-dev --verbose -R --from @standardnotes/snjs run build",
|
||||
"build:services": "yarn workspaces foreach -pt --topological-dev --verbose -R --from @standardnotes/services run build",
|
||||
"build:api": "yarn workspaces foreach -pt --topological-dev --verbose -R --from @standardnotes/api run build",
|
||||
"start:web": "yarn workspace @standardnotes/web start",
|
||||
"e2e": "lerna run start:test-server --scope=@standardnotes/snjs",
|
||||
"e2e:test": "yarn dlx mocha-headless-chrome --timeout 3600000 -f http://localhost:9001/mocha/test.html",
|
||||
"reset": "find . -type dir -name node_modules | xargs rm -rf && rm -rf yarn.lock && yarn install",
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.26.69](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api
|
||||
|
||||
## [1.26.68](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-26)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api",
|
||||
"version": "1.26.68",
|
||||
"version": "1.26.69",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,126 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.1.321](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.320](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.319](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.318](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.317](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.316](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.315](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.314](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.313](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.312](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.311](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.310](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.309](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.308](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.307](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.306](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.305](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.304](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.303](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.302](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.301](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.300](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.299](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.298](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.297](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.296](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.295](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.294](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.293](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.292](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-28)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
## [1.1.291](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-27)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/clipper
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@standardnotes/clipper",
|
||||
"description": "Web clipper browser extension for Standard Notes",
|
||||
"version": "1.1.291",
|
||||
"version": "1.1.321",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build-mv2": "yarn clean && webpack --config ./webpack.config.prod.js",
|
||||
|
||||
@@ -3,6 +3,126 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [3.108.255](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.254](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.253](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.252](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.251](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.250](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.249](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.248](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.247](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.246](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.245](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.244](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.243](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.242](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.241](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.240](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.239](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.238](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.237](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.236](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.235](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.234](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.233](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.232](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.231](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.230](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.229](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.228](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.227](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.226](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-28)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.108.225](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-27)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@standardnotes/desktop",
|
||||
"main": "./app/dist/index.js",
|
||||
"version": "3.108.225",
|
||||
"version": "3.108.255",
|
||||
"license": "AGPL-3.0",
|
||||
"author": "Standard Notes.",
|
||||
"private": true,
|
||||
@@ -53,6 +53,7 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "*",
|
||||
"@babel/preset-env": "*",
|
||||
"@electron/notarize": "^2.1.0",
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"@types/lodash": "^4.14.189",
|
||||
"@types/mime-types": "^2.1.1",
|
||||
@@ -63,7 +64,6 @@
|
||||
"babel-loader": "^9.1.0",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"electron-builder": "23.6.0",
|
||||
"electron-notarize": "^1.2.1",
|
||||
"eslint": "*",
|
||||
"eslint-config-prettier": "^8.9.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const electronNotarize = require('electron-notarize')
|
||||
const electronNotarize = require('@electron/notarize')
|
||||
|
||||
module.exports = async function (params) {
|
||||
const platformName = params.electronPlatformName
|
||||
@@ -21,6 +21,7 @@ module.exports = async function (params) {
|
||||
try {
|
||||
electronNotarize
|
||||
.notarize({
|
||||
teamId: process.env.APPLE_TEAM_ID,
|
||||
appBundleId: appId,
|
||||
appPath: appPath,
|
||||
appleId: process.env.NOTARIZE_APPLE_ID,
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.21.91](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/encryption
|
||||
|
||||
## [1.21.90](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-26)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/encryption
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/encryption",
|
||||
"version": "1.21.90",
|
||||
"version": "1.21.91",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.28.103](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/filepicker
|
||||
|
||||
## [1.28.102](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/filepicker
|
||||
|
||||
## [1.28.101](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-26)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/filepicker
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/filepicker",
|
||||
"version": "1.28.101",
|
||||
"version": "1.28.103",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.18.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files
|
||||
|
||||
# [1.18.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
### Features
|
||||
|
||||
* When exporting a Super note, embedded files can be inlined in the note or exported along the note in a zip file. You can now also choose to include frontmatter when exporting to Markdown format. ([991de1d](https://github.com/standardnotes/app/commit/991de1ddf5dbb1016348d603d244699c676d9b5f)), closes [#2610](https://github.com/standardnotes/app/issues/2610)
|
||||
|
||||
## [1.17.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-26)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/files",
|
||||
"version": "1.17.20",
|
||||
"version": "1.18.1",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
import { FileItem } from '@standardnotes/models'
|
||||
import { GenerateUuid } from '@standardnotes/services'
|
||||
|
||||
export interface SuperConverterServiceInterface {
|
||||
isValidSuperString(superString: string): boolean
|
||||
convertSuperStringToOtherFormat: (superString: string, toFormat: 'txt' | 'md' | 'html' | 'json') => string
|
||||
convertSuperStringToOtherFormat: (superString: string, toFormat: 'txt' | 'md' | 'html' | 'json') => Promise<string>
|
||||
convertOtherFormatToSuperString: (otherFormatString: string, fromFormat: 'txt' | 'md' | 'html' | 'json') => string
|
||||
getEmbeddedFileIDsFromSuperString(superString: string): string[]
|
||||
uploadAndReplaceInlineFilesInSuperString(
|
||||
superString: string,
|
||||
uploadFile: (file: File) => Promise<FileItem | undefined>,
|
||||
linkFile: (file: FileItem) => Promise<void>,
|
||||
generateUuid: GenerateUuid,
|
||||
): Promise<string>
|
||||
}
|
||||
|
||||
@@ -3,6 +3,144 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [3.56.237](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-11)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed issue on Android where only one selected file would be uploaded instead of all ([e0d48af](https://github.com/standardnotes/app/commit/e0d48afbe22987624214b18ed613b0c31e6eb901))
|
||||
|
||||
## [3.56.236](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.235](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.234](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.233](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.232](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.231](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.230](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.229](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.228](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.227](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.226](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.225](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.224](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.223](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.222](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.221](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed white flash issue when starting app on iOS ([d28b200](https://github.com/standardnotes/app/commit/d28b20008c6c1dcf8876ca4613e468fa5511ae3e))
|
||||
|
||||
## [3.56.220](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.219](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.218](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.217](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.216](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.215](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.214](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed issue where a brief flash of white would appear when starting the app on mobile ([572c9b7](https://github.com/standardnotes/app/commit/572c9b7dfaa42773c050772940e383df2940a79f))
|
||||
|
||||
## [3.56.213](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.212](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.211](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.210](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.209](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.208](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.207](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.206](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.205](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-28)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.56.204](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-27)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
@@ -3,13 +3,17 @@ GEM
|
||||
specs:
|
||||
CFPropertyList (3.0.6)
|
||||
rexml
|
||||
activesupport (6.1.5)
|
||||
activesupport (7.1.1)
|
||||
base64
|
||||
bigdecimal
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
connection_pool (>= 2.2.5)
|
||||
drb
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
mutex_m
|
||||
tzinfo (~> 2.0)
|
||||
zeitwerk (~> 2.3)
|
||||
addressable (2.8.4)
|
||||
addressable (2.8.5)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
algoliasearch (1.27.5)
|
||||
httpclient (~> 2.8, >= 2.8.3)
|
||||
@@ -17,32 +21,34 @@ GEM
|
||||
artifactory (3.0.15)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.755.0)
|
||||
aws-sdk-core (3.171.0)
|
||||
aws-partitions (1.843.0)
|
||||
aws-sdk-core (3.185.1)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
aws-sigv4 (~> 1.5)
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
aws-sdk-kms (1.63.0)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sdk-kms (1.72.0)
|
||||
aws-sdk-core (~> 3, >= 3.184.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.121.0)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sdk-s3 (1.136.0)
|
||||
aws-sdk-core (~> 3, >= 3.181.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.4)
|
||||
aws-sigv4 (1.5.2)
|
||||
aws-sigv4 (~> 1.6)
|
||||
aws-sigv4 (1.6.1)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
babosa (1.0.4)
|
||||
claide (1.0.3)
|
||||
cocoapods (1.11.3)
|
||||
base64 (0.1.1)
|
||||
bigdecimal (3.1.4)
|
||||
claide (1.1.0)
|
||||
cocoapods (1.14.2)
|
||||
addressable (~> 2.8)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.11.3)
|
||||
cocoapods-core (= 1.14.2)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 1.4.0, < 2.0)
|
||||
cocoapods-downloader (>= 2.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
cocoapods-search (>= 1.0.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.4.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.6.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
@@ -50,10 +56,10 @@ GEM
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.8.0)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (>= 1.0, < 3.0)
|
||||
xcodeproj (>= 1.21.0, < 2.0)
|
||||
cocoapods-core (1.11.3)
|
||||
activesupport (>= 5.0, < 7)
|
||||
ruby-macho (>= 2.3.0, < 3.0)
|
||||
xcodeproj (>= 1.23.0, < 2.0)
|
||||
cocoapods-core (1.14.2)
|
||||
activesupport (>= 5.0, < 8)
|
||||
addressable (~> 2.8)
|
||||
algoliasearch (~> 1.0)
|
||||
concurrent-ruby (~> 1.1)
|
||||
@@ -63,7 +69,7 @@ GEM
|
||||
public_suffix (~> 4.0)
|
||||
typhoeus (~> 1.0)
|
||||
cocoapods-deintegrate (1.0.5)
|
||||
cocoapods-downloader (1.5.1)
|
||||
cocoapods-downloader (2.0)
|
||||
cocoapods-plugins (1.0.0)
|
||||
nap
|
||||
cocoapods-search (1.0.1)
|
||||
@@ -75,18 +81,21 @@ GEM
|
||||
colored2 (3.1.2)
|
||||
commander (4.6.0)
|
||||
highline (~> 2.0.0)
|
||||
concurrent-ruby (1.1.9)
|
||||
concurrent-ruby (1.2.2)
|
||||
connection_pool (2.4.1)
|
||||
declarative (0.0.20)
|
||||
digest-crc (0.6.4)
|
||||
digest-crc (0.6.5)
|
||||
rake (>= 12.0.0, < 14.0.0)
|
||||
domain_name (0.5.20190701)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
dotenv (2.8.1)
|
||||
drb (2.1.1)
|
||||
ruby2_keywords
|
||||
emoji_regex (3.2.3)
|
||||
escape (0.0.4)
|
||||
ethon (0.15.0)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
excon (0.99.0)
|
||||
excon (0.104.0)
|
||||
faraday (1.10.3)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
@@ -115,8 +124,8 @@ GEM
|
||||
faraday-retry (1.0.3)
|
||||
faraday_middleware (1.2.0)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.2.6)
|
||||
fastlane (2.212.2)
|
||||
fastimage (2.2.7)
|
||||
fastlane (2.216.0)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.8, < 3.0.0)
|
||||
artifactory (~> 3.0)
|
||||
@@ -137,10 +146,11 @@ GEM
|
||||
google-apis-playcustomapp_v1 (~> 0.1)
|
||||
google-cloud-storage (~> 1.31)
|
||||
highline (~> 2.0)
|
||||
http-cookie (~> 1.0.5)
|
||||
json (< 3.0.0)
|
||||
jwt (>= 2.1.0, < 3)
|
||||
mini_magick (>= 4.9.4, < 5.0.0)
|
||||
multipart-post (~> 2.0.0)
|
||||
multipart-post (>= 2.0.0, < 3.0.0)
|
||||
naturally (~> 2.2)
|
||||
optparse (~> 0.1.1)
|
||||
plist (>= 3.1.0, < 4.0.0)
|
||||
@@ -148,21 +158,21 @@ GEM
|
||||
security (= 0.1.3)
|
||||
simctl (~> 1.6.3)
|
||||
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||
terminal-table (>= 1.4.5, < 2.0.0)
|
||||
terminal-table (~> 3)
|
||||
tty-screen (>= 0.6.3, < 1.0.0)
|
||||
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||
word_wrap (~> 1.0.0)
|
||||
xcodeproj (>= 1.13.0, < 2.0.0)
|
||||
xcpretty (~> 0.3.0)
|
||||
xcpretty-travis-formatter (>= 0.0.3)
|
||||
fastlane-plugin-bundletool (1.0.5)
|
||||
ffi (1.15.5)
|
||||
fastlane-plugin-bundletool (1.0.9)
|
||||
ffi (1.16.3)
|
||||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
google-apis-androidpublisher_v3 (0.40.0)
|
||||
google-apis-androidpublisher_v3 (0.51.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-core (0.11.0)
|
||||
google-apis-core (0.11.2)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (>= 0.16.2, < 2.a)
|
||||
httpclient (>= 2.8.1, < 3.a)
|
||||
@@ -191,10 +201,9 @@ GEM
|
||||
google-cloud-core (~> 1.6)
|
||||
googleauth (>= 0.16.2, < 2.a)
|
||||
mini_mime (~> 1.0)
|
||||
googleauth (1.5.2)
|
||||
googleauth (1.8.1)
|
||||
faraday (>= 0.17.3, < 3.a)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
memoist (~> 0.16)
|
||||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (>= 0.16, < 2.a)
|
||||
@@ -202,18 +211,18 @@ GEM
|
||||
http-cookie (1.0.5)
|
||||
domain_name (~> 0.5)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.10.0)
|
||||
i18n (1.14.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jmespath (1.6.2)
|
||||
json (2.6.3)
|
||||
jwt (2.7.0)
|
||||
memoist (0.16.2)
|
||||
jwt (2.7.1)
|
||||
mini_magick (4.12.0)
|
||||
mini_mime (1.1.2)
|
||||
minitest (5.15.0)
|
||||
mini_mime (1.1.5)
|
||||
minitest (5.20.0)
|
||||
molinillo (0.8.0)
|
||||
multi_json (1.15.0)
|
||||
multipart-post (2.0.0)
|
||||
multipart-post (2.3.0)
|
||||
mutex_m (0.1.2)
|
||||
nanaimo (0.3.0)
|
||||
nap (1.1.0)
|
||||
naturally (2.2.1)
|
||||
@@ -222,19 +231,19 @@ GEM
|
||||
os (1.1.4)
|
||||
plist (3.7.0)
|
||||
public_suffix (4.0.7)
|
||||
rake (13.0.6)
|
||||
rake (13.1.0)
|
||||
representable (3.2.0)
|
||||
declarative (< 0.1.0)
|
||||
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||
uber (< 0.2.0)
|
||||
retriable (3.1.2)
|
||||
rexml (3.2.5)
|
||||
rexml (3.2.6)
|
||||
rouge (2.0.7)
|
||||
ruby-macho (2.5.1)
|
||||
ruby2_keywords (0.0.5)
|
||||
rubyzip (2.3.2)
|
||||
security (0.1.3)
|
||||
signet (0.17.0)
|
||||
signet (0.18.0)
|
||||
addressable (~> 2.8)
|
||||
faraday (>= 0.17.5, < 3.a)
|
||||
jwt (>= 1.5, < 3.0)
|
||||
@@ -243,8 +252,8 @@ GEM
|
||||
CFPropertyList
|
||||
naturally
|
||||
terminal-notifier (2.0.0)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
terminal-table (3.0.2)
|
||||
unicode-display_width (>= 1.1.1, < 3)
|
||||
trailblazer-option (0.1.2)
|
||||
tty-cursor (0.7.1)
|
||||
tty-screen (0.8.1)
|
||||
@@ -252,19 +261,19 @@ GEM
|
||||
tty-cursor (~> 0.7)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.4)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
uber (0.1.0)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.8.2)
|
||||
unicode-display_width (1.8.0)
|
||||
unicode-display_width (2.5.0)
|
||||
webrick (1.8.1)
|
||||
word_wrap (1.0.0)
|
||||
xcode-install (2.8.0)
|
||||
claide (>= 0.9.1, < 1.1.0)
|
||||
xcode-install (2.8.1)
|
||||
claide (>= 0.9.1)
|
||||
fastlane (>= 2.1.0, < 3.0.0)
|
||||
xcodeproj (1.22.0)
|
||||
xcodeproj (1.23.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
@@ -275,14 +284,13 @@ GEM
|
||||
rouge (~> 2.0.7)
|
||||
xcpretty-travis-formatter (1.0.1)
|
||||
xcpretty (~> 0.2, >= 0.0.7)
|
||||
zeitwerk (2.5.4)
|
||||
|
||||
PLATFORMS
|
||||
arm64-darwin-21
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
cocoapods (~> 1.11, >= 1.11.3)
|
||||
cocoapods (~> 1.12)
|
||||
fastlane
|
||||
fastlane-plugin-bundletool
|
||||
xcode-install
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_monochrome" />
|
||||
</adaptive-icon>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="background">#2E2E2E</color>
|
||||
<color name="background">#000000</color>
|
||||
</resources>
|
||||
@@ -25,6 +25,12 @@
|
||||
};
|
||||
</script>
|
||||
<script src="web-src/app.js"></script>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
background-color: black;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17125"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
@@ -17,7 +16,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
@@ -25,9 +24,4 @@
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -507,6 +507,11 @@ PODS:
|
||||
- React-Core
|
||||
- RNKeychain (8.1.2):
|
||||
- React-Core
|
||||
- RNNotifee (7.8.0):
|
||||
- React-Core
|
||||
- RNNotifee/NotifeeCore (= 7.8.0)
|
||||
- RNNotifee/NotifeeCore (7.8.0):
|
||||
- React-Core
|
||||
- RNPrivacySnapshot (1.0.0):
|
||||
- React-Core
|
||||
- RNShare (9.4.1):
|
||||
@@ -593,6 +598,7 @@ DEPENDENCIES:
|
||||
- RNFS (from `../node_modules/react-native-fs`)
|
||||
- RNIap (from `../node_modules/react-native-iap`)
|
||||
- RNKeychain (from `../node_modules/react-native-keychain`)
|
||||
- "RNNotifee (from `../node_modules/@notifee/react-native`)"
|
||||
- RNPrivacySnapshot (from `../node_modules/react-native-privacy-snapshot`)
|
||||
- RNShare (from `../node_modules/react-native-share`)
|
||||
- RNStoreReview (from `../node_modules/react-native-store-review`)
|
||||
@@ -716,6 +722,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native-iap"
|
||||
RNKeychain:
|
||||
:path: "../node_modules/react-native-keychain"
|
||||
RNNotifee:
|
||||
:path: "../node_modules/@notifee/react-native"
|
||||
RNPrivacySnapshot:
|
||||
:path: "../node_modules/react-native-privacy-snapshot"
|
||||
RNShare:
|
||||
@@ -789,6 +797,7 @@ SPEC CHECKSUMS:
|
||||
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
|
||||
RNIap: c397f49db45af3b10dca64b2325f21bb8078ad21
|
||||
RNKeychain: a65256b6ca6ba6976132cc4124b238a5b13b3d9c
|
||||
RNNotifee: f3c01b391dd8e98e67f539f9a35a9cbcd3bae744
|
||||
RNPrivacySnapshot: 8eaf571478a353f2e5184f5c803164f22428b023
|
||||
RNShare: 32e97adc8d8c97d4a26bcdd3c45516882184f8b6
|
||||
RNStoreReview: 923b1c888c13469925bf0256dc2c046eab557ce5
|
||||
@@ -800,4 +809,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: c3b827e3c92cdf3199eddc52083480826e717b88
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
COCOAPODS: 1.14.2
|
||||
|
||||
@@ -991,6 +991,7 @@
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
"-Wl -ld_classic ",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
@@ -1059,6 +1060,7 @@
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
"-Wl -ld_classic ",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
|
||||
@@ -24,14 +24,15 @@
|
||||
|
||||
[self clearWebEditorCache];
|
||||
|
||||
NSString *CFBundleIdentifier = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
|
||||
|
||||
NSDictionary * initialProperties = @{@"env" : [CFBundleIdentifier isEqualToString:@"com.standardnotes.standardnotes.dev"] ? @"dev" : @"prod"};
|
||||
|
||||
self.moduleName = @"StandardNotes";
|
||||
self.initialProps = @{};
|
||||
|
||||
return [super application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
BOOL success = [super application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
if (success) {
|
||||
self.window.rootViewController.view.backgroundColor = [UIColor colorWithWhite:0.0 alpha:1.0];
|
||||
self.window.backgroundColor = [UIColor colorWithWhite:0.0 alpha:1.0];
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/mobile",
|
||||
"version": "3.56.204",
|
||||
"version": "3.56.237",
|
||||
"author": "Standard Notes.",
|
||||
"private": true,
|
||||
"license": "AGPL-3.0",
|
||||
@@ -72,6 +72,7 @@
|
||||
"node": ">=16"
|
||||
},
|
||||
"dependencies": {
|
||||
"@notifee/react-native": "^7.8.0",
|
||||
"react-native-store-review": "^0.4.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ import { Database } from './Database/Database'
|
||||
import { isLegacyIdentifier } from './Database/LegacyIdentifier'
|
||||
import { LegacyKeyValueStore } from './Database/LegacyKeyValueStore'
|
||||
import Keychain from './Keychain'
|
||||
import notifee, { AuthorizationStatus, Notification, NotificationSettings } from '@notifee/react-native'
|
||||
|
||||
export type BiometricsType = 'Fingerprint' | 'Face ID' | 'Biometrics' | 'Touch ID'
|
||||
|
||||
@@ -71,11 +72,57 @@ export class MobileDevice implements MobileDeviceInterface {
|
||||
private keyValueStore = new LegacyKeyValueStore()
|
||||
private databases = new Map<string, Database>()
|
||||
|
||||
private notificationSettings: NotificationSettings | undefined
|
||||
|
||||
constructor(
|
||||
private stateObserverService?: AppStateObserverService,
|
||||
private androidBackHandlerService?: AndroidBackHandlerService,
|
||||
private colorSchemeService?: ColorSchemeObserverService,
|
||||
) {}
|
||||
) {
|
||||
this.initializeNotifications().catch(console.error)
|
||||
}
|
||||
|
||||
async initializeNotifications() {
|
||||
if (Platform.OS !== 'android') {
|
||||
return
|
||||
}
|
||||
|
||||
await notifee.createChannel({
|
||||
id: 'files',
|
||||
name: 'File Upload/Download',
|
||||
})
|
||||
|
||||
const didAskForPermission = await this.keyValueStore.getValue<boolean>('didAskForNotificationPermission')
|
||||
|
||||
if (!didAskForPermission) {
|
||||
this.notificationSettings = await notifee.requestPermission()
|
||||
await this.keyValueStore.set('didAskForNotificationPermission', 'true')
|
||||
}
|
||||
|
||||
this.notificationSettings = await notifee.getNotificationSettings()
|
||||
}
|
||||
|
||||
async canDisplayNotifications(): Promise<boolean> {
|
||||
if (!this.notificationSettings) {
|
||||
return false
|
||||
}
|
||||
|
||||
return this.notificationSettings.authorizationStatus >= AuthorizationStatus.AUTHORIZED
|
||||
}
|
||||
|
||||
async displayNotification(options: Notification): Promise<string> {
|
||||
return await notifee.displayNotification({
|
||||
...options,
|
||||
android: {
|
||||
...options.android,
|
||||
channelId: 'files',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async cancelNotification(notificationId: string): Promise<void> {
|
||||
await notifee.cancelNotification(notificationId)
|
||||
}
|
||||
|
||||
async removeRawStorageValuesForIdentifier(identifier: string): Promise<void> {
|
||||
await this.removeRawStorageValue(namespacedKey(identifier, RawStorageKey.SnjsVersion))
|
||||
|
||||
@@ -14,6 +14,7 @@ import { MobileDevice, MobileDeviceEvent } from './Lib/MobileDevice'
|
||||
import { IsDev } from './Lib/Utils'
|
||||
import { ReceivedSharedItemsHandler } from './ReceivedSharedItemsHandler'
|
||||
import { ReviewService } from './ReviewService'
|
||||
import notifee, { EventType } from '@notifee/react-native'
|
||||
|
||||
const LoggingEnabled = IsDev
|
||||
|
||||
@@ -117,6 +118,34 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
|
||||
}
|
||||
}, [webViewRef, stateService, device, androidBackHandlerService, colorSchemeService])
|
||||
|
||||
useEffect(() => {
|
||||
return notifee.onForegroundEvent(({ type, detail }) => {
|
||||
if (type !== EventType.ACTION_PRESS) {
|
||||
return
|
||||
}
|
||||
|
||||
const { notification, pressAction } = detail
|
||||
|
||||
if (!notification || !pressAction) {
|
||||
return
|
||||
}
|
||||
|
||||
if (pressAction.id !== 'open-file') {
|
||||
return
|
||||
}
|
||||
|
||||
webViewRef.current?.postMessage(
|
||||
JSON.stringify({
|
||||
reactNativeEvent: ReactNativeToWebEvent.OpenFilePreview,
|
||||
messageType: 'event',
|
||||
messageData: {
|
||||
id: notification.id,
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const observer = device.addMobileDeviceEventReceiver((event) => {
|
||||
if (event === MobileDeviceEvent.RequestsWebViewReload) {
|
||||
@@ -242,6 +271,10 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
|
||||
setShowAndroidWebviewUpdatePrompt(true)
|
||||
return
|
||||
}
|
||||
if (message === 'appLoaded') {
|
||||
setDidLoadEnd(true)
|
||||
return
|
||||
}
|
||||
try {
|
||||
const functionData = JSON.parse(message)
|
||||
void onFunctionMessage(functionData.functionName, functionData.messageId, functionData.args)
|
||||
@@ -308,6 +341,8 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
|
||||
})
|
||||
}, [device])
|
||||
|
||||
const [didLoadEnd, setDidLoadEnd] = useState(false)
|
||||
|
||||
if (showAndroidWebviewUpdatePrompt) {
|
||||
return (
|
||||
<View
|
||||
@@ -350,41 +385,52 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
|
||||
}
|
||||
|
||||
return (
|
||||
<WebView
|
||||
ref={webViewRef}
|
||||
source={{ uri: sourceUri }}
|
||||
style={{ backgroundColor: 'black' }}
|
||||
originWhitelist={['*']}
|
||||
onError={(err) => console.error('An error has occurred', err)}
|
||||
onHttpError={() => console.error('An HTTP error occurred')}
|
||||
onMessage={onMessage}
|
||||
onContentProcessDidTerminate={() => {
|
||||
webViewRef.current?.reload()
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
backgroundColor: '#000000',
|
||||
}}
|
||||
onRenderProcessGone={() => {
|
||||
webViewRef.current?.reload()
|
||||
}}
|
||||
hideKeyboardAccessoryView={true}
|
||||
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
|
||||
allowFileAccess={true}
|
||||
allowUniversalAccessFromFileURLs={true}
|
||||
injectedJavaScriptBeforeContentLoaded={injectedJS}
|
||||
bounces={false}
|
||||
keyboardDisplayRequiresUserAction={false}
|
||||
allowsInlineMediaPlayback={requireInlineMediaPlaybackForMomentsFeature}
|
||||
mediaPlaybackRequiresUserAction={requireMediaUserInteractionForMomentsFeature}
|
||||
scalesPageToFit={true}
|
||||
/**
|
||||
* This disables the global window scroll but keeps scroll within div elements like lists and textareas.
|
||||
* This is needed to prevent the keyboard from pushing the webview up and down when it appears and disappears.
|
||||
*/
|
||||
scrollEnabled={false}
|
||||
overScrollMode="never"
|
||||
nativeConfig={Platform.select({
|
||||
android: {
|
||||
component: CustomAndroidWebView,
|
||||
} as WebViewNativeConfig,
|
||||
})}
|
||||
/>
|
||||
>
|
||||
<WebView
|
||||
ref={webViewRef}
|
||||
source={{ uri: sourceUri }}
|
||||
style={{
|
||||
backgroundColor: Platform.OS === 'ios' ? 'transparent' : '#000000',
|
||||
opacity: didLoadEnd ? 1 : 0,
|
||||
}}
|
||||
originWhitelist={['*']}
|
||||
onError={(err) => console.error('An error has occurred', err)}
|
||||
onHttpError={() => console.error('An HTTP error occurred')}
|
||||
onMessage={onMessage}
|
||||
onContentProcessDidTerminate={() => {
|
||||
webViewRef.current?.reload()
|
||||
}}
|
||||
onRenderProcessGone={() => {
|
||||
webViewRef.current?.reload()
|
||||
}}
|
||||
hideKeyboardAccessoryView={true}
|
||||
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
|
||||
allowFileAccess={true}
|
||||
allowUniversalAccessFromFileURLs={true}
|
||||
injectedJavaScriptBeforeContentLoaded={injectedJS}
|
||||
bounces={false}
|
||||
keyboardDisplayRequiresUserAction={false}
|
||||
allowsInlineMediaPlayback={requireInlineMediaPlaybackForMomentsFeature}
|
||||
mediaPlaybackRequiresUserAction={requireMediaUserInteractionForMomentsFeature}
|
||||
scalesPageToFit={true}
|
||||
/**
|
||||
* This disables the global window scroll but keeps scroll within div elements like lists and textareas.
|
||||
* This is needed to prevent the keyboard from pushing the webview up and down when it appears and disappears.
|
||||
*/
|
||||
scrollEnabled={false}
|
||||
overScrollMode="never"
|
||||
nativeConfig={Platform.select({
|
||||
android: {
|
||||
component: CustomAndroidWebView,
|
||||
} as WebViewNativeConfig,
|
||||
})}
|
||||
webviewDebuggingEnabled
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.49.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
### Features
|
||||
|
||||
* When exporting a Super note, embedded files can be inlined in the note or exported along the note in a zip file. You can now also choose to include frontmatter when exporting to Markdown format. ([991de1d](https://github.com/standardnotes/app/commit/991de1ddf5dbb1016348d603d244699c676d9b5f)), closes [#2610](https://github.com/standardnotes/app/issues/2610)
|
||||
|
||||
## [1.48.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-26)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/models
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/models",
|
||||
"version": "1.48.1",
|
||||
"version": "1.49.0",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
||||
@@ -40,6 +40,8 @@ export const PrefDefaults = {
|
||||
[PrefKey.ClipperDefaultTagUuid]: undefined,
|
||||
[PrefKey.DefaultEditorIdentifier]: NativeFeatureIdentifier.TYPES.PlainEditor,
|
||||
[PrefKey.SuperNoteExportFormat]: 'json',
|
||||
[PrefKey.SuperNoteExportEmbedBehavior]: 'reference',
|
||||
[PrefKey.SuperNoteExportUseMDFrontmatter]: true,
|
||||
[PrefKey.SystemViewPreferences]: {},
|
||||
[PrefKey.AuthenticatorNames]: '',
|
||||
[PrefKey.ComponentPreferences]: {},
|
||||
|
||||
@@ -41,6 +41,8 @@ export enum PrefKey {
|
||||
ClipperDefaultTagUuid = 'clipperDefaultTagUuid',
|
||||
SystemViewPreferences = 'systemViewPreferences',
|
||||
SuperNoteExportFormat = 'superNoteExportFormat',
|
||||
SuperNoteExportEmbedBehavior = 'superNoteExportEmbedBehavior',
|
||||
SuperNoteExportUseMDFrontmatter = 'superNoteExportUseMDFrontmatter',
|
||||
AuthenticatorNames = 'authenticatorNames',
|
||||
PaneGesturesEnabled = 'paneGesturesEnabled',
|
||||
ComponentPreferences = 'componentPreferences',
|
||||
@@ -83,6 +85,8 @@ export type PrefValue = {
|
||||
[PrefKey.ClipperDefaultTagUuid]: string | undefined
|
||||
[PrefKey.SystemViewPreferences]: Partial<Record<SystemViewId, TagPreferences>>
|
||||
[PrefKey.SuperNoteExportFormat]: 'json' | 'md' | 'html'
|
||||
[PrefKey.SuperNoteExportEmbedBehavior]: 'reference' | 'inline' | 'separate'
|
||||
[PrefKey.SuperNoteExportUseMDFrontmatter]: boolean
|
||||
[PrefKey.AuthenticatorNames]: string
|
||||
[PrefKey.PaneGesturesEnabled]: boolean
|
||||
[PrefKey.ComponentPreferences]: AllComponentPreferences
|
||||
|
||||
@@ -3,6 +3,138 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.4.612](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.611](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.610](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.609](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.608](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.607](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.606](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.605](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.604](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.603](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.602](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.601](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.600](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.599](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.598](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.597](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.596](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.595](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.594](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.593](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.592](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.591](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.590](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.589](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.588](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.587](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.586](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.585](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.584](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.583](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.582](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.581](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.580](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-28)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.4.579](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-27)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/releases",
|
||||
"version": "1.4.579",
|
||||
"version": "1.4.612",
|
||||
"license": "AGPL-3.0",
|
||||
"main": "dist/releases.json",
|
||||
"types": "dist/index.d.ts",
|
||||
|
||||
@@ -3,6 +3,24 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.65.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/services
|
||||
|
||||
## [1.65.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/services
|
||||
|
||||
## [1.65.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/services
|
||||
|
||||
# [1.65.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
### Features
|
||||
|
||||
* When exporting a Super note, embedded files can be inlined in the note or exported along the note in a zip file. You can now also choose to include frontmatter when exporting to Markdown format. ([991de1d](https://github.com/standardnotes/app/commit/991de1ddf5dbb1016348d603d244699c676d9b5f)), closes [#2610](https://github.com/standardnotes/app/issues/2610)
|
||||
|
||||
## [1.64.38](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-26)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/services
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/services",
|
||||
"version": "1.64.38",
|
||||
"version": "1.65.3",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -462,7 +462,7 @@ export class FilesBackupService
|
||||
const tagNames = tags.map((tag) => this.items.getTagLongTitle(tag))
|
||||
const text =
|
||||
note.noteType === NoteType.Super
|
||||
? this.markdownConverter.convertSuperStringToOtherFormat(note.text, 'md')
|
||||
? await this.markdownConverter.convertSuperStringToOtherFormat(note.text, 'md')
|
||||
: note.text
|
||||
await this.device.savePlaintextNoteBackup(location, note.uuid, note.title, tagNames, text)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import { DeviceInterface } from './DeviceInterface'
|
||||
import { AppleIAPReceipt } from '../Subscription/AppleIAPReceipt'
|
||||
import { ApplicationEvent } from '../Event/ApplicationEvent'
|
||||
|
||||
import type { Notification } from '../../../../mobile/node_modules/@notifee/react-native/dist/index'
|
||||
|
||||
export interface MobileDeviceInterface extends DeviceInterface {
|
||||
environment: Environment.Mobile
|
||||
platform: Platform.Ios | Platform.Android
|
||||
@@ -34,4 +36,8 @@ export interface MobileDeviceInterface extends DeviceInterface {
|
||||
purchaseSubscriptionIAP(plan: AppleIAPProductId): Promise<AppleIAPReceipt | undefined>
|
||||
authenticateWithU2F(authenticationOptionsJSONString: string): Promise<Record<string, unknown> | null>
|
||||
notifyApplicationEvent(event: ApplicationEvent): void
|
||||
|
||||
canDisplayNotifications(): Promise<boolean>
|
||||
displayNotification(options: Notification): Promise<string>
|
||||
cancelNotification(notificationId: string): Promise<void>
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ComponentInterface, DecryptedItemInterface } from '@standardnotes/model
|
||||
import { FeatureStatus } from './FeatureStatus'
|
||||
import { SetOfflineFeaturesFunctionResponse } from './SetOfflineFeaturesFunctionResponse'
|
||||
import { NativeFeatureIdentifier } from '@standardnotes/features'
|
||||
import { Uuid } from '@standardnotes/domain-core'
|
||||
import { RoleName, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
export interface FeaturesClientInterface {
|
||||
getFeatureStatus(
|
||||
@@ -11,7 +11,7 @@ export interface FeaturesClientInterface {
|
||||
options?: { inContextOfItem?: DecryptedItemInterface },
|
||||
): FeatureStatus
|
||||
hasMinimumRole(role: string): boolean
|
||||
|
||||
hasRole(roleName: RoleName): boolean
|
||||
hasFirstPartyOfflineSubscription(): boolean
|
||||
setOfflineFeaturesCode(code: string): Promise<SetOfflineFeaturesFunctionResponse>
|
||||
hasOfflineRepo(): boolean
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.202.109](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/snjs
|
||||
|
||||
## [2.202.108](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/snjs
|
||||
|
||||
## [2.202.107](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/snjs
|
||||
|
||||
## [2.202.106](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/snjs
|
||||
|
||||
## [2.202.105](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/snjs
|
||||
|
||||
## [2.202.104](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/snjs
|
||||
|
||||
## [2.202.103](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-26)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/snjs
|
||||
|
||||
@@ -12,4 +12,5 @@ export enum ReactNativeToWebEvent {
|
||||
ReceivedFile = 'ReceivedFile',
|
||||
ReceivedLink = 'ReceivedLink',
|
||||
ReceivedText = 'ReceivedText',
|
||||
OpenFilePreview = 'OpenFilePreview',
|
||||
}
|
||||
|
||||
@@ -412,6 +412,10 @@ export class FeaturesService
|
||||
return Object.values(RoleName.NAMES).filter((role) => roles.includes(role))
|
||||
}
|
||||
|
||||
hasRole(roleName: RoleName): boolean {
|
||||
return this.onlineRoles.includes(roleName.value) || this.offlineRoles.includes(roleName.value)
|
||||
}
|
||||
|
||||
public hasMinimumRole(role: string): boolean {
|
||||
const sortedAllRoles = Object.values(RoleName.NAMES)
|
||||
|
||||
|
||||
@@ -197,7 +197,9 @@ export class SessionManager
|
||||
|
||||
this.apiService.setSession(session, persist)
|
||||
|
||||
void this.webSocketsService.startWebSocketConnection()
|
||||
if (this.isSignedIntoFirstPartyServer()) {
|
||||
void this.webSocketsService.startWebSocketConnection()
|
||||
}
|
||||
}
|
||||
|
||||
public online() {
|
||||
|
||||
@@ -112,7 +112,7 @@ describe('files', function () {
|
||||
it('should encrypt and upload small file', async function () {
|
||||
await setup({ fakeCrypto: false, subscription: true })
|
||||
|
||||
const response = await fetch('/packages/snjs/mocha/assets/small_file.md')
|
||||
const response = await fetch('/mocha/assets/small_file.md')
|
||||
const buffer = new Uint8Array(await response.arrayBuffer())
|
||||
|
||||
const file = await Files.uploadFile(fileService, buffer, 'my-file', 'md', 1000)
|
||||
@@ -125,7 +125,7 @@ describe('files', function () {
|
||||
it('should encrypt and upload big file', async function () {
|
||||
await setup({ fakeCrypto: false, subscription: true })
|
||||
|
||||
const response = await fetch('/packages/snjs/mocha/assets/two_mb_file.md')
|
||||
const response = await fetch('/mocha/assets/two_mb_file.md')
|
||||
const buffer = new Uint8Array(await response.arrayBuffer())
|
||||
|
||||
const file = await Files.uploadFile(fileService, buffer, 'my-file', 'md', 100000)
|
||||
@@ -138,7 +138,7 @@ describe('files', function () {
|
||||
it('should delete file', async function () {
|
||||
await setup({ fakeCrypto: false, subscription: true })
|
||||
|
||||
const response = await fetch('/packages/snjs/mocha/assets/small_file.md')
|
||||
const response = await fetch('/mocha/assets/small_file.md')
|
||||
const buffer = new Uint8Array(await response.arrayBuffer())
|
||||
|
||||
const file = await Files.uploadFile(fileService, buffer, 'my-file', 'md', 1000)
|
||||
|
||||
@@ -147,7 +147,7 @@ describe('settings service', function () {
|
||||
|
||||
await context.activatePaidSubscriptionForUser()
|
||||
|
||||
const response = await fetch('/packages/snjs/mocha/assets/small_file.md')
|
||||
const response = await fetch('/mocha/assets/small_file.md')
|
||||
const buffer = new Uint8Array(await response.arrayBuffer())
|
||||
|
||||
await Files.uploadFile(application.files, buffer, 'my-file', 'md', 1000)
|
||||
@@ -161,7 +161,7 @@ describe('settings service', function () {
|
||||
const usedSettingBefore = await application.settings.getSubscriptionSetting(
|
||||
SettingName.create(SettingName.NAMES.FileUploadBytesUsed).getValue(),
|
||||
)
|
||||
expect(usedSettingBefore).to.equal('196')
|
||||
expect(usedSettingBefore).to.equal('1374')
|
||||
|
||||
await context.activatePaidSubscriptionForUser({
|
||||
cancelPreviousSubscription: true,
|
||||
@@ -181,7 +181,7 @@ describe('settings service', function () {
|
||||
)
|
||||
expect(usedSettingAfter).to.equal(usedSettingBefore)
|
||||
|
||||
const afterResponse = await fetch('/packages/snjs/mocha/assets/small_file.md')
|
||||
const afterResponse = await fetch('/mocha/assets/small_file.md')
|
||||
const afterBuffer = new Uint8Array(await afterResponse.arrayBuffer())
|
||||
|
||||
await Files.uploadFile(application.files, afterBuffer, 'my-file', 'md', 1000)
|
||||
@@ -196,6 +196,6 @@ describe('settings service', function () {
|
||||
const usedSettingAfterSecondUpload = await application.settings.getSubscriptionSetting(
|
||||
SettingName.create(SettingName.NAMES.FileUploadBytesUsed).getValue(),
|
||||
)
|
||||
expect(usedSettingAfterSecondUpload).to.equal('392')
|
||||
expect(usedSettingAfterSecondUpload).to.equal('2748')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -572,6 +572,39 @@ describe('online syncing', function () {
|
||||
expect(rawPayloads.length).to.equal(expectedItemCount)
|
||||
}).timeout(Factory.SixtySecondTimeout)
|
||||
|
||||
it('should sync all items including ones that are breaching transfer limit', async function () {
|
||||
const response = await fetch('/mocha/assets/small_file.md')
|
||||
const buffer = new Uint8Array(await response.arrayBuffer())
|
||||
const numberOfNotesToExceedThe1MBTransferLimit = 80
|
||||
|
||||
const testContext = await Factory.createAppContextWithFakeCrypto()
|
||||
await testContext.launch()
|
||||
await testContext.register()
|
||||
const email = testContext.email
|
||||
const password = testContext.password
|
||||
|
||||
for (let i = 0; i < numberOfNotesToExceedThe1MBTransferLimit; i++) {
|
||||
await testContext.createSyncedNote(`note ${i}`, buffer.toString())
|
||||
await testContext.sync()
|
||||
}
|
||||
await testContext.deinit()
|
||||
|
||||
const secondContext = await Factory.createAppContextWithFakeCrypto(Math.random(), email, password)
|
||||
await secondContext.launch()
|
||||
const firstSyncPromise = secondContext.awaitNextSyncEvent(SyncEvent.PaginatedSyncRequestCompleted)
|
||||
await secondContext.signIn()
|
||||
|
||||
const firstSyncResult = await firstSyncPromise
|
||||
|
||||
expect(firstSyncResult.retrievedPayloads.length > 0).to.be.true
|
||||
expect(firstSyncResult.retrievedPayloads.length < numberOfNotesToExceedThe1MBTransferLimit).to.be.true
|
||||
expect(firstSyncResult.successResponseData.cursor_token).not.to.be.undefined
|
||||
|
||||
expect(secondContext.noteCount).to.equal(numberOfNotesToExceedThe1MBTransferLimit)
|
||||
|
||||
await secondContext.deinit()
|
||||
}).timeout(Factory.SixtySecondTimeout)
|
||||
|
||||
it('syncing an item should storage it encrypted', async function () {
|
||||
const note = await Factory.createMappedNote(application)
|
||||
await application.mutator.setItemDirty(note)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/snjs",
|
||||
"version": "2.202.103",
|
||||
"version": "2.202.109",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,42 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/ui-services
|
||||
|
||||
## [1.34.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-07)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed issue where non-image inlined files would not correctly be imported from a Markdown file ([8941675](https://github.com/standardnotes/app/commit/894167520dc829b72f721bdf63acc6038ff8816f))
|
||||
|
||||
# [1.34.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
### Features
|
||||
|
||||
* Importing markdown files from the Import dialog will now automatically use Super notes ([3bf670e](https://github.com/standardnotes/app/commit/3bf670ece754df3f452a3ae305830c772687d36a))
|
||||
|
||||
## [1.33.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/ui-services
|
||||
|
||||
## [1.33.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/ui-services
|
||||
|
||||
## [1.33.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed issue where exporting multiple files with the same name would error ([f408950](https://github.com/standardnotes/app/commit/f408950aa4e59389db81a4ca2b9db5ea49147aaf))
|
||||
|
||||
# [1.33.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
### Features
|
||||
|
||||
* When exporting a Super note, embedded files can be inlined in the note or exported along the note in a zip file. You can now also choose to include frontmatter when exporting to Markdown format. ([991de1d](https://github.com/standardnotes/app/commit/991de1ddf5dbb1016348d603d244699c676d9b5f)), closes [#2610](https://github.com/standardnotes/app/issues/2610)
|
||||
|
||||
## [1.32.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-26)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/ui-services
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/ui-services",
|
||||
"version": "1.32.7",
|
||||
"version": "1.34.2",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -19,6 +19,11 @@ function zippableFileName(name: string, suffix = '', format = 'txt'): string {
|
||||
return sanitizedName.slice(0, maxFileNameLength - nameEnd.length) + nameEnd
|
||||
}
|
||||
|
||||
export function parseAndCreateZippableFileName(name: string, suffix = '') {
|
||||
const { name: parsedName, ext } = parseFileName(name)
|
||||
return zippableFileName(parsedName, suffix, ext)
|
||||
}
|
||||
|
||||
type ZippableData = {
|
||||
name: string
|
||||
content: Blob
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
import { DecryptedTransferPayload, NoteContent, TagContent } from '@standardnotes/models'
|
||||
import { DecryptedTransferPayload, FileItem, NoteContent, TagContent } from '@standardnotes/models'
|
||||
import { EvernoteConverter, EvernoteResource } from './EvernoteConverter'
|
||||
import { createTestResourceElement, enex, enexWithNoNoteOrTag } from './testData'
|
||||
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
|
||||
@@ -31,7 +31,14 @@ describe('EvernoteConverter', () => {
|
||||
const superConverterService: SuperConverterServiceInterface = {
|
||||
isValidSuperString: () => true,
|
||||
convertOtherFormatToSuperString: (data: string) => data,
|
||||
convertSuperStringToOtherFormat: (data: string) => data,
|
||||
convertSuperStringToOtherFormat: async (data: string) => data,
|
||||
getEmbeddedFileIDsFromSuperString: () => [],
|
||||
uploadAndReplaceInlineFilesInSuperString: async (
|
||||
superString: string,
|
||||
_uploadFile: (file: File) => Promise<FileItem | undefined>,
|
||||
_linkFile: (file: FileItem) => Promise<void>,
|
||||
_generateUuid: GenerateUuid,
|
||||
) => superString,
|
||||
}
|
||||
|
||||
const generateUuid = new GenerateUuid(crypto)
|
||||
|
||||
@@ -6,7 +6,7 @@ import { jsonTextContentData, htmlTestData, jsonListContentData } from './testDa
|
||||
import { GoogleKeepConverter } from './GoogleKeepConverter'
|
||||
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
|
||||
import { GenerateUuid } from '@standardnotes/services'
|
||||
import { SuperConverterServiceInterface } from '@standardnotes/snjs'
|
||||
import { FileItem, SuperConverterServiceInterface } from '@standardnotes/snjs'
|
||||
|
||||
describe('GoogleKeepConverter', () => {
|
||||
const crypto = {
|
||||
@@ -16,7 +16,14 @@ describe('GoogleKeepConverter', () => {
|
||||
const superConverterService: SuperConverterServiceInterface = {
|
||||
isValidSuperString: () => true,
|
||||
convertOtherFormatToSuperString: (data: string) => data,
|
||||
convertSuperStringToOtherFormat: (data: string) => data,
|
||||
convertSuperStringToOtherFormat: async (data: string) => data,
|
||||
getEmbeddedFileIDsFromSuperString: () => [],
|
||||
uploadAndReplaceInlineFilesInSuperString: async (
|
||||
superString: string,
|
||||
_uploadFile: (file: File) => Promise<FileItem | undefined>,
|
||||
_linkFile: (file: FileItem) => Promise<void>,
|
||||
_generateUuid: GenerateUuid,
|
||||
) => superString,
|
||||
}
|
||||
const generateUuid = new GenerateUuid(crypto)
|
||||
|
||||
|
||||
@@ -6,14 +6,23 @@ import {
|
||||
ItemManagerInterface,
|
||||
MutatorClientInterface,
|
||||
} from '@standardnotes/services'
|
||||
import { NativeFeatureIdentifier } from '@standardnotes/features'
|
||||
import { NativeFeatureIdentifier, NoteType } from '@standardnotes/features'
|
||||
import { AegisToAuthenticatorConverter } from './AegisConverter/AegisToAuthenticatorConverter'
|
||||
import { EvernoteConverter } from './EvernoteConverter/EvernoteConverter'
|
||||
import { GoogleKeepConverter } from './GoogleKeepConverter/GoogleKeepConverter'
|
||||
import { PlaintextConverter } from './PlaintextConverter/PlaintextConverter'
|
||||
import { SimplenoteConverter } from './SimplenoteConverter/SimplenoteConverter'
|
||||
import { readFileAsText } from './Utils'
|
||||
import { DecryptedTransferPayload, NoteContent } from '@standardnotes/models'
|
||||
import {
|
||||
DecryptedItemInterface,
|
||||
DecryptedTransferPayload,
|
||||
FileItem,
|
||||
ItemContent,
|
||||
NoteContent,
|
||||
NoteMutator,
|
||||
SNNote,
|
||||
isNote,
|
||||
} from '@standardnotes/models'
|
||||
import { HTMLConverter } from './HTMLConverter/HTMLConverter'
|
||||
import { SuperConverterServiceInterface } from '@standardnotes/snjs/dist/@types'
|
||||
import { SuperConverter } from './SuperConverter/SuperConverter'
|
||||
@@ -34,12 +43,27 @@ export class Importer {
|
||||
private mutator: MutatorClientInterface,
|
||||
private items: ItemManagerInterface,
|
||||
private superConverterService: SuperConverterServiceInterface,
|
||||
_generateUuid: GenerateUuid,
|
||||
private filesController: {
|
||||
uploadNewFile(
|
||||
fileOrHandle: File | FileSystemFileHandle,
|
||||
options?: {
|
||||
showToast?: boolean
|
||||
note?: SNNote
|
||||
},
|
||||
): Promise<FileItem | undefined>
|
||||
},
|
||||
private linkingController: {
|
||||
linkItems(
|
||||
item: DecryptedItemInterface<ItemContent>,
|
||||
itemToLink: DecryptedItemInterface<ItemContent>,
|
||||
): Promise<void>
|
||||
},
|
||||
private _generateUuid: GenerateUuid,
|
||||
) {
|
||||
this.aegisConverter = new AegisToAuthenticatorConverter(_generateUuid)
|
||||
this.googleKeepConverter = new GoogleKeepConverter(this.superConverterService, _generateUuid)
|
||||
this.simplenoteConverter = new SimplenoteConverter(_generateUuid)
|
||||
this.plaintextConverter = new PlaintextConverter(_generateUuid)
|
||||
this.plaintextConverter = new PlaintextConverter(this.superConverterService, _generateUuid)
|
||||
this.evernoteConverter = new EvernoteConverter(this.superConverterService, _generateUuid)
|
||||
this.htmlConverter = new HTMLConverter(this.superConverterService, _generateUuid)
|
||||
this.superConverter = new SuperConverter(this.superConverterService, _generateUuid)
|
||||
@@ -110,7 +134,7 @@ export class Importer {
|
||||
} else if (type === 'evernote') {
|
||||
return await this.evernoteConverter.convertENEXFileToNotesAndTags(file, isEntitledToSuper)
|
||||
} else if (type === 'plaintext') {
|
||||
return [await this.plaintextConverter.convertPlaintextFileToNote(file)]
|
||||
return [await this.plaintextConverter.convertPlaintextFileToNote(file, isEntitledToSuper)]
|
||||
} else if (type === 'html') {
|
||||
return [await this.htmlConverter.convertHTMLFileToNote(file, isEntitledToSuper)]
|
||||
}
|
||||
@@ -142,4 +166,28 @@ export class Importer {
|
||||
)
|
||||
return insertedItems
|
||||
}
|
||||
|
||||
async uploadAndReplaceInlineFilesInInsertedItems(insertedItems: DecryptedItemInterface<ItemContent>[]) {
|
||||
for (const item of insertedItems) {
|
||||
if (!isNote(item)) {
|
||||
continue
|
||||
}
|
||||
if (item.noteType !== NoteType.Super) {
|
||||
continue
|
||||
}
|
||||
try {
|
||||
const text = await this.superConverterService.uploadAndReplaceInlineFilesInSuperString(
|
||||
item.text,
|
||||
async (file) => await this.filesController.uploadNewFile(file, { showToast: true, note: item }),
|
||||
async (file) => await this.linkingController.linkItems(item, file),
|
||||
this._generateUuid,
|
||||
)
|
||||
await this.mutator.changeItem<NoteMutator>(item, (mutator) => {
|
||||
mutator.text = text
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,15 +3,23 @@ import { parseFileName } from '@standardnotes/filepicker'
|
||||
import { DecryptedTransferPayload, NoteContent } from '@standardnotes/models'
|
||||
import { readFileAsText } from '../Utils'
|
||||
import { GenerateUuid } from '@standardnotes/services'
|
||||
import { SuperConverterServiceInterface } from '@standardnotes/files'
|
||||
import { NativeFeatureIdentifier, NoteType } from '@standardnotes/features'
|
||||
|
||||
export class PlaintextConverter {
|
||||
constructor(private _generateUuid: GenerateUuid) {}
|
||||
constructor(
|
||||
private superConverterService: SuperConverterServiceInterface,
|
||||
private _generateUuid: GenerateUuid,
|
||||
) {}
|
||||
|
||||
static isValidPlaintextFile(file: File): boolean {
|
||||
return file.type === 'text/plain' || file.type === 'text/markdown'
|
||||
}
|
||||
|
||||
async convertPlaintextFileToNote(file: File): Promise<DecryptedTransferPayload<NoteContent>> {
|
||||
async convertPlaintextFileToNote(
|
||||
file: File,
|
||||
isEntitledToSuper: boolean,
|
||||
): Promise<DecryptedTransferPayload<NoteContent>> {
|
||||
const content = await readFileAsText(file)
|
||||
|
||||
const { name } = parseFileName(file.name)
|
||||
@@ -19,6 +27,8 @@ export class PlaintextConverter {
|
||||
const createdAtDate = file.lastModified ? new Date(file.lastModified) : new Date()
|
||||
const updatedAtDate = file.lastModified ? new Date(file.lastModified) : new Date()
|
||||
|
||||
const shouldConvertToSuper = file.type === 'text/markdown' && isEntitledToSuper
|
||||
|
||||
return {
|
||||
created_at: createdAtDate,
|
||||
created_at_timestamp: createdAtDate.getTime(),
|
||||
@@ -28,8 +38,16 @@ export class PlaintextConverter {
|
||||
content_type: ContentType.TYPES.Note,
|
||||
content: {
|
||||
title: name,
|
||||
text: content,
|
||||
text: shouldConvertToSuper
|
||||
? this.superConverterService.convertOtherFormatToSuperString(content, 'md')
|
||||
: content,
|
||||
references: [],
|
||||
...(isEntitledToSuper
|
||||
? {
|
||||
noteType: NoteType.Super,
|
||||
editorIdentifier: NativeFeatureIdentifier.TYPES.SuperEditor,
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ export const SUPER_SHOW_MARKDOWN_PREVIEW = createKeyboardCommand('SUPER_SHOW_MAR
|
||||
|
||||
export const SUPER_EXPORT_JSON = createKeyboardCommand('SUPER_EXPORT_JSON')
|
||||
export const SUPER_EXPORT_MARKDOWN = createKeyboardCommand('SUPER_EXPORT_MARKDOWN')
|
||||
export const SUPER_EXPORT_HTML = createKeyboardCommand('SUPER_EXPORT_HTML')
|
||||
export const OPEN_PREFERENCES_COMMAND = createKeyboardCommand('OPEN_PREFERENCES_COMMAND')
|
||||
|
||||
export const CHANGE_EDITOR_WIDTH_COMMAND = createKeyboardCommand('CHANGE_EDITOR_WIDTH_COMMAND')
|
||||
|
||||
@@ -24,6 +24,7 @@ export interface WebApplicationInterface extends ApplicationInterface {
|
||||
handleReceivedFileEvent(file: { name: string; mimeType: string; data: string }): void
|
||||
handleReceivedTextEvent(item: { text: string; title?: string }): Promise<void>
|
||||
handleReceivedLinkEvent(item: { link: string; title: string }): Promise<void>
|
||||
handleOpenFilePreviewEvent(item: { id: string }): void
|
||||
isNativeMobileWeb(): boolean
|
||||
handleAndroidBackButtonPressed(): void
|
||||
addAndroidBackHandlerEventListener(listener: () => boolean): (() => void) | undefined
|
||||
|
||||
@@ -3,6 +3,138 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [3.181.24](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.23](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.22](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.21](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.19](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-07)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed issue where non-image inlined files would not correctly be imported from a Markdown file ([8941675](https://github.com/standardnotes/app/commit/894167520dc829b72f721bdf63acc6038ff8816f))
|
||||
|
||||
## [3.181.18](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.17](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.16](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-04)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.14](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed issue where exporting multiple files with the same name would error ([f408950](https://github.com/standardnotes/app/commit/f408950aa4e59389db81a4ca2b9db5ea49147aaf))
|
||||
|
||||
## [3.181.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed issue where a brief flash of white would appear when starting the app on mobile ([572c9b7](https://github.com/standardnotes/app/commit/572c9b7dfaa42773c050772940e383df2940a79f))
|
||||
|
||||
## [3.181.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.181.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
# [3.181.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
### Features
|
||||
|
||||
* When exporting a Super note, embedded files can be inlined in the note or exported along the note in a zip file. You can now also choose to include frontmatter when exporting to Markdown format.
|
||||
|
||||
## [3.180.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.180.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed issue with checklist items in Super notes not being correctly exported to HTML ([198efdc](https://github.com/standardnotes/app/commit/198efdc41c403ce10a40fc2f20345d5b44c83462))
|
||||
|
||||
## [3.180.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.180.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
## [3.180.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-28)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed check list indentation in Super notes ([ce0db04](https://github.com/standardnotes/app/commit/ce0db04646737ec1dcb88ac989cd12927c46a156))
|
||||
|
||||
## [3.180.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-27)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/web
|
||||
|
||||
@@ -1,5 +1,353 @@
|
||||
{
|
||||
"versions": [
|
||||
{
|
||||
"version": "3.181.24",
|
||||
"title": "[3.181.24](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-11)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.23",
|
||||
"title": "[3.181.23](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.22",
|
||||
"title": "[3.181.22](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.21",
|
||||
"title": "[3.181.21](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-09)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.20",
|
||||
"title": "[3.181.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-08)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.19",
|
||||
"title": "[3.181.19](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-07)",
|
||||
"date": null,
|
||||
"body": "### Bug Fixes\n\n* Fixed issue where non-image inlined files would not correctly be imported from a Markdown file ([8941675](https://github.com/standardnotes/app/commit/894167520dc829b72f721bdf63acc6038ff8816f))",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Fixed issue where non-image inlined files would not correctly be imported from a Markdown file (8941675)"
|
||||
],
|
||||
"Bug Fixes": [
|
||||
"Fixed issue where non-image inlined files would not correctly be imported from a Markdown file (8941675)"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.18",
|
||||
"title": "[3.181.18](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.17",
|
||||
"title": "[3.181.17](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.16",
|
||||
"title": "[3.181.16](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-06)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.15",
|
||||
"title": "[3.181.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-04)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.14",
|
||||
"title": "[3.181.14](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.13",
|
||||
"title": "[3.181.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-03)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.12",
|
||||
"title": "[3.181.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.11",
|
||||
"title": "[3.181.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.10",
|
||||
"title": "[3.181.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.9",
|
||||
"title": "[3.181.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-02)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.8",
|
||||
"title": "[3.181.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.7",
|
||||
"title": "[3.181.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.6",
|
||||
"title": "[3.181.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-01)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.5",
|
||||
"title": "[3.181.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.4",
|
||||
"title": "[3.181.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)",
|
||||
"date": null,
|
||||
"body": "### Bug Fixes\n\n* Fixed issue where exporting multiple files with the same name would error ([f408950](https://github.com/standardnotes/app/commit/f408950aa4e59389db81a4ca2b9db5ea49147aaf))",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Fixed issue where exporting multiple files with the same name would error (f408950)"
|
||||
],
|
||||
"Bug Fixes": [
|
||||
"Fixed issue where exporting multiple files with the same name would error (f408950)"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.3",
|
||||
"title": "[3.181.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)",
|
||||
"date": null,
|
||||
"body": "### Bug Fixes\n\n* Fixed issue where a brief flash of white would appear when starting the app on mobile ([572c9b7](https://github.com/standardnotes/app/commit/572c9b7dfaa42773c050772940e383df2940a79f))",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Fixed issue where a brief flash of white would appear when starting the app on mobile (572c9b7)"
|
||||
],
|
||||
"Bug Fixes": [
|
||||
"Fixed issue where a brief flash of white would appear when starting the app on mobile (572c9b7)"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.2",
|
||||
"title": "[3.181.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-31)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.1",
|
||||
"title": "[3.181.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.181.0",
|
||||
"title": "[3.181.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)",
|
||||
"date": null,
|
||||
"body": "### Features\n\n* When exporting a Super note, embedded files can be inlined in the note or exported along the note in a zip file. You can now also choose to include frontmatter when exporting to Markdown format.",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"When exporting a Super note, embedded files can be inlined in the note or exported along the note in a zip file. You can now also choose to include frontmatter when exporting to Markdown format."
|
||||
],
|
||||
"Features": [
|
||||
"When exporting a Super note, embedded files can be inlined in the note or exported along the note in a zip file. You can now also choose to include frontmatter when exporting to Markdown format."
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.180.8",
|
||||
"title": "[3.180.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-30)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.180.7",
|
||||
"title": "[3.180.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)",
|
||||
"date": null,
|
||||
"body": "### Bug Fixes\n\n* Fixed issue with checklist items in Super notes not being correctly exported to HTML ([198efdc](https://github.com/standardnotes/app/commit/198efdc41c403ce10a40fc2f20345d5b44c83462))",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Fixed issue with checklist items in Super notes not being correctly exported to HTML (198efdc)"
|
||||
],
|
||||
"Bug Fixes": [
|
||||
"Fixed issue with checklist items in Super notes not being correctly exported to HTML (198efdc)"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.180.6",
|
||||
"title": "[3.180.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.180.5",
|
||||
"title": "[3.180.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-29)",
|
||||
"date": null,
|
||||
"body": "**Note:** Version bump only for package @standardnotes/web",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Note: Version bump only for package @standardnotes/web"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.180.4",
|
||||
"title": "[3.180.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-28)",
|
||||
"date": null,
|
||||
"body": "### Bug Fixes\n\n* Fixed check list indentation in Super notes ([ce0db04](https://github.com/standardnotes/app/commit/ce0db04646737ec1dcb88ac989cd12927c46a156))",
|
||||
"parsed": {
|
||||
"_": [
|
||||
"Fixed check list indentation in Super notes (ce0db04)"
|
||||
],
|
||||
"Bug Fixes": [
|
||||
"Fixed check list indentation in Super notes (ce0db04)"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "3.180.3",
|
||||
"title": "[3.180.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-10-27)",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/web",
|
||||
"version": "3.180.3",
|
||||
"version": "3.181.24",
|
||||
"license": "AGPL-3.0",
|
||||
"main": "dist/app.js",
|
||||
"author": "Standard Notes.",
|
||||
|
||||
@@ -16,6 +16,9 @@ declare global {
|
||||
webClient?: DesktopManagerInterface
|
||||
electronRemoteBridge?: unknown
|
||||
reactNativeDevice?: WebDevice
|
||||
ReactNativeWebView?: {
|
||||
postMessage: (message: string) => void
|
||||
}
|
||||
platform?: Platform
|
||||
isClipper?: boolean
|
||||
|
||||
@@ -91,6 +94,10 @@ const startApplication: StartApplication = async function startApplication(
|
||||
onDestroy={onDestroy}
|
||||
/>,
|
||||
)
|
||||
|
||||
if (window.ReactNativeWebView) {
|
||||
window.ReactNativeWebView.postMessage('appLoaded')
|
||||
}
|
||||
}
|
||||
|
||||
const domReady = document.readyState === 'complete' || document.readyState === 'interactive'
|
||||
|
||||
@@ -34,7 +34,7 @@ import { SubscriptionController } from '@/Controllers/Subscription/SubscriptionC
|
||||
import { PurchaseFlowController } from '@/Controllers/PurchaseFlow/PurchaseFlowController'
|
||||
import { FilesController } from '@/Controllers/FilesController'
|
||||
import { HistoryModalController } from '@/Controllers/NoteHistory/HistoryModalController'
|
||||
import { ImportModalController } from '@/Controllers/ImportModalController'
|
||||
import { ImportModalController } from '@/Components/ImportModal/ImportModalController'
|
||||
import { ApplicationEventObserver } from '@/Event/ApplicationEventObserver'
|
||||
import { SearchOptionsController } from '@/Controllers/SearchOptionsController'
|
||||
import { LinkingController } from '@/Controllers/LinkingController'
|
||||
@@ -64,6 +64,8 @@ export class WebDependencies extends DependencyContainer {
|
||||
application.mutator,
|
||||
application.items,
|
||||
this.get<HeadlessSuperConverter>(Web_TYPES.SuperConverter),
|
||||
this.get<FilesController>(Web_TYPES.FilesController),
|
||||
this.get<LinkingController>(Web_TYPES.LinkingController),
|
||||
application.generateUuid,
|
||||
)
|
||||
})
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
NoteContent,
|
||||
SNNote,
|
||||
DesktopManagerInterface,
|
||||
FileItem,
|
||||
} from '@standardnotes/snjs'
|
||||
import { action, computed, makeObservable, observable } from 'mobx'
|
||||
import { startAuthentication, startRegistration } from '@simplewebauthn/browser'
|
||||
@@ -65,7 +66,7 @@ import { PurchaseFlowController } from '@/Controllers/PurchaseFlow/PurchaseFlowC
|
||||
import { AccountMenuController } from '@/Controllers/AccountMenu/AccountMenuController'
|
||||
import { PreferencesController } from '@/Controllers/PreferencesController'
|
||||
import { NotesController } from '@/Controllers/NotesController/NotesController'
|
||||
import { ImportModalController } from '@/Controllers/ImportModalController'
|
||||
import { ImportModalController } from '@/Components/ImportModal/ImportModalController'
|
||||
import { SyncStatusController } from '@/Controllers/SyncStatusController'
|
||||
import { HistoryModalController } from '@/Controllers/NoteHistory/HistoryModalController'
|
||||
import { NavigationController } from '@/Controllers/Navigation/NavigationController'
|
||||
@@ -76,6 +77,7 @@ import { NoAccountWarningController } from '@/Controllers/NoAccountWarningContro
|
||||
import { SearchOptionsController } from '@/Controllers/SearchOptionsController'
|
||||
import { PersistenceService } from '@/Controllers/Abstract/PersistenceService'
|
||||
import { removeFromArray } from '@standardnotes/utils'
|
||||
import { FileItemActionType } from '@/Components/AttachedFilesPopover/PopoverFileItemAction'
|
||||
|
||||
export type WebEventObserver = (event: WebAppEvent, data?: unknown) => void
|
||||
|
||||
@@ -353,6 +355,21 @@ export class WebApplication extends SNApplication implements WebApplicationInter
|
||||
this.notifyWebEvent(WebAppEvent.MobileKeyboardDidChangeFrame, frame)
|
||||
}
|
||||
|
||||
handleOpenFilePreviewEvent({ id }: { id: string }): void {
|
||||
const file = this.items.findItem<FileItem>(id)
|
||||
if (!file) {
|
||||
return
|
||||
}
|
||||
this.filesController
|
||||
.handleFileAction({
|
||||
type: FileItemActionType.PreviewFile,
|
||||
payload: {
|
||||
file,
|
||||
},
|
||||
})
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
handleReceivedFileEvent(file: { name: string; mimeType: string; data: string }): void {
|
||||
const filesController = this.filesController
|
||||
const blob = getBlobFromBase64(file.data, file.mimeType)
|
||||
|
||||
@@ -78,7 +78,8 @@ const NoteListItem: FunctionComponent<DisplayableListItemProps<SNNote>> = ({
|
||||
|
||||
const onClick = useCallback(
|
||||
(event: MouseEvent) => {
|
||||
if ((event.ctrlKey || event.metaKey) && !application.itemListController.isMultipleSelectionMode) {
|
||||
const hasMultiSelectionModifierKey = !isMobileScreen && (event.ctrlKey || event.metaKey)
|
||||
if (hasMultiSelectionModifierKey && !application.itemListController.isMultipleSelectionMode) {
|
||||
application.itemListController.enableMultipleSelectionMode()
|
||||
}
|
||||
if (selected && !application.itemListController.isMultipleSelectionMode) {
|
||||
@@ -87,7 +88,7 @@ const NoteListItem: FunctionComponent<DisplayableListItemProps<SNNote>> = ({
|
||||
}
|
||||
onSelect(item, true).catch(console.error)
|
||||
},
|
||||
[application.itemListController, item, onSelect, selected],
|
||||
[application.itemListController, isMobileScreen, item, onSelect, selected],
|
||||
)
|
||||
|
||||
useContextMenuEvent(listItemRef, handleContextMenuEvent)
|
||||
|
||||
@@ -4,7 +4,7 @@ import ImportModalFileItem from './ImportModalFileItem'
|
||||
import ImportModalInitialPage from './InitialPage'
|
||||
import Modal, { ModalAction } from '../Modal/Modal'
|
||||
import ModalOverlay from '../Modal/ModalOverlay'
|
||||
import { ImportModalController } from '@/Controllers/ImportModalController'
|
||||
import { ImportModalController } from '@/Components/ImportModal/ImportModalController'
|
||||
import { useApplication } from '../ApplicationProvider'
|
||||
import Switch from '../Switch/Switch'
|
||||
|
||||
@@ -66,7 +66,7 @@ const ImportModal = ({ importModalController }: { importModalController: ImportM
|
||||
)}
|
||||
</div>
|
||||
{files.length > 0 && (
|
||||
<label className="py-2 px-4 flex items-center gap-2 border-t border-border">
|
||||
<label className="flex items-center gap-2 border-t border-border px-4 py-2">
|
||||
<Switch checked={shouldCreateTag} onChange={setShouldCreateTag} />
|
||||
<span className="text-sm">Create tag with all imported notes</span>
|
||||
</label>
|
||||
|
||||
+10
-2
@@ -8,7 +8,7 @@ import {
|
||||
} from '@standardnotes/snjs'
|
||||
import { Importer, NoteImportType } from '@standardnotes/ui-services'
|
||||
import { action, makeObservable, observable } from 'mobx'
|
||||
import { NavigationController } from './Navigation/NavigationController'
|
||||
import { NavigationController } from '../../Controllers/Navigation/NavigationController'
|
||||
|
||||
type ImportModalFileCommon = {
|
||||
id: string
|
||||
@@ -21,6 +21,7 @@ export type ImportModalFile = (
|
||||
| { status: 'ready'; payloads?: DecryptedTransferPayload[] }
|
||||
| { status: 'parsing' }
|
||||
| { status: 'importing' }
|
||||
| { status: 'uploading-files' }
|
||||
| { status: 'success'; successMessage: string }
|
||||
| { status: 'error'; error: Error }
|
||||
) &
|
||||
@@ -105,7 +106,14 @@ export class ImportModalController {
|
||||
})
|
||||
|
||||
try {
|
||||
await this.importer.importFromTransferPayloads(payloads)
|
||||
const insertedItems = await this.importer.importFromTransferPayloads(payloads)
|
||||
|
||||
this.updateFile({
|
||||
...file,
|
||||
status: 'uploading-files',
|
||||
})
|
||||
|
||||
await this.importer.uploadAndReplaceInlineFilesInInsertedItems(insertedItems)
|
||||
|
||||
const notesImported = payloads.filter((payload) => payload.content_type === ContentType.TYPES.Note)
|
||||
const tagsImported = payloads.filter((payload) => payload.content_type === ContentType.TYPES.Tag)
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ImportModalController, ImportModalFile } from '@/Controllers/ImportModalController'
|
||||
import { ImportModalController, ImportModalFile } from '@/Components/ImportModal/ImportModalController'
|
||||
import { classNames, ContentType, DecryptedTransferPayload, pluralize } from '@standardnotes/snjs'
|
||||
import { Importer, NoteImportType } from '@standardnotes/ui-services'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
@@ -103,6 +103,7 @@ const ImportModalFileItem = ({
|
||||
{file.status === 'pending' && 'Could not auto-detect service. Please select manually.'}
|
||||
{file.status === 'parsing' && 'Parsing...'}
|
||||
{file.status === 'importing' && 'Importing...'}
|
||||
{file.status === 'uploading-files' && 'Uploading and embedding files...'}
|
||||
{file.status === 'error' && JSON.stringify(file.error)}
|
||||
{file.status === 'success' && file.successMessage}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ImportModalController } from '@/Controllers/ImportModalController'
|
||||
import { ImportModalController } from '@/Components/ImportModal/ImportModalController'
|
||||
import { ClassicFileReader } from '@standardnotes/filepicker'
|
||||
import { NoteImportType } from '@standardnotes/ui-services'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
@@ -41,30 +41,30 @@ const ImportModalInitialPage = ({ setFiles }: Props) => {
|
||||
<div className="text-lg font-semibold">Drag and drop files to auto-detect and import</div>
|
||||
<div className="text-sm">Or click to open file picker</div>
|
||||
</button>
|
||||
<div className="text-center my-4 w-full">or import from:</div>
|
||||
<div className="my-4 w-full text-center">or import from:</div>
|
||||
<div className="flex flex-wrap items-center justify-center gap-4">
|
||||
<Button className="flex items-center !py-2" onClick={() => selectFiles('evernote')}>
|
||||
<Icon type="evernote" className="text-[#14cc45] mr-2" />
|
||||
<Icon type="evernote" className="mr-2 text-[#14cc45]" />
|
||||
Evernote
|
||||
</Button>
|
||||
<Button className="flex items-center !py-2" onClick={() => selectFiles('google-keep')}>
|
||||
<Icon type="gkeep" className="text-[#fbbd00] mr-2" />
|
||||
<Icon type="gkeep" className="mr-2 text-[#fbbd00]" />
|
||||
Google Keep
|
||||
</Button>
|
||||
<Button className="flex items-center !py-2" onClick={() => selectFiles('simplenote')}>
|
||||
<Icon type="simplenote" className="text-[#3360cc] mr-2" />
|
||||
<Icon type="simplenote" className="mr-2 text-[#3360cc]" />
|
||||
Simplenote
|
||||
</Button>
|
||||
<Button className="flex items-center !py-2" onClick={() => selectFiles('aegis')}>
|
||||
<Icon type="aegis" className="bg-[#0d47a1] text-[#fff] rounded mr-2 p-1" size="normal" />
|
||||
<Icon type="aegis" className="mr-2 rounded bg-[#0d47a1] p-1 text-[#fff]" size="normal" />
|
||||
Aegis
|
||||
</Button>
|
||||
<Button className="flex items-center !py-2" onClick={() => selectFiles('plaintext')}>
|
||||
<Icon type="plain-text" className="text-info mr-2" />
|
||||
<Icon type="plain-text" className="mr-2 text-info" />
|
||||
Plaintext / Markdown
|
||||
</Button>
|
||||
<Button className="flex items-center !py-2" onClick={() => selectFiles('html')}>
|
||||
<Icon type="rich-text" className="text-accessory-tint-2 mr-2" />
|
||||
<Icon type="rich-text" className="mr-2 text-accessory-tint-2" />
|
||||
HTML
|
||||
</Button>
|
||||
<Button
|
||||
@@ -81,7 +81,7 @@ const ImportModalInitialPage = ({ setFiles }: Props) => {
|
||||
selectFiles('super').catch(console.error)
|
||||
}}
|
||||
>
|
||||
<Icon type="file-doc" className="text-accessory-tint-1 mr-2" />
|
||||
<Icon type="file-doc" className="mr-2 text-accessory-tint-1" />
|
||||
Super (JSON)
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
+20
-16
@@ -27,25 +27,29 @@ export const DiffView = ({
|
||||
const [textDiff, setTextDiff] = useState<fastdiff.Diff[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
const firstNote = selectedNotes[0]
|
||||
const firstTitle = firstNote.title
|
||||
const firstText =
|
||||
firstNote.noteType === NoteType.Super && convertSuperToMarkdown
|
||||
? new HeadlessSuperConverter().convertSuperStringToOtherFormat(firstNote.text, 'md')
|
||||
: firstNote.text
|
||||
const setDiffs = async () => {
|
||||
const firstNote = selectedNotes[0]
|
||||
const firstTitle = firstNote.title
|
||||
const firstText =
|
||||
firstNote.noteType === NoteType.Super && convertSuperToMarkdown
|
||||
? await new HeadlessSuperConverter().convertSuperStringToOtherFormat(firstNote.text, 'md')
|
||||
: firstNote.text
|
||||
|
||||
const secondNote = selectedNotes[1]
|
||||
const secondTitle = secondNote.title
|
||||
const secondText =
|
||||
secondNote.noteType === NoteType.Super && convertSuperToMarkdown
|
||||
? new HeadlessSuperConverter().convertSuperStringToOtherFormat(secondNote.text, 'md')
|
||||
: secondNote.text
|
||||
const secondNote = selectedNotes[1]
|
||||
const secondTitle = secondNote.title
|
||||
const secondText =
|
||||
secondNote.noteType === NoteType.Super && convertSuperToMarkdown
|
||||
? await new HeadlessSuperConverter().convertSuperStringToOtherFormat(secondNote.text, 'md')
|
||||
: secondNote.text
|
||||
|
||||
const titleDiff = fastdiff(firstTitle, secondTitle, undefined, true)
|
||||
const textDiff = fastdiff(firstText, secondText, undefined, true)
|
||||
const titleDiff = fastdiff(firstTitle, secondTitle, undefined, true)
|
||||
const textDiff = fastdiff(firstText, secondText, undefined, true)
|
||||
|
||||
setTitleDiff(titleDiff)
|
||||
setTextDiff(textDiff)
|
||||
setTitleDiff(titleDiff)
|
||||
setTextDiff(textDiff)
|
||||
}
|
||||
|
||||
setDiffs().catch(console.error)
|
||||
}, [convertSuperToMarkdown, selectedNotes])
|
||||
|
||||
const [preElement, setPreElement] = useState<HTMLPreElement | null>(null)
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
VaultUserServiceEvent,
|
||||
} from '@standardnotes/snjs'
|
||||
import { confirmDialog, DELETE_NOTE_KEYBOARD_COMMAND, KeyboardKey } from '@standardnotes/ui-services'
|
||||
import { ChangeEventHandler, createRef, CSSProperties, KeyboardEventHandler, RefObject } from 'react'
|
||||
import { ChangeEventHandler, createRef, CSSProperties, FocusEvent, KeyboardEventHandler, RefObject } from 'react'
|
||||
import { SuperEditor } from '../SuperEditor/SuperEditor'
|
||||
import IndicatorCircle from '../IndicatorCircle/IndicatorCircle'
|
||||
import LinkedItemBubblesContainer from '../LinkedItems/LinkedItemBubblesContainer'
|
||||
@@ -826,7 +826,10 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
|
||||
this.setState({ plainEditorFocused: true })
|
||||
}
|
||||
|
||||
onPlainBlur = () => {
|
||||
onPlainBlur = (event: FocusEvent) => {
|
||||
if (event.relatedTarget?.id === ElementIds.NoteOptionsButton) {
|
||||
return
|
||||
}
|
||||
this.setState({ plainEditorFocused: false })
|
||||
}
|
||||
|
||||
@@ -897,8 +900,9 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
|
||||
>
|
||||
<div
|
||||
className={classNames(
|
||||
'mb-2 flex flex-wrap justify-between gap-2 md:mb-0 md:flex-nowrap md:gap-4 xl:items-center',
|
||||
'mb-2 flex justify-between md:mb-0 md:flex-nowrap md:gap-4 xl:items-center',
|
||||
shouldShowConflictsButton ? 'items-center' : 'items-start',
|
||||
!renderHeaderOptions ? 'flex-nowrap gap-4' : 'flex-wrap gap-2 ',
|
||||
)}
|
||||
>
|
||||
<div className={classNames(this.state.noteLocked && 'locked', 'flex flex-grow items-center')}>
|
||||
@@ -937,30 +941,33 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
|
||||
{pluralize(this.state.conflictedNotes.length, 'conflict', 'conflicts')}
|
||||
</Button>
|
||||
)}
|
||||
{renderHeaderOptions && (
|
||||
<div className="note-view-options-buttons flex items-center gap-3">
|
||||
{!this.state.readonly && (
|
||||
<>
|
||||
<LinkedItemsButton
|
||||
linkingController={this.application.linkingController}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
/>
|
||||
<ChangeEditorButton
|
||||
noteViewController={this.controller}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
/>
|
||||
<PinNoteButton
|
||||
notesController={this.application.notesController}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<NotesOptionsPanel
|
||||
notesController={this.application.notesController}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="note-view-options-buttons flex items-center gap-3">
|
||||
{!this.state.readonly && renderHeaderOptions && (
|
||||
<>
|
||||
<LinkedItemsButton
|
||||
linkingController={this.application.linkingController}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
/>
|
||||
<ChangeEditorButton
|
||||
noteViewController={this.controller}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
/>
|
||||
<PinNoteButton
|
||||
notesController={this.application.notesController}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<NotesOptionsPanel
|
||||
notesController={this.application.notesController}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
onButtonBlur={() => {
|
||||
this.setState({
|
||||
plainEditorFocused: false,
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-1 mt-2.5 md:hidden">
|
||||
<CollaborationInfoHUD item={this.note} />
|
||||
|
||||
@@ -16,7 +16,16 @@ import {
|
||||
PrefDefaults,
|
||||
} from '@standardnotes/snjs'
|
||||
import { TAB_COMMAND } from '@standardnotes/ui-services'
|
||||
import { ChangeEventHandler, forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'
|
||||
import {
|
||||
ChangeEventHandler,
|
||||
forwardRef,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useRef,
|
||||
useState,
|
||||
FocusEvent,
|
||||
} from 'react'
|
||||
import { NoteViewController } from '../Controller/NoteViewController'
|
||||
|
||||
type Props = {
|
||||
@@ -25,7 +34,7 @@ type Props = {
|
||||
controller: NoteViewController
|
||||
locked: boolean
|
||||
onFocus: () => void
|
||||
onBlur: () => void
|
||||
onBlur: (event: FocusEvent) => void
|
||||
}
|
||||
|
||||
export type PlainEditorInterface = {
|
||||
@@ -106,13 +115,16 @@ export const PlainEditor = forwardRef<PlainEditorInterface, Props>(
|
||||
onFocus()
|
||||
}, [application, isAdjustingMobileCursor, lastEditorFocusEventSource, onFocus])
|
||||
|
||||
const onContentBlur = useCallback(() => {
|
||||
if (lastEditorFocusEventSource.current) {
|
||||
application.notifyWebEvent(WebAppEvent.EditorFocused, { eventSource: lastEditorFocusEventSource })
|
||||
}
|
||||
lastEditorFocusEventSource.current = undefined
|
||||
onBlur()
|
||||
}, [application, lastEditorFocusEventSource, onBlur])
|
||||
const onContentBlur = useCallback(
|
||||
(event: FocusEvent) => {
|
||||
if (lastEditorFocusEventSource.current) {
|
||||
application.notifyWebEvent(WebAppEvent.EditorFocused, { eventSource: lastEditorFocusEventSource })
|
||||
}
|
||||
lastEditorFocusEventSource.current = undefined
|
||||
onBlur(event)
|
||||
},
|
||||
[application, lastEditorFocusEventSource, onBlur],
|
||||
)
|
||||
|
||||
const scrollMobileCursorIntoViewAfterWebviewResize = useCallback(() => {
|
||||
if (needsAdjustMobileCursor.current) {
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import Icon from '@/Components/Icon/Icon'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useState, useEffect, useMemo, useCallback, useRef } from 'react'
|
||||
import { NoteType, Platform, SNNote } from '@standardnotes/snjs'
|
||||
import { useState, useEffect, useMemo, useCallback } from 'react'
|
||||
import { NoteType, Platform, SNNote, pluralize } from '@standardnotes/snjs'
|
||||
import {
|
||||
CHANGE_EDITOR_WIDTH_COMMAND,
|
||||
OPEN_NOTE_HISTORY_COMMAND,
|
||||
PIN_NOTE_COMMAND,
|
||||
SHOW_HIDDEN_OPTIONS_KEYBOARD_COMMAND,
|
||||
STAR_NOTE_COMMAND,
|
||||
SUPER_EXPORT_HTML,
|
||||
SUPER_EXPORT_JSON,
|
||||
SUPER_EXPORT_MARKDOWN,
|
||||
SUPER_SHOW_MARKDOWN_PREVIEW,
|
||||
} from '@standardnotes/ui-services'
|
||||
import ChangeEditorOption from './ChangeEditorOption'
|
||||
@@ -20,9 +17,7 @@ import { addToast, dismissToast, ToastType } from '@standardnotes/toast'
|
||||
import { NotesOptionsProps } from './NotesOptionsProps'
|
||||
import { useResponsiveAppPane } from '../Panes/ResponsivePaneProvider'
|
||||
import { AppPaneId } from '../Panes/AppPaneMetadata'
|
||||
import { getNoteBlob, getNoteFileName } from '@/Utils/NoteExportUtils'
|
||||
import { shareSelectedNotes } from '@/NativeMobileWeb/ShareSelectedNotes'
|
||||
import { downloadSelectedNotesOnAndroid } from '@/NativeMobileWeb/DownloadSelectedNotesOnAndroid'
|
||||
import { createNoteExport } from '@/Utils/NoteExportUtils'
|
||||
import ProtectedUnauthorizedLabel from '../ProtectedItemOverlay/ProtectedUnauthorizedLabel'
|
||||
import { MenuItemIconSize } from '@/Constants/TailwindClassNames'
|
||||
import { KeyboardShortcutIndicator } from '../KeyboardShortcutIndicator/KeyboardShortcutIndicator'
|
||||
@@ -39,9 +34,9 @@ import SuperExportModal from './SuperExportModal'
|
||||
import { useApplication } from '../ApplicationProvider'
|
||||
import { MutuallyExclusiveMediaQueryBreakpoints } from '@/Hooks/useMediaQuery'
|
||||
import AddToVaultMenuOption from '../Vaults/AddToVaultMenuOption'
|
||||
import Menu from '../Menu/Menu'
|
||||
import Popover from '../Popover/Popover'
|
||||
import MenuSection from '../Menu/MenuSection'
|
||||
import { downloadOrShareBlobBasedOnPlatform } from '@/Utils/DownloadOrShareBasedOnPlatform'
|
||||
import { shareBlobOnMobile } from '@/NativeMobileWeb/ShareBlobOnMobile'
|
||||
|
||||
const iconSize = MenuItemIconSize
|
||||
const iconClassDanger = `text-danger mr-2 ${iconSize}`
|
||||
@@ -104,33 +99,48 @@ const NotesOptions = ({ notes, closeMenu }: NotesOptionsProps) => {
|
||||
}, [])
|
||||
|
||||
const downloadSelectedItems = useCallback(async () => {
|
||||
if (notes.length === 1) {
|
||||
const note = notes[0]
|
||||
const blob = getNoteBlob(application, note)
|
||||
application.archiveService.downloadData(blob, getNoteFileName(application, note))
|
||||
if (notes.length === 0) {
|
||||
return
|
||||
}
|
||||
const toast = addToast({
|
||||
type: ToastType.Progress,
|
||||
message: `Exporting ${notes.length} ${pluralize(notes.length, 'note', 'notes')}...`,
|
||||
})
|
||||
try {
|
||||
const result = await createNoteExport(application, notes)
|
||||
if (!result) {
|
||||
return
|
||||
}
|
||||
const { blob, fileName } = result
|
||||
void downloadOrShareBlobBasedOnPlatform({
|
||||
archiveService: application.archiveService,
|
||||
platform: application.platform,
|
||||
mobileDevice: application.mobileDevice,
|
||||
blob: blob,
|
||||
filename: fileName,
|
||||
isNativeMobileWeb: application.isNativeMobileWeb(),
|
||||
})
|
||||
dismissToast(toast)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
addToast({
|
||||
type: ToastType.Error,
|
||||
message: 'Could not export notes',
|
||||
})
|
||||
dismissToast(toast)
|
||||
}
|
||||
}, [application, notes])
|
||||
|
||||
const exportSelectedItems = useCallback(() => {
|
||||
const hasSuperNote = notes.some((note) => note.noteType === NoteType.Super)
|
||||
|
||||
if (hasSuperNote) {
|
||||
setShowExportSuperModal(true)
|
||||
return
|
||||
}
|
||||
|
||||
if (notes.length > 1) {
|
||||
const loadingToastId = addToast({
|
||||
type: ToastType.Loading,
|
||||
message: `Exporting ${notes.length} notes...`,
|
||||
})
|
||||
await application.archiveService.downloadDataAsZip(
|
||||
notes.map((note) => {
|
||||
return {
|
||||
name: getNoteFileName(application, note),
|
||||
content: getNoteBlob(application, note),
|
||||
}
|
||||
}),
|
||||
)
|
||||
dismissToast(loadingToastId)
|
||||
addToast({
|
||||
type: ToastType.Success,
|
||||
message: `Exported ${notes.length} notes`,
|
||||
})
|
||||
}
|
||||
}, [application, notes])
|
||||
downloadSelectedItems().catch(console.error)
|
||||
}, [downloadSelectedItems, notes])
|
||||
|
||||
const closeMenuAndToggleNotesList = useCallback(() => {
|
||||
const isMobileScreen = matchMedia(MutuallyExclusiveMediaQueryBreakpoints.sm).matches
|
||||
@@ -199,9 +209,6 @@ const NotesOptions = ({ notes, closeMenu }: NotesOptionsProps) => {
|
||||
[application],
|
||||
)
|
||||
|
||||
const superExportButtonRef = useRef<HTMLButtonElement>(null)
|
||||
const [isSuperExportMenuOpen, setIsSuperExportMenuOpen] = useState(false)
|
||||
|
||||
const unauthorized = notes.some((note) => !application.isAuthorizedToRenderItem(note))
|
||||
if (unauthorized) {
|
||||
return <ProtectedUnauthorizedLabel />
|
||||
@@ -224,8 +231,6 @@ const NotesOptions = ({ notes, closeMenu }: NotesOptionsProps) => {
|
||||
return null
|
||||
}
|
||||
|
||||
const isOnlySuperNoteSelected = notes.length === 1 && notes[0].noteType === NoteType.Super
|
||||
|
||||
return (
|
||||
<>
|
||||
{notes.length === 1 && (
|
||||
@@ -342,77 +347,35 @@ const NotesOptions = ({ notes, closeMenu }: NotesOptionsProps) => {
|
||||
{pinShortcut && <KeyboardShortcutIndicator className="ml-auto" shortcut={pinShortcut} />}
|
||||
</MenuItem>
|
||||
)}
|
||||
{isOnlySuperNoteSelected ? (
|
||||
<>
|
||||
<MenuItem
|
||||
ref={superExportButtonRef}
|
||||
onClick={() => {
|
||||
setIsSuperExportMenuOpen((open) => !open)
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<Icon type="download" className={iconClass} />
|
||||
Export
|
||||
</div>
|
||||
<Icon type="chevron-right" className="ml-auto text-neutral" />
|
||||
</MenuItem>
|
||||
<Popover
|
||||
title="Export note"
|
||||
side="left"
|
||||
align="start"
|
||||
open={isSuperExportMenuOpen}
|
||||
anchorElement={superExportButtonRef.current}
|
||||
togglePopover={() => {
|
||||
setIsSuperExportMenuOpen(!isSuperExportMenuOpen)
|
||||
}}
|
||||
className="md:py-1"
|
||||
>
|
||||
<Menu a11yLabel={'Super note export menu'}>
|
||||
<MenuSection>
|
||||
<MenuItem onClick={() => commandService.triggerCommand(SUPER_EXPORT_JSON, notes[0].title)}>
|
||||
<Icon type="code" className={iconClass} />
|
||||
Export as JSON
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => commandService.triggerCommand(SUPER_EXPORT_MARKDOWN, notes[0].title)}>
|
||||
<Icon type="markdown" className={iconClass} />
|
||||
Export as Markdown
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => commandService.triggerCommand(SUPER_EXPORT_HTML, notes[0].title)}>
|
||||
<Icon type="rich-text" className={iconClass} />
|
||||
Export as HTML
|
||||
</MenuItem>
|
||||
</MenuSection>
|
||||
</Menu>
|
||||
</Popover>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
if (application.isNativeMobileWeb()) {
|
||||
void shareSelectedNotes(application, notes)
|
||||
} else {
|
||||
const hasSuperNote = notes.some((note) => note.noteType === NoteType.Super)
|
||||
|
||||
if (hasSuperNote) {
|
||||
setShowExportSuperModal(true)
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
if (application.isNativeMobileWeb()) {
|
||||
createNoteExport(application, notes)
|
||||
.then((result) => {
|
||||
if (!result) {
|
||||
return
|
||||
}
|
||||
|
||||
void downloadSelectedItems()
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon type={application.platform === Platform.Android ? 'share' : 'download'} className={iconClass} />
|
||||
{application.platform === Platform.Android ? 'Share' : 'Export'}
|
||||
</MenuItem>
|
||||
{application.platform === Platform.Android && (
|
||||
<MenuItem onClick={() => downloadSelectedNotesOnAndroid(application, notes)}>
|
||||
<Icon type="download" className={iconClass} />
|
||||
Export
|
||||
</MenuItem>
|
||||
)}
|
||||
</>
|
||||
const { blob, fileName } = result
|
||||
|
||||
shareBlobOnMobile(application.mobileDevice, application.isNativeMobileWeb(), blob, fileName).catch(
|
||||
console.error,
|
||||
)
|
||||
})
|
||||
.catch(console.error)
|
||||
} else {
|
||||
exportSelectedItems()
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Icon type={application.platform === Platform.Android ? 'share' : 'download'} className={iconClass} />
|
||||
{application.platform === Platform.Android ? 'Share' : 'Export'}
|
||||
</MenuItem>
|
||||
{application.platform === Platform.Android && (
|
||||
<MenuItem onClick={exportSelectedItems}>
|
||||
<Icon type="download" className={iconClass} />
|
||||
Export
|
||||
</MenuItem>
|
||||
)}
|
||||
<MenuItem onClick={duplicateSelectedItems} disabled={areSomeNotesInReadonlySharedVault}>
|
||||
<Icon type="copy" className={iconClass} />
|
||||
@@ -541,7 +504,7 @@ const NotesOptions = ({ notes, closeMenu }: NotesOptionsProps) => {
|
||||
)}
|
||||
|
||||
<ModalOverlay isOpen={showExportSuperModal} close={closeSuperExportModal}>
|
||||
<SuperExportModal exportNotes={downloadSelectedItems} close={closeSuperExportModal} />
|
||||
<SuperExportModal notes={notes} exportNotes={downloadSelectedItems} close={closeSuperExportModal} />
|
||||
</ModalOverlay>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import { useCallback, useRef, useState } from 'react'
|
||||
import { FocusEvent, useCallback, useRef, useState } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import NotesOptions from './NotesOptions'
|
||||
import { NotesController } from '@/Controllers/NotesController/NotesController'
|
||||
import Popover from '../Popover/Popover'
|
||||
import RoundIconButton from '../Button/RoundIconButton'
|
||||
import Menu from '../Menu/Menu'
|
||||
import { ElementIds } from '@/Constants/ElementIDs'
|
||||
|
||||
type Props = {
|
||||
notesController: NotesController
|
||||
onClickPreprocessing?: () => Promise<void>
|
||||
onButtonBlur?: (event: FocusEvent) => void
|
||||
}
|
||||
|
||||
const NotesOptionsPanel = ({ notesController, onClickPreprocessing }: Props) => {
|
||||
const NotesOptionsPanel = ({ notesController, onClickPreprocessing, onButtonBlur }: Props) => {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const buttonRef = useRef<HTMLButtonElement>(null)
|
||||
|
||||
@@ -30,7 +32,14 @@ const NotesOptionsPanel = ({ notesController, onClickPreprocessing }: Props) =>
|
||||
|
||||
return (
|
||||
<>
|
||||
<RoundIconButton label="Note options menu" onClick={toggleMenu} ref={buttonRef} icon="more" />
|
||||
<RoundIconButton
|
||||
id={ElementIds.NoteOptionsButton}
|
||||
label="Note options menu"
|
||||
onClick={toggleMenu}
|
||||
onBlur={onButtonBlur}
|
||||
ref={buttonRef}
|
||||
icon="more"
|
||||
/>
|
||||
<Popover
|
||||
title="Note options"
|
||||
disableClickOutside={disableClickOutside}
|
||||
|
||||
@@ -1,17 +1,34 @@
|
||||
import { PrefKey, PrefValue } from '@standardnotes/snjs'
|
||||
import { PrefKey, PrefValue, SNNote } from '@standardnotes/snjs'
|
||||
import { useApplication } from '../ApplicationProvider'
|
||||
import Dropdown from '../Dropdown/Dropdown'
|
||||
import Modal from '../Modal/Modal'
|
||||
import usePreference from '@/Hooks/usePreference'
|
||||
import RadioButtonGroup from '../RadioButtonGroup/RadioButtonGroup'
|
||||
import { useEffect } from 'react'
|
||||
import Switch from '../Switch/Switch'
|
||||
import { noteHasEmbeddedFiles } from '@/Utils/NoteExportUtils'
|
||||
|
||||
type Props = {
|
||||
notes: SNNote[]
|
||||
exportNotes: () => void
|
||||
close: () => void
|
||||
}
|
||||
|
||||
const SuperExportModal = ({ exportNotes, close }: Props) => {
|
||||
const SuperExportModal = ({ notes, exportNotes, close }: Props) => {
|
||||
const application = useApplication()
|
||||
const superNoteExportFormat = usePreference(PrefKey.SuperNoteExportFormat)
|
||||
const superNoteExportEmbedBehavior = usePreference(PrefKey.SuperNoteExportEmbedBehavior)
|
||||
const superNoteExportUseMDFrontmatter = usePreference(PrefKey.SuperNoteExportUseMDFrontmatter)
|
||||
|
||||
useEffect(() => {
|
||||
if (superNoteExportFormat === 'json' && superNoteExportEmbedBehavior === 'separate') {
|
||||
void application.setPreference(PrefKey.SuperNoteExportEmbedBehavior, 'reference')
|
||||
}
|
||||
if (superNoteExportFormat === 'md' && superNoteExportEmbedBehavior === 'reference') {
|
||||
void application.setPreference(PrefKey.SuperNoteExportEmbedBehavior, 'separate')
|
||||
}
|
||||
}, [application, superNoteExportEmbedBehavior, superNoteExportFormat])
|
||||
|
||||
const someNotesHaveEmbeddedFiles = notes.some(noteHasEmbeddedFiles)
|
||||
|
||||
return (
|
||||
<Modal
|
||||
@@ -28,20 +45,21 @@ const SuperExportModal = ({ exportNotes, close }: Props) => {
|
||||
{
|
||||
label: 'Export',
|
||||
type: 'primary',
|
||||
onClick: exportNotes,
|
||||
onClick: () => {
|
||||
close()
|
||||
exportNotes()
|
||||
},
|
||||
mobileSlot: 'right',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<div className="mb-4">
|
||||
<div className="mb-1 text-base">
|
||||
We detected your selection includes Super notes. How do you want to export them?
|
||||
</div>
|
||||
<Dropdown
|
||||
label="Super notes export format"
|
||||
<div className="mb-2">
|
||||
<div className="mb-3 text-base">We detected your selection includes Super notes.</div>
|
||||
<div className="mb-1">What format do you want to export them in?</div>
|
||||
<RadioButtonGroup
|
||||
items={[
|
||||
{ label: 'Keep as Super', value: 'json' },
|
||||
{ label: 'Markdown', value: 'md' },
|
||||
{ label: 'Super (.json)', value: 'json' },
|
||||
{ label: 'Markdown (.md)', value: 'md' },
|
||||
{ label: 'HTML', value: 'html' },
|
||||
]}
|
||||
value={superNoteExportFormat}
|
||||
@@ -52,12 +70,47 @@ const SuperExportModal = ({ exportNotes, close }: Props) => {
|
||||
)
|
||||
}}
|
||||
/>
|
||||
{superNoteExportFormat === 'md' && (
|
||||
<div className="mt-2 text-xs text-passive-0">
|
||||
Note that conversion to Markdown is not lossless. Some features like collapsible blocks and formatting like
|
||||
superscript/subscript may not be correctly converted.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-passive-0">
|
||||
Note that if you convert Super notes to Markdown then import them back into Standard Notes in the future, you
|
||||
will lose some formatting that the Markdown format is incapable of expressing, such as collapsible blocks and
|
||||
embeds.
|
||||
</div>
|
||||
{superNoteExportFormat === 'md' && (
|
||||
<div className="mt-4">
|
||||
<Switch
|
||||
checked={superNoteExportUseMDFrontmatter}
|
||||
onChange={(checked) => {
|
||||
void application.setPreference(
|
||||
PrefKey.SuperNoteExportUseMDFrontmatter,
|
||||
checked as PrefValue[PrefKey.SuperNoteExportUseMDFrontmatter],
|
||||
)
|
||||
}}
|
||||
className="!flex items-center"
|
||||
>
|
||||
<span className="ml-2">Export with frontmatter</span>
|
||||
</Switch>
|
||||
</div>
|
||||
)}
|
||||
{superNoteExportFormat !== 'json' && someNotesHaveEmbeddedFiles && (
|
||||
<div className="mb-2 mt-4">
|
||||
<div className="mb-1">How do you want embedded files to be handled?</div>
|
||||
<RadioButtonGroup
|
||||
items={[
|
||||
{ label: 'Inline', value: 'inline' },
|
||||
{ label: 'Export separately', value: 'separate' },
|
||||
].concat(superNoteExportFormat !== 'md' ? [{ label: 'Keep as reference', value: 'reference' }] : [])}
|
||||
value={superNoteExportEmbedBehavior}
|
||||
onChange={(value) => {
|
||||
void application.setPreference(
|
||||
PrefKey.SuperNoteExportEmbedBehavior,
|
||||
value as PrefValue[PrefKey.SuperNoteExportEmbedBehavior],
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useDisableBodyScrollOnMobile } from '@/Hooks/useDisableBodyScrollOnMobile'
|
||||
import { classNames } from '@standardnotes/snjs'
|
||||
import { ReactNode, useCallback, useEffect, useRef } from 'react'
|
||||
import { ReactNode, useCallback, useEffect } from 'react'
|
||||
import Portal from '../Portal/Portal'
|
||||
import MobileModalAction from '../Modal/MobileModalAction'
|
||||
import { MobileModalAnimationOptions, useModalAnimation } from '../Modal/useModalAnimation'
|
||||
@@ -10,6 +10,7 @@ import { DialogWithClose } from '@/Utils/CloseOpenModalsAndPopovers'
|
||||
import { useMediaQuery, MutuallyExclusiveMediaQueryBreakpoints } from '@/Hooks/useMediaQuery'
|
||||
import { SupportsPassiveListeners } from '@/Constants/Constants'
|
||||
import { useLifecycleAnimation } from '@/Hooks/useLifecycleAnimation'
|
||||
import { getScrollParent } from '@/Utils'
|
||||
|
||||
const DisableScroll = () => {
|
||||
useDisableBodyScrollOnMobile()
|
||||
@@ -61,17 +62,16 @@ const MobilePopoverContent = ({
|
||||
options: MobileModalAnimationOptions,
|
||||
},
|
||||
})
|
||||
const scrollContainerRef = useRef<HTMLDivElement | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
const closestScrollContainer = scrollContainerRef.current
|
||||
|
||||
if (!element || !closestScrollContainer) {
|
||||
if (!element) {
|
||||
return
|
||||
}
|
||||
|
||||
let closestScrollContainer: HTMLElement | null = null
|
||||
let elementY = 0
|
||||
let startY = 0
|
||||
let startTimestamp = Date.now()
|
||||
let closestScrollContainerScrollTop = 0
|
||||
let isClosestScrollContainerScrolledAtStart = false
|
||||
let containerScrollChangedAfterTouchStart = false
|
||||
@@ -79,6 +79,8 @@ const MobilePopoverContent = ({
|
||||
const touchStartHandler = (e: TouchEvent) => {
|
||||
startY = e.touches[0].clientY
|
||||
elementY = element.getBoundingClientRect().y
|
||||
startTimestamp = Date.now()
|
||||
closestScrollContainer = getScrollParent(e.target as HTMLElement)
|
||||
closestScrollContainerScrollTop = closestScrollContainer?.scrollTop || 0
|
||||
isClosestScrollContainerScrolledAtStart = !!closestScrollContainer && closestScrollContainerScrollTop > 0
|
||||
containerScrollChangedAfterTouchStart = false
|
||||
@@ -103,7 +105,7 @@ const MobilePopoverContent = ({
|
||||
}
|
||||
|
||||
const y = element.getBoundingClientRect().y
|
||||
if (y > elementY) {
|
||||
if (y > elementY && closestScrollContainer) {
|
||||
closestScrollContainer.style.overflowY = 'hidden'
|
||||
}
|
||||
|
||||
@@ -117,11 +119,17 @@ const MobilePopoverContent = ({
|
||||
},
|
||||
)
|
||||
}
|
||||
const touchEndHandler = () => {
|
||||
const touchEndHandler = (event: TouchEvent) => {
|
||||
const y = element.getBoundingClientRect().y
|
||||
const threshold = window.innerHeight * 0.75
|
||||
|
||||
if (y > threshold && !isClosestScrollContainerScrolledAtStart) {
|
||||
const endTimestamp = Date.now()
|
||||
const deltaY = event.changedTouches[0].clientY - startY
|
||||
const velocity = deltaY / (endTimestamp - startTimestamp)
|
||||
|
||||
if (y < threshold && velocity > 2) {
|
||||
requestClose()
|
||||
} else if (y > threshold && !isClosestScrollContainerScrolledAtStart) {
|
||||
requestClose()
|
||||
} else {
|
||||
element.animate(
|
||||
@@ -136,7 +144,9 @@ const MobilePopoverContent = ({
|
||||
}
|
||||
|
||||
startY = 0
|
||||
closestScrollContainer.style.overflowY = ''
|
||||
if (closestScrollContainer) {
|
||||
closestScrollContainer.style.overflowY = ''
|
||||
}
|
||||
}
|
||||
|
||||
element.addEventListener('touchstart', touchStartHandler, SupportsPassiveListeners ? { passive: true } : false)
|
||||
@@ -191,12 +201,7 @@ const MobilePopoverContent = ({
|
||||
Done
|
||||
</MobileModalAction>
|
||||
</MobileModalHeader>
|
||||
<div
|
||||
className={classNames('h-full overflow-y-auto overscroll-none bg-passive-5', className)}
|
||||
ref={scrollContainerRef}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
<div className={classNames('h-full overflow-y-auto overscroll-none bg-passive-5', className)}>{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Portal>
|
||||
|
||||
@@ -2,7 +2,6 @@ import { FunctionComponent, UIEventHandler, useCallback, useState } from 'react'
|
||||
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin'
|
||||
import { ContentEditable } from '@lexical/react/LexicalContentEditable'
|
||||
import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin'
|
||||
import { CheckListPlugin } from '@lexical/react/LexicalCheckListPlugin'
|
||||
import { ClearEditorPlugin } from '@lexical/react/LexicalClearEditorPlugin'
|
||||
import { MarkdownShortcutPlugin } from '@lexical/react/LexicalMarkdownShortcutPlugin'
|
||||
import { TablePlugin } from '@lexical/react/LexicalTablePlugin'
|
||||
@@ -28,6 +27,8 @@ import { RemoveBrokenTablesPlugin } from './Plugins/TablePlugin'
|
||||
import TableActionMenuPlugin from './Plugins/TableCellActionMenuPlugin'
|
||||
import ToolbarPlugin from './Plugins/ToolbarPlugin/ToolbarPlugin'
|
||||
import { useMediaQuery, MutuallyExclusiveMediaQueryBreakpoints } from '@/Hooks/useMediaQuery'
|
||||
import { CheckListPlugin } from './Plugins/List/CheckListPlugin'
|
||||
import { EmptyLinePlaceholderPlugin } from './Plugins/EmptyLinePlaceholderPlugin'
|
||||
|
||||
type BlocksEditorProps = {
|
||||
onChange?: (value: string, preview: string) => void
|
||||
@@ -113,6 +114,7 @@ export const BlocksEditor: FunctionComponent<BlocksEditorProps> = ({
|
||||
<CollapsiblePlugin />
|
||||
<TabIndentationPlugin />
|
||||
<RemoveBrokenTablesPlugin />
|
||||
<EmptyLinePlaceholderPlugin />
|
||||
{!readonly && floatingAnchorElem && (
|
||||
<>
|
||||
<DraggableBlockPlugin anchorElem={floatingAnchorElem} />
|
||||
|
||||
@@ -16,8 +16,11 @@ import { FileNode } from '../../Plugins/EncryptedFilePlugin/Nodes/FileNode'
|
||||
import { BubbleNode } from '../../Plugins/ItemBubblePlugin/Nodes/BubbleNode'
|
||||
import { RemoteImageNode } from '../../Plugins/RemoteImagePlugin/RemoteImageNode'
|
||||
import { InlineFileNode } from '../../Plugins/InlineFilePlugin/InlineFileNode'
|
||||
import { CreateEditorArgs } from 'lexical'
|
||||
import { ListHTMLExportNode } from '../../Plugins/List/ListHTMLExportNode'
|
||||
import { FileExportNode } from './FileExportNode'
|
||||
|
||||
export const BlockEditorNodes = [
|
||||
const CommonNodes = [
|
||||
AutoLinkNode,
|
||||
CodeHighlightNode,
|
||||
CodeNode,
|
||||
@@ -29,7 +32,6 @@ export const BlockEditorNodes = [
|
||||
HorizontalRuleNode,
|
||||
LinkNode,
|
||||
ListItemNode,
|
||||
ListNode,
|
||||
MarkNode,
|
||||
OverflowNode,
|
||||
QuoteNode,
|
||||
@@ -43,3 +45,17 @@ export const BlockEditorNodes = [
|
||||
RemoteImageNode,
|
||||
InlineFileNode,
|
||||
]
|
||||
|
||||
export const BlockEditorNodes = [...CommonNodes, ListNode]
|
||||
|
||||
export const SuperExportNodes: CreateEditorArgs['nodes'] = [
|
||||
...CommonNodes,
|
||||
FileExportNode,
|
||||
ListHTMLExportNode,
|
||||
{
|
||||
replace: ListNode,
|
||||
with(node) {
|
||||
return new ListHTMLExportNode(node.getListType(), node.getStart())
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
import { DecoratorBlockNode, SerializedDecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode'
|
||||
import { parseAndCreateZippableFileName } from '@standardnotes/ui-services'
|
||||
import { DOMExportOutput, Spread } from 'lexical'
|
||||
|
||||
type SerializedFileExportNode = Spread<
|
||||
{
|
||||
version: 1
|
||||
type: 'file-export'
|
||||
name: string
|
||||
mimeType: string
|
||||
},
|
||||
SerializedDecoratorBlockNode
|
||||
>
|
||||
|
||||
export class FileExportNode extends DecoratorBlockNode {
|
||||
__name: string
|
||||
__mimeType: string
|
||||
|
||||
static getType(): string {
|
||||
return 'file-export'
|
||||
}
|
||||
|
||||
constructor(name: string, mimeType: string) {
|
||||
super()
|
||||
this.__name = name
|
||||
this.__mimeType = mimeType
|
||||
}
|
||||
|
||||
static clone(node: FileExportNode): FileExportNode {
|
||||
return new FileExportNode(node.__name, node.__mimeType)
|
||||
}
|
||||
|
||||
static importJSON(serializedNode: SerializedFileExportNode): FileExportNode {
|
||||
const node = new FileExportNode(serializedNode.name, serializedNode.mimeType)
|
||||
return node
|
||||
}
|
||||
|
||||
exportJSON(): SerializedFileExportNode {
|
||||
return {
|
||||
...super.exportJSON(),
|
||||
name: this.__name,
|
||||
mimeType: this.__mimeType,
|
||||
version: 1,
|
||||
type: 'file-export',
|
||||
}
|
||||
}
|
||||
|
||||
getZippableFileName(): string {
|
||||
return parseAndCreateZippableFileName(this.__name)
|
||||
}
|
||||
|
||||
getTextContent(): string {
|
||||
return `${this.__mimeType.startsWith('image/') ? '!' : ''}[${this.__name}](./${this.getZippableFileName()})`
|
||||
}
|
||||
|
||||
exportDOM(): DOMExportOutput {
|
||||
const src = `./${this.getZippableFileName()}`
|
||||
if (this.__mimeType.startsWith('image/')) {
|
||||
const img = document.createElement('img')
|
||||
img.setAttribute('src', src)
|
||||
return { element: img }
|
||||
} else if (this.__mimeType.startsWith('audio')) {
|
||||
const audio = document.createElement('audio')
|
||||
audio.setAttribute('controls', '')
|
||||
const source = document.createElement('source')
|
||||
source.setAttribute('src', src)
|
||||
source.setAttribute('type', this.__mimeType)
|
||||
audio.appendChild(source)
|
||||
return { element: audio }
|
||||
} else if (this.__mimeType.startsWith('video')) {
|
||||
const video = document.createElement('video')
|
||||
video.setAttribute('controls', '')
|
||||
const source = document.createElement('source')
|
||||
source.setAttribute('src', src)
|
||||
source.setAttribute('type', this.__mimeType)
|
||||
video.appendChild(source)
|
||||
return { element: video }
|
||||
}
|
||||
const object = document.createElement('object')
|
||||
object.setAttribute('data', src)
|
||||
object.setAttribute('type', this.__mimeType)
|
||||
return { element: object }
|
||||
}
|
||||
|
||||
decorate(): JSX.Element {
|
||||
// Doesn't need to actually render anything since this is only used for export
|
||||
return <></>
|
||||
}
|
||||
}
|
||||
|
||||
export function $createFileExportNode(name: string, mimeType: string): FileExportNode {
|
||||
return new FileExportNode(name, mimeType)
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
@import 'lists';
|
||||
|
||||
.Lexical__ltr {
|
||||
text-align: left;
|
||||
}
|
||||
@@ -163,70 +165,6 @@
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.4);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.Lexical__tableAddColumns {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 20px;
|
||||
background-color: #eee;
|
||||
height: 100%;
|
||||
right: 0;
|
||||
animation: table-controls 0.2s ease;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.Lexical__tableAddColumns:after {
|
||||
background-image: url(#{$blocks-editor-icons-path}/plus.svg);
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.4;
|
||||
}
|
||||
.Lexical__tableAddColumns:hover {
|
||||
background-color: #c9dbf0;
|
||||
}
|
||||
.Lexical__tableAddRows {
|
||||
position: absolute;
|
||||
bottom: -25px;
|
||||
width: calc(100% - 25px);
|
||||
background-color: #eee;
|
||||
height: 20px;
|
||||
left: 0;
|
||||
animation: table-controls 0.2s ease;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.Lexical__tableAddRows:after {
|
||||
background-image: url(#{$blocks-editor-icons-path}/plus.svg);
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.4;
|
||||
}
|
||||
.Lexical__tableAddRows:hover {
|
||||
background-color: #c9dbf0;
|
||||
}
|
||||
@keyframes table-controls {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.Lexical__tableCellResizeRuler {
|
||||
display: block;
|
||||
position: absolute;
|
||||
@@ -261,118 +199,6 @@
|
||||
display: inline;
|
||||
background-color: #ffbbbb !important;
|
||||
}
|
||||
:root {
|
||||
--lexical-ordered-list-left-margin: 16px;
|
||||
}
|
||||
.monospace-font {
|
||||
--lexical-ordered-list-left-margin: 42px;
|
||||
}
|
||||
@for $i from 1 through 5 {
|
||||
.Lexical__ol#{$i} {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin-left: var(--lexical-ordered-list-left-margin);
|
||||
list-style-position: outside;
|
||||
|
||||
&.Lexical__rtl {
|
||||
margin-left: 0;
|
||||
margin-right: var(--lexical-ordered-list-left-margin);
|
||||
}
|
||||
}
|
||||
}
|
||||
.Lexical__ol2 {
|
||||
list-style-type: upper-alpha;
|
||||
}
|
||||
.Lexical__ol3 {
|
||||
list-style-type: lower-alpha;
|
||||
}
|
||||
.Lexical__ol4 {
|
||||
list-style-type: upper-roman;
|
||||
}
|
||||
.Lexical__ol5 {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
.Lexical__ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin-left: 16px;
|
||||
list-style-position: outside;
|
||||
|
||||
&.Lexical__rtl {
|
||||
margin-left: 0;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
.Lexical__listItem {
|
||||
margin: 0 0px;
|
||||
}
|
||||
.Lexical__listItemChecked,
|
||||
.Lexical__listItemUnchecked {
|
||||
position: relative;
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
list-style-type: none;
|
||||
outline: none;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.Lexical__listItemChecked {
|
||||
text-decoration: line-through;
|
||||
opacity: 0.4;
|
||||
}
|
||||
.Lexical__listItemUnchecked:before,
|
||||
.Lexical__listItemChecked:before {
|
||||
content: '';
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
left: 0;
|
||||
top: 5px;
|
||||
cursor: pointer;
|
||||
background-size: cover;
|
||||
position: absolute;
|
||||
}
|
||||
.Lexical__listItemUnchecked[dir='rtl']:before,
|
||||
.Lexical__listItemChecked[dir='rtl']:before {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
.Lexical__listItemUnchecked:focus:before,
|
||||
.Lexical__listItemChecked:focus:before {
|
||||
box-shadow: 0 0 0 2px #a6cdfe;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.Lexical__listItemUnchecked:before {
|
||||
border: 1px solid #999;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.Lexical__listItemChecked:before {
|
||||
border: 1px solid var(--sn-stylekit-info-color);
|
||||
border-radius: 2px;
|
||||
background-color: var(--sn-stylekit-info-color);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.Lexical__listItemChecked:after {
|
||||
content: '';
|
||||
cursor: pointer;
|
||||
border-color: var(--sn-stylekit-info-contrast-color);
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 7px;
|
||||
width: 5px;
|
||||
left: 6px;
|
||||
height: 10px;
|
||||
transform: rotate(45deg);
|
||||
border-width: 0 2px 2px 0;
|
||||
}
|
||||
.Lexical__nestedListItem {
|
||||
list-style-type: none;
|
||||
}
|
||||
.Lexical__nestedListItem:before,
|
||||
.Lexical__nestedListItem:after {
|
||||
display: none;
|
||||
}
|
||||
.Lexical__tokenComment {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
.Lexical__listItemUnchecked,
|
||||
.Lexical__listItemChecked {
|
||||
min-height: 18px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.Lexical__listItemUnchecked:before,
|
||||
.Lexical__listItemChecked:before {
|
||||
top: 0px;
|
||||
}
|
||||
.Lexical__listItemChecked:after {
|
||||
top: 1px;
|
||||
}
|
||||
.Lexical__table {
|
||||
margin: 10px 0;
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
.icon.plus {
|
||||
background-image: url(#{$blocks-editor-icons-path}/plus.svg);
|
||||
}
|
||||
|
||||
/**
|
||||
.icon.dropdown-more {
|
||||
background-image: url(#{$blocks-editor-icons-path}/dropdown-more.svg);
|
||||
}
|
||||
|
||||
.icon.font-color {
|
||||
background-image: url(#{$blocks-editor-icons-path}/font-color.svg);
|
||||
}
|
||||
|
||||
.icon.font-family {
|
||||
background-image: url(#{$blocks-editor-icons-path}/font-family.svg);
|
||||
}
|
||||
|
||||
.icon.bg-color {
|
||||
background-image: url(#{$blocks-editor-icons-path}/bg-color.svg);
|
||||
}
|
||||
|
||||
i.palette {
|
||||
background-image: url(#{$blocks-editor-icons-path}/palette.svg);
|
||||
}
|
||||
|
||||
i.bucket {
|
||||
background-image: url(#{$blocks-editor-icons-path}/paint-bucket.svg);
|
||||
}
|
||||
|
||||
i.clear {
|
||||
background-image: url(#{$blocks-editor-icons-path}/trash.svg);
|
||||
}
|
||||
|
||||
i.image {
|
||||
background-image: url(#{$blocks-editor-icons-path}/file-image.svg);
|
||||
}
|
||||
|
||||
i.close {
|
||||
background-image: url(#{$blocks-editor-icons-path}/close.svg);
|
||||
}
|
||||
|
||||
i.figma {
|
||||
background-image: url(#{$blocks-editor-icons-path}/figma.svg);
|
||||
}
|
||||
|
||||
i.poll {
|
||||
background-image: url(#{$blocks-editor-icons-path}/card-checklist.svg);
|
||||
}
|
||||
|
||||
i.indent {
|
||||
background-image: url(#{$blocks-editor-icons-path}/indent.svg);
|
||||
}
|
||||
|
||||
i.markdown {
|
||||
background-image: url(#{$blocks-editor-icons-path}/markdown.svg);
|
||||
}
|
||||
|
||||
i.outdent {
|
||||
background-image: url(#{$blocks-editor-icons-path}/outdent.svg);
|
||||
}
|
||||
|
||||
i.undo {
|
||||
background-image: url(#{$blocks-editor-icons-path}/arrow-counterclockwise.svg);
|
||||
}
|
||||
|
||||
i.redo {
|
||||
background-image: url(#{$blocks-editor-icons-path}/arrow-clockwise.svg);
|
||||
}
|
||||
|
||||
i.sticky {
|
||||
background-image: url(#{$blocks-editor-icons-path}/sticky.svg);
|
||||
}
|
||||
|
||||
i.mic {
|
||||
background-image: url(#{$blocks-editor-icons-path}/mic.svg);
|
||||
}
|
||||
|
||||
i.import {
|
||||
background-image: url(#{$blocks-editor-icons-path}/upload.svg);
|
||||
}
|
||||
|
||||
i.export {
|
||||
background-image: url(#{$blocks-editor-icons-path}/download.svg);
|
||||
}
|
||||
|
||||
i.diagram-2 {
|
||||
background-image: url(#{$blocks-editor-icons-path}/diagram-2.svg);
|
||||
}
|
||||
|
||||
i.user {
|
||||
background-image: url(#{$blocks-editor-icons-path}/user.svg);
|
||||
}
|
||||
|
||||
i.equation {
|
||||
background-image: url(#{$blocks-editor-icons-path}/plus-slash-minus.svg);
|
||||
}
|
||||
|
||||
i.gif {
|
||||
background-image: url(#{$blocks-editor-icons-path}/filetype-gif.svg);
|
||||
}
|
||||
|
||||
i.copy {
|
||||
background-image: url(#{$blocks-editor-icons-path}/copy.svg);
|
||||
}
|
||||
|
||||
i.success {
|
||||
background-image: url(#{$blocks-editor-icons-path}/success.svg);
|
||||
}
|
||||
|
||||
i.prettier {
|
||||
background-image: url(#{$blocks-editor-icons-path}/prettier.svg);
|
||||
}
|
||||
|
||||
i.prettier-error {
|
||||
background-image: url(#{$blocks-editor-icons-path}/prettier-error.svg);
|
||||
}
|
||||
*/
|
||||
@@ -1,5 +1,3 @@
|
||||
@import 'base';
|
||||
@import 'custom';
|
||||
@import 'editor';
|
||||
@import 'icons';
|
||||
@import 'links';
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
.button.active,
|
||||
.toolbar .button.active {
|
||||
background-color: var(--sn-stylekit-contrast-background-color);
|
||||
}
|
||||
|
||||
.link-editor {
|
||||
background-color: var(--sn-stylekit-secondary-background-color);
|
||||
border-radius: 8px;
|
||||
border: 0;
|
||||
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3);
|
||||
box-sizing: border-box;
|
||||
display: absolute;
|
||||
font-family: inherit;
|
||||
font-size: 15px;
|
||||
left: 0;
|
||||
margin: 8px 12px;
|
||||
max-width: 400px;
|
||||
opacity: 0;
|
||||
outline: 0;
|
||||
padding: 8px 12px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
transition: opacity 0.5s;
|
||||
width: 100%;
|
||||
will-change: transform;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.link-input {
|
||||
background-color: var(--sn-stylekit-background-color);
|
||||
border-radius: 15px;
|
||||
border: 0;
|
||||
box-sizing: border-box;
|
||||
color: var(--sn-stylekit-contrast-color);
|
||||
display: absolute;
|
||||
font-family: inherit;
|
||||
font-size: 15px;
|
||||
margin: 8px 12px;
|
||||
outline: 0;
|
||||
padding: 8px 12px;
|
||||
position: relative;
|
||||
width: calc(100% - 24px);
|
||||
}
|
||||
|
||||
.link-editor div.link-edit {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-size: 16px;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
vertical-align: -0.25em;
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.link-editor .link-input a {
|
||||
color: rgb(33, 111, 219);
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
margin-right: 30px;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.link-editor .link-input a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.link-editor .font-size-wrapper,
|
||||
.link-editor .font-family-wrapper {
|
||||
display: flex;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.link-editor select {
|
||||
padding: 6px;
|
||||
border: none;
|
||||
background-color: rgba(0, 0, 0, 0.075);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.link-editor .button {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
padding: 6px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.link-editor .button.hovered {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-block;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.link-editor .button i,
|
||||
.actions i {
|
||||
background-size: contain;
|
||||
display: inline-block;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
vertical-align: -0.25em;
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
:root {
|
||||
--lexical-ordered-list-left-margin: 16px;
|
||||
}
|
||||
.monospace-font {
|
||||
--lexical-ordered-list-left-margin: 42px;
|
||||
}
|
||||
@for $i from 1 through 5 {
|
||||
.Lexical__ol#{$i} {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin-left: var(--lexical-ordered-list-left-margin);
|
||||
list-style-position: outside;
|
||||
|
||||
&.Lexical__rtl {
|
||||
margin-left: 0;
|
||||
margin-right: var(--lexical-ordered-list-left-margin);
|
||||
}
|
||||
}
|
||||
}
|
||||
.Lexical__ol2 {
|
||||
list-style-type: upper-alpha;
|
||||
}
|
||||
.Lexical__ol3 {
|
||||
list-style-type: lower-alpha;
|
||||
}
|
||||
.Lexical__ol4 {
|
||||
list-style-type: upper-roman;
|
||||
}
|
||||
.Lexical__ol5 {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
.Lexical__ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin-left: 16px;
|
||||
list-style-position: outside;
|
||||
|
||||
&.Lexical__rtl {
|
||||
margin-left: 0;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
.Lexical__checkList {
|
||||
margin-left: 0;
|
||||
.Lexical__nestedListItem & {
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
.Lexical__listItem {
|
||||
margin: 0 0px;
|
||||
}
|
||||
.Lexical__listItemChecked,
|
||||
.Lexical__listItemUnchecked {
|
||||
position: relative;
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
list-style-type: none;
|
||||
outline: none;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.Lexical__listItemChecked {
|
||||
text-decoration: line-through;
|
||||
opacity: 0.4;
|
||||
}
|
||||
.Lexical__listItemUnchecked:before,
|
||||
.Lexical__listItemChecked:before {
|
||||
content: '';
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
left: 0;
|
||||
top: 7px;
|
||||
cursor: pointer;
|
||||
background-size: cover;
|
||||
position: absolute;
|
||||
}
|
||||
.Lexical__listItemUnchecked[dir='rtl']:before,
|
||||
.Lexical__listItemChecked[dir='rtl']:before {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
.Lexical__listItemUnchecked:focus:before,
|
||||
.Lexical__listItemChecked:focus:before {
|
||||
box-shadow: 0 0 0 2px #a6cdfe;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.Lexical__listItemUnchecked:before {
|
||||
border: 1px solid #999;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.Lexical__listItemChecked:before {
|
||||
border: 1px solid var(--sn-stylekit-info-color);
|
||||
border-radius: 2px;
|
||||
background-color: var(--sn-stylekit-info-color);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.Lexical__listItemChecked:after {
|
||||
content: '';
|
||||
cursor: pointer;
|
||||
border-color: var(--sn-stylekit-info-contrast-color);
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 9px;
|
||||
width: 5px;
|
||||
left: 6px;
|
||||
height: 10px;
|
||||
transform: rotate(45deg);
|
||||
border-width: 0 2px 2px 0;
|
||||
}
|
||||
.Lexical__nestedListItem {
|
||||
list-style-type: none;
|
||||
&.Lexical__listItemUnchecked {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
.Lexical__nestedListItem:before,
|
||||
.Lexical__nestedListItem:after {
|
||||
display: none;
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
$isRemoteImageNode,
|
||||
RemoteImageNode,
|
||||
} from './Plugins/RemoteImagePlugin/RemoteImageNode'
|
||||
import { $createInlineFileNode, $isInlineFileNode, InlineFileNode } from './Plugins/InlineFilePlugin/InlineFileNode'
|
||||
|
||||
const HorizontalRule: ElementTransformer = {
|
||||
dependencies: [HorizontalRuleNode],
|
||||
@@ -72,6 +73,26 @@ const IMAGE: TextMatchTransformer = {
|
||||
type: 'text-match',
|
||||
}
|
||||
|
||||
const INLINE_FILE: TextMatchTransformer = {
|
||||
dependencies: [InlineFileNode],
|
||||
export: (node) => {
|
||||
if (!$isInlineFileNode(node)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return node.getTextContent()
|
||||
},
|
||||
importRegExp: /(?:\[([^[]*)\])(?:\((data:(.*);[^(]+)\))/,
|
||||
regExp: /(?:\[([^[]*)\])(?:\((data:(.*);[^(]+)\))$/,
|
||||
replace: (textNode, match) => {
|
||||
const [, name, src, mimeType] = match
|
||||
const inlineFileNode = $createInlineFileNode(src, mimeType, name)
|
||||
textNode.replace(inlineFileNode)
|
||||
},
|
||||
trigger: ')',
|
||||
type: 'text-match',
|
||||
}
|
||||
|
||||
// Table transformer, taken from Lexical Playground
|
||||
const TABLE_ROW_REG_EXP = /^(?:\|)(.+)(?:\|)\s?$/
|
||||
const TABLE_ROW_DIVIDER_REG_EXP = /^(\| ?:?-*:? ?)+\|\s?$/
|
||||
@@ -224,6 +245,7 @@ export const MarkdownTransformers = [
|
||||
TABLE,
|
||||
CHECK_LIST,
|
||||
IMAGE,
|
||||
INLINE_FILE,
|
||||
...ELEMENT_TRANSFORMERS,
|
||||
...TEXT_FORMAT_TRANSFORMERS,
|
||||
...TEXT_MATCH_TRANSFORMERS,
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||
import {
|
||||
$getSelection,
|
||||
$isRangeSelection,
|
||||
$isParagraphNode,
|
||||
$isTextNode,
|
||||
SELECTION_CHANGE_COMMAND,
|
||||
COMMAND_PRIORITY_LOW,
|
||||
} from 'lexical'
|
||||
import { useCallback, useEffect, useRef } from 'react'
|
||||
import { getSelectedNode } from '../Lexical/Utils/getSelectedNode'
|
||||
import { mergeRegister } from '@lexical/utils'
|
||||
|
||||
export const EmptyLinePlaceholderPlugin = () => {
|
||||
const [editor] = useLexicalComposerContext()
|
||||
|
||||
const placeholderElementRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
const cursorUpdate = useCallback((): boolean => {
|
||||
const selection = $getSelection()
|
||||
if (selection && $isRangeSelection(selection)) {
|
||||
if (!placeholderElementRef.current) {
|
||||
return false
|
||||
}
|
||||
const node = getSelectedNode(selection)
|
||||
if (!node) {
|
||||
return false
|
||||
}
|
||||
const isParagraph = $isParagraphNode(node) || $isTextNode(node)
|
||||
const text = node.getTextContent()
|
||||
if (!isParagraph) {
|
||||
return false
|
||||
}
|
||||
const rootElement = editor.getRootElement()
|
||||
const nodeElement = editor.getElementByKey(node.getKey())
|
||||
const placeholder = placeholderElementRef.current
|
||||
if (!nodeElement || !placeholder.parentElement || !rootElement) {
|
||||
return false
|
||||
}
|
||||
const rect = nodeElement.getBoundingClientRect()
|
||||
const parentRect = placeholder.parentElement.getBoundingClientRect()
|
||||
const rootRect = rootElement.getBoundingClientRect()
|
||||
if (!text && editor.isEditable()) {
|
||||
placeholder.style.top = `${rect.y}px`
|
||||
placeholder.style.left = `${rect.x - parentRect.x + rootRect.x}px`
|
||||
placeholder.style.opacity = '0.65'
|
||||
} else {
|
||||
placeholder.style.opacity = '0'
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}, [editor])
|
||||
|
||||
useEffect(() => {
|
||||
return mergeRegister(
|
||||
editor.registerCommand(SELECTION_CHANGE_COMMAND, cursorUpdate, COMMAND_PRIORITY_LOW),
|
||||
editor.registerEditableListener(cursorUpdate),
|
||||
)
|
||||
}, [cursorUpdate, editor])
|
||||
|
||||
useEffect(() => {
|
||||
const scrollerElem = editor.getRootElement()
|
||||
|
||||
const update = () => {
|
||||
editor.getEditorState().read(() => {
|
||||
cursorUpdate()
|
||||
})
|
||||
}
|
||||
|
||||
window.addEventListener('resize', update)
|
||||
if (scrollerElem) {
|
||||
scrollerElem.addEventListener('scroll', update)
|
||||
}
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('resize', update)
|
||||
if (scrollerElem) {
|
||||
scrollerElem.removeEventListener('scroll', update)
|
||||
}
|
||||
}
|
||||
}, [cursorUpdate, editor])
|
||||
|
||||
return (
|
||||
<div
|
||||
className="super-empty-line-placeholder pointer-events-none fixed text-passive-1 opacity-0"
|
||||
ref={placeholderElementRef}
|
||||
>
|
||||
Type <span className="rounded bg-passive-4-opacity-variant p-0.5">/</span> for commands...
|
||||
</div>
|
||||
)
|
||||
}
|
||||
-111
@@ -1,111 +0,0 @@
|
||||
import { useApplication } from '@/Components/ApplicationProvider'
|
||||
import { downloadBlobOnAndroid } from '@/NativeMobileWeb/DownloadBlobOnAndroid'
|
||||
import { shareBlobOnMobile } from '@/NativeMobileWeb/ShareBlobOnMobile'
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||
import { Platform } from '@standardnotes/snjs'
|
||||
import {
|
||||
sanitizeFileName,
|
||||
SUPER_EXPORT_HTML,
|
||||
SUPER_EXPORT_JSON,
|
||||
SUPER_EXPORT_MARKDOWN,
|
||||
} from '@standardnotes/ui-services'
|
||||
import { useCallback, useEffect, useRef } from 'react'
|
||||
import { useCommandService } from '@/Components/CommandProvider'
|
||||
import { HeadlessSuperConverter } from '../../Tools/HeadlessSuperConverter'
|
||||
|
||||
export const ExportPlugin = () => {
|
||||
const application = useApplication()
|
||||
const [editor] = useLexicalComposerContext()
|
||||
const commandService = useCommandService()
|
||||
|
||||
const converter = useRef(new HeadlessSuperConverter())
|
||||
|
||||
const downloadData = useCallback(
|
||||
(data: Blob, fileName: string) => {
|
||||
if (!application.isNativeMobileWeb()) {
|
||||
application.archiveService.downloadData(data, fileName)
|
||||
return
|
||||
}
|
||||
|
||||
if (application.platform === Platform.Android) {
|
||||
downloadBlobOnAndroid(application.mobileDevice, data, fileName).catch(console.error)
|
||||
} else {
|
||||
shareBlobOnMobile(application.mobileDevice, application.isNativeMobileWeb(), data, fileName).catch(
|
||||
console.error,
|
||||
)
|
||||
}
|
||||
},
|
||||
[application],
|
||||
)
|
||||
|
||||
const exportJson = useCallback(
|
||||
(title: string) => {
|
||||
const content = converter.current.convertSuperStringToOtherFormat(JSON.stringify(editor.getEditorState()), 'json')
|
||||
const blob = new Blob([content], { type: 'application/json' })
|
||||
downloadData(blob, `${sanitizeFileName(title)}.json`)
|
||||
},
|
||||
[downloadData, editor],
|
||||
)
|
||||
|
||||
const exportMarkdown = useCallback(
|
||||
(title: string) => {
|
||||
const content = converter.current.convertSuperStringToOtherFormat(JSON.stringify(editor.getEditorState()), 'md')
|
||||
const blob = new Blob([content], { type: 'text/markdown' })
|
||||
downloadData(blob, `${sanitizeFileName(title)}.md`)
|
||||
},
|
||||
[downloadData, editor],
|
||||
)
|
||||
|
||||
const exportHtml = useCallback(
|
||||
(title: string) => {
|
||||
const content = converter.current.convertSuperStringToOtherFormat(JSON.stringify(editor.getEditorState()), 'html')
|
||||
const blob = new Blob([content], { type: 'text/html' })
|
||||
downloadData(blob, `${sanitizeFileName(title)}.html`)
|
||||
},
|
||||
[downloadData, editor],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
return commandService.addCommandHandler({
|
||||
command: SUPER_EXPORT_JSON,
|
||||
onKeyDown: (_, data) => {
|
||||
if (!data) {
|
||||
throw new Error('No data provided for export command')
|
||||
}
|
||||
|
||||
const title = data as string
|
||||
exportJson(title)
|
||||
},
|
||||
})
|
||||
}, [commandService, exportJson])
|
||||
|
||||
useEffect(() => {
|
||||
return commandService.addCommandHandler({
|
||||
command: SUPER_EXPORT_MARKDOWN,
|
||||
onKeyDown: (_, data) => {
|
||||
if (!data) {
|
||||
throw new Error('No data provided for export command')
|
||||
}
|
||||
|
||||
const title = data as string
|
||||
exportMarkdown(title)
|
||||
},
|
||||
})
|
||||
}, [commandService, exportMarkdown])
|
||||
|
||||
useEffect(() => {
|
||||
return commandService.addCommandHandler({
|
||||
command: SUPER_EXPORT_HTML,
|
||||
onKeyDown: (_, data) => {
|
||||
if (!data) {
|
||||
throw new Error('No data provided for export command')
|
||||
}
|
||||
|
||||
const title = data as string
|
||||
exportHtml(title)
|
||||
},
|
||||
})
|
||||
}, [commandService, exportHtml])
|
||||
|
||||
return null
|
||||
}
|
||||
+1
-1
@@ -22,7 +22,7 @@ export default function ImportPlugin({
|
||||
const [editor] = useLexicalComposerContext()
|
||||
|
||||
useEffect(() => {
|
||||
const dontAllowConversionOfEmptyStringWhichWouldResultInError = text.length === 0
|
||||
const dontAllowConversionOfEmptyStringWhichWouldResultInError = text.trim().length === 0
|
||||
if (dontAllowConversionOfEmptyStringWhichWouldResultInError) {
|
||||
return
|
||||
}
|
||||
|
||||
+4
@@ -148,6 +148,10 @@ export class InlineFileNode extends DecoratorBlockNode {
|
||||
return { element: object }
|
||||
}
|
||||
|
||||
getTextContent(): string {
|
||||
return `${this.__mimeType.startsWith('image/') ? '!' : ''}[${this.__fileName}](${this.__src})`
|
||||
}
|
||||
|
||||
decorate(_editor: LexicalEditor, config: EditorConfig): JSX.Element {
|
||||
const embedBlockTheme = config.theme.embedBlock || {}
|
||||
const className = {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { CheckListPlugin as LexicalCheckListPlugin } from '@lexical/react/LexicalCheckListPlugin'
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||
import { ListNode } from '@lexical/list'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
export function CheckListPlugin() {
|
||||
const [editor] = useLexicalComposerContext()
|
||||
|
||||
useEffect(() => {
|
||||
return editor.registerNodeTransform(ListNode, (node) => {
|
||||
if (node.getListType() !== 'check') {
|
||||
return
|
||||
}
|
||||
editor.getEditorState().read(() => {
|
||||
const element = editor.getElementByKey(node.getKey())
|
||||
if (!element) {
|
||||
return
|
||||
}
|
||||
element.classList.add('Lexical__checkList')
|
||||
})
|
||||
})
|
||||
}, [editor])
|
||||
|
||||
return <LexicalCheckListPlugin />
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import { ListNode, SerializedListNode } from '@lexical/list'
|
||||
import { DOMExportOutput, LexicalEditor, Spread } from 'lexical'
|
||||
|
||||
export type SerializedListHTMLExportNode = Spread<
|
||||
{
|
||||
type: 'list-html-export'
|
||||
},
|
||||
SerializedListNode
|
||||
>
|
||||
|
||||
export class ListHTMLExportNode extends ListNode {
|
||||
static getType(): string {
|
||||
return 'list-html-export'
|
||||
}
|
||||
|
||||
static clone(node: ListNode): ListHTMLExportNode {
|
||||
return new ListHTMLExportNode(node.getListType(), node.getStart(), node.getKey())
|
||||
}
|
||||
|
||||
static importJSON(serializedNode: SerializedListNode): ListNode {
|
||||
return super.importJSON(serializedNode)
|
||||
}
|
||||
|
||||
exportDOM(editor: LexicalEditor): DOMExportOutput {
|
||||
const { element } = super.exportDOM(editor)
|
||||
if (this.getListType() === 'check' && element instanceof HTMLElement) {
|
||||
element.classList.add('Lexical__checkList')
|
||||
}
|
||||
return { element }
|
||||
}
|
||||
|
||||
exportJSON(): SerializedListHTMLExportNode {
|
||||
return {
|
||||
...super.exportJSON(),
|
||||
type: 'list-html-export',
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -580,11 +580,10 @@ const ToolbarPlugin = () => {
|
||||
'bg-contrast',
|
||||
!isEditable ? 'hidden opacity-0' : '',
|
||||
isMobile && !canShowToolbarOnMobile ? 'hidden' : '',
|
||||
!isMobile &&
|
||||
'border-b border-border translucent-ui:border-[--popover-border-color] translucent-ui:bg-[--popover-background-color] translucent-ui:[backdrop-filter:var(--popover-backdrop-filter)]',
|
||||
!isMobile && 'border-b border-border bg-default',
|
||||
!isMobile
|
||||
? !isToolbarFixedToTop
|
||||
? 'fixed left-0 top-0 z-tooltip translate-x-[--translate-x] translate-y-[--translate-y] rounded border py-0.5 opacity-0'
|
||||
? 'fixed left-0 top-0 z-tooltip translate-x-[--translate-x] translate-y-[--translate-y] rounded border py-0.5 opacity-0 translucent-ui:border-[--popover-border-color] translucent-ui:bg-[--popover-background-color] translucent-ui:[backdrop-filter:var(--popover-backdrop-filter)]'
|
||||
: 'w-full px-1 py-1'
|
||||
: '',
|
||||
)}
|
||||
|
||||
@@ -37,7 +37,6 @@ import PasswordPlugin from './Plugins/PasswordPlugin/PasswordPlugin'
|
||||
import { useCommandService } from '@/Components/CommandProvider'
|
||||
import { SUPER_SHOW_MARKDOWN_PREVIEW } from '@standardnotes/ui-services'
|
||||
import { SuperNoteMarkdownPreview } from './SuperNoteMarkdownPreview'
|
||||
import { ExportPlugin } from './Plugins/ExportPlugin/ExportPlugin'
|
||||
import GetMarkdownPlugin, { GetMarkdownPluginInterface } from './Plugins/GetMarkdownPlugin/GetMarkdownPlugin'
|
||||
import { useResponsiveEditorFontSize } from '@/Utils/getPlaintextFontSize'
|
||||
import ReadonlyPlugin from './Plugins/ReadonlyPlugin/ReadonlyPlugin'
|
||||
@@ -211,7 +210,14 @@ export const SuperEditor: FunctionComponent<Props> = ({
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="font-editor relative flex h-full w-full flex-col" ref={ref}>
|
||||
<div
|
||||
className={classNames(
|
||||
'font-editor relative flex h-full w-full flex-col',
|
||||
lineHeight && `leading-${lineHeight.toLowerCase()}`,
|
||||
responsiveFontSize,
|
||||
)}
|
||||
ref={ref}
|
||||
>
|
||||
{featureStatus !== FeatureStatus.Entitled && (
|
||||
<NotEntitledBanner featureStatus={featureStatus} feature={GetSuperNoteFeature()} />
|
||||
)}
|
||||
@@ -243,7 +249,6 @@ export const SuperEditor: FunctionComponent<Props> = ({
|
||||
/>
|
||||
<NodeObserverPlugin nodeType={BubbleNode} onRemove={handleBubbleRemove} />
|
||||
<NodeObserverPlugin nodeType={FileNode} onRemove={handleBubbleRemove} />
|
||||
<ExportPlugin />
|
||||
{readonly === undefined && <ReadonlyPlugin note={note.current} />}
|
||||
<AutoFocusPlugin isEnabled={controller.isTemplateNote} />
|
||||
<SuperSearchContextProvider>
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
isUIFeatureAnIframeFeature,
|
||||
spaceSeparatedStrings,
|
||||
} from '@standardnotes/snjs'
|
||||
import { useCallback, useEffect, useMemo } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useApplication } from '../ApplicationProvider'
|
||||
import IframeFeatureView from '../ComponentView/IframeFeatureView'
|
||||
import Icon from '../Icon/Icon'
|
||||
@@ -52,18 +52,23 @@ const SuperNoteConverter = ({
|
||||
return 'json'
|
||||
}, [uiFeature])
|
||||
|
||||
const convertedContent = useMemo(() => {
|
||||
if (note.text.length === 0) {
|
||||
const [convertedContent, setConvertedContent] = useState<string>('')
|
||||
|
||||
useEffect(() => {
|
||||
const convertContent = async () => {
|
||||
if (note.text.length === 0) {
|
||||
return note.text
|
||||
}
|
||||
|
||||
try {
|
||||
return new HeadlessSuperConverter().convertSuperStringToOtherFormat(note.text, format)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
|
||||
return note.text
|
||||
}
|
||||
|
||||
try {
|
||||
return new HeadlessSuperConverter().convertSuperStringToOtherFormat(note.text, format)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
|
||||
return note.text
|
||||
convertContent().then(setConvertedContent).catch(console.error)
|
||||
}, [format, note])
|
||||
|
||||
const componentViewer = useMemo(() => {
|
||||
|
||||
+172
-18
@@ -1,6 +1,6 @@
|
||||
import { createHeadlessEditor } from '@lexical/headless'
|
||||
import { $convertToMarkdownString, $convertFromMarkdownString } from '@lexical/markdown'
|
||||
import { SuperConverterServiceInterface } from '@standardnotes/snjs'
|
||||
import { FileItem, GenerateUuid, PrefKey, PrefValue, SuperConverterServiceInterface } from '@standardnotes/snjs'
|
||||
import {
|
||||
$createParagraphNode,
|
||||
$getRoot,
|
||||
@@ -11,42 +11,119 @@ import {
|
||||
ParagraphNode,
|
||||
} from 'lexical'
|
||||
import BlocksEditorTheme from '../Lexical/Theme/Theme'
|
||||
import { BlockEditorNodes } from '../Lexical/Nodes/AllNodes'
|
||||
import { BlockEditorNodes, SuperExportNodes } from '../Lexical/Nodes/AllNodes'
|
||||
import { MarkdownTransformers } from '../MarkdownTransformers'
|
||||
import { $generateHtmlFromNodes, $generateNodesFromDOM } from '@lexical/html'
|
||||
|
||||
import { FileNode } from '../Plugins/EncryptedFilePlugin/Nodes/FileNode'
|
||||
import { $createFileExportNode } from '../Lexical/Nodes/FileExportNode'
|
||||
import { $createInlineFileNode, $isInlineFileNode, InlineFileNode } from '../Plugins/InlineFilePlugin/InlineFileNode'
|
||||
import { $createFileNode } from '../Plugins/EncryptedFilePlugin/Nodes/FileUtils'
|
||||
import { RemoteImageNode } from '../Plugins/RemoteImagePlugin/RemoteImageNode'
|
||||
export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
||||
private editor: LexicalEditor
|
||||
private importEditor: LexicalEditor
|
||||
private exportEditor: LexicalEditor
|
||||
|
||||
constructor() {
|
||||
this.editor = createHeadlessEditor({
|
||||
this.importEditor = createHeadlessEditor({
|
||||
namespace: 'BlocksEditor',
|
||||
theme: BlocksEditorTheme,
|
||||
editable: false,
|
||||
onError: (error: Error) => console.error(error),
|
||||
nodes: [...BlockEditorNodes],
|
||||
nodes: BlockEditorNodes,
|
||||
})
|
||||
this.exportEditor = createHeadlessEditor({
|
||||
namespace: 'BlocksEditor',
|
||||
theme: BlocksEditorTheme,
|
||||
editable: false,
|
||||
onError: (error: Error) => console.error(error),
|
||||
nodes: SuperExportNodes,
|
||||
})
|
||||
}
|
||||
|
||||
isValidSuperString(superString: string): boolean {
|
||||
try {
|
||||
this.editor.parseEditorState(superString)
|
||||
this.importEditor.parseEditorState(superString)
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
convertSuperStringToOtherFormat(superString: string, toFormat: 'txt' | 'md' | 'html' | 'json'): string {
|
||||
async convertSuperStringToOtherFormat(
|
||||
superString: string,
|
||||
toFormat: 'txt' | 'md' | 'html' | 'json',
|
||||
config?: {
|
||||
embedBehavior?: PrefValue[PrefKey.SuperNoteExportEmbedBehavior]
|
||||
getFileItem?: (id: string) => FileItem | undefined
|
||||
getFileBase64?: (id: string) => Promise<string | undefined>
|
||||
},
|
||||
): Promise<string> {
|
||||
if (superString.length === 0) {
|
||||
return superString
|
||||
}
|
||||
|
||||
this.editor.setEditorState(this.editor.parseEditorState(superString))
|
||||
const { embedBehavior, getFileItem, getFileBase64 } = config ?? { embedBehavior: 'reference' }
|
||||
|
||||
if (embedBehavior === 'separate' && !getFileItem) {
|
||||
throw new Error('getFileItem must be provided when embedBehavior is "separate"')
|
||||
}
|
||||
if (embedBehavior === 'inline' && !getFileItem && !getFileBase64) {
|
||||
throw new Error('getFileItem and getFileBase64 must be provided when embedBehavior is "inline"')
|
||||
}
|
||||
|
||||
this.exportEditor.setEditorState(this.exportEditor.parseEditorState(superString))
|
||||
|
||||
let content: string | undefined
|
||||
|
||||
this.editor.update(
|
||||
await new Promise<void>((resolve) => {
|
||||
this.exportEditor.update(
|
||||
() => {
|
||||
if (embedBehavior === 'reference') {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
if (!getFileItem) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
const fileNodes = $nodesOfType(FileNode)
|
||||
Promise.all(
|
||||
fileNodes.map(async (fileNode) => {
|
||||
const fileItem = getFileItem(fileNode.getId())
|
||||
if (!fileItem) {
|
||||
return
|
||||
}
|
||||
if (embedBehavior === 'inline' && getFileBase64) {
|
||||
const fileBase64 = await getFileBase64(fileNode.getId())
|
||||
if (!fileBase64) {
|
||||
return
|
||||
}
|
||||
this.exportEditor.update(
|
||||
() => {
|
||||
const inlineFileNode = $createInlineFileNode(fileBase64, fileItem.mimeType, fileItem.name)
|
||||
fileNode.replace(inlineFileNode)
|
||||
},
|
||||
{ discrete: true },
|
||||
)
|
||||
} else {
|
||||
this.exportEditor.update(
|
||||
() => {
|
||||
const fileExportNode = $createFileExportNode(fileItem.name, fileItem.mimeType)
|
||||
fileNode.replace(fileExportNode)
|
||||
},
|
||||
{ discrete: true },
|
||||
)
|
||||
}
|
||||
}),
|
||||
)
|
||||
.then(() => resolve())
|
||||
.catch(console.error)
|
||||
},
|
||||
{ discrete: true },
|
||||
)
|
||||
})
|
||||
|
||||
this.exportEditor.update(
|
||||
() => {
|
||||
switch (toFormat) {
|
||||
case 'txt':
|
||||
@@ -61,7 +138,7 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
||||
break
|
||||
}
|
||||
case 'html':
|
||||
content = $generateHtmlFromNodes(this.editor)
|
||||
content = $generateHtmlFromNodes(this.exportEditor)
|
||||
break
|
||||
case 'json':
|
||||
default:
|
||||
@@ -88,7 +165,7 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
||||
return otherFormatString
|
||||
}
|
||||
|
||||
this.editor.update(
|
||||
this.importEditor.update(
|
||||
() => {
|
||||
$getRoot().clear()
|
||||
},
|
||||
@@ -99,12 +176,12 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
||||
|
||||
let didThrow = false
|
||||
if (fromFormat === 'html') {
|
||||
this.editor.update(
|
||||
this.importEditor.update(
|
||||
() => {
|
||||
try {
|
||||
const parser = new DOMParser()
|
||||
const dom = parser.parseFromString(otherFormatString, 'text/html')
|
||||
const generatedNodes = $generateNodesFromDOM(this.editor, dom)
|
||||
const generatedNodes = $generateNodesFromDOM(this.importEditor, dom)
|
||||
const nodesToInsert: LexicalNode[] = []
|
||||
generatedNodes.forEach((node) => {
|
||||
const type = node.getType()
|
||||
@@ -114,9 +191,9 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
||||
if (
|
||||
type === 'text' ||
|
||||
type === 'link' ||
|
||||
type === 'linebreak' ||
|
||||
type === 'unencrypted-image' ||
|
||||
type === 'inline-file' ||
|
||||
node.isParentRequired()
|
||||
type === 'inline-file'
|
||||
) {
|
||||
const paragraphNode = $createParagraphNode()
|
||||
paragraphNode.append(node)
|
||||
@@ -138,7 +215,7 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
||||
{ discrete: true },
|
||||
)
|
||||
} else {
|
||||
this.editor.update(
|
||||
this.importEditor.update(
|
||||
() => {
|
||||
try {
|
||||
$convertFromMarkdownString(otherFormatString, MarkdownTransformers)
|
||||
@@ -157,6 +234,83 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
||||
throw new Error('Could not import note')
|
||||
}
|
||||
|
||||
return JSON.stringify(this.editor.getEditorState())
|
||||
return JSON.stringify(this.importEditor.getEditorState())
|
||||
}
|
||||
|
||||
getEmbeddedFileIDsFromSuperString(superString: string): string[] {
|
||||
if (superString.length === 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
this.exportEditor.setEditorState(this.exportEditor.parseEditorState(superString))
|
||||
|
||||
const ids: string[] = []
|
||||
|
||||
this.exportEditor.getEditorState().read(() => {
|
||||
const fileNodes = $nodesOfType(FileNode)
|
||||
fileNodes.forEach((fileNode) => {
|
||||
ids.push(fileNode.getId())
|
||||
})
|
||||
})
|
||||
|
||||
return ids
|
||||
}
|
||||
|
||||
async uploadAndReplaceInlineFilesInSuperString(
|
||||
superString: string,
|
||||
uploadFile: (file: File) => Promise<FileItem | undefined>,
|
||||
linkFile: (file: FileItem) => Promise<void>,
|
||||
generateUuid: GenerateUuid,
|
||||
): Promise<string> {
|
||||
if (superString.length === 0) {
|
||||
return superString
|
||||
}
|
||||
|
||||
this.importEditor.setEditorState(this.importEditor.parseEditorState(superString))
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
this.importEditor.update(
|
||||
() => {
|
||||
const inlineFileNodes = $nodesOfType(InlineFileNode)
|
||||
const remoteImageNodes = $nodesOfType(RemoteImageNode).filter((node) => node.__src.startsWith('data:'))
|
||||
const concatenatedNodes = [...inlineFileNodes, ...remoteImageNodes]
|
||||
if (concatenatedNodes.length === 0) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
Promise.all(
|
||||
concatenatedNodes.map(async (node) => {
|
||||
const blob = await fetch(node.__src).then((response) => response.blob())
|
||||
const name = $isInlineFileNode(node) ? node.__fileName : node.__alt
|
||||
const mimeType = $isInlineFileNode(node) ? node.__mimeType : node.__src.split(';')[0].split(':')[1]
|
||||
const file = new File([blob], name || generateUuid.execute().getValue(), {
|
||||
type: mimeType,
|
||||
})
|
||||
|
||||
const uploadedFile = await uploadFile(file)
|
||||
|
||||
if (!uploadedFile) {
|
||||
return
|
||||
}
|
||||
|
||||
this.importEditor.update(
|
||||
() => {
|
||||
const fileNode = $createFileNode(uploadedFile.uuid)
|
||||
node.replace(fileNode)
|
||||
},
|
||||
{ discrete: true },
|
||||
)
|
||||
|
||||
await linkFile(uploadedFile)
|
||||
}),
|
||||
)
|
||||
.then(() => resolve())
|
||||
.catch(console.error)
|
||||
},
|
||||
{ discrete: true },
|
||||
)
|
||||
})
|
||||
|
||||
return JSON.stringify(this.importEditor.getEditorState())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ const Switch = ({
|
||||
disabled = false,
|
||||
tabIndex,
|
||||
forceDesktopStyle,
|
||||
children,
|
||||
}: {
|
||||
checked: boolean
|
||||
onChange: (checked: boolean) => void
|
||||
@@ -15,20 +16,12 @@ const Switch = ({
|
||||
disabled?: boolean
|
||||
tabIndex?: number
|
||||
forceDesktopStyle?: boolean
|
||||
children?: React.ReactNode
|
||||
}) => {
|
||||
const isActive = checked && !disabled
|
||||
|
||||
return (
|
||||
<label
|
||||
className={classNames(
|
||||
'relative box-content inline-block flex-shrink-0 cursor-pointer rounded-full border-2 border-solid border-transparent bg-clip-padding transition-colors duration-150 ease-out',
|
||||
'ring-2 ring-transparent focus-within:border-default focus-within:shadow-none focus-within:outline-none focus-within:ring-info',
|
||||
disabled ? 'opacity-50' : '',
|
||||
isActive ? 'bg-info' : 'bg-neutral',
|
||||
forceDesktopStyle ? 'h-4.5 w-8' : 'h-7 w-12 md:h-4.5 md:w-8',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<label className={classNames(disabled ? 'opacity-50' : '', className)}>
|
||||
<VisuallyHidden>
|
||||
<Checkbox
|
||||
checked={checked}
|
||||
@@ -40,15 +33,25 @@ const Switch = ({
|
||||
</VisuallyHidden>
|
||||
<div
|
||||
className={classNames(
|
||||
'absolute top-1/2 block -translate-y-1/2 rounded-full bg-default transition-transform duration-150 ease-out',
|
||||
forceDesktopStyle ? 'left-[2px] h-3.5 w-3.5' : 'left-[0.15rem] h-6 w-6 md:left-[2px] md:h-3.5 md:w-3.5',
|
||||
checked
|
||||
? forceDesktopStyle
|
||||
? 'translate-x-[calc(2rem-1.125rem)]'
|
||||
: 'translate-x-[calc(3.25rem-1.5rem-0.5rem)] md:translate-x-[calc(2rem-1.125rem)]'
|
||||
: '',
|
||||
'relative box-content inline-block flex-shrink-0 cursor-pointer rounded-full border-2 border-solid border-transparent bg-clip-padding transition-colors duration-150 ease-out',
|
||||
'ring-2 ring-transparent focus-within:border-default focus-within:shadow-none focus-within:outline-none focus-within:ring-info',
|
||||
isActive ? 'bg-info' : 'bg-neutral',
|
||||
forceDesktopStyle ? 'h-4.5 w-8' : 'h-7 w-12 md:h-4.5 md:w-8',
|
||||
)}
|
||||
/>
|
||||
>
|
||||
<div
|
||||
className={classNames(
|
||||
'absolute top-1/2 block -translate-y-1/2 rounded-full bg-default transition-transform duration-150 ease-out',
|
||||
forceDesktopStyle ? 'left-[2px] h-3.5 w-3.5' : 'left-[0.15rem] h-6 w-6 md:left-[2px] md:h-3.5 md:w-3.5',
|
||||
checked
|
||||
? forceDesktopStyle
|
||||
? 'translate-x-[calc(2rem-1.125rem)]'
|
||||
: 'translate-x-[calc(3.25rem-1.5rem-0.5rem)] md:translate-x-[calc(2rem-1.125rem)]'
|
||||
: '',
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{children}
|
||||
</label>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ const SmartViewsListItem: FunctionComponent<Props> = ({ view, tagsState, setEdit
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={FOCUSABLE_BUT_NOT_TABBABLE}
|
||||
className={classNames('tag group px-3.5', isSelected && 'selected', isFaded && 'opacity-50')}
|
||||
className={classNames('tag group px-3.5 py-1 md:py-0', isSelected && 'selected', isFaded && 'opacity-50')}
|
||||
onClick={selectCurrentTag}
|
||||
onContextMenu={(event) => {
|
||||
event.preventDefault()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user