Compare commits

...
Author SHA1 Message Date
StandardNotes CI ed5e6a2227 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2023-11-19 20:48:17 +00:00
Aman Harwara c98fd0861a chore: remove shadow from super toolbar in focus mode [skip e2e] 2023-11-20 02:10:00 +05:30
Aman Harwara 620825c7a9 chore: upgrade lexical 2023-11-20 02:09:41 +05:30
Aman Harwara 53925a96d4 chore: remove super empty line placeholder temporarily 2023-11-20 01:58:42 +05:30
StandardNotes CI 29f2c18311 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2023-11-11 20:24:20 +00:00
Aman Harwara e37cd1d299 chore: fix super note html export style [skip e2e] 2023-11-12 01:40:22 +05:30
Aman Harwara e0d48afbe2 fix: Fixed issue on Android where only one selected file would be uploaded instead of all 2023-11-12 00:00:28 +05:30
Aman Harwara 7d9dabb818 chore: dont show embedded file export options if no selected super note has them 2023-11-11 22:17:32 +05:30
StandardNotes CI 991a7a521f chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2023-11-09 15:10:42 +00:00
Aman Harwara a49549177c chore: fix range selection logic on ios [skip e2e] 2023-11-09 20:31:46 +05:30
StandardNotes CI 6097cb50d9 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2023-11-09 13:31:43 +00:00
Aman Harwara 9d532e83e1 chore: potential fix for unintentional multiple selection after editing on ios [skip e2e] 2023-11-09 18:49:55 +05:30
StandardNotes CI 1bf3a99911 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2023-11-09 06:59:05 +00:00
Aman Harwara 67494b647e chore: trigger release [skip e2e] 2023-11-09 12:19:41 +05:30
StandardNotes CI 54ba30ea1d chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
2023-11-08 21:18:05 +00:00
Aman Harwara e2c04b3576 chore: android material you themed icon (#2629) [skip e2e] 2023-11-09 02:31:21 +05:30
StandardNotes CI 9c06b6ae71 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].3
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].2
 - @standardnotes/[email protected]
2023-11-08 20:11:40 +00:00
Aman Harwara 2d687d9786 chore: on android use notification to display file upload progress instead of toast (#2628) [skip e2e] 2023-11-09 01:31:34 +05:30
StandardNotes CI 6a7c5277f8 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].1
 - @standardnotes/[email protected]
2023-11-07 07:29:17 +00:00
Aman Harwara 894167520d fix: Fixed issue where non-image inlined files would not correctly be imported from a Markdown file 2023-11-07 12:11:21 +05:30
StandardNotes CI a1317b2bfd chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2023-11-06 15:41:31 +00:00
Karol Sójko a6be2f0a9a chore: add test for breaching transfer limit (#2620) 2023-11-06 16:03:11 +01:00
StandardNotes CI 6295f179a1 chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected].0
 - @standardnotes/[email protected]
2023-11-06 11:46:38 +00:00
Aman Harwara 3bf670ece7 feat: Importing markdown files from the Import dialog will now automatically use Super notes 2023-11-06 16:25:22 +05:30
StandardNotes CI a3978f142b chore(release): publish
- @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
 - @standardnotes/[email protected]
2023-11-06 09:59:15 +00:00
Aman Harwara 7a24ea3c25 chore: fix converting empty plaintext note with only spaces to super 2023-11-06 14:52:03 +05:30
Aman Harwara 56c522b5c3 chore: fix scroll in mobile popovers [skip e2e] 2023-11-06 14:45:27 +05:30
Aman Harwara ade6c8bb1e chore: ios window color [skip e2e] 2023-11-06 14:38:05 +05:30
88 changed files with 980 additions and 310 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+40
View File
@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.322](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-19)
**Note:** Version bump only for package @standardnotes/clipper
## [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
View File
@@ -1,7 +1,7 @@
{
"name": "@standardnotes/clipper",
"description": "Web clipper browser extension for Standard Notes",
"version": "1.1.312",
"version": "1.1.322",
"private": true,
"scripts": {
"build-mv2": "yarn clean && webpack --config ./webpack.config.prod.js",
+40
View File
@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.108.256](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-19)
**Note:** Version bump only for package @standardnotes/desktop
## [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
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@standardnotes/desktop",
"main": "./app/dist/index.js",
"version": "3.108.246",
"version": "3.108.256",
"license": "AGPL-3.0",
"author": "Standard Notes.",
"private": true,
+46
View File
@@ -3,6 +3,52 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.56.238](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-19)
**Note:** Version bump only for package @standardnotes/mobile
## [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
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>
+9
View File
@@ -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
+2 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/mobile",
"version": "3.56.227",
"version": "3.56.238",
"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"
}
}
+48 -1
View File
@@ -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))
+73 -37
View File
@@ -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) {
@@ -356,45 +385,52 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
}
return (
<WebView
ref={webViewRef}
source={{ uri: sourceUri }}
<View
style={{
flex: 1,
backgroundColor: '#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
/>
>
<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>
)
}
+44
View File
@@ -3,6 +3,50 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.4.613](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-19)
**Note:** Version bump only for package @standardnotes/releases
## [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 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/releases",
"version": "1.4.602",
"version": "1.4.613",
"license": "AGPL-3.0",
"main": "dist/releases.json",
"types": "dist/index.d.ts",
+4
View File
@@ -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.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 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/services",
"version": "1.65.2",
"version": "1.65.3",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -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>
}
+8
View File
@@ -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.
## [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
@@ -12,4 +12,5 @@ export enum ReactNativeToWebEvent {
ReceivedFile = 'ReceivedFile',
ReceivedLink = 'ReceivedLink',
ReceivedText = 'ReceivedText',
OpenFilePreview = 'OpenFilePreview',
}
+3 -3
View File
@@ -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)
+4 -4
View File
@@ -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 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/snjs",
"version": "2.202.107",
"version": "2.202.109",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+16
View File
@@ -3,6 +3,22 @@
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 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@standardnotes/ui-services",
"version": "1.33.3",
"version": "1.34.2",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
+6 -3
View File
@@ -63,7 +63,7 @@ export class Importer {
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)
@@ -134,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)]
}
@@ -164,6 +164,10 @@ export class Importer {
return this.mutator.insertItem(note)
}),
)
return insertedItems
}
async uploadAndReplaceInlineFilesInInsertedItems(insertedItems: DecryptedItemInterface<ItemContent>[]) {
for (const item of insertedItems) {
if (!isNote(item)) {
continue
@@ -185,6 +189,5 @@ export class Importer {
console.error(error)
}
}
return insertedItems
}
}
@@ -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,
}
: {}),
},
}
}
@@ -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
+42
View File
@@ -3,6 +3,48 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.181.25](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-19)
**Note:** Version bump only for package @standardnotes/web
## [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
+113
View File
@@ -1,5 +1,118 @@
{
"versions": [
{
"version": "3.181.25",
"title": "[3.181.25](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2023-11-19)",
"date": null,
"body": "**Note:** Version bump only for package @standardnotes/web",
"parsed": {
"_": [
"Note: Version bump only for package @standardnotes/web"
]
}
},
{
"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)",
+5 -5
View File
@@ -1,9 +1,9 @@
{
"name": "@standardnotes/web",
"version": "3.181.15",
"version": "3.181.25",
"license": "AGPL-3.0",
"main": "dist/app.js",
"author": "Standard Notes",
"author": "Standard Notes.",
"private": true,
"files": [
"dist"
@@ -28,7 +28,7 @@
"@babel/plugin-transform-react-jsx": "^7.19.0",
"@babel/preset-env": "*",
"@babel/preset-typescript": "^7.21.5",
"@lexical/react": "0.12.2",
"@lexical/react": "0.12.4",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@simplewebauthn/browser": "^8.0.2",
"@standardnotes/authenticator": "^2.4.0",
@@ -76,7 +76,7 @@
"identity-obj-proxy": "^3.0.0",
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.3.1",
"lexical": "0.12.2",
"lexical": "0.12.4",
"lint-staged": ">=13",
"mini-css-extract-plugin": "^2.7.2",
"minimatch": "^5.1.1",
@@ -109,7 +109,7 @@
},
"dependencies": {
"@ariakit/react": "^0.3.5",
"@lexical/headless": "0.12.2",
"@lexical/headless": "0.12.4",
"@radix-ui/react-slot": "^1.0.1",
"fast-diff": "^1.3.0"
}
@@ -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'
@@ -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)
@@ -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)
@@ -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>
@@ -504,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 { PrefKey, PrefValue } from '@standardnotes/snjs'
import { PrefKey, PrefValue, SNNote } from '@standardnotes/snjs'
import { useApplication } from '../ApplicationProvider'
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)
@@ -26,6 +28,8 @@ const SuperExportModal = ({ exportNotes, close }: Props) => {
}
}, [application, superNoteExportEmbedBehavior, superNoteExportFormat])
const someNotesHaveEmbeddedFiles = notes.some(noteHasEmbeddedFiles)
return (
<Modal
title="Export notes"
@@ -89,7 +93,7 @@ const SuperExportModal = ({ exportNotes, close }: Props) => {
</Switch>
</div>
)}
{superNoteExportFormat !== 'json' && (
{superNoteExportFormat !== 'json' && someNotesHaveEmbeddedFiles && (
<div className="mb-2 mt-4">
<div className="mb-1">How do you want embedded files to be handled?</div>
<RadioButtonGroup
@@ -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,15 +62,13 @@ 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()
@@ -81,6 +80,7 @@ const MobilePopoverContent = ({
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
@@ -105,7 +105,7 @@ const MobilePopoverContent = ({
}
const y = element.getBoundingClientRect().y
if (y > elementY) {
if (y > elementY && closestScrollContainer) {
closestScrollContainer.style.overflowY = 'hidden'
}
@@ -144,7 +144,9 @@ const MobilePopoverContent = ({
}
startY = 0
closestScrollContainer.style.overflowY = ''
if (closestScrollContainer) {
closestScrollContainer.style.overflowY = ''
}
}
element.addEventListener('touchstart', touchStartHandler, SupportsPassiveListeners ? { passive: true } : false)
@@ -199,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>
@@ -28,7 +28,6 @@ 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
@@ -114,7 +113,6 @@ export const BlocksEditor: FunctionComponent<BlocksEditorProps> = ({
<CollapsiblePlugin />
<TabIndentationPlugin />
<RemoveBrokenTablesPlugin />
<EmptyLinePlaceholderPlugin />
{!readonly && floatingAnchorElem && (
<>
<DraggableBlockPlugin anchorElem={floatingAnchorElem} />
@@ -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,
@@ -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
}
@@ -16,8 +16,9 @@ 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, InlineFileNode } from '../Plugins/InlineFilePlugin/InlineFileNode'
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 importEditor: LexicalEditor
private exportEditor: LexicalEditor
@@ -271,15 +272,19 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
this.importEditor.update(
() => {
const inlineFileNodes = $nodesOfType(InlineFileNode)
if (inlineFileNodes.length === 0) {
const remoteImageNodes = $nodesOfType(RemoteImageNode).filter((node) => node.__src.startsWith('data:'))
const concatenatedNodes = [...inlineFileNodes, ...remoteImageNodes]
if (concatenatedNodes.length === 0) {
resolve()
return
}
Promise.all(
inlineFileNodes.map(async (node) => {
concatenatedNodes.map(async (node) => {
const blob = await fetch(node.__src).then((response) => response.blob())
const file = new File([blob], node.__fileName || generateUuid.execute().getValue(), {
type: node.__mimeType,
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)
@@ -291,6 +291,11 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
private async downloadFile(file: FileItem): Promise<void> {
let downloadingToastId = ''
let canShowProgressNotification = false
if (this.mobileDevice && this.platform === Platform.Android) {
canShowProgressNotification = await this.mobileDevice.canDisplayNotifications()
}
try {
const saver = StreamingFileSaver.available() ? new StreamingFileSaver(file.name) : new ClassicFileSaver()
@@ -301,11 +306,21 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
await saver.selectFileToSaveTo()
}
downloadingToastId = addToast({
type: ToastType.Progress,
message: `Downloading file "${file.name}" (0%)`,
progress: 0,
})
if (this.mobileDevice && canShowProgressNotification) {
downloadingToastId = await this.mobileDevice.displayNotification({
title: `Downloading file "${file.name}"`,
android: {
progress: { max: 100, current: 0, indeterminate: true },
onlyAlertOnce: true,
},
})
} else {
downloadingToastId = addToast({
type: ToastType.Progress,
message: `Downloading file "${file.name}" (0%)`,
progress: 0,
})
}
const decryptedBytesArray: Uint8Array[] = []
@@ -320,10 +335,23 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
const progressPercent = Math.floor(progress.percentComplete)
updateToast(downloadingToastId, {
message: fileProgressToHumanReadableString(progress, file.name, { showPercent: true }),
progress: progressPercent,
})
if (this.mobileDevice && canShowProgressNotification) {
this.mobileDevice
.displayNotification({
id: downloadingToastId,
title: `Downloading file "${file.name}"`,
android: {
progress: { max: 100, current: progressPercent, indeterminate: false },
onlyAlertOnce: true,
},
})
.catch(console.error)
} else {
updateToast(downloadingToastId, {
message: fileProgressToHumanReadableString(progress, file.name, { showPercent: true }),
progress: progressPercent,
})
}
lastProgress = progress
})
@@ -339,7 +367,6 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
const blob = new Blob([finalBytes], {
type: file.mimeType,
})
// await downloadOrShareBlobBasedOnPlatform(this, blob, file.name, false)
await downloadOrShareBlobBasedOnPlatform({
archiveService: this.archiveService,
platform: this.platform,
@@ -351,12 +378,18 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
})
}
addToast({
type: ToastType.Success,
message: `Successfully downloaded file${
lastProgress && lastProgress.source === 'local' ? ' from local backup' : ''
}`,
})
if (this.mobileDevice && canShowProgressNotification) {
await this.mobileDevice.displayNotification({
title: `Successfully downloaded file "${file.name}"`,
})
} else {
addToast({
type: ToastType.Success,
message: `Successfully downloaded file${
lastProgress && lastProgress.source === 'local' ? ' from local backup' : ''
}`,
})
}
} catch (error) {
console.error(error)
@@ -366,8 +399,12 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
})
}
if (downloadingToastId.length > 0) {
dismissToast(downloadingToastId)
if (downloadingToastId) {
if (this.mobileDevice && canShowProgressNotification) {
this.mobileDevice.cancelNotification(downloadingToastId).catch(console.error)
} else {
dismissToast(downloadingToastId)
}
}
}
@@ -412,6 +449,11 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
const { showToast = true, note } = options
let toastId: string | undefined
let canShowProgressNotification = false
if (showToast && this.mobileDevice && this.platform === Platform.Android) {
canShowProgressNotification = await this.mobileDevice.canDisplayNotifications()
}
try {
const minimumChunkSize = this.files.minimumChunkSize()
@@ -449,11 +491,21 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
const initialProgress = operation.getProgress().percentComplete
if (showToast) {
toastId = addToast({
type: ToastType.Progress,
message: `Uploading file "${fileToUpload.name}" (${initialProgress}%)`,
progress: initialProgress,
})
if (this.mobileDevice && canShowProgressNotification) {
toastId = await this.mobileDevice.displayNotification({
title: `Uploading file "${fileToUpload.name}"`,
android: {
progress: { max: 100, current: initialProgress, indeterminate: true },
onlyAlertOnce: true,
},
})
} else {
toastId = addToast({
type: ToastType.Progress,
message: `Uploading file "${fileToUpload.name}" (${initialProgress}%)`,
progress: initialProgress,
})
}
}
const onChunk: OnChunkCallbackNoProgress = async ({ data, index, isLast }) => {
@@ -461,10 +513,21 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
const percentComplete = Math.round(operation.getProgress().percentComplete)
if (toastId) {
updateToast(toastId, {
message: `Uploading file "${fileToUpload.name}" (${percentComplete}%)`,
progress: percentComplete,
})
if (this.mobileDevice && canShowProgressNotification) {
await this.mobileDevice.displayNotification({
id: toastId,
title: `Uploading file "${fileToUpload.name}"`,
android: {
progress: { max: 100, current: percentComplete, indeterminate: false },
onlyAlertOnce: true,
},
})
} else {
updateToast(toastId, {
message: `Uploading file "${fileToUpload.name}" (${percentComplete}%)`,
progress: percentComplete,
})
}
}
}
@@ -480,32 +543,54 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
if (uploadedFile instanceof ClientDisplayableError) {
addToast({
type: ToastType.Error,
message: 'Unable to close upload session',
message: uploadedFile.text,
})
throw new Error('Unable to close upload session')
throw new Error(uploadedFile.text)
}
if (toastId) {
if (this.mobileDevice && canShowProgressNotification) {
this.mobileDevice.cancelNotification(toastId).catch(console.error)
}
dismissToast(toastId)
}
if (showToast) {
addToast({
type: ToastType.Success,
message: `Uploaded file "${uploadedFile.name}"`,
actions: [
{
label: 'Open',
handler: (toastId) => {
void this.handleFileAction({
type: FileItemActionType.PreviewFile,
payload: { file: uploadedFile },
})
dismissToast(toastId)
if (this.mobileDevice && canShowProgressNotification) {
this.mobileDevice
.displayNotification({
id: uploadedFile.uuid,
title: `Uploaded file "${uploadedFile.name}"`,
android: {
actions: [
{
title: 'Open',
pressAction: {
id: 'open-file',
},
},
],
},
},
],
autoClose: true,
})
})
.catch(console.error)
} else {
addToast({
type: ToastType.Success,
message: `Uploaded file "${uploadedFile.name}"`,
actions: [
{
label: 'Open',
handler: (toastId) => {
void this.handleFileAction({
type: FileItemActionType.PreviewFile,
payload: { file: uploadedFile },
})
dismissToast(toastId)
},
},
],
autoClose: true,
})
}
}
return uploadedFile
@@ -513,12 +598,23 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
console.error(error)
if (toastId) {
if (this.mobileDevice && canShowProgressNotification) {
this.mobileDevice.cancelNotification(toastId).catch(console.error)
}
dismissToast(toastId)
}
addToast({
type: ToastType.Error,
message: 'There was an error while uploading the file',
})
if (this.mobileDevice && canShowProgressNotification) {
this.mobileDevice
.displayNotification({
title: 'There was an error while uploading the file',
})
.catch(console.error)
} else {
addToast({
type: ToastType.Error,
message: 'There was an error while uploading the file',
})
}
}
return undefined
@@ -1185,7 +1185,7 @@ export class ItemListController
const hasMoreThanOneSelected = this.selectedItemsCount > 1
const isAuthorizedForAccess = await this.protections.authorizeItemAccess(item)
if (userTriggered && hasShift) {
if (userTriggered && hasShift && !isMobileScreen()) {
await this.selectItemsRange({ selectedItem: item })
} else if (userTriggered && this.isMultipleSelectionMode) {
if (this.selectedUuids.has(uuid) && hasMoreThanOneSelected) {
@@ -98,7 +98,9 @@ export class MobileWebReceiver {
case ReactNativeToWebEvent.ReceivedLink:
void this.application.handleReceivedLinkEvent(messageData as { link: string; title: string })
break
case ReactNativeToWebEvent.OpenFilePreview:
void this.application.handleOpenFilePreviewEvent(messageData as { id: string })
break
default:
break
}
@@ -4,11 +4,11 @@ import { NoteType, PrefKey, SNNote, PrefDefaults, FileItem, PrefValue } from '@s
import { WebApplicationInterface, parseAndCreateZippableFileName } from '@standardnotes/ui-services'
import { ZipDirectoryEntry } from '@zip.js/zip.js'
// @ts-expect-error Using inline loaders to load CSS as string
import superEditorCSS from '!css-loader!sass-loader!../Components/SuperEditor/Lexical/Theme/editor.scss'
import superEditorCSS from '!css-loader?{"sourceMap":false}!sass-loader!../Components/SuperEditor/Lexical/Theme/editor.scss'
// @ts-expect-error Using inline loaders to load CSS as string
import snColorsCSS from '!css-loader!sass-loader!@standardnotes/styles/src/Styles/_colors.scss'
import snColorsCSS from '!css-loader?{"sourceMap":false}!sass-loader!@standardnotes/styles/src/Styles/_colors.scss'
// @ts-expect-error Using inline loaders to load CSS as string
import exportOverridesCSS from '!css-loader!sass-loader!../Components/SuperEditor/Lexical/Theme/export-overrides.scss'
import exportOverridesCSS from '!css-loader?{"sourceMap":false}!sass-loader!../Components/SuperEditor/Lexical/Theme/export-overrides.scss'
import { getBase64FromBlob } from './Utils'
import { parseFileName } from '@standardnotes/filepicker'
@@ -39,9 +39,9 @@ const superHTML = (note: SNNote, content: string) => `<!DOCTYPE html>
<meta charset="utf-8" />
<title>${note.title}</title>
<style>
${snColorsCSS.toString()}
${superEditorCSS.toString()}
${exportOverridesCSS.toString()}
${snColorsCSS.toString()}
${superEditorCSS.toString()}
${exportOverridesCSS.toString()}
</style>
</head>
<body>
@@ -120,7 +120,7 @@ const isSuperNote = (note: SNNote) => {
return note.noteType === NoteType.Super
}
const noteHasEmbeddedFiles = (note: SNNote) => {
export const noteHasEmbeddedFiles = (note: SNNote) => {
return note.text.includes('"type":"snfile"')
}
@@ -33,7 +33,6 @@
background-color: var(--sn-stylekit-contrast-background-color);
.editor {
box-shadow: 0 0 5px 0.5px var(--sn-stylekit-shadow-color);
overflow: hidden;
}
+168 -157
View File
@@ -2856,255 +2856,256 @@ __metadata:
languageName: node
linkType: hard
"@lexical/clipboard@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/clipboard@npm:0.12.2"
"@lexical/clipboard@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/clipboard@npm:0.12.4"
dependencies:
"@lexical/html": 0.12.2
"@lexical/list": 0.12.2
"@lexical/selection": 0.12.2
"@lexical/utils": 0.12.2
"@lexical/html": 0.12.4
"@lexical/list": 0.12.4
"@lexical/selection": 0.12.4
"@lexical/utils": 0.12.4
peerDependencies:
lexical: 0.12.2
checksum: 15e529b9664b0777f52f5967b2ed59b6842f16442bd04195da8d5843369a69623a864854ae37e2d843af4d1a661194efac51b058f42ce680ace954200f731ab1
lexical: 0.12.4
checksum: bbd01c9901e03a56888f393499f44d7565a2f5c8f07cc37fb1b5fa92bc8eac483f8be7dc7cc6539ceba6066241559dacced4138913af36652b422ba3733fa18a
languageName: node
linkType: hard
"@lexical/code@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/code@npm:0.12.2"
"@lexical/code@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/code@npm:0.12.4"
dependencies:
"@lexical/utils": 0.12.2
"@lexical/utils": 0.12.4
prismjs: ^1.27.0
peerDependencies:
lexical: 0.12.2
checksum: 3c99ac8fb19454f7d7317bc71690b10301df18d64ecc27c65ccd2ec4e999983952049f0c0713eb2000a1ddd60708e8eb4229dfd50bdd6601b9912570c986edb5
lexical: 0.12.4
checksum: 555315703f93bd0b4545f48547c4af3910fab6d367092fbe4dcacc7663ea886464ffda943d18c395cdcbeb6b32a6979d6e14512950042413525b7ebbf4b85213
languageName: node
linkType: hard
"@lexical/dragon@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/dragon@npm:0.12.2"
"@lexical/dragon@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/dragon@npm:0.12.4"
peerDependencies:
lexical: 0.12.2
checksum: 0f7f3b6cf5727b93082c4a505c4784c85fce0ec2c80a97df2b78570d2589cbe6d42d6d3d1a098bfb191ae477fd78bb7b15c740254a9ee7c76bf988503b991b95
lexical: 0.12.4
checksum: 28e95c0669725751e34b27f2e31e21ed621a2de536918812c179ba478432d103bc9b3e1bfe828dc3990448068f42a34ae01ac48a685423dbe138982cff44c632
languageName: node
linkType: hard
"@lexical/hashtag@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/hashtag@npm:0.12.2"
"@lexical/hashtag@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/hashtag@npm:0.12.4"
dependencies:
"@lexical/utils": 0.12.2
"@lexical/utils": 0.12.4
peerDependencies:
lexical: 0.12.2
checksum: 185e8afd8277c60fe495bb02c5321636f1c2575dc3c276c0fa5174f55ec79357f30b3678fea24fe9109aa9308162f5555f5d8e1ede7b6df32dc2023701997630
lexical: 0.12.4
checksum: 25c403e2b1482834af20275fde081e803967cdee9d635c2d2eae19ce16cc5a27643829c533c544acad4eebf9763abf6f351c63c1d0b0b6e32fc321d1d5c0e39c
languageName: node
linkType: hard
"@lexical/headless@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/headless@npm:0.12.2"
"@lexical/headless@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/headless@npm:0.12.4"
peerDependencies:
lexical: 0.12.2
checksum: 8954bf8efb6cabe6f69e138d65e4785999b6b675275e46937c1573e55376598a153f408904583976543d46fa986da9c6f04c1a34117e2b51768599afa190987e
lexical: 0.12.4
checksum: f24f9b3d92af412436fef80ef7f6a10d85d0835a40ca4ee04b649719370b9e763c62d87a0eb53d03acf31f3cd8b233ca1ff031359b0b40faa8348bcb0c385297
languageName: node
linkType: hard
"@lexical/history@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/history@npm:0.12.2"
"@lexical/history@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/history@npm:0.12.4"
dependencies:
"@lexical/utils": 0.12.2
"@lexical/utils": 0.12.4
peerDependencies:
lexical: 0.12.2
checksum: a813313e7d8d54f0c50a4a5114a5d04d095bb00aaaa8bf916d86cbe64434097fe3dcd10838fae50420987861b1cd9e52dc443077a8bd14e0073e92d60c944ed8
lexical: 0.12.4
checksum: 101a94052ef4f129baa954826b1e4d5553ef65b52c9cf16e7004f5ba1b5fe51a76c6f9d5169cb4d3968fdcd088310c41e9d281a8adeaf2e0915d12d844ef861a
languageName: node
linkType: hard
"@lexical/html@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/html@npm:0.12.2"
"@lexical/html@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/html@npm:0.12.4"
dependencies:
"@lexical/selection": 0.12.2
"@lexical/selection": 0.12.4
"@lexical/utils": 0.12.4
peerDependencies:
lexical: 0.12.2
checksum: a3538d923f2ffd5d0b5db186016d5cdeab21f42c55ac40d393b7cfbd59f1e42f12515b79ce291eafa57d67960995bbe90bc46a5042a177753f4acccfc1746fa1
lexical: 0.12.4
checksum: 3dc05e459a54203682edb0443adcd21410a7f56f76c7c4c514fea84fdbe7c85267ce1d600425f01751c529ca7b84efde7ac82e472ac3f47a1d68da96faadef0b
languageName: node
linkType: hard
"@lexical/link@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/link@npm:0.12.2"
"@lexical/link@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/link@npm:0.12.4"
dependencies:
"@lexical/utils": 0.12.2
"@lexical/utils": 0.12.4
peerDependencies:
lexical: 0.12.2
checksum: fab9b1a62deb7b232b67135696c4faf1a7738be415f8e993c56298a45cdbdbe0a04a8d2d71e3e7cc574c94b24aad8b93fb657d1553858c874c86d74916f16767
lexical: 0.12.4
checksum: 206214255505d68e8d14e53dfcdf5fa71813cde94fa30b489440278df9560aab262385a7334b4b094384a0d316de50469a33133db606d2da23f33fec049107b4
languageName: node
linkType: hard
"@lexical/list@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/list@npm:0.12.2"
"@lexical/list@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/list@npm:0.12.4"
dependencies:
"@lexical/utils": 0.12.2
"@lexical/utils": 0.12.4
peerDependencies:
lexical: 0.12.2
checksum: 196e40c79613f21bcbdd035ea6b970460b10dde86c22674d6c2e009f093d56a48565e631416ac1d60c9bb84b6225d85ba182c9d1362a197b7f84abef817eced0
lexical: 0.12.4
checksum: 2a3e35b5c4304c03262d578b4e319444e7f52e785b60775d25d9a906e1227551a6dad06d6090ffd8fd96415b3e3201db16c9990579d598d6f94857fe51f914af
languageName: node
linkType: hard
"@lexical/mark@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/mark@npm:0.12.2"
"@lexical/mark@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/mark@npm:0.12.4"
dependencies:
"@lexical/utils": 0.12.2
"@lexical/utils": 0.12.4
peerDependencies:
lexical: 0.12.2
checksum: aff24ec8ee4dc91e0ac9a3000cd2a7f6556f9755eb1af68aa3de94ef1a73405e4a90e0013d28d41c2887ef67d744154863d22a8b5bcc9b1ee1f9cac71f4af4b8
lexical: 0.12.4
checksum: 6a7a5410a7dcd62facade8cf1c1aac463029ca1cbed0ab5a95c39ba5ffea682a438231dac2c6bd5e5a3229d0ff22619c33edc5670338f587c5614898d35a5ce9
languageName: node
linkType: hard
"@lexical/markdown@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/markdown@npm:0.12.2"
"@lexical/markdown@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/markdown@npm:0.12.4"
dependencies:
"@lexical/code": 0.12.2
"@lexical/link": 0.12.2
"@lexical/list": 0.12.2
"@lexical/rich-text": 0.12.2
"@lexical/text": 0.12.2
"@lexical/utils": 0.12.2
"@lexical/code": 0.12.4
"@lexical/link": 0.12.4
"@lexical/list": 0.12.4
"@lexical/rich-text": 0.12.4
"@lexical/text": 0.12.4
"@lexical/utils": 0.12.4
peerDependencies:
lexical: 0.12.2
checksum: 8dd8b32fd00c43d0df2d5a5201c67cf5596083b2412319c0de882c67fe51c5cdafec709beb4ccac7aa80a650d1565b906087e985fb9e19530546e97a1b91282d
lexical: 0.12.4
checksum: a540a07c6fa0d3ffd7da2603376458463c106fe8f0e1e7f62535e23a77db27e253b8cce4bf6cb179ae810e8ee6bfff0bdd8eb03e6c3e0be5fc4f5ae6f96ace9f
languageName: node
linkType: hard
"@lexical/offset@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/offset@npm:0.12.2"
"@lexical/offset@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/offset@npm:0.12.4"
peerDependencies:
lexical: 0.12.2
checksum: 4f3f609a6fc8f383279e491fa4a437060f49600ce8440ae381e896f5c67c9ad52d6264ba7c3ea6e86a66eb00ebcfe06e6bf122827242a6eb2d9c41c3f55d14c2
lexical: 0.12.4
checksum: a9f8c3d1bd43d927bafa1d7ba666d6d46982a0d285596bd23ff7eee679f74840f9e65f252937b1767bfc64dcaaee83a820f9c5662c295b74e3946173f520e322
languageName: node
linkType: hard
"@lexical/overflow@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/overflow@npm:0.12.2"
"@lexical/overflow@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/overflow@npm:0.12.4"
peerDependencies:
lexical: 0.12.2
checksum: ef0a8d517d22d9b13fe4a535e27be4be6a4e0f29056fe77d73b174ba1ce6e0b0af0a8f8dc401aee37ad4da65e4c15fd860f79dc3156c37aa3dee07c036ef9989
lexical: 0.12.4
checksum: 559315fd8b31bbcaaf1ea7892debc71e52b9afd945c76fb02b271d4164014361db460398751ef355a74680886e131d1ef0e75d997d8973703b9584fe4cbaced3
languageName: node
linkType: hard
"@lexical/plain-text@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/plain-text@npm:0.12.2"
"@lexical/plain-text@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/plain-text@npm:0.12.4"
peerDependencies:
"@lexical/clipboard": 0.12.2
"@lexical/selection": 0.12.2
"@lexical/utils": 0.12.2
lexical: 0.12.2
checksum: f1142c075284bc7a654aa100585f3779575599a3b1305be26f2571dd98bc0eac0953a40eeea735da755a7fd0b9bb3d18e5dcfd3efae661c05abf52297039eaa4
"@lexical/clipboard": 0.12.4
"@lexical/selection": 0.12.4
"@lexical/utils": 0.12.4
lexical: 0.12.4
checksum: fb60d6a7b690c3d24830cbdff74652b27841253660b014e0d70ecd2bccb8208372024666a94211b366fd4db4a36adcf1d91edbede8ac84418846211ce29a5b5f
languageName: node
linkType: hard
"@lexical/react@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/react@npm:0.12.2"
"@lexical/react@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/react@npm:0.12.4"
dependencies:
"@lexical/clipboard": 0.12.2
"@lexical/code": 0.12.2
"@lexical/dragon": 0.12.2
"@lexical/hashtag": 0.12.2
"@lexical/history": 0.12.2
"@lexical/link": 0.12.2
"@lexical/list": 0.12.2
"@lexical/mark": 0.12.2
"@lexical/markdown": 0.12.2
"@lexical/overflow": 0.12.2
"@lexical/plain-text": 0.12.2
"@lexical/rich-text": 0.12.2
"@lexical/selection": 0.12.2
"@lexical/table": 0.12.2
"@lexical/text": 0.12.2
"@lexical/utils": 0.12.2
"@lexical/yjs": 0.12.2
"@lexical/clipboard": 0.12.4
"@lexical/code": 0.12.4
"@lexical/dragon": 0.12.4
"@lexical/hashtag": 0.12.4
"@lexical/history": 0.12.4
"@lexical/link": 0.12.4
"@lexical/list": 0.12.4
"@lexical/mark": 0.12.4
"@lexical/markdown": 0.12.4
"@lexical/overflow": 0.12.4
"@lexical/plain-text": 0.12.4
"@lexical/rich-text": 0.12.4
"@lexical/selection": 0.12.4
"@lexical/table": 0.12.4
"@lexical/text": 0.12.4
"@lexical/utils": 0.12.4
"@lexical/yjs": 0.12.4
react-error-boundary: ^3.1.4
peerDependencies:
lexical: 0.12.2
lexical: 0.12.4
react: ">=17.x"
react-dom: ">=17.x"
checksum: 9a6a603116467f8ae477e4504c71a99a10148e18d64840f0835d527d653005f89bcc643e7d0dccfa07fc772b2158767620247f4b35c6dec403879ef91f2bf110
checksum: 4b224a54619b60591cba118b75e415b4e48d1f528cd25f10e8f8928163aa9bb283a070a7813af9b6d573dcec97113d9e80c8de1edab0f3f8997bc2f979c7abdc
languageName: node
linkType: hard
"@lexical/rich-text@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/rich-text@npm:0.12.2"
"@lexical/rich-text@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/rich-text@npm:0.12.4"
peerDependencies:
"@lexical/clipboard": 0.12.2
"@lexical/selection": 0.12.2
"@lexical/utils": 0.12.2
lexical: 0.12.2
checksum: b3ff3dbcb321cb1981de7f71c30fbf2ed643ac259fc360e1454af9e2f8c3567ef0ff157a7febc32c8cf3d133252d064b1c2ee5fa6e4ec83cd9bed9f7a236d5e3
"@lexical/clipboard": 0.12.4
"@lexical/selection": 0.12.4
"@lexical/utils": 0.12.4
lexical: 0.12.4
checksum: 35829c744a3e5d633309981ee59576688f839589ecd3f492b3083ee25a9b118de719cf390771333a99df98b43e25abbc0d2c4ca94d81078106901527113c54e4
languageName: node
linkType: hard
"@lexical/selection@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/selection@npm:0.12.2"
"@lexical/selection@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/selection@npm:0.12.4"
peerDependencies:
lexical: 0.12.2
checksum: 4c35dc644c401c3782ed8a10e404a92b1f18c763332035e1f8707a1ac6143754b463bbb122b7cc82c99766e0b5650927025e2d081538ffbbd76386cf9cf4c66c
lexical: 0.12.4
checksum: d3448e2510d4ab88ae6e99f0a4ae791f76b5a6a74664b48f0a1d29c0fdebdf9eed07c254a244cce87c912d87daffa444f351cb0600657422a07c3992991583cf
languageName: node
linkType: hard
"@lexical/table@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/table@npm:0.12.2"
"@lexical/table@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/table@npm:0.12.4"
dependencies:
"@lexical/utils": 0.12.2
"@lexical/utils": 0.12.4
peerDependencies:
lexical: 0.12.2
checksum: 051cd08a39b3ec86734db6ff2ff5c5fc1952890fa282696983c89a949ccea134131930d704eec98afa26c104ec05d1e26d705738b9f20aa90df1f341294a67b5
lexical: 0.12.4
checksum: 941c03f5f8c51ee87ec9b2666315465d1d98d7b1733c7f01fb2149933b70e73b22e6a22f5ab3fc1674949f875cd4f9ae676dab8791824219fe8f256cc04d7505
languageName: node
linkType: hard
"@lexical/text@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/text@npm:0.12.2"
"@lexical/text@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/text@npm:0.12.4"
peerDependencies:
lexical: 0.12.2
checksum: 4ab65132a6bb804b73a58ab924a2a46e1e767cbd4a6cd671e082d951c381515981c44cece18e6b6d998dd9ef1e6cc8c1b6ff7740c3f125c3fc8f3284128c59be
lexical: 0.12.4
checksum: 4de5404f6bbb7dc27dac31e893b1ff15a47712d32b5260d803bcdb43a850828e52ae2563ef69ba6b9213431e9ae27c030ee0748fc206e6a47707bfa167d65432
languageName: node
linkType: hard
"@lexical/utils@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/utils@npm:0.12.2"
"@lexical/utils@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/utils@npm:0.12.4"
dependencies:
"@lexical/list": 0.12.2
"@lexical/selection": 0.12.2
"@lexical/table": 0.12.2
"@lexical/list": 0.12.4
"@lexical/selection": 0.12.4
"@lexical/table": 0.12.4
peerDependencies:
lexical: 0.12.2
checksum: 579fd0b5a5b085f4842721d23076aa43eb295497952c81239f211c4c50ce8b33c10734f72acce3107af4b391dcd5d399461a6ab63eab1d6cd7b57db27f7a1066
lexical: 0.12.4
checksum: 85e47b9f62c8b0fc07607e170d34f476a9886d697be8b27358a0aed85b8ffe03eb151faeab6db1fa7d31de7ccdaba6cd88ff846fd812e8938a9fa2e866ba1e11
languageName: node
linkType: hard
"@lexical/yjs@npm:0.12.2":
version: 0.12.2
resolution: "@lexical/yjs@npm:0.12.2"
"@lexical/yjs@npm:0.12.4":
version: 0.12.4
resolution: "@lexical/yjs@npm:0.12.4"
dependencies:
"@lexical/offset": 0.12.2
"@lexical/offset": 0.12.4
peerDependencies:
lexical: 0.12.2
lexical: 0.12.4
yjs: ">=13.5.22"
checksum: 552e4b6eaca32e4eae7e7eb754ee8a5d927cc97eb5a4734d9f5a4ce810ed116b932f63c86e5e2c3084957c342da2cedad11dd53e8bcb8dd3ecec1cbd09789b0d
checksum: 75e2e5a24d6800b2b4316e0b02490ba9c2364a89b19097ffdd323cac84868b414b40d71f186e6e5b48814ee71c7e7af222240d5bdd280b2090609d5215e2a679
languageName: node
linkType: hard
@@ -3206,6 +3207,15 @@ __metadata:
languageName: node
linkType: hard
"@notifee/react-native@npm:^7.8.0":
version: 7.8.0
resolution: "@notifee/react-native@npm:7.8.0"
peerDependencies:
react-native: "*"
checksum: 800233c9505195046e918ee42a4b11d8e84cf1846ea4a0b52599e1a40181b2bbfcab09c64b445b5a7eed98c38556c97550bce32ed24a51ce05ccd8b65047548d
languageName: node
linkType: hard
"@npmcli/arborist@npm:^6.2.5":
version: 6.3.0
resolution: "@npmcli/arborist@npm:6.3.0"
@@ -4585,6 +4595,7 @@ __metadata:
"@babel/core": "*"
"@babel/preset-typescript": ^7.18.6
"@babel/runtime": ^7.20.1
"@notifee/react-native": ^7.8.0
"@react-native-async-storage/async-storage": 1.19.3
"@react-native/eslint-config": ^0.72.2
"@react-native/metro-config": ^0.72.11
@@ -5013,8 +5024,8 @@ __metadata:
"@babel/plugin-transform-react-jsx": ^7.19.0
"@babel/preset-env": "*"
"@babel/preset-typescript": ^7.21.5
"@lexical/headless": 0.12.2
"@lexical/react": 0.12.2
"@lexical/headless": 0.12.4
"@lexical/react": 0.12.4
"@pmmmwh/react-refresh-webpack-plugin": ^0.5.10
"@radix-ui/react-slot": ^1.0.1
"@simplewebauthn/browser": ^8.0.2
@@ -5064,7 +5075,7 @@ __metadata:
identity-obj-proxy: ^3.0.0
jest: ^29.3.1
jest-environment-jsdom: ^29.3.1
lexical: 0.12.2
lexical: 0.12.4
lint-staged: ">=13"
mini-css-extract-plugin: ^2.7.2
minimatch: ^5.1.1
@@ -15470,10 +15481,10 @@ __metadata:
languageName: node
linkType: hard
"lexical@npm:0.12.2":
version: 0.12.2
resolution: "lexical@npm:0.12.2"
checksum: f02cd11aa015f1babb960d39a31ada30060c3af5446dcc4a6d26e300af8b889bc307633cf77604cf7538e776efdf6ca19d919b82ad24e29c451f58939e91621f
"lexical@npm:0.12.4":
version: 0.12.4
resolution: "lexical@npm:0.12.4"
checksum: c2af8fa2a6bf55dde453240b583b433abd5b6dac860598d33be54fc191005ff5ee8ba8af03d21717cc08c6c87f8a3e45a0bd969f436c765aded57eb9387c8972
languageName: node
linkType: hard