Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eac878d563 | ||
|
|
de08c01c4c | ||
|
|
7937fd1f3a | ||
|
|
eef5c2bf66 | ||
|
|
9c769cd7e5 | ||
|
|
eac58dc212 | ||
|
|
d3241cdecb |
No files matched your search
@@ -1,6 +1,13 @@
|
||||
# Release Notes
|
||||
|
||||
## Version 0.4.1 - 01/03/2024
|
||||
### Bug fixes
|
||||
- Fix import AppFlowy data folder
|
||||
|
||||
## Version 0.4.0 - 12/30/2023
|
||||
1. Added capability to import data from an AppFlowy data folder. For detailed information, please see [AppFlowy Data Storage Documentation](https://docs.appflowy.io/docs/appflowy/product/data-storage).
|
||||
2. Enhanced user interface and fixed various bugs.
|
||||
3. Improved the efficiency of data synchronization in AppFlowy Cloud
|
||||
|
||||
## Version 0.3.9.1 - 12/07/2023
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -12,7 +12,7 @@
|
||||
"program": "./lib/main.dart",
|
||||
"type": "dart",
|
||||
"env": {
|
||||
"RUST_LOG": "debug",
|
||||
"RUST_LOG": "trace",
|
||||
"RUST_BACKTRACE": "1"
|
||||
},
|
||||
// uncomment the following line to testing performance.
|
||||
|
||||
@@ -25,7 +25,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
||||
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
||||
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
||||
LIB_NAME = "dart_ffi"
|
||||
CURRENT_APP_VERSION = "0.4.0"
|
||||
APPFLOWY_VERSION = "0.4.1"
|
||||
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite"
|
||||
PRODUCT_NAME = "AppFlowy"
|
||||
MACOSX_DEPLOYMENT_TARGET = "11.0"
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:appflowy_backend/appflowy_backend.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
|
||||
import 'deps_resolver.dart';
|
||||
import 'entry_point.dart';
|
||||
@@ -83,6 +84,12 @@ class FlowyRunner {
|
||||
rustEnvs: rustEnvsBuilder?.call() ?? {},
|
||||
);
|
||||
|
||||
if (!mode.isUnitTest) {
|
||||
// Unit test can't use the package_info_plus plugin
|
||||
config.rustEnvs["APP_VERSION"] =
|
||||
await PackageInfo.fromPlatform().then((value) => value.version);
|
||||
}
|
||||
|
||||
// Specify the env
|
||||
await initGetIt(getIt, mode, f, config);
|
||||
await didInitGetItCallback?.call();
|
||||
|
||||
@@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 0.4.0
|
||||
version: 0.4.1
|
||||
|
||||
environment:
|
||||
flutter: ">=3.18.0-0.2.pre"
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@svgr/plugin-svgo": "^8.0.1",
|
||||
"@tauri-apps/cli": "^1.2.2",
|
||||
"@tauri-apps/cli": "^1.5.6",
|
||||
"@types/google-protobuf": "^3.15.6",
|
||||
"@types/is-hotkey": "^0.1.7",
|
||||
"@types/jest": "^29.5.3",
|
||||
|
||||
Generated
+132
-53
@@ -1,5 +1,9 @@
|
||||
lockfileVersion: '6.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
'@emoji-mart/data':
|
||||
specifier: ^1.1.2
|
||||
@@ -181,8 +185,8 @@ devDependencies:
|
||||
specifier: ^8.0.1
|
||||
version: 8.0.1(@svgr/core@7.0.0)
|
||||
'@tauri-apps/cli':
|
||||
specifier: ^1.2.2
|
||||
version: 1.3.1
|
||||
specifier: ^1.5.6
|
||||
version: 1.5.6
|
||||
'@types/google-protobuf':
|
||||
specifier: ^3.15.6
|
||||
version: 3.15.6
|
||||
@@ -321,6 +325,13 @@ packages:
|
||||
dependencies:
|
||||
'@babel/highlight': 7.18.6
|
||||
|
||||
/@babel/code-frame@7.23.5:
|
||||
resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/highlight': 7.23.4
|
||||
chalk: 2.4.2
|
||||
|
||||
/@babel/compat-data@7.21.7:
|
||||
resolution: {integrity: sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -337,7 +348,7 @@ packages:
|
||||
'@babel/helpers': 7.21.5
|
||||
'@babel/parser': 7.21.8
|
||||
'@babel/template': 7.20.7
|
||||
'@babel/traverse': 7.21.5
|
||||
'@babel/traverse': 7.23.7
|
||||
'@babel/types': 7.21.5
|
||||
convert-source-map: 1.9.0
|
||||
debug: 4.3.4
|
||||
@@ -356,6 +367,15 @@ packages:
|
||||
'@jridgewell/trace-mapping': 0.3.18
|
||||
jsesc: 2.5.2
|
||||
|
||||
/@babel/generator@7.23.6:
|
||||
resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.23.6
|
||||
'@jridgewell/gen-mapping': 0.3.3
|
||||
'@jridgewell/trace-mapping': 0.3.18
|
||||
jsesc: 2.5.2
|
||||
|
||||
/@babel/helper-compilation-targets@7.21.5(@babel/core@7.21.8):
|
||||
resolution: {integrity: sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -373,18 +393,22 @@ packages:
|
||||
resolution: {integrity: sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
/@babel/helper-function-name@7.21.0:
|
||||
resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==}
|
||||
/@babel/helper-environment-visitor@7.22.20:
|
||||
resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/template': 7.20.7
|
||||
'@babel/types': 7.21.5
|
||||
|
||||
/@babel/helper-hoist-variables@7.18.6:
|
||||
resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==}
|
||||
/@babel/helper-function-name@7.23.0:
|
||||
resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.21.5
|
||||
'@babel/template': 7.22.15
|
||||
'@babel/types': 7.23.6
|
||||
|
||||
/@babel/helper-hoist-variables@7.22.5:
|
||||
resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.23.6
|
||||
|
||||
/@babel/helper-module-imports@7.21.4:
|
||||
resolution: {integrity: sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==}
|
||||
@@ -402,7 +426,7 @@ packages:
|
||||
'@babel/helper-split-export-declaration': 7.18.6
|
||||
'@babel/helper-validator-identifier': 7.19.1
|
||||
'@babel/template': 7.20.7
|
||||
'@babel/traverse': 7.21.5
|
||||
'@babel/traverse': 7.23.7
|
||||
'@babel/types': 7.21.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -423,14 +447,28 @@ packages:
|
||||
dependencies:
|
||||
'@babel/types': 7.21.5
|
||||
|
||||
/@babel/helper-split-export-declaration@7.22.6:
|
||||
resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.23.6
|
||||
|
||||
/@babel/helper-string-parser@7.21.5:
|
||||
resolution: {integrity: sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
/@babel/helper-string-parser@7.23.4:
|
||||
resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
/@babel/helper-validator-identifier@7.19.1:
|
||||
resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
/@babel/helper-validator-identifier@7.22.20:
|
||||
resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
/@babel/helper-validator-option@7.21.0:
|
||||
resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -440,7 +478,7 @@ packages:
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/template': 7.20.7
|
||||
'@babel/traverse': 7.21.5
|
||||
'@babel/traverse': 7.23.7
|
||||
'@babel/types': 7.21.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -453,6 +491,14 @@ packages:
|
||||
chalk: 2.4.2
|
||||
js-tokens: 4.0.0
|
||||
|
||||
/@babel/highlight@7.23.4:
|
||||
resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/helper-validator-identifier': 7.22.20
|
||||
chalk: 2.4.2
|
||||
js-tokens: 4.0.0
|
||||
|
||||
/@babel/parser@7.21.8:
|
||||
resolution: {integrity: sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
@@ -460,6 +506,13 @@ packages:
|
||||
dependencies:
|
||||
'@babel/types': 7.21.5
|
||||
|
||||
/@babel/parser@7.23.6:
|
||||
resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@babel/types': 7.23.6
|
||||
|
||||
/@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.21.8):
|
||||
resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
|
||||
peerDependencies:
|
||||
@@ -629,18 +682,26 @@ packages:
|
||||
'@babel/parser': 7.21.8
|
||||
'@babel/types': 7.21.5
|
||||
|
||||
/@babel/traverse@7.21.5:
|
||||
resolution: {integrity: sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==}
|
||||
/@babel/template@7.22.15:
|
||||
resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.21.4
|
||||
'@babel/generator': 7.21.5
|
||||
'@babel/helper-environment-visitor': 7.21.5
|
||||
'@babel/helper-function-name': 7.21.0
|
||||
'@babel/helper-hoist-variables': 7.18.6
|
||||
'@babel/helper-split-export-declaration': 7.18.6
|
||||
'@babel/parser': 7.21.8
|
||||
'@babel/types': 7.21.5
|
||||
'@babel/code-frame': 7.23.5
|
||||
'@babel/parser': 7.23.6
|
||||
'@babel/types': 7.23.6
|
||||
|
||||
/@babel/traverse@7.23.7:
|
||||
resolution: {integrity: sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.23.5
|
||||
'@babel/generator': 7.23.6
|
||||
'@babel/helper-environment-visitor': 7.22.20
|
||||
'@babel/helper-function-name': 7.23.0
|
||||
'@babel/helper-hoist-variables': 7.22.5
|
||||
'@babel/helper-split-export-declaration': 7.22.6
|
||||
'@babel/parser': 7.23.6
|
||||
'@babel/types': 7.23.6
|
||||
debug: 4.3.4
|
||||
globals: 11.12.0
|
||||
transitivePeerDependencies:
|
||||
@@ -654,6 +715,14 @@ packages:
|
||||
'@babel/helper-validator-identifier': 7.19.1
|
||||
to-fast-properties: 2.0.0
|
||||
|
||||
/@babel/types@7.23.6:
|
||||
resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/helper-string-parser': 7.23.4
|
||||
'@babel/helper-validator-identifier': 7.22.20
|
||||
to-fast-properties: 2.0.0
|
||||
|
||||
/@bcoe/v8-coverage@0.2.3:
|
||||
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
|
||||
|
||||
@@ -2005,8 +2074,8 @@ packages:
|
||||
engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'}
|
||||
dev: false
|
||||
|
||||
/@tauri-apps/cli-darwin-arm64@1.3.1:
|
||||
resolution: {integrity: sha512-QlepYVPgOgspcwA/u4kGG4ZUijlXfdRtno00zEy+LxinN/IRXtk+6ErVtsmoLi1ZC9WbuMwzAcsRvqsD+RtNAg==}
|
||||
/@tauri-apps/cli-darwin-arm64@1.5.6:
|
||||
resolution: {integrity: sha512-NNvG3XLtciCMsBahbDNUEvq184VZmOveTGOuy0So2R33b/6FDkuWaSgWZsR1mISpOuP034htQYW0VITCLelfqg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
@@ -2014,8 +2083,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@tauri-apps/cli-darwin-x64@1.3.1:
|
||||
resolution: {integrity: sha512-fKcAUPVFO3jfDKXCSDGY0MhZFF/wDtx3rgFnogWYu4knk38o9RaqRkvMvqJhLYPuWaEM5h6/z1dRrr9KKCbrVg==}
|
||||
/@tauri-apps/cli-darwin-x64@1.5.6:
|
||||
resolution: {integrity: sha512-nkiqmtUQw3N1j4WoVjv81q6zWuZFhBLya/RNGUL94oafORloOZoSY0uTZJAoeieb3Y1YK0rCHSDl02MyV2Fi4A==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
@@ -2023,8 +2092,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@tauri-apps/cli-linux-arm-gnueabihf@1.3.1:
|
||||
resolution: {integrity: sha512-+4H0dv8ltJHYu/Ma1h9ixUPUWka9EjaYa8nJfiMsdCI4LJLNE6cPveE7RmhZ59v9GW1XB108/k083JUC/OtGvA==}
|
||||
/@tauri-apps/cli-linux-arm-gnueabihf@1.5.6:
|
||||
resolution: {integrity: sha512-z6SPx+axZexmWXTIVPNs4Tg7FtvdJl9EKxYN6JPjOmDZcqA13iyqWBQal2DA/GMZ1Xqo3vyJf6EoEaKaliymPQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
@@ -2032,8 +2101,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@tauri-apps/cli-linux-arm64-gnu@1.3.1:
|
||||
resolution: {integrity: sha512-Pj3odVO1JAxLjYmoXKxcrpj/tPxcA8UP8N06finhNtBtBaxAjrjjxKjO4968KB0BUH7AASIss9EL4Tr0FGnDuw==}
|
||||
/@tauri-apps/cli-linux-arm64-gnu@1.5.6:
|
||||
resolution: {integrity: sha512-QuQjMQmpsCbzBrmtQiG4uhnfAbdFx3nzm+9LtqjuZlurc12+Mj5MTgqQ3AOwQedH3f7C+KlvbqD2AdXpwTg7VA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
@@ -2041,8 +2110,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@tauri-apps/cli-linux-arm64-musl@1.3.1:
|
||||
resolution: {integrity: sha512-tA0JdDLPFaj42UDIVcF2t8V0tSha40rppcmAR/MfQpTCxih6399iMjwihz9kZE1n4b5O4KTq9GliYo50a8zYlQ==}
|
||||
/@tauri-apps/cli-linux-arm64-musl@1.5.6:
|
||||
resolution: {integrity: sha512-8j5dH3odweFeom7bRGlfzDApWVOT4jIq8/214Wl+JeiNVehouIBo9lZGeghZBH3XKFRwEvU23i7sRVjuh2s8mg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
@@ -2050,8 +2119,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@tauri-apps/cli-linux-x64-gnu@1.3.1:
|
||||
resolution: {integrity: sha512-FDU+Mnvk6NLkqQimcNojdKpMN4Y3W51+SQl+NqG9AFCWprCcSg62yRb84751ujZuf2MGT8HQOfmd0i77F4Q3tQ==}
|
||||
/@tauri-apps/cli-linux-x64-gnu@1.5.6:
|
||||
resolution: {integrity: sha512-gbFHYHfdEGW0ffk8SigDsoXks6USpilF6wR0nqB/JbWzbzFR/sBuLVNQlJl1RKNakyJHu+lsFxGy0fcTdoX8xA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
@@ -2059,8 +2128,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@tauri-apps/cli-linux-x64-musl@1.3.1:
|
||||
resolution: {integrity: sha512-MpO3akXFmK8lZYEbyQRDfhdxz1JkTBhonVuz5rRqxwA7gnGWHa1aF1+/2zsy7ahjB2tQ9x8DDFDMdVE20o9HrA==}
|
||||
/@tauri-apps/cli-linux-x64-musl@1.5.6:
|
||||
resolution: {integrity: sha512-9v688ogoLkeFYQNgqiSErfhTreLUd8B3prIBSYUt+x4+5Kcw91zWvIh+VSxL1n3KCGGsM7cuXhkGPaxwlEh1ug==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
@@ -2068,8 +2137,17 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@tauri-apps/cli-win32-ia32-msvc@1.3.1:
|
||||
resolution: {integrity: sha512-9Boeo3K5sOrSBAZBuYyGkpV2RfnGQz3ZhGJt4hE6P+HxRd62lS6+qDKAiw1GmkZ0l1drc2INWrNeT50gwOKwIQ==}
|
||||
/@tauri-apps/cli-win32-arm64-msvc@1.5.6:
|
||||
resolution: {integrity: sha512-DRNDXFNZb6y5IZrw+lhTTA9l4wbzO4TNRBAlHAiXUrH+pRFZ/ZJtv5WEuAj9ocVSahVw2NaK5Yaold4NPAxHog==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@tauri-apps/cli-win32-ia32-msvc@1.5.6:
|
||||
resolution: {integrity: sha512-oUYKNR/IZjF4fsOzRpw0xesl2lOjhsQEyWlgbpT25T83EU113Xgck9UjtI7xemNI/OPCv1tPiaM1e7/ABdg5iA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
@@ -2077,8 +2155,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@tauri-apps/cli-win32-x64-msvc@1.3.1:
|
||||
resolution: {integrity: sha512-wMrTo91hUu5CdpbElrOmcZEoJR4aooTG+fbtcc87SMyPGQy1Ux62b+ZdwLvL1sVTxnIm//7v6QLRIWGiUjCPwA==}
|
||||
/@tauri-apps/cli-win32-x64-msvc@1.5.6:
|
||||
resolution: {integrity: sha512-RmEf1os9C8//uq2hbjXi7Vgz9ne7798ZxqemAZdUwo1pv3oLVZSz1/IvZmUHPdy2e6zSeySqWu1D0Y3QRNN+dg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
@@ -2086,20 +2164,21 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@tauri-apps/cli@1.3.1:
|
||||
resolution: {integrity: sha512-o4I0JujdITsVRm3/0spfJX7FcKYrYV1DXJqzlWIn6IY25/RltjU6qbC1TPgVww3RsRX63jyVUTcWpj5wwFl+EQ==}
|
||||
/@tauri-apps/cli@1.5.6:
|
||||
resolution: {integrity: sha512-k4Y19oVCnt7WZb2TnDzLqfs7o98Jq0tUoVMv+JQSzuRDJqaVu2xMBZ8dYplEn+EccdR5SOMyzaLBJWu38TVK1A==}
|
||||
engines: {node: '>= 10'}
|
||||
hasBin: true
|
||||
optionalDependencies:
|
||||
'@tauri-apps/cli-darwin-arm64': 1.3.1
|
||||
'@tauri-apps/cli-darwin-x64': 1.3.1
|
||||
'@tauri-apps/cli-linux-arm-gnueabihf': 1.3.1
|
||||
'@tauri-apps/cli-linux-arm64-gnu': 1.3.1
|
||||
'@tauri-apps/cli-linux-arm64-musl': 1.3.1
|
||||
'@tauri-apps/cli-linux-x64-gnu': 1.3.1
|
||||
'@tauri-apps/cli-linux-x64-musl': 1.3.1
|
||||
'@tauri-apps/cli-win32-ia32-msvc': 1.3.1
|
||||
'@tauri-apps/cli-win32-x64-msvc': 1.3.1
|
||||
'@tauri-apps/cli-darwin-arm64': 1.5.6
|
||||
'@tauri-apps/cli-darwin-x64': 1.5.6
|
||||
'@tauri-apps/cli-linux-arm-gnueabihf': 1.5.6
|
||||
'@tauri-apps/cli-linux-arm64-gnu': 1.5.6
|
||||
'@tauri-apps/cli-linux-arm64-musl': 1.5.6
|
||||
'@tauri-apps/cli-linux-x64-gnu': 1.5.6
|
||||
'@tauri-apps/cli-linux-x64-musl': 1.5.6
|
||||
'@tauri-apps/cli-win32-arm64-msvc': 1.5.6
|
||||
'@tauri-apps/cli-win32-ia32-msvc': 1.5.6
|
||||
'@tauri-apps/cli-win32-x64-msvc': 1.5.6
|
||||
dev: true
|
||||
|
||||
/@tootallnate/once@2.0.0:
|
||||
@@ -4667,7 +4746,7 @@ packages:
|
||||
'@babel/generator': 7.21.5
|
||||
'@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.21.8)
|
||||
'@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.21.8)
|
||||
'@babel/traverse': 7.21.5
|
||||
'@babel/traverse': 7.23.7
|
||||
'@babel/types': 7.21.5
|
||||
'@jest/expect-utils': 29.5.0
|
||||
'@jest/transform': 29.5.0
|
||||
|
||||
+72
-58
@@ -139,7 +139,7 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
[[package]]
|
||||
name = "app-error"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@@ -193,7 +193,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -204,7 +204,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -352,7 +352,7 @@ dependencies = [
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -734,7 +734,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -831,7 +831,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -840,6 +840,7 @@ dependencies = [
|
||||
"parking_lot",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
@@ -850,7 +851,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-database"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -879,7 +880,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-document"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@@ -897,7 +898,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -911,7 +912,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-folder"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@@ -948,7 +949,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-persistence"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -969,7 +970,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-plugins"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -995,7 +996,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-user"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@@ -1253,7 +1254,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1317,7 +1318,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1328,7 +1329,7 @@ checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1353,10 +1354,11 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
"bincode",
|
||||
"chrono",
|
||||
"collab-entity",
|
||||
"serde",
|
||||
@@ -1431,7 +1433,7 @@ dependencies = [
|
||||
"diesel_table_macro_syntax",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1451,7 +1453,7 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5"
|
||||
dependencies = [
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2320,7 +2322,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2649,7 +2651,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@@ -2665,7 +2667,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -3087,7 +3089,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@@ -3893,7 +3895,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4103,7 +4105,7 @@ dependencies = [
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4257,7 +4259,7 @@ dependencies = [
|
||||
"phf_shared 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4305,7 +4307,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4422,7 +4424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9825a04601d60621feed79c4e6b56d65db77cdca55cef43b46b0de1096d1c282"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4476,9 +4478,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.63"
|
||||
version = "1.0.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
|
||||
checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -4510,7 +4512,7 @@ dependencies = [
|
||||
"prost",
|
||||
"prost-types",
|
||||
"regex",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
"tempfile",
|
||||
"which",
|
||||
]
|
||||
@@ -4525,7 +4527,7 @@ dependencies = [
|
||||
"itertools 0.11.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4681,9 +4683,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.30"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5907a1b7c277254a8b15170f6e7c97cfa60ee7872a3217663bb81151e48184bb"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -4817,7 +4819,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "realtime-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@@ -4839,7 +4841,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "realtime-protocol"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@@ -5391,7 +5393,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5407,13 +5409,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.16"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00"
|
||||
checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5462,7 +5464,7 @@ dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5546,7 +5548,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared_entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -5904,7 +5906,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5926,9 +5928,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.32"
|
||||
version = "2.0.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2"
|
||||
checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -6309,7 +6311,7 @@ checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6401,7 +6403,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6562,11 +6564,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-appender"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e"
|
||||
checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
@@ -6579,7 +6582,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6596,7 +6599,7 @@ dependencies = [
|
||||
"time",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
"tracing-log 0.1.3",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
@@ -6621,6 +6624,17 @@ dependencies = [
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-serde"
|
||||
version = "0.1.3"
|
||||
@@ -6633,9 +6647,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
|
||||
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
@@ -6648,7 +6662,7 @@ dependencies = [
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
"tracing-log 0.2.0",
|
||||
"tracing-serde",
|
||||
]
|
||||
|
||||
@@ -6995,7 +7009,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -7029,7 +7043,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@@ -7436,7 +7450,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "workspace-template"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -7562,7 +7576,7 @@ checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -57,7 +57,7 @@ custom-protocol = ["tauri/custom-protocol"]
|
||||
# Run the script:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "a455c9de8e6448cec956da5a00ba5cc136ed7274" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "40daff472d026d155fc703aacce899b1c5ab98ea" }
|
||||
# Please use the following script to update collab.
|
||||
# Working directory: frontend
|
||||
#
|
||||
@@ -67,14 +67,14 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "a45
|
||||
# To switch to the local path, run:
|
||||
# scripts/tool/update_collab_source.sh
|
||||
# ⚠️⚠️⚠️️
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -303,12 +303,13 @@
|
||||
"importAppFlowyData": "Daten von einem externen AppFlowy Ordner importieren.",
|
||||
"importAppFlowyDataDescription": "Daten von einem externen AppFlowy Ordner kopieren und in den aktuellen AppFlowy Datenordner importieren.",
|
||||
"importSuccess": "Der AppFlowy Datenordner wurde erfolgreich importiert",
|
||||
"importFailed": "Der AppFlowy Datenordner-Import ist fehlgeschlagen"
|
||||
"importFailed": "Der AppFlowy Datenordner-Import ist fehlgeschlagen",
|
||||
"importGuide": "Für weitere Details, bitte das verlinkte Dokument prüfen"
|
||||
},
|
||||
"notifications": {
|
||||
"enableNotifications": {
|
||||
"label": "Benachrichtigungen aktivieren",
|
||||
"hint": "Ausschalten, um die lokalen Benachrichtigungen abzuschalten"
|
||||
"hint": "Ausschalten, damit die lokalen Benachrichtigungen nicht mehr angezeigt werden"
|
||||
}
|
||||
},
|
||||
"appearance": {
|
||||
@@ -323,8 +324,35 @@
|
||||
"dark": "Dunkles Design",
|
||||
"system": "Automatisch, wie Betriebssystem"
|
||||
},
|
||||
"documentSettings": {
|
||||
"cursorColor": "Dokument Cursor-Farbe",
|
||||
"selectionColor": "Dokument Auswahl-Farbe",
|
||||
"hexEmptyError": "Hex-Farbe darf nicht leer sein",
|
||||
"hexLengthError": "Hex-Wert muss 6 Zeichen lang sein",
|
||||
"hexInvalidError": "Ungültiger Hex-Wert",
|
||||
"opacityEmptyError": "Transparenz darf nicht leer sein",
|
||||
"opacityRangeError": "Transparenz ist ein Wert zwischen 1 und 100",
|
||||
"app": "App",
|
||||
"flowy": "Flowy",
|
||||
"apply": "Apply"
|
||||
},
|
||||
"layoutDirection": {
|
||||
"label": "Layoutrichtung",
|
||||
"hint": "Steuere den Umlauf der Inhalte auf deinem Bildschirm: Von Links nach Rechts oder von Rechts nach Links.",
|
||||
"ltr": "LNR",
|
||||
"rtl": "RNL"
|
||||
},
|
||||
"textDirection": {
|
||||
"label": "Textrichtung",
|
||||
"hint": "Wie soll der Text laufen: von Links nach Rechts oder von Rechts nach Links?",
|
||||
"ltr": "LNR",
|
||||
"rtl": "RNL",
|
||||
"auto": "AUTO",
|
||||
"fallback": "Wie die Layoutrichtung"
|
||||
},
|
||||
"themeUpload": {
|
||||
"button": "Hochladen",
|
||||
"uploadTheme": "Theme hochladen",
|
||||
"description": "Laden Sie Ihr eigenes AppFlowy-Theme über die Schaltfläche unten hoch.",
|
||||
"failure": "Das hochgeladene Theme hatte ein ungültiges Format.",
|
||||
"loading": "Bitte warten Sie, während wir Ihr Theme validieren und hochladen ...",
|
||||
@@ -333,78 +361,123 @@
|
||||
"filePickerDialogTitle": "Wählen Sie eine .flowy_plugin-Datei",
|
||||
"urlUploadFailure": "URL konnte nicht geöffnet werden: {}"
|
||||
},
|
||||
"theme": "Thema",
|
||||
"theme": "Theme",
|
||||
"builtInsLabel": "Integrierte Themes",
|
||||
"pluginsLabel": "Plugins",
|
||||
"lightLabel": "Heller Modus",
|
||||
"darkLabel": "Dunkler Modus"
|
||||
"dateFormat": {
|
||||
"label": "Datumsformat",
|
||||
"local": "Lokal",
|
||||
"us": "US",
|
||||
"iso": "ISO",
|
||||
"friendly": "Freundlich",
|
||||
"dmy": "T/M/J"
|
||||
},
|
||||
"timeFormat": {
|
||||
"label": "Zeitformat",
|
||||
"twelveHour": "12 Stunden",
|
||||
"twentyFourHour": "24 Stunden"
|
||||
},
|
||||
"showNamingDialogWhenCreatingPage": "Zeige Bennenungsfenster wenn eine neue Seite erstellt wird"
|
||||
},
|
||||
"files": {
|
||||
"copy": "Kopieren",
|
||||
"defaultLocation": "Lesen Sie Dateien und Datenspeicherort",
|
||||
"exportData": "Exportieren Sie Ihre Daten",
|
||||
"doubleTapToCopy": "Tippen Sie zweimal, um den Pfad zu kopieren",
|
||||
"restoreLocation": "Stellen Sie den AppFlowy-Standardpfad wieder her",
|
||||
"customizeLocation": "Öffnen Sie einen anderen Ordner",
|
||||
"defaultLocation": "Dateien und Speicherort",
|
||||
"exportData": "Daten exportieren",
|
||||
"doubleTapToCopy": "Zweimal tippen, um den Pfad zu kopieren",
|
||||
"restoreLocation": "AppFlowy-Standardpfad wiederherstellen",
|
||||
"customizeLocation": "Einen anderen Ordner öffnen",
|
||||
"restartApp": "Bitte starten Sie die App neu, damit die Änderungen wirksam werden.",
|
||||
"exportDatabase": "Datenbank exportieren",
|
||||
"selectFiles": "Wählen Sie die Dateien aus, die exportiert werden sollen",
|
||||
"selectAll": "Wählen Sie Alle",
|
||||
"selectFiles": "Dateien auswählen, die exportiert werden sollen",
|
||||
"selectAll": "Alle auswählen",
|
||||
"deselectAll": "Alle abwählen",
|
||||
"createNewFolder": "Einen neuen Ordner erstellen",
|
||||
"createNewFolderDesc": "Teilen Sie uns mit, wo Sie Ihre Daten speichern möchten",
|
||||
"defineWhereYourDataIsStored": "Legen Sie fest, wo Ihre Daten gespeichert werden",
|
||||
"createNewFolderDesc": "Wo sollen die Daten gespeichert werden?",
|
||||
"defineWhereYourDataIsStored": "Wo sind die Daten gespeichert?",
|
||||
"open": "Offen",
|
||||
"openFolder": "Öffnen Sie einen vorhandenen Ordner",
|
||||
"openFolderDesc": "Lesen Sie es und schreiben Sie es in Ihren vorhandenen AppFlowy-Ordner",
|
||||
"openFolder": "Einen vorhandenen Ordner öffnen",
|
||||
"openFolderDesc": "Öffnen und speichern im vorhandenen AppFlowy-Ordner",
|
||||
"folderHintText": "Ordnernamen",
|
||||
"location": "Erstellen eines neuen Ordners",
|
||||
"locationDesc": "Wählen Sie einen Namen für Ihren AppFlowy-Datenordner",
|
||||
"browser": "Durchsuche",
|
||||
"location": "Ein neuen Ordner erstellen",
|
||||
"locationDesc": "Einen Namen für den AppFlowy-Datenordner festlegen",
|
||||
"browser": "Durchsuchen",
|
||||
"create": "Erstellen",
|
||||
"set": "Festlegen",
|
||||
"folderPath": "Pfad zum Speichern Ihres Ordners",
|
||||
"folderPath": "Pfad zum Speichern des Ordners",
|
||||
"locationCannotBeEmpty": "Der Pfad darf nicht leer sein",
|
||||
"pathCopiedSnackbar": "Dateispeicherpfad in Zwischenablage kopiert!",
|
||||
"changeLocationTooltips": "Ändern Sie das Datenverzeichnis",
|
||||
"changeLocationTooltips": "Datenverzeichnis ändern",
|
||||
"change": "Ändern",
|
||||
"openLocationTooltips": "Öffnen Sie ein anderes Datenverzeichnis",
|
||||
"openLocationTooltips": "Win anderes Datenverzeichnis öffnen",
|
||||
"openCurrentDataFolder": "Aktuelles Datenverzeichnis öffnen",
|
||||
"recoverLocationTooltips": "Zurücksetzen auf das Standarddatenverzeichnis von AppFlowy",
|
||||
"exportFileSuccess": "Datei erfolgreich exportieren!",
|
||||
"exportFileFail": "Datei exportieren fehlgeschlagen!",
|
||||
"exportFileSuccess": "Datei erfolgreich exportiert!",
|
||||
"exportFileFail": "Datei-Export fehlgeschlagen!",
|
||||
"export": "Export"
|
||||
},
|
||||
"user": {
|
||||
"name": "Name",
|
||||
"email": "E-Mail",
|
||||
"selectAnIcon": "Wählen Sie ein Symbol aus",
|
||||
"pleaseInputYourOpenAIKey": "Bitte geben Sie Ihren OpenAI-Schlüssel ein"
|
||||
"tooltipSelectIcon": "Symbol auswählen",
|
||||
"selectAnIcon": "Ein Symbol auswählen",
|
||||
"pleaseInputYourOpenAIKey": "Bitte geben Sie Ihren OpenAI-Schlüssel ein",
|
||||
"pleaseInputYourStabilityAIKey": "Bitte geben Sie Ihren Stability AI Schlüssel ein",
|
||||
"clickToLogout": "Klicken, um den aktuellen Nutzer auszulogen"
|
||||
},
|
||||
"shortcuts": {
|
||||
"shortcutsLabel": "Verknüpfungen",
|
||||
"shortcutsLabel": "Tastenkürzel",
|
||||
"command": "Befehl",
|
||||
"keyBinding": "Tastenkombination",
|
||||
"addNewCommand": "Neuen Befehl hinzufügen",
|
||||
"updateShortcutStep": "Drücken Sie die gewünschte Tastenkombination und drücken Sie ENTER",
|
||||
"updateShortcutStep": "Die gewünschte Tastenkombination drücken und mit ENTER bestätigen",
|
||||
"shortcutIsAlreadyUsed": "Diese Verknüpfung wird bereits verwendet für: {conflict}",
|
||||
"resetToDefault": "Zurücksetzen"
|
||||
"resetToDefault": "Zurücksetzen",
|
||||
"couldNotLoadErrorMsg": "Tastenkürzel konnten nicht geladen werden. Bitte nochmal versuchen.",
|
||||
"couldNotSaveErrorMsg": "Tastenkürzel konnten nicht gespeichert werden. Bitte nochmal versuchen."
|
||||
},
|
||||
"mobile": {
|
||||
"personalInfo": "Persönliche Informationen",
|
||||
"username": "Nutzername",
|
||||
"usernameEmptyError": "Der Nutzername darf nicht leer sein",
|
||||
"about": "Über",
|
||||
"pushNotifications": "Push Benachrichtigungen",
|
||||
"support": "Support",
|
||||
"joinDiscord": "Komm zu uns bei Discord",
|
||||
"privacyPolicy": "Datenschutz",
|
||||
"userAgreement": "Nutzungsbedingungen",
|
||||
"userprofileError": "Das Nutzerprofil konnte nicht geladen werden",
|
||||
"userprofileErrorDescription": "Bitte abmelden und wieder anmelden, um zu prüfen ob das Problem weiterhin bestehen bleibt.",
|
||||
"selectLayout": "Layout auswählen",
|
||||
"selectStartingDay": "Ersten Tag auswählen"
|
||||
}
|
||||
},
|
||||
"grid": {
|
||||
"deleteView": "Möchten Sie diese Ansicht wirklich löschen?",
|
||||
"createView": "Neu",
|
||||
"title": {
|
||||
"placeholder": "Unbenannt"
|
||||
},
|
||||
"settings": {
|
||||
"filter": "Filter",
|
||||
"sort": "Sortieren",
|
||||
"sortBy": "Sortiere nach",
|
||||
"properties": "Eigenschaften",
|
||||
"reorderPropertiesTooltip": "Ziehen Sie, um die Eigenschaften neu anzuordnen",
|
||||
"reorderPropertiesTooltip": "Ziehen, um die Eigenschaften neu anzuordnen",
|
||||
"group": "Gruppe",
|
||||
"addFilter": "Filter hinzufügen",
|
||||
"deleteFilter": "Filter löschen",
|
||||
"filterBy": "Filtern nach...",
|
||||
"typeAValue": "Geben Sie einen Wert ein...",
|
||||
"typeAValue": "Einen Wert eingeben...",
|
||||
"layout": "Layout",
|
||||
"databaseLayout": "Layout"
|
||||
"databaseLayout": "Layout",
|
||||
"viewList": "Datenbank-Ansichten",
|
||||
"editView": "Ansicht editieren",
|
||||
"boardSettings": "Board-Einstellungen",
|
||||
"calendarSettings": "Kalender-Einstellungen",
|
||||
"createView": "New Ansicht",
|
||||
"duplicateView": "Ansicht duplizieren",
|
||||
"deleteView": "Anslicht löschen",
|
||||
"numberOfVisibleFields": "{} zeigen"
|
||||
},
|
||||
"textFilter": {
|
||||
"contains": "Enthält",
|
||||
@@ -446,8 +519,19 @@
|
||||
"isEmpty": "Ist leer",
|
||||
"isNotEmpty": "Ist nicht leer"
|
||||
},
|
||||
"dateFilter": {
|
||||
"is": "Ist",
|
||||
"before": "Ist bevor",
|
||||
"after": "Ist nach",
|
||||
"onOrBefore": "Ist am oder bevor",
|
||||
"onOrAfter": "Ist am oder nach",
|
||||
"between": "Ist zwischen",
|
||||
"empty": "Ist leer",
|
||||
"notEmpty": "Ist nicht leer"
|
||||
},
|
||||
"field": {
|
||||
"hide": "Verstecken",
|
||||
"show": "Anzeigen",
|
||||
"insertLeft": "Links einfügen",
|
||||
"insertRight": "Rechts einfügen",
|
||||
"duplicate": "Duplikat",
|
||||
@@ -465,6 +549,7 @@
|
||||
"numberFormat": "Zahlenformat",
|
||||
"dateFormat": "Datumsformat",
|
||||
"includeTime": "Zeit einbeziehen",
|
||||
"isRange": "Enddatum",
|
||||
"dateFormatFriendly": "Monat Tag, Jahr",
|
||||
"dateFormatISO": "Jahr-Monat-Tag",
|
||||
"dateFormatLocal": "Monat/Tag/Jahr",
|
||||
@@ -474,32 +559,64 @@
|
||||
"invalidTimeFormat": "Ungültiges Format",
|
||||
"timeFormatTwelveHour": "12 Stunden",
|
||||
"timeFormatTwentyFourHour": "24 Stunden",
|
||||
"clearDate": "Datum löschen",
|
||||
"dateTime": "Datum und Zeit",
|
||||
"startDateTime": "Beginn Datum und Zeit",
|
||||
"endDateTime": "Ende Datum und Zeit",
|
||||
"failedToLoadDate": "Laden des Datums ist fehlgeschlagen",
|
||||
"selectTime": "Auswahl Zeit",
|
||||
"selectDate": "Auswahl Datum",
|
||||
"visibility": "Sichtbarkeit",
|
||||
"propertyType": "Eigenschaftstyp",
|
||||
"addSelectOption": "Fügen Sie eine Option hinzu",
|
||||
"typeANewOption": "Eine neue Option eingeben",
|
||||
"optionTitle": "Optionen",
|
||||
"addOption": "Option hinzufügen",
|
||||
"editProperty": "Eigenschaft bearbeiten",
|
||||
"newProperty": "Neue Eigenschaft",
|
||||
"deleteFieldPromptMessage": "Bist du dir sicher? Diese Eigenschaft wird gelöscht"
|
||||
"deleteFieldPromptMessage": "Sicher? Diese Eigenschaft wird gelöscht",
|
||||
"newColumn": "Neue Spalte",
|
||||
"format": "Format"
|
||||
},
|
||||
"rowPage": {
|
||||
"newField": "Ein neues Feld hinzufügen",
|
||||
"fieldDragElementTooltip": "Klicken, um das Menü zu öffnen",
|
||||
"showHiddenFields": {
|
||||
"one": "Zeige {count} verstecktes Feld",
|
||||
"many": "Zeige {count} versteckte Felder",
|
||||
"other": "Zeige {count} versteckte Felder"
|
||||
},
|
||||
"hideHiddenFields": {
|
||||
"one": "Blende {count} verstecktes Feld aus",
|
||||
"many": "Blende {count} versteckte Felder aus",
|
||||
"other": "Blende {count} versteckte Felder aus"
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"ascending": "Aufsteigend",
|
||||
"descending": "Absteigend",
|
||||
"addSort": "Sortierung hinzufügen",
|
||||
"deleteSort": "Sortierung löschen"
|
||||
"deleteAllSorts": "Alle Sortierungen entfernen",
|
||||
"addSort": "Sortierung hinzufügen"
|
||||
},
|
||||
"row": {
|
||||
"duplicate": "Duplikat",
|
||||
"delete": "Löschen",
|
||||
"titlePlaceholder": "Unbenannt",
|
||||
"textPlaceholder": "Leer",
|
||||
"copyProperty": "Eigenschaft in die Zwischenablage kopiert",
|
||||
"count": "Zählen",
|
||||
"newRow": "Neue Reihe",
|
||||
"action": "Aktion"
|
||||
"newRow": "Neue Zeile",
|
||||
"action": "Aktion",
|
||||
"add": "Klicken, um unten hinzuzufügen",
|
||||
"drag": "Ziehen, um zu verschieben",
|
||||
"dragAndClick": "Ziehen, um zu verschieben. Klicke, um das Menü zu öffnen",
|
||||
"insertRecordAbove": "Füge Datensatz oben ein",
|
||||
"insertRecordBelow": "Füge Datensatz unten ein"
|
||||
},
|
||||
"selectOption": {
|
||||
"create": "Erstellen",
|
||||
"purpleColor": "Lila",
|
||||
"pinkColor": "Rosa",
|
||||
"pinkColor": "Pink",
|
||||
"lightPinkColor": "Hell-Pink",
|
||||
"orangeColor": "Orange",
|
||||
"yellowColor": "Gelb",
|
||||
@@ -508,48 +625,62 @@
|
||||
"aquaColor": "Aqua",
|
||||
"blueColor": "Blau",
|
||||
"deleteTag": "Tag löschen",
|
||||
"colorPanelTitle": "Farben",
|
||||
"colorPanelTitle": "Farbe",
|
||||
"panelTitle": "Eine Option auswählen oder erstellen",
|
||||
"searchOption": "Suchen Sie nach einer Option"
|
||||
"searchOption": "Nach einer Option suchen",
|
||||
"searchOrCreateOption": "Eine Option suchen oder erstellen...",
|
||||
"createNew": "Neu erstellen",
|
||||
"orSelectOne": "Oder eine Option auswählen",
|
||||
"typeANewOption": "Tippe eine neue Option",
|
||||
"tagName": "Tag-Name"
|
||||
},
|
||||
"checklist": {
|
||||
"addNew": "Fügen Sie einen Artikel hinzu"
|
||||
"taskHint": "Aufgbenbeschreibbung",
|
||||
"addNew": "Fügen Sie einen Artikel hinzu",
|
||||
"submitNewTask": "Erstellen",
|
||||
"hideComplete": "Blende abgeschlossene Aufgaben aus",
|
||||
"showComplete": "Zeige alle Aufgaben"
|
||||
},
|
||||
"menuName": "Netz",
|
||||
"menuName": "Raster",
|
||||
"referencedGridPrefix": "Sicht von"
|
||||
},
|
||||
"document": {
|
||||
"menuName": "Dokumentieren",
|
||||
"menuName": "Dokument",
|
||||
"date": {
|
||||
"timeHintTextInTwelveHour": "13:00 Uhr",
|
||||
"timeHintTextInTwentyFourHour": "13:00"
|
||||
},
|
||||
"slashMenu": {
|
||||
"board": {
|
||||
"selectABoardToLinkTo": "Wählen Sie ein Board aus, zu dem Sie einen Link erstellen möchten",
|
||||
"createANewBoard": "Erstellen Sie ein neues Board"
|
||||
"selectABoardToLinkTo": "Ein Board zum Verknüpfen auswählen",
|
||||
"createANewBoard": "Ein neues Board erstellen"
|
||||
},
|
||||
"grid": {
|
||||
"selectAGridToLinkTo": "Wählen Sie ein Raster zum Verknüpfen aus",
|
||||
"createANewGrid": "Erstellen Sie ein neues Raster"
|
||||
"selectAGridToLinkTo": "Ein Raster zum Verknüpfen auswählen",
|
||||
"createANewGrid": "Ein neues Raster erstellen"
|
||||
},
|
||||
"calendar": {
|
||||
"selectACalendarToLinkTo": "Wählen Sie einen Kalender aus, mit dem Sie eine Verknüpfung erstellen möchten",
|
||||
"createANewCalendar": "Erstellen Sie einen neuen Kalender"
|
||||
"selectACalendarToLinkTo": "Einen Kalender zum Verknüpfen auswählen",
|
||||
"createANewCalendar": "Einen neuen Kalender erstellen"
|
||||
},
|
||||
"document": {
|
||||
"selectADocumentToLinkTo": "Ein Raster zum Verknüpfen auswählen"
|
||||
}
|
||||
},
|
||||
"selectionMenu": {
|
||||
"outline": "Umriss"
|
||||
"outline": "Gliederung",
|
||||
"codeBlock": "Code Block"
|
||||
},
|
||||
"plugins": {
|
||||
"referencedBoard": "Referenziertes Board",
|
||||
"referencedGrid": "Referenziertes Raster",
|
||||
"referencedCalendar": "Referenzierter Kalender",
|
||||
"referencedDocument": "Referenziertes Dokument",
|
||||
"autoGeneratorMenuItemName": "OpenAI-Autor",
|
||||
"autoGeneratorTitleName": "OpenAI: Bitten Sie die KI, etwas zu schreiben ...",
|
||||
"autoGeneratorLearnMore": "Erfahren Sie mehr",
|
||||
"autoGeneratorGenerate": "Generieren",
|
||||
"autoGeneratorHintText": "Fragen Sie OpenAI ...",
|
||||
"autoGeneratorTitleName": "OpenAI: Die KI bitten, etwas zu schreiben ...",
|
||||
"autoGeneratorLearnMore": "Mehr erfahren",
|
||||
"autoGeneratorGenerate": "Erstellen",
|
||||
"autoGeneratorHintText": "OpenAI fragen ...",
|
||||
"autoGeneratorCantGetOpenAIKey": "Der OpenAI-Schlüssel kann nicht abgerufen werden",
|
||||
"autoGeneratorRewrite": "Umschreiben",
|
||||
"smartEdit": "KI-Assistenten",
|
||||
@@ -557,14 +688,20 @@
|
||||
"smartEditFixSpelling": "Korrigiere Rechtschreibung",
|
||||
"warning": "⚠️ KI-Antworten können ungenau oder irreführend sein.",
|
||||
"smartEditSummarize": "Zusammenfassen",
|
||||
"smartEditImproveWriting": "Verbessern Sie das Schreiben",
|
||||
"smartEditImproveWriting": "Das Geschriebene verbessern",
|
||||
"smartEditMakeLonger": "Länger machen",
|
||||
"smartEditCouldNotFetchResult": "Das Ergebnis konnte nicht von OpenAI abgerufen werden",
|
||||
"smartEditCouldNotFetchKey": "Der OpenAI-Schlüssel konnte nicht abgerufen werden",
|
||||
"smartEditDisabled": "Verbinden Sie OpenAI in den Einstellungen",
|
||||
"smartEditDisabled": "OpenAI in den Einstellungen verbinden",
|
||||
"discardResponse": "Möchten Sie die KI-Antworten verwerfen?",
|
||||
"createInlineMathEquation": "Formel erstellen",
|
||||
"fonts": "Schriftarten",
|
||||
"toggleList": "Liste umschalten",
|
||||
"quoteList": "Kursblatt",
|
||||
"numberedList": "Nummerierte Liste",
|
||||
"bulletedList": "Stichpunktliste",
|
||||
"todoList": "Offene Aufgaben Liste",
|
||||
"callout": "Hervorhebung",
|
||||
"cover": {
|
||||
"changeCover": "Titelbild wechseln",
|
||||
"colors": "Farben",
|
||||
@@ -575,23 +712,25 @@
|
||||
"addLocalImage": "Lokales Bild hinzufügen",
|
||||
"invalidImageUrl": "Ungültige Bild-URL",
|
||||
"failedToAddImageToGallery": "Das Bild konnte nicht zur Galerie hinzugefügt werden",
|
||||
"enterImageUrl": "Geben Sie die Bild-URL ein",
|
||||
"enterImageUrl": "Bild-URL eingeben",
|
||||
"add": "Hinzufügen",
|
||||
"back": "Zurück",
|
||||
"saveToGallery": "In der Galerie speichern",
|
||||
"removeIcon": "Symbol entfernen",
|
||||
"pasteImageUrl": "Bild-URL einfügen",
|
||||
"or": "ODER",
|
||||
"pickFromFiles": "Wählen Sie aus Dateien",
|
||||
"pickFromFiles": "Dateien auswählen",
|
||||
"couldNotFetchImage": "Bild konnte nicht abgerufen werden",
|
||||
"imageSavingFailed": "Bildspeicherung fehlgeschlagen",
|
||||
"addIcon": "Symbol hinzufügen",
|
||||
"coverRemoveAlert": "Nach dem Löschen wird es aus der Abdeckung entfernt.",
|
||||
"alertDialogConfirmation": "Bist du dir sicher, dass du weitermachen willst?"
|
||||
"changeIcon": "Symbol wechseln",
|
||||
"coverRemoveAlert": "Nach dem Löschen wird es aus dem Titelbild entfernt.",
|
||||
"alertDialogConfirmation": "Sicher, dass Sie weitermachen wollen?"
|
||||
},
|
||||
"mathEquation": {
|
||||
"name": "Mathematische Formel",
|
||||
"addMathEquation": "Mathematische Formel hinzufügen",
|
||||
"editMathEquation": "Bearbeiten Sie die mathematische Formel"
|
||||
"editMathEquation": "Mathematische Formel bearbeiten"
|
||||
},
|
||||
"optionAction": {
|
||||
"click": "Klicken",
|
||||
@@ -599,45 +738,93 @@
|
||||
"delete": "Löschen",
|
||||
"duplicate": "Duplikat",
|
||||
"turnInto": "Einbiegen in",
|
||||
"moveUp": "Bewegen Sie sich nach oben",
|
||||
"moveDown": "Sich abwärts bewegen",
|
||||
"moveUp": "Nach oben verschieben",
|
||||
"moveDown": "Nach unten verschieben",
|
||||
"color": "Farbe",
|
||||
"align": "Ausrichten",
|
||||
"left": "Links",
|
||||
"center": "Center",
|
||||
"center": "Zentriert",
|
||||
"right": "Rechts",
|
||||
"defaultColor": "Standard"
|
||||
},
|
||||
"image": {
|
||||
"copiedToPasteBoard": "Der Bildlink wurde in die Zwischenablage kopiert"
|
||||
"copiedToPasteBoard": "Der Bildlink wurde in die Zwischenablage kopiert",
|
||||
"addAnImage": "Ein Bild hinzufügen"
|
||||
},
|
||||
"urlPreview": {
|
||||
"copiedToPasteBoard": "Der Link wurde in die Zwischenablage kopiert"
|
||||
},
|
||||
"outline": {
|
||||
"addHeadingToCreateOutline": "Fügen Sie Überschriften hinzu, um ein Inhaltsverzeichnis zu erstellen."
|
||||
},
|
||||
"table": {
|
||||
"addAfter": "Danach einfügen",
|
||||
"addBefore": "Davor einfügen",
|
||||
"delete": "Löschen",
|
||||
"clear": "Inhalt löschen",
|
||||
"duplicate": "Duplikat",
|
||||
"bgColor": "Hintergrundfarbe"
|
||||
},
|
||||
"contextMenu": {
|
||||
"copy": "Kopieren",
|
||||
"cut": "Ausschneiden",
|
||||
"paste": "Einfügen"
|
||||
},
|
||||
"action": "Aktionen",
|
||||
"database": {
|
||||
"selectDataSource": "Datenquelle auswählen",
|
||||
"noDataSource": "Keine Datenquelle",
|
||||
"selectADataSource": "Eine Datenquelle auswählen",
|
||||
"toContinue": "fortfahren",
|
||||
"newDatabase": "Neue Datenbank",
|
||||
"linkToDatabase": "Verknüpfung zur Datenbank"
|
||||
}
|
||||
},
|
||||
"textBlock": {
|
||||
"placeholder": "Geben Sie „/“ für Befehle ein"
|
||||
"placeholder": "Geben Sie „/“ für Inhaltsblöcke ein"
|
||||
},
|
||||
"title": {
|
||||
"placeholder": "Ohne Titel"
|
||||
},
|
||||
"imageBlock": {
|
||||
"placeholder": "Klicken Sie, um ein Bild hinzuzufügen",
|
||||
"placeholder": "Klicken, um ein Bild hinzuzufügen",
|
||||
"upload": {
|
||||
"label": "Hochladen",
|
||||
"placeholder": "Klicken Sie, um das Bild hochzuladen"
|
||||
"placeholder": "Klicken, um das Bild hochzuladen"
|
||||
},
|
||||
"url": {
|
||||
"label": "Bild URL",
|
||||
"placeholder": "Geben Sie die Bild-URL ein"
|
||||
"placeholder": "Bild-URL eingeben"
|
||||
},
|
||||
"ai": {
|
||||
"label": "Bild mit OpenAI erstellen",
|
||||
"placeholder": "Bitte den Prompt für OpenAI eingeben, um ein Bild zu erstellen"
|
||||
},
|
||||
"stability_ai": {
|
||||
"label": "Bild mit Stability AI erstellen",
|
||||
"placeholder": "Bitte den Prompt für Stability AI eingeben, um ein Bild zu erstellen"
|
||||
},
|
||||
"support": "Die Bildgrößenbeschränkung beträgt 5 MB. Unterstützte Formate: JPEG, PNG, GIF, SVG",
|
||||
"error": {
|
||||
"invalidImage": "Ungültiges Bild",
|
||||
"invalidImageSize": "Die Bildgröße muss weniger als 5 MB betragen",
|
||||
"invalidImageSize": "Die Bildgröße muss kleiner als 5 MB sein",
|
||||
"invalidImageFormat": "Das Bildformat wird nicht unterstützt. Unterstützte Formate: JPEG, PNG, GIF, SVG",
|
||||
"invalidImageUrl": "Ungültige Bild-URL"
|
||||
}
|
||||
},
|
||||
"embedLink": {
|
||||
"label": "Eingebetteter Link",
|
||||
"placeholder": "Bild-Link einfügen oder eintippen"
|
||||
},
|
||||
"unsplash": {
|
||||
"label": "Unsplash"
|
||||
},
|
||||
"searchForAnImage": "Nach einem Bild suchen",
|
||||
"pleaseInputYourOpenAIKey": "biitte den OpenAI Schlüssel in der Einstellungsseite eingeben",
|
||||
"pleaseInputYourStabilityAIKey": "biitte den Stability AI Schlüssel in der Einstellungsseite eingeben",
|
||||
"saveImageToGallery": "Bild speichern",
|
||||
"failedToAddImageToGallery": "Das Bild konnte nicht zur Galerie hinzugefügt werden",
|
||||
"successToAddImageToGallery": "Das Bild wurde zur Galerie hinzugefügt werden",
|
||||
"unableToLoadImage": "Das Bild konnte nicht geladen werden"
|
||||
},
|
||||
"codeBlock": {
|
||||
"language": {
|
||||
@@ -646,23 +833,74 @@
|
||||
}
|
||||
},
|
||||
"inlineLink": {
|
||||
"placeholder": "Fügen Sie einen Link ein oder geben Sie ihn ein",
|
||||
"placeholder": "Link einfügen oder eintippen",
|
||||
"openInNewTab": "Im neuen Tab öffnen",
|
||||
"copyLink": "Link kopieren",
|
||||
"removeLink": "Link entfernen",
|
||||
"url": {
|
||||
"label": "URL verknüpfen",
|
||||
"placeholder": "Geben Sie die Link-URL ein"
|
||||
"placeholder": "Link-URL eingeben"
|
||||
},
|
||||
"title": {
|
||||
"label": "Linktitel",
|
||||
"placeholder": "Geben Sie den Linktitel ein"
|
||||
"placeholder": "Linktitel eingeben"
|
||||
}
|
||||
},
|
||||
"mention": {
|
||||
"placeholder": "Eine Person, Seite oder Datum erwähnen...",
|
||||
"page": {
|
||||
"label": "Link zur Seite",
|
||||
"tooltip": "Klicken, um die Seite zu öffnen"
|
||||
}
|
||||
},
|
||||
"toolbar": {
|
||||
"resetToDefaultFont": "Auf den Standard zurücksetzen"
|
||||
},
|
||||
"errorBlock": {
|
||||
"theBlockIsNotSupported": "Die aktuelle Version unterstützt diesen Block nicht.",
|
||||
"blockContentHasBeenCopied": "Der Blockinhalt wurde kopiert."
|
||||
}
|
||||
},
|
||||
"board": {
|
||||
"column": {
|
||||
"createNewCard": "Neu"
|
||||
"createNewCard": "Neu",
|
||||
"renameGroupTooltip": "Drücken, um die Gruppe umzubenennen",
|
||||
"createNewColumn": "Eine neue Gruppe hinzufügen",
|
||||
"addToColumnTopTooltip": "Eine neue Karte am oberen Ende hinzufügen",
|
||||
"addToColumnBottomTooltip": "Eine neue Karte am unteren Ende hinzufügen",
|
||||
"renameColumn": "Umbenennen",
|
||||
"hideColumn": "Verstecken",
|
||||
"groupActions": "Gruppenaktion",
|
||||
"newGroup": "Neue Gruppe",
|
||||
"deleteColumn": "Löschen",
|
||||
"deleteColumnConfirmation": "Das wird diese Gruppe und alle enthaltenen Karten löschen.\nSicher, dass Sie fortsetzen möchte?"
|
||||
},
|
||||
"hiddenGroupSection": {
|
||||
"sectionTitle": "Versteckte Gruppen",
|
||||
"collapseTooltip": "Verstecke die versteckten Gruppen",
|
||||
"expandTooltip": "Zeige die versteckten Gruppen"
|
||||
},
|
||||
"cardDetail": "Kartendetail",
|
||||
"cardActions": "Kartenaktionen",
|
||||
"cardDuplicated": "Karte wurde dupliziert",
|
||||
"cardDeleted": "Karte wurde gelöscht",
|
||||
"showOnCard": "Zeige das Kartendetail",
|
||||
"setting": "Einstellung",
|
||||
"propertyName": "Eigenschaftname",
|
||||
"menuName": "Board",
|
||||
"referencedBoardPrefix": "Sicht von"
|
||||
"showUngrouped": "Zeige nichtgruppierte Elemente",
|
||||
"ungroupedButtonText": "Nichtgruppiert",
|
||||
"ungroupedButtonTooltip": "Enthält Karten, die keiner Gruppe zugeordnet sind",
|
||||
"ungroupedItemsTitle": "Klicke, um dem Board hinzuzufügen",
|
||||
"groupBy": "Gruppiert nach",
|
||||
"referencedBoardPrefix": "Sicht von",
|
||||
"notesTooltip": "Notizen vorhanden",
|
||||
"mobile": {
|
||||
"editURL": "Bearbeite URL",
|
||||
"unhideGroup": "Zeige die Gruppe",
|
||||
"unhideGroupContent": "Sicher, dass diese Gruppe auf dem Board angezeigt werden soll?",
|
||||
"faildToLoad": "Board Sicht konnte nicht geladen werden"
|
||||
}
|
||||
},
|
||||
"calendar": {
|
||||
"menuName": "Kalender",
|
||||
|
||||
Generated
+70
-55
@@ -125,7 +125,7 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
[[package]]
|
||||
name = "app-error"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@@ -204,7 +204,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -215,7 +215,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -413,7 +413,7 @@ dependencies = [
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -670,7 +670,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -736,7 +736,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -745,6 +745,7 @@ dependencies = [
|
||||
"parking_lot",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
@@ -755,7 +756,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-database"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -784,7 +785,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-document"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@@ -802,7 +803,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -816,7 +817,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-folder"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@@ -853,7 +854,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-persistence"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -874,7 +875,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-plugins"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -900,7 +901,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-user"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=7d7f53250f7a8297c69e2cdc72e441f5469eaf11#7d7f53250f7a8297c69e2cdc72e441f5469eaf11"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=b036feb396aa6a1dbbab9589bd032e29db8ab024#b036feb396aa6a1dbbab9589bd032e29db8ab024"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@@ -1132,7 +1133,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1249,10 +1250,11 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
"bincode",
|
||||
"chrono",
|
||||
"collab-entity",
|
||||
"serde",
|
||||
@@ -1365,7 +1367,7 @@ dependencies = [
|
||||
"diesel_table_macro_syntax",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1385,7 +1387,7 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5"
|
||||
dependencies = [
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1532,6 +1534,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"assert-json-diff",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"collab",
|
||||
"collab-database",
|
||||
"collab-document",
|
||||
@@ -2300,7 +2303,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2450,7 +2453,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@@ -2466,7 +2469,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -2827,7 +2830,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@@ -3392,7 +3395,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3572,7 +3575,7 @@ dependencies = [
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3700,7 +3703,7 @@ dependencies = [
|
||||
"phf_shared 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3747,7 +3750,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3837,7 +3840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8832c0f9be7e3cae60727e6256cfd2cd3c3e2b6cd5dad4190ecb2fd658c9030b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3881,9 +3884,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.66"
|
||||
version = "1.0.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
|
||||
checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -3915,7 +3918,7 @@ dependencies = [
|
||||
"prost",
|
||||
"prost-types",
|
||||
"regex",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
"tempfile",
|
||||
"which",
|
||||
]
|
||||
@@ -3930,7 +3933,7 @@ dependencies = [
|
||||
"itertools 0.11.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4099,9 +4102,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -4266,7 +4269,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "realtime-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@@ -4288,7 +4291,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "realtime-protocol"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@@ -4838,7 +4841,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4854,13 +4857,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.16"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00"
|
||||
checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4946,7 +4949,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared_entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@@ -5262,7 +5265,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5284,9 +5287,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.31"
|
||||
version = "2.0.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398"
|
||||
checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -5397,7 +5400,7 @@ checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5502,7 +5505,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5718,11 +5721,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-appender"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e"
|
||||
checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
@@ -5735,7 +5739,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5752,7 +5756,7 @@ dependencies = [
|
||||
"time",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
"tracing-log 0.1.3",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
@@ -5777,6 +5781,17 @@ dependencies = [
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-serde"
|
||||
version = "0.1.3"
|
||||
@@ -5789,9 +5804,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.17"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
|
||||
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
@@ -5804,7 +5819,7 @@ dependencies = [
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
"tracing-log 0.2.0",
|
||||
"tracing-serde",
|
||||
]
|
||||
|
||||
@@ -6127,7 +6142,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -6161,7 +6176,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@@ -6351,7 +6366,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "workspace-template"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=a455c9de8e6448cec956da5a00ba5cc136ed7274#a455c9de8e6448cec956da5a00ba5cc136ed7274"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=40daff472d026d155fc703aacce899b1c5ab98ea#40daff472d026d155fc703aacce899b1c5ab98ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -6409,7 +6424,7 @@ checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.31",
|
||||
"syn 2.0.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -107,7 +107,7 @@ incremental = false
|
||||
# Run the script:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "a455c9de8e6448cec956da5a00ba5cc136ed7274" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "40daff472d026d155fc703aacce899b1c5ab98ea" }
|
||||
# Please use the following script to update collab.
|
||||
# Working directory: frontend
|
||||
#
|
||||
@@ -117,11 +117,11 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "a45
|
||||
# To switch to the local path, run:
|
||||
# scripts/tool/update_collab_source.sh
|
||||
# ⚠️⚠️⚠️️
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "7d7f53250f7a8297c69e2cdc72e441f5469eaf11" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
collab-persistence = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "b036feb396aa6a1dbbab9589bd032e29db8ab024" }
|
||||
@@ -48,6 +48,7 @@ tempdir = "0.3.7"
|
||||
uuid.workspace = true
|
||||
assert-json-diff = "2.0.2"
|
||||
tokio-postgres = { version = "0.7.8" }
|
||||
chrono = "0.4.31"
|
||||
zip = "0.6.6"
|
||||
|
||||
[features]
|
||||
|
||||
@@ -64,17 +64,6 @@ impl EventIntegrationTest {
|
||||
.items
|
||||
}
|
||||
|
||||
pub async fn get_views(&self, parent_view_id: &str) -> ViewPB {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(FolderEvent::GetView)
|
||||
.payload(ViewIdPB {
|
||||
value: parent_view_id.to_string(),
|
||||
})
|
||||
.async_send()
|
||||
.await
|
||||
.parse::<ViewPB>()
|
||||
}
|
||||
|
||||
pub async fn get_trash(&self) -> RepeatedTrashPB {
|
||||
EventBuilder::new(self.clone())
|
||||
.event(FolderEvent::ListTrashItems)
|
||||
|
||||
@@ -53,10 +53,8 @@ impl EventIntegrationTest {
|
||||
let path = path_buf.to_str().unwrap().to_string();
|
||||
let device_id = uuid::Uuid::new_v4().to_string();
|
||||
|
||||
let level = "info";
|
||||
std::env::set_var("RUST_LOG", level);
|
||||
let config = AppFlowyCoreConfig::new(path.clone(), path, device_id, name).log_filter(
|
||||
level,
|
||||
"trace",
|
||||
vec![
|
||||
"flowy_test".to_string(),
|
||||
"tokio".to_string(),
|
||||
@@ -79,27 +77,16 @@ impl EventIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_appflowy_cloud_server(&self) -> Arc<dyn AppFlowyServer> {
|
||||
self
|
||||
.appflowy_core
|
||||
.server_provider
|
||||
.get_appflowy_cloud_server()
|
||||
.unwrap()
|
||||
pub fn get_server(&self) -> Arc<dyn AppFlowyServer> {
|
||||
self.appflowy_core.server_provider.get_server().unwrap()
|
||||
}
|
||||
|
||||
pub async fn wait_ws_connected(&self) {
|
||||
if self
|
||||
.get_appflowy_cloud_server()
|
||||
.get_ws_state()
|
||||
.is_connected()
|
||||
{
|
||||
if self.get_server().get_ws_state().is_connected() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut ws_state = self
|
||||
.get_appflowy_cloud_server()
|
||||
.subscribe_ws_state()
|
||||
.unwrap();
|
||||
let mut ws_state = self.get_server().subscribe_ws_state().unwrap();
|
||||
loop {
|
||||
select! {
|
||||
_ = sleep(Duration::from_secs(20)) => {
|
||||
@@ -121,7 +108,7 @@ impl EventIntegrationTest {
|
||||
oid: &str,
|
||||
collay_type: CollabType,
|
||||
) -> Result<CollabDocState, FlowyError> {
|
||||
let server = self.server_provider.get_appflowy_cloud_server().unwrap();
|
||||
let server = self.server_provider.get_server().unwrap();
|
||||
let workspace_id = self.get_current_workspace().await.id;
|
||||
let uid = self.get_user_profile().await?.id;
|
||||
let doc_state = server
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -24,12 +24,12 @@ async fn reading_039_anon_user_data_test() {
|
||||
);
|
||||
assert_eq!(first_level_views[0].name, "Document1".to_string());
|
||||
|
||||
let second_level_views = test.get_views(&first_level_views[0].id).await.child_views;
|
||||
let second_level_views = test.get_view(&first_level_views[0].id).await.child_views;
|
||||
assert_eq!(second_level_views.len(), 1);
|
||||
assert_eq!(second_level_views[0].name, "Document2".to_string());
|
||||
|
||||
// In the 039_local, there is only one view of the workspaces child
|
||||
let third_level_views = test.get_views(&second_level_views[0].id).await.child_views;
|
||||
let third_level_views = test.get_view(&second_level_views[0].id).await.child_views;
|
||||
assert_eq!(third_level_views.len(), 2);
|
||||
assert_eq!(third_level_views[0].name, "Grid1".to_string());
|
||||
assert_eq!(third_level_views[1].name, "Grid2".to_string());
|
||||
@@ -62,11 +62,11 @@ async fn migrate_anon_user_data_to_af_cloud_test() {
|
||||
|
||||
let anon_first_level_views = test.get_all_workspace_views().await;
|
||||
let anon_second_level_views = test
|
||||
.get_views(&anon_first_level_views[0].id)
|
||||
.get_view(&anon_first_level_views[0].id)
|
||||
.await
|
||||
.child_views;
|
||||
let anon_third_level_views = test
|
||||
.get_views(&anon_second_level_views[0].id)
|
||||
.get_view(&anon_second_level_views[0].id)
|
||||
.await
|
||||
.child_views;
|
||||
|
||||
@@ -82,12 +82,12 @@ async fn migrate_anon_user_data_to_af_cloud_test() {
|
||||
|
||||
println!("user first level views: {:?}", user_first_level_views);
|
||||
let user_second_level_views = test
|
||||
.get_views(&user_first_level_views[0].id)
|
||||
.get_view(&user_first_level_views[0].id)
|
||||
.await
|
||||
.child_views;
|
||||
println!("user second level views: {:?}", user_second_level_views);
|
||||
let user_third_level_views = test
|
||||
.get_views(&user_second_level_views[0].id)
|
||||
.get_view(&user_second_level_views[0].id)
|
||||
.await
|
||||
.child_views;
|
||||
println!("user third level views: {:?}", user_third_level_views);
|
||||
|
||||
+64
-11
@@ -1,5 +1,6 @@
|
||||
use crate::util::unzip_history_user_db;
|
||||
use assert_json_diff::assert_json_include;
|
||||
use collab_database::rows::database_row_document_id_from_row_id;
|
||||
use collab_entity::CollabType;
|
||||
use event_integration::user_event::user_localhost_af_cloud;
|
||||
use event_integration::{document_data_from_document_doc_state, EventIntegrationTest};
|
||||
@@ -45,22 +46,33 @@ async fn import_appflowy_data_folder_into_new_view_test() {
|
||||
assert_eq!(views.len(), 2);
|
||||
assert_eq!(views[1].name, import_container_name);
|
||||
|
||||
let local_child_views = test.get_views(&views[1].id).await.child_views;
|
||||
// the 040_local should be an empty document, so try to get the document data
|
||||
let _ = test.get_document_data(&views[1].id).await;
|
||||
|
||||
let local_child_views = test.get_view(&views[1].id).await.child_views;
|
||||
assert_eq!(local_child_views.len(), 1);
|
||||
assert_eq!(local_child_views[0].name, "Document1");
|
||||
|
||||
let document1_child_views = test.get_views(&local_child_views[0].id).await.child_views;
|
||||
let document1_child_views = test.get_view(&local_child_views[0].id).await.child_views;
|
||||
assert_eq!(document1_child_views.len(), 1);
|
||||
assert_eq!(document1_child_views[0].name, "Document2");
|
||||
|
||||
let document2_child_views = test
|
||||
.get_views(&document1_child_views[0].id)
|
||||
.get_view(&document1_child_views[0].id)
|
||||
.await
|
||||
.child_views;
|
||||
assert_eq!(document2_child_views.len(), 2);
|
||||
assert_eq!(document2_child_views[0].name, "Grid1");
|
||||
assert_eq!(document2_child_views[1].name, "Grid2");
|
||||
|
||||
let rows = test.get_database(&document2_child_views[1].id).await.rows;
|
||||
assert_eq!(rows.len(), 3);
|
||||
|
||||
// In the 040_local, only the first row has a document with content
|
||||
let row_document_id = database_row_document_id_from_row_id(&rows[0].id);
|
||||
let row_document_data = test.get_document_data(&row_document_id).await;
|
||||
assert_json_include!(actual: json!(row_document_data), expected: expected_row_doc_json());
|
||||
|
||||
drop(cleaner);
|
||||
}
|
||||
|
||||
@@ -97,12 +109,12 @@ async fn import_appflowy_data_folder_into_current_workspace_test() {
|
||||
assert_eq!(views.len(), 2);
|
||||
assert_eq!(views[1].name, "Document1");
|
||||
|
||||
let document_1_child_views = test.get_views(&views[1].id).await.child_views;
|
||||
let document_1_child_views = test.get_view(&views[1].id).await.child_views;
|
||||
assert_eq!(document_1_child_views.len(), 1);
|
||||
assert_eq!(document_1_child_views[0].name, "Document2");
|
||||
|
||||
let document2_child_views = test
|
||||
.get_views(&document_1_child_views[0].id)
|
||||
.get_view(&document_1_child_views[0].id)
|
||||
.await
|
||||
.child_views;
|
||||
assert_eq!(document2_child_views.len(), 2);
|
||||
@@ -216,14 +228,12 @@ async fn assert_040_local_2_import_content(test: &EventIntegrationTest, view_id:
|
||||
// Doc3_grid_1
|
||||
// Doc3_grid_2
|
||||
// Doc3_calendar_1
|
||||
let _local_2_child_views = test.get_views(view_id).await.child_views;
|
||||
let _local_2_child_views = test.get_view(view_id).await.child_views;
|
||||
assert_eq!(_local_2_child_views.len(), 1);
|
||||
assert_eq!(_local_2_child_views[0].name, "Getting started");
|
||||
|
||||
let local_2_getting_started_child_views = test
|
||||
.get_views(&_local_2_child_views[0].id)
|
||||
.await
|
||||
.child_views;
|
||||
let local_2_getting_started_child_views =
|
||||
test.get_view(&_local_2_child_views[0].id).await.child_views;
|
||||
|
||||
// Check doc 1 local content
|
||||
let doc_1 = local_2_getting_started_child_views[0].clone();
|
||||
@@ -258,7 +268,7 @@ async fn assert_040_local_2_import_content(test: &EventIntegrationTest, view_id:
|
||||
assert_eq!(local_2_getting_started_child_views[3].name, "Doc3");
|
||||
|
||||
let doc_3_child_views = test
|
||||
.get_views(&local_2_getting_started_child_views[3].id)
|
||||
.get_view(&local_2_getting_started_child_views[3].id)
|
||||
.await
|
||||
.child_views;
|
||||
assert_eq!(doc_3_child_views.len(), 3);
|
||||
@@ -372,3 +382,46 @@ fn expected_doc_2_json() -> Value {
|
||||
"page_id": "ZVogdaK9yO"
|
||||
})
|
||||
}
|
||||
|
||||
fn expected_row_doc_json() -> Value {
|
||||
json!( {
|
||||
"blocks": {
|
||||
"eSBQHZ28e0": {
|
||||
"children": "RbLAaE9UDJ",
|
||||
"data": {},
|
||||
"external_id": null,
|
||||
"external_type": null,
|
||||
"id": "eSBQHZ28e0",
|
||||
"parent": "",
|
||||
"ty": "page"
|
||||
},
|
||||
"eUIL6qjgj3": {
|
||||
"children": "fUnGRcvPEA",
|
||||
"data": {
|
||||
"delta": [
|
||||
{
|
||||
"insert": "document in database row"
|
||||
}
|
||||
]
|
||||
},
|
||||
"external_id": "-DliEUjHr2",
|
||||
"external_type": "text",
|
||||
"id": "eUIL6qjgj3",
|
||||
"parent": "eSBQHZ28e0",
|
||||
"ty": "paragraph"
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"children_map": {
|
||||
"RbLAaE9UDJ": [
|
||||
"eUIL6qjgj3"
|
||||
],
|
||||
"fUnGRcvPEA": []
|
||||
},
|
||||
"text_map": {
|
||||
"-DliEUjHr2": "[{\"insert\":\"document in database row\"}]"
|
||||
}
|
||||
},
|
||||
"page_id": "eSBQHZ28e0"
|
||||
})
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
use event_integration::EventIntegrationTest;
|
||||
use flowy_core::DEFAULT_NAME;
|
||||
use flowy_folder::entities::ViewLayoutPB;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::util::unzip_history_user_db;
|
||||
|
||||
@@ -26,7 +27,7 @@ async fn migrate_020_historical_empty_document_test() {
|
||||
assert!(!data.meta.children_map.is_empty());
|
||||
|
||||
// Check the child views of the parent view
|
||||
let child_views = test.get_views(&parent_view.id).await.child_views;
|
||||
let child_views = test.get_view(&parent_view.id).await.child_views;
|
||||
assert_eq!(child_views.len(), 4);
|
||||
assert_eq!(child_views[0].layout, ViewLayoutPB::Document);
|
||||
assert_eq!(child_views[1].layout, ViewLayoutPB::Grid);
|
||||
@@ -55,8 +56,127 @@ async fn migrate_036_fav_v1_workspace_array_test() {
|
||||
assert_eq!(views[0].name, "root page");
|
||||
assert_eq!(views[1].name, "⭐\u{fe0f} Getting started");
|
||||
|
||||
let views = test.get_views(&views[1].id).await;
|
||||
let views = test.get_view(&views[1].id).await;
|
||||
assert_eq!(views.child_views.len(), 3);
|
||||
assert!(views.child_views[2].is_favorite);
|
||||
drop(cleaner);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn migrate_038_trash_test() {
|
||||
// Used to test migration: WorkspaceTrashMapToSectionMigration
|
||||
let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "038_local").unwrap();
|
||||
// Getting started
|
||||
// Document1
|
||||
// Document2(deleted)
|
||||
// Document3(deleted)
|
||||
// Document
|
||||
// Document4(deleted)
|
||||
// Document5
|
||||
|
||||
let test =
|
||||
EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await;
|
||||
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views.len(), 2);
|
||||
assert_eq!(views[0].name, "Getting started");
|
||||
assert_eq!(views[1].name, "Documents");
|
||||
|
||||
let get_started_child_views = test.get_view(&views[0].id).await.child_views;
|
||||
assert_eq!(get_started_child_views.len(), 1);
|
||||
assert_eq!(get_started_child_views[0].name, "Document1");
|
||||
|
||||
let get_started_child_views = test.get_view(&views[1].id).await.child_views;
|
||||
assert_eq!(get_started_child_views.len(), 1);
|
||||
assert_eq!(get_started_child_views[0].name, "Document5");
|
||||
|
||||
let trash_items = test.get_trash().await.items;
|
||||
assert_eq!(trash_items.len(), 3);
|
||||
assert_eq!(trash_items[0].name, "Document3");
|
||||
assert_eq!(trash_items[1].name, "Document2");
|
||||
assert_eq!(trash_items[2].name, "Document4");
|
||||
|
||||
drop(cleaner);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn migrate_038_trash_test2() {
|
||||
// Used to test migration: WorkspaceTrashMapToSectionMigration
|
||||
let (cleaner, user_db_path) =
|
||||
unzip_history_user_db("./tests/asset", "038_document_with_grid").unwrap();
|
||||
// Getting started
|
||||
// document
|
||||
// grid
|
||||
// board
|
||||
|
||||
let test =
|
||||
EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await;
|
||||
|
||||
let views = test.get_all_workspace_views().await;
|
||||
assert_eq!(views.len(), 1);
|
||||
assert_eq!(views[0].name, "Getting started");
|
||||
|
||||
let views = test.get_view(&views[0].id).await.child_views;
|
||||
assert_eq!(views[0].name, "document");
|
||||
|
||||
let views = test.get_view(&views[0].id).await.child_views;
|
||||
assert_eq!(views[0].name, "grid");
|
||||
|
||||
let views = test.get_view(&views[0].id).await.child_views;
|
||||
assert_eq!(views[0].name, "board");
|
||||
|
||||
drop(cleaner);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn collab_db_backup_test() {
|
||||
// Used to test migration: WorkspaceTrashMapToSectionMigration
|
||||
let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "038_local").unwrap();
|
||||
let test =
|
||||
EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await;
|
||||
|
||||
let uid = test.get_user_profile().await.unwrap().id;
|
||||
let backups = test.user_manager.get_collab_backup_list(uid);
|
||||
|
||||
assert_eq!(backups.len(), 1);
|
||||
assert_eq!(
|
||||
backups[0],
|
||||
format!("collab_db_{}", chrono::Local::now().format("%Y%m%d"))
|
||||
);
|
||||
drop(cleaner);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn delete_outdated_collab_db_backup_test() {
|
||||
// Used to test migration: WorkspaceTrashMapToSectionMigration
|
||||
let (cleaner, user_db_path) =
|
||||
unzip_history_user_db("./tests/asset", "040_collab_backups").unwrap();
|
||||
let test =
|
||||
EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await;
|
||||
|
||||
let uid = test.get_user_profile().await.unwrap().id;
|
||||
// saving the backup is a background task, so we need to wait for it to finish
|
||||
// 2 seconds should be enough for the background task to finish
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
let backups = test.user_manager.get_collab_backup_list(uid);
|
||||
|
||||
if backups.len() != 10 {
|
||||
dbg!("backups: {:?}", backups.clone());
|
||||
}
|
||||
|
||||
assert_eq!(backups.len(), 10);
|
||||
assert_eq!(backups[0], "collab_db_0.4.0_20231202");
|
||||
assert_eq!(backups[1], "collab_db_0.4.0_20231203");
|
||||
assert_eq!(backups[2], "collab_db_0.4.0_20231204");
|
||||
assert_eq!(backups[3], "collab_db_0.4.0_20231205");
|
||||
assert_eq!(backups[4], "collab_db_0.4.0_20231206");
|
||||
assert_eq!(backups[5], "collab_db_0.4.0_20231207");
|
||||
assert_eq!(backups[6], "collab_db_0.4.0_20231208");
|
||||
assert_eq!(backups[7], "collab_db_0.4.0_20231209");
|
||||
assert_eq!(backups[8], "collab_db_0.4.0_20231210");
|
||||
assert_eq!(
|
||||
backups[9],
|
||||
format!("collab_db_{}", chrono::Local::now().format("%Y%m%d"))
|
||||
);
|
||||
drop(cleaner);
|
||||
}
|
||||
@@ -27,7 +27,7 @@ use flowy_user::entities::{AuthenticatorPB, UpdateUserProfilePayloadPB};
|
||||
use flowy_user::errors::FlowyError;
|
||||
|
||||
use flowy_user::event_map::UserEvent::*;
|
||||
use flowy_user_deps::cloud::{UserCloudService, UserCloudServiceProvider};
|
||||
use flowy_user_deps::cloud::UserCloudService;
|
||||
use flowy_user_deps::entities::Authenticator;
|
||||
|
||||
pub fn get_supabase_config() -> Option<SupabaseConfiguration> {
|
||||
|
||||
@@ -41,7 +41,7 @@ impl fmt::Debug for AppFlowyCoreConfig {
|
||||
}
|
||||
}
|
||||
|
||||
fn migrate_local_version_data_folder(root: &str, url: &str) -> String {
|
||||
fn make_user_data_folder(root: &str, url: &str) -> String {
|
||||
// Isolate the user data folder by using the base url of AppFlowy cloud. This is to avoid
|
||||
// the user data folder being shared by different AppFlowy cloud.
|
||||
let storage_path = if !url.is_empty() {
|
||||
@@ -82,10 +82,10 @@ impl AppFlowyCoreConfig {
|
||||
let supabase_config = SupabaseConfiguration::from_env().ok();
|
||||
match &supabase_config {
|
||||
None => custom_application_path,
|
||||
Some(config) => migrate_local_version_data_folder(&custom_application_path, &config.url),
|
||||
Some(config) => make_user_data_folder(&custom_application_path, &config.url),
|
||||
}
|
||||
},
|
||||
Some(config) => migrate_local_version_data_folder(&custom_application_path, &config.base_url),
|
||||
Some(config) => make_user_data_folder(&custom_application_path, &config.base_url),
|
||||
};
|
||||
|
||||
AppFlowyCoreConfig {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
use collab::core::collab_plugin::EncodedCollabV1;
|
||||
use collab::core::collab_plugin::EncodedCollab;
|
||||
use collab_plugins::local_storage::rocksdb::RocksdbBackup;
|
||||
use diesel::SqliteConnection;
|
||||
|
||||
@@ -22,12 +22,7 @@ impl RocksdbBackupImpl {
|
||||
}
|
||||
|
||||
impl RocksdbBackup for RocksdbBackupImpl {
|
||||
fn save_doc(
|
||||
&self,
|
||||
uid: i64,
|
||||
object_id: &str,
|
||||
data: EncodedCollabV1,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
fn save_doc(&self, uid: i64, object_id: &str, data: EncodedCollab) -> Result<(), anyhow::Error> {
|
||||
let row = RocksdbBackupRow {
|
||||
object_id: object_id.to_string(),
|
||||
timestamp: timestamp(),
|
||||
@@ -40,7 +35,7 @@ impl RocksdbBackup for RocksdbBackupImpl {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_doc(&self, uid: i64, object_id: &str) -> Result<EncodedCollabV1, anyhow::Error> {
|
||||
fn get_doc(&self, uid: i64, object_id: &str) -> Result<EncodedCollab, anyhow::Error> {
|
||||
let sql = dsl::rocksdb_backup
|
||||
.filter(dsl::object_id.eq(object_id))
|
||||
.into_boxed();
|
||||
@@ -50,7 +45,7 @@ impl RocksdbBackup for RocksdbBackupImpl {
|
||||
.get()
|
||||
.map(|mut conn| sql.first::<RocksdbBackupRow>(&mut *conn))??;
|
||||
|
||||
Ok(EncodedCollabV1::decode_from_bytes(&row.data)?)
|
||||
Ok(EncodedCollab::decode_from_bytes(&row.data)?)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -238,8 +238,16 @@ impl FolderOperationHandler for DocumentFolderOperation {
|
||||
let view_id = view_id.to_string();
|
||||
let manager = self.0.clone();
|
||||
FutureResult::new(async move {
|
||||
manager.create_document(user_id, &view_id, None).await?;
|
||||
Ok(())
|
||||
match manager.create_document(user_id, &view_id, None).await {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
if err.is_already_exists() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -368,8 +376,17 @@ impl FolderOperationHandler for DatabaseFolderOperation {
|
||||
},
|
||||
};
|
||||
FutureResult::new(async move {
|
||||
database_manager.create_database_with_params(data).await?;
|
||||
Ok(())
|
||||
let result = database_manager.create_database_with_params(data).await;
|
||||
match result {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
if err.is_already_exists() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ pub(crate) fn create_log_filter(level: String, with_crates: Vec<String>) -> Stri
|
||||
.map(|crate_name| format!("{}={}", crate_name, level))
|
||||
.collect::<Vec<String>>();
|
||||
filters.push(format!("flowy_core={}", level));
|
||||
filters.push(format!("flowy_folder2={}", level));
|
||||
filters.push(format!("flowy_folder={}", level));
|
||||
filters.push(format!("collab_sync={}", level));
|
||||
filters.push(format!("collab_folder={}", level));
|
||||
filters.push(format!("collab_persistence={}", level));
|
||||
@@ -28,7 +28,7 @@ pub(crate) fn create_log_filter(level: String, with_crates: Vec<String>) -> Stri
|
||||
filters.push(format!("collab_integrate={}", level));
|
||||
filters.push(format!("collab={}", level));
|
||||
filters.push(format!("flowy_user={}", level));
|
||||
filters.push(format!("flowy_document2={}", level));
|
||||
filters.push(format!("flowy_document={}", level));
|
||||
filters.push(format!("flowy_database2={}", level));
|
||||
filters.push(format!("flowy_server={}", level));
|
||||
filters.push(format!("flowy_notification={}", "info"));
|
||||
|
||||
@@ -33,6 +33,12 @@ pub enum Server {
|
||||
Supabase = 2,
|
||||
}
|
||||
|
||||
impl Server {
|
||||
pub fn is_local(&self) -> bool {
|
||||
matches!(self, Server::Local)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Server {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
@@ -49,7 +55,6 @@ impl Display for Server {
|
||||
/// Each server implements the [AppFlowyServer] trait, which provides the [UserCloudService], etc.
|
||||
pub struct ServerProvider {
|
||||
config: AppFlowyCoreConfig,
|
||||
server: RwLock<Server>,
|
||||
providers: RwLock<HashMap<Server, Arc<dyn AppFlowyServer>>>,
|
||||
pub(crate) encryption: RwLock<Arc<dyn AppFlowyEncryption>>,
|
||||
#[allow(dead_code)]
|
||||
@@ -57,7 +62,7 @@ pub struct ServerProvider {
|
||||
pub(crate) user_enable_sync: RwLock<bool>,
|
||||
|
||||
/// The authenticator type of the user.
|
||||
pub(crate) user_authenticator: RwLock<Authenticator>,
|
||||
authenticator: RwLock<Authenticator>,
|
||||
pub(crate) uid: Arc<RwLock<Option<i64>>>,
|
||||
}
|
||||
|
||||
@@ -70,10 +75,9 @@ impl ServerProvider {
|
||||
let encryption = EncryptionImpl::new(None);
|
||||
Self {
|
||||
config,
|
||||
server: RwLock::new(server),
|
||||
providers: RwLock::new(HashMap::new()),
|
||||
user_enable_sync: RwLock::new(true),
|
||||
user_authenticator: RwLock::new(Authenticator::Local),
|
||||
authenticator: RwLock::new(Authenticator::from(server)),
|
||||
encryption: RwLock::new(Arc::new(encryption)),
|
||||
store_preferences,
|
||||
uid: Default::default(),
|
||||
@@ -81,30 +85,32 @@ impl ServerProvider {
|
||||
}
|
||||
|
||||
pub fn get_server_type(&self) -> Server {
|
||||
self.server.read().clone()
|
||||
match &*self.authenticator.read() {
|
||||
Authenticator::Local => Server::Local,
|
||||
Authenticator::AppFlowyCloud => Server::AppFlowyCloud,
|
||||
Authenticator::Supabase => Server::Supabase,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_server_type(&self, server_type: Server) {
|
||||
let old_server_type = self.server.read().clone();
|
||||
if server_type != old_server_type {
|
||||
pub fn set_authenticator(&self, authenticator: Authenticator) {
|
||||
let old_server_type = self.get_server_type();
|
||||
*self.authenticator.write() = authenticator;
|
||||
let new_server_type = self.get_server_type();
|
||||
|
||||
if old_server_type != new_server_type {
|
||||
self.providers.write().remove(&old_server_type);
|
||||
}
|
||||
|
||||
*self.server.write() = server_type;
|
||||
}
|
||||
|
||||
pub fn get_user_authenticator(&self) -> Authenticator {
|
||||
self.user_authenticator.read().clone()
|
||||
}
|
||||
|
||||
pub fn get_appflowy_cloud_server(&self) -> FlowyResult<Arc<dyn AppFlowyServer>> {
|
||||
let server = self.get_server(&Server::AppFlowyCloud)?;
|
||||
Ok(server)
|
||||
pub fn get_authenticator(&self) -> Authenticator {
|
||||
self.authenticator.read().clone()
|
||||
}
|
||||
|
||||
/// Returns a [AppFlowyServer] trait implementation base on the provider_type.
|
||||
pub fn get_server(&self, server_type: &Server) -> FlowyResult<Arc<dyn AppFlowyServer>> {
|
||||
if let Some(provider) = self.providers.read().get(server_type) {
|
||||
pub fn get_server(&self) -> FlowyResult<Arc<dyn AppFlowyServer>> {
|
||||
let server_type = self.get_server_type();
|
||||
|
||||
if let Some(provider) = self.providers.read().get(&server_type) {
|
||||
return Ok(provider.clone());
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ use crate::integrate::server::{Server, ServerProvider};
|
||||
|
||||
impl FileStorageService for ServerProvider {
|
||||
fn create_object(&self, object: StorageObject) -> FutureResult<String, FlowyError> {
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
FutureResult::new(async move {
|
||||
let storage = server?.file_storage().ok_or(FlowyError::internal())?;
|
||||
storage.create_object(object).await
|
||||
@@ -40,7 +40,7 @@ impl FileStorageService for ServerProvider {
|
||||
}
|
||||
|
||||
fn delete_object_by_url(&self, object_url: String) -> FutureResult<(), FlowyError> {
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
FutureResult::new(async move {
|
||||
let storage = server?.file_storage().ok_or(FlowyError::internal())?;
|
||||
storage.delete_object_by_url(object_url).await
|
||||
@@ -48,7 +48,7 @@ impl FileStorageService for ServerProvider {
|
||||
}
|
||||
|
||||
fn get_object_by_url(&self, object_url: String) -> FutureResult<Bytes, FlowyError> {
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
FutureResult::new(async move {
|
||||
let storage = server?.file_storage().ok_or(FlowyError::internal())?;
|
||||
storage.get_object_by_url(object_url).await
|
||||
@@ -58,42 +58,40 @@ impl FileStorageService for ServerProvider {
|
||||
|
||||
impl UserCloudServiceProvider for ServerProvider {
|
||||
fn set_token(&self, token: &str) -> Result<(), FlowyError> {
|
||||
let server = self.get_server(&self.get_server_type())?;
|
||||
let server = self.get_server()?;
|
||||
server.set_token(token)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn subscribe_token_state(&self) -> Option<WatchStream<UserTokenState>> {
|
||||
let server = self.get_server(&self.get_server_type()).ok()?;
|
||||
let server = self.get_server().ok()?;
|
||||
server.subscribe_token_state()
|
||||
}
|
||||
|
||||
fn set_enable_sync(&self, uid: i64, enable_sync: bool) {
|
||||
if let Ok(server) = self.get_server(&self.get_server_type()) {
|
||||
if let Ok(server) = self.get_server() {
|
||||
server.set_enable_sync(uid, enable_sync);
|
||||
*self.user_enable_sync.write() = enable_sync;
|
||||
*self.uid.write() = Some(uid);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_user_authenticator(&self, authenticator: &Authenticator) {
|
||||
debug!("set user authenticator: {:?}", authenticator);
|
||||
*self.user_authenticator.write() = authenticator.clone();
|
||||
}
|
||||
|
||||
/// When user login, the provider type is set by the [Authenticator] and save to disk for next use.
|
||||
///
|
||||
/// Each [Authenticator] has a corresponding [Server]. The [Server] is used
|
||||
/// to create a new [AppFlowyServer] if it doesn't exist. Once the [Server] is set,
|
||||
/// it will be used when user open the app again.
|
||||
///
|
||||
fn set_authenticator(&self, authenticator: Authenticator) {
|
||||
let server_type: Server = authenticator.into();
|
||||
self.set_server_type(server_type.clone());
|
||||
fn set_user_authenticator(&self, authenticator: &Authenticator) {
|
||||
self.set_authenticator(authenticator.clone());
|
||||
}
|
||||
|
||||
fn get_user_authenticator(&self) -> Authenticator {
|
||||
self.get_authenticator()
|
||||
}
|
||||
|
||||
fn set_network_reachable(&self, reachable: bool) {
|
||||
if let Ok(server) = self.get_server(&self.get_server_type()) {
|
||||
if let Ok(server) = self.get_server() {
|
||||
server.set_network_reachable(reachable);
|
||||
}
|
||||
}
|
||||
@@ -103,16 +101,10 @@ impl UserCloudServiceProvider for ServerProvider {
|
||||
self.encryption.write().set_secret(secret);
|
||||
}
|
||||
|
||||
fn get_authenticator(&self) -> Authenticator {
|
||||
let server_type = self.get_server_type();
|
||||
Authenticator::from(server_type)
|
||||
}
|
||||
|
||||
/// Returns the [UserCloudService] base on the current [Server].
|
||||
/// Creates a new [AppFlowyServer] if it doesn't exist.
|
||||
fn get_user_service(&self) -> Result<Arc<dyn UserCloudService>, FlowyError> {
|
||||
let server_type = self.get_server_type();
|
||||
let user_service = self.get_server(&server_type)?.user_service();
|
||||
let user_service = self.get_server()?.user_service();
|
||||
Ok(user_service)
|
||||
}
|
||||
|
||||
@@ -131,19 +123,19 @@ impl UserCloudServiceProvider for ServerProvider {
|
||||
|
||||
impl FolderCloudService for ServerProvider {
|
||||
fn create_workspace(&self, uid: i64, name: &str) -> FutureResult<Workspace, Error> {
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
let name = name.to_string();
|
||||
FutureResult::new(async move { server?.folder_service().create_workspace(uid, &name).await })
|
||||
}
|
||||
|
||||
fn open_workspace(&self, workspace_id: &str) -> FutureResult<(), Error> {
|
||||
let workspace_id = workspace_id.to_string();
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
FutureResult::new(async move { server?.folder_service().open_workspace(&workspace_id).await })
|
||||
}
|
||||
|
||||
fn get_all_workspace(&self) -> FutureResult<Vec<WorkspaceRecord>, Error> {
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
FutureResult::new(async move { server?.folder_service().get_all_workspace().await })
|
||||
}
|
||||
|
||||
@@ -153,7 +145,7 @@ impl FolderCloudService for ServerProvider {
|
||||
uid: &i64,
|
||||
) -> FutureResult<Option<FolderData>, Error> {
|
||||
let uid = *uid;
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
let workspace_id = workspace_id.to_string();
|
||||
FutureResult::new(async move {
|
||||
server?
|
||||
@@ -169,7 +161,7 @@ impl FolderCloudService for ServerProvider {
|
||||
limit: usize,
|
||||
) -> FutureResult<Vec<FolderSnapshot>, Error> {
|
||||
let workspace_id = workspace_id.to_string();
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
FutureResult::new(async move {
|
||||
server?
|
||||
.folder_service()
|
||||
@@ -187,7 +179,7 @@ impl FolderCloudService for ServerProvider {
|
||||
) -> FutureResult<CollabDocState, Error> {
|
||||
let object_id = object_id.to_string();
|
||||
let workspace_id = workspace_id.to_string();
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
FutureResult::new(async move {
|
||||
server?
|
||||
.folder_service()
|
||||
@@ -202,7 +194,7 @@ impl FolderCloudService for ServerProvider {
|
||||
objects: Vec<FolderCollabParams>,
|
||||
) -> FutureResult<(), Error> {
|
||||
let workspace_id = workspace_id.to_string();
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
FutureResult::new(async move {
|
||||
server?
|
||||
.folder_service()
|
||||
@@ -213,7 +205,7 @@ impl FolderCloudService for ServerProvider {
|
||||
|
||||
fn service_name(&self) -> String {
|
||||
self
|
||||
.get_server(&self.get_server_type())
|
||||
.get_server()
|
||||
.map(|provider| provider.folder_service().service_name())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
@@ -227,7 +219,7 @@ impl DatabaseCloudService for ServerProvider {
|
||||
workspace_id: &str,
|
||||
) -> FutureResult<CollabDocState, Error> {
|
||||
let workspace_id = workspace_id.to_string();
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
let database_id = object_id.to_string();
|
||||
FutureResult::new(async move {
|
||||
server?
|
||||
@@ -244,7 +236,7 @@ impl DatabaseCloudService for ServerProvider {
|
||||
workspace_id: &str,
|
||||
) -> FutureResult<CollabDocStateByOid, Error> {
|
||||
let workspace_id = workspace_id.to_string();
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
FutureResult::new(async move {
|
||||
server?
|
||||
.database_service()
|
||||
@@ -258,7 +250,7 @@ impl DatabaseCloudService for ServerProvider {
|
||||
object_id: &str,
|
||||
limit: usize,
|
||||
) -> FutureResult<Vec<DatabaseSnapshot>, Error> {
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
let database_id = object_id.to_string();
|
||||
FutureResult::new(async move {
|
||||
server?
|
||||
@@ -277,7 +269,7 @@ impl DocumentCloudService for ServerProvider {
|
||||
) -> FutureResult<CollabDocState, FlowyError> {
|
||||
let workspace_id = workspace_id.to_string();
|
||||
let document_id = document_id.to_string();
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
FutureResult::new(async move {
|
||||
server?
|
||||
.document_service()
|
||||
@@ -293,7 +285,7 @@ impl DocumentCloudService for ServerProvider {
|
||||
workspace_id: &str,
|
||||
) -> FutureResult<Vec<DocumentSnapshot>, Error> {
|
||||
let workspace_id = workspace_id.to_string();
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
let document_id = document_id.to_string();
|
||||
FutureResult::new(async move {
|
||||
server?
|
||||
@@ -309,7 +301,7 @@ impl DocumentCloudService for ServerProvider {
|
||||
workspace_id: &str,
|
||||
) -> FutureResult<Option<DocumentData>, Error> {
|
||||
let workspace_id = workspace_id.to_string();
|
||||
let server = self.get_server(&self.get_server_type());
|
||||
let server = self.get_server();
|
||||
let document_id = document_id.to_string();
|
||||
FutureResult::new(async move {
|
||||
server?
|
||||
@@ -328,7 +320,7 @@ impl CollabCloudPluginProvider for ServerProvider {
|
||||
#[instrument(level = "debug", skip(self, context), fields(server_type = %self.get_server_type()))]
|
||||
fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Arc<dyn CollabPlugin>>> {
|
||||
// If the user is local, we don't need to create a sync plugin.
|
||||
if self.user_authenticator.read().is_local() {
|
||||
if self.get_server_type().is_local() {
|
||||
debug!(
|
||||
"User authenticator is local, skip create sync plugin for: {}",
|
||||
context
|
||||
@@ -343,7 +335,7 @@ impl CollabCloudPluginProvider for ServerProvider {
|
||||
collab_object,
|
||||
local_collab,
|
||||
} => {
|
||||
if let Ok(server) = self.get_server(&Server::AppFlowyCloud) {
|
||||
if let Ok(server) = self.get_server() {
|
||||
to_fut(async move {
|
||||
let mut plugins: Vec<Arc<dyn CollabPlugin>> = vec![];
|
||||
|
||||
@@ -394,7 +386,7 @@ impl CollabCloudPluginProvider for ServerProvider {
|
||||
} => {
|
||||
let mut plugins: Vec<Arc<dyn CollabPlugin>> = vec![];
|
||||
if let Some(remote_collab_storage) = self
|
||||
.get_server(&Server::Supabase)
|
||||
.get_server()
|
||||
.ok()
|
||||
.and_then(|provider| provider.collab_storage(&collab_object))
|
||||
{
|
||||
|
||||
@@ -3,12 +3,12 @@ use std::sync::Arc;
|
||||
use std::sync::Weak;
|
||||
|
||||
use collab::core::collab::{CollabDocState, MutexCollab};
|
||||
use collab::core::collab_plugin::EncodedCollabV1;
|
||||
use collab::core::collab_plugin::EncodedCollab;
|
||||
use collab::core::origin::CollabOrigin;
|
||||
use collab::preclude::Collab;
|
||||
use collab_document::blocks::DocumentData;
|
||||
use collab_document::document::Document;
|
||||
use collab_document::document_data::{default_document_collab_data, default_document_data};
|
||||
use collab_document::document_data::default_document_data;
|
||||
use collab_document::YrsDocAction;
|
||||
use collab_entity::CollabType;
|
||||
use lru::LruCache;
|
||||
@@ -86,25 +86,45 @@ impl DocumentManager {
|
||||
///
|
||||
/// if the document already exists, return the existing document.
|
||||
/// if the data is None, will create a document with default data.
|
||||
#[instrument(level = "info", skip(self, data))]
|
||||
pub async fn create_document(
|
||||
&self,
|
||||
uid: i64,
|
||||
doc_id: &str,
|
||||
data: Option<DocumentData>,
|
||||
) -> FlowyResult<()> {
|
||||
tracing::trace!("create a document: {:?}", doc_id);
|
||||
if self.is_doc_exist(doc_id).unwrap_or(false) {
|
||||
Err(FlowyError::new(
|
||||
ErrorCode::RecordAlreadyExists,
|
||||
format!("document {} already exists", doc_id),
|
||||
))
|
||||
} else {
|
||||
let encoded_collab_v1 =
|
||||
doc_state_from_document_data(doc_id, data.unwrap_or_else(default_document_data))?;
|
||||
let collab = self
|
||||
.collab_for_document(uid, doc_id, encoded_collab_v1.doc_state.to_vec(), false)
|
||||
.await?;
|
||||
collab.lock().flush();
|
||||
let result: Result<CollabDocState, FlowyError> = self
|
||||
.cloud_service
|
||||
.get_document_doc_state(doc_id, &self.user.workspace_id()?)
|
||||
.await;
|
||||
|
||||
match result {
|
||||
Ok(data) => {
|
||||
let collab = self.collab_for_document(uid, doc_id, data, false).await?;
|
||||
collab.lock().flush();
|
||||
},
|
||||
Err(err) => {
|
||||
if err.is_record_not_found() {
|
||||
let doc_state =
|
||||
doc_state_from_document_data(doc_id, data.unwrap_or_else(default_document_data))?
|
||||
.doc_state
|
||||
.to_vec();
|
||||
let collab = self
|
||||
.collab_for_document(uid, doc_id, doc_state, false)
|
||||
.await?;
|
||||
collab.lock().flush();
|
||||
} else {
|
||||
return Err(err);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -119,29 +139,10 @@ impl DocumentManager {
|
||||
let mut doc_state = vec![];
|
||||
if !self.is_doc_exist(doc_id)? {
|
||||
// Try to get the document from the cloud service
|
||||
let result: Result<CollabDocState, FlowyError> = self
|
||||
doc_state = self
|
||||
.cloud_service
|
||||
.get_document_doc_state(doc_id, &self.user.workspace_id()?)
|
||||
.await;
|
||||
|
||||
doc_state = match result {
|
||||
Ok(data) => data,
|
||||
Err(err) => {
|
||||
if err.is_record_not_found() {
|
||||
// The document's ID exists in the cloud, but its content does not.
|
||||
// This occurs when user A's document hasn't finished syncing and user B tries to open it.
|
||||
// As a result, a blank document is created for user B.
|
||||
event!(
|
||||
tracing::Level::INFO,
|
||||
"can't find the document in the cloud, doc_id: {}",
|
||||
doc_id
|
||||
);
|
||||
default_document_collab_data(doc_id).doc_state.to_vec()
|
||||
} else {
|
||||
return Err(err);
|
||||
}
|
||||
},
|
||||
}
|
||||
.await?;
|
||||
}
|
||||
|
||||
let uid = self.user.user_id()?;
|
||||
@@ -273,7 +274,7 @@ impl DocumentManager {
|
||||
fn doc_state_from_document_data(
|
||||
doc_id: &str,
|
||||
data: DocumentData,
|
||||
) -> Result<EncodedCollabV1, FlowyError> {
|
||||
) -> Result<EncodedCollab, FlowyError> {
|
||||
let collab = Arc::new(MutexCollab::from_collab(Collab::new_with_origin(
|
||||
CollabOrigin::Empty,
|
||||
doc_id,
|
||||
|
||||
@@ -21,7 +21,7 @@ use collab_integrate::RocksCollabDB;
|
||||
use flowy_document::document::MutexDocument;
|
||||
use flowy_document::manager::{DocumentManager, DocumentUser};
|
||||
use flowy_document_deps::cloud::*;
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_error::{ErrorCode, FlowyError};
|
||||
use flowy_storage::{FileStorageService, StorageObject};
|
||||
use lib_infra::async_trait::async_trait;
|
||||
use lib_infra::future::{to_fut, Fut, FutureResult};
|
||||
@@ -135,10 +135,16 @@ pub struct LocalTestDocumentCloudServiceImpl();
|
||||
impl DocumentCloudService for LocalTestDocumentCloudServiceImpl {
|
||||
fn get_document_doc_state(
|
||||
&self,
|
||||
_document_id: &str,
|
||||
document_id: &str,
|
||||
_workspace_id: &str,
|
||||
) -> FutureResult<CollabDocState, FlowyError> {
|
||||
FutureResult::new(async move { Ok(vec![]) })
|
||||
let document_id = document_id.to_string();
|
||||
FutureResult::new(async move {
|
||||
Err(FlowyError::new(
|
||||
ErrorCode::RecordNotFound,
|
||||
format!("Document {} not found", document_id),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
fn get_document_snapshots(
|
||||
|
||||
@@ -55,6 +55,10 @@ impl FlowyError {
|
||||
self.code == ErrorCode::RecordNotFound
|
||||
}
|
||||
|
||||
pub fn is_already_exists(&self) -> bool {
|
||||
self.code == ErrorCode::RecordAlreadyExists
|
||||
}
|
||||
|
||||
pub fn is_unauthorized(&self) -> bool {
|
||||
self.code == ErrorCode::UserUnauthorized || self.code == ErrorCode::RecordNotFound
|
||||
}
|
||||
|
||||
@@ -398,11 +398,13 @@ impl FolderManager {
|
||||
params: CreateViewParams,
|
||||
) -> FlowyResult<View> {
|
||||
let view_layout: ViewLayout = params.layout.clone().into();
|
||||
// TODO(nathan): remove orphan view. Just use for create document in row
|
||||
let handler = self.get_handler(&view_layout)?;
|
||||
let user_id = self.user.user_id()?;
|
||||
handler
|
||||
.create_built_in_view(user_id, ¶ms.view_id, ¶ms.name, view_layout.clone())
|
||||
.await?;
|
||||
|
||||
let view = create_view(self.user.user_id()?, params, view_layout);
|
||||
self.with_folder(
|
||||
|| (),
|
||||
|
||||
@@ -3,7 +3,7 @@ use client_api::entity::QueryCollabResult::{Failed, Success};
|
||||
use client_api::entity::{QueryCollab, QueryCollabParams};
|
||||
use client_api::error::ErrorCode::RecordNotFound;
|
||||
use collab::core::collab::CollabDocState;
|
||||
use collab::core::collab_plugin::EncodedCollabV1;
|
||||
use collab::core::collab_plugin::EncodedCollab;
|
||||
use collab_entity::CollabType;
|
||||
use tracing::error;
|
||||
|
||||
@@ -72,7 +72,7 @@ where
|
||||
.into_iter()
|
||||
.flat_map(|(object_id, result)| match result {
|
||||
Success { encode_collab_v1 } => {
|
||||
match EncodedCollabV1::decode_from_bytes(&encode_collab_v1) {
|
||||
match EncodedCollab::decode_from_bytes(&encode_collab_v1) {
|
||||
Ok(encode) => Some((object_id, encode.doc_state.to_vec())),
|
||||
Err(err) => {
|
||||
error!("Failed to decode collab: {}", err);
|
||||
|
||||
@@ -264,7 +264,7 @@ where
|
||||
.into_iter()
|
||||
.map(|object| CollabParams {
|
||||
object_id: object.object_id,
|
||||
encoded_collab_v1: object.encoded_collab_v1,
|
||||
encoded_collab_v1: object.encoded_collab,
|
||||
collab_type: object.collab_type,
|
||||
override_if_exist: false,
|
||||
})
|
||||
|
||||
@@ -2,7 +2,7 @@ use anyhow::Error;
|
||||
use collab::core::collab::CollabDocState;
|
||||
|
||||
use flowy_document_deps::cloud::*;
|
||||
use flowy_error::FlowyError;
|
||||
use flowy_error::{ErrorCode, FlowyError};
|
||||
use lib_infra::future::FutureResult;
|
||||
|
||||
pub(crate) struct LocalServerDocumentCloudServiceImpl();
|
||||
@@ -10,10 +10,16 @@ pub(crate) struct LocalServerDocumentCloudServiceImpl();
|
||||
impl DocumentCloudService for LocalServerDocumentCloudServiceImpl {
|
||||
fn get_document_doc_state(
|
||||
&self,
|
||||
_document_id: &str,
|
||||
document_id: &str,
|
||||
_workspace_id: &str,
|
||||
) -> FutureResult<CollabDocState, FlowyError> {
|
||||
FutureResult::new(async move { Ok(vec![]) })
|
||||
let document_id = document_id.to_string();
|
||||
FutureResult::new(async move {
|
||||
Err(FlowyError::new(
|
||||
ErrorCode::RecordNotFound,
|
||||
format!("Document {} not found", document_id),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
fn get_document_snapshots(
|
||||
|
||||
@@ -86,16 +86,15 @@ pub trait UserCloudServiceProvider: Send + Sync + 'static {
|
||||
/// * `enable_sync`: A boolean indicating whether synchronization should be enabled or disabled.
|
||||
fn set_enable_sync(&self, uid: i64, enable_sync: bool);
|
||||
|
||||
/// Sets the authentication type for a user. The authentication type is the type when user sign in or sign up.
|
||||
fn set_user_authenticator(&self, authenticator: &Authenticator);
|
||||
|
||||
/// Sets the authenticator when user sign in or sign up.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `authenticator`: An `Authenticator` object.
|
||||
fn set_authenticator(&self, authenticator: Authenticator);
|
||||
fn set_user_authenticator(&self, authenticator: &Authenticator);
|
||||
|
||||
/// Sets the network reachability status.
|
||||
fn get_user_authenticator(&self) -> Authenticator;
|
||||
|
||||
/// Sets the network reachability statset_user_authenticatorus.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `reachable`: A boolean indicating whether the network is reachable.
|
||||
@@ -107,12 +106,6 @@ pub trait UserCloudServiceProvider: Send + Sync + 'static {
|
||||
/// * `secret`: A `String` representing the encryption secret.
|
||||
fn set_encrypt_secret(&self, secret: String);
|
||||
|
||||
/// Retrieves the current authenticator.
|
||||
///
|
||||
/// # Returns
|
||||
/// The current `Authenticator` object.
|
||||
fn get_authenticator(&self) -> Authenticator;
|
||||
|
||||
/// Retrieves the user-specific cloud service.
|
||||
///
|
||||
/// # Returns
|
||||
@@ -247,6 +240,6 @@ pub fn uuid_from_map(map: &HashMap<String, String>) -> Result<Uuid, Error> {
|
||||
#[derive(Debug)]
|
||||
pub struct UserCollabParams {
|
||||
pub object_id: String,
|
||||
pub encoded_collab_v1: Vec<u8>,
|
||||
pub encoded_collab: Vec<u8>,
|
||||
pub collab_type: CollabType,
|
||||
}
|
||||
@@ -43,8 +43,16 @@ pub async fn sign_in_with_email_password_handler(
|
||||
let params: SignInParams = data.into_inner().try_into()?;
|
||||
let auth_type = params.auth_type.clone();
|
||||
|
||||
let user_profile: UserProfilePB = manager.sign_in(params, auth_type).await?.into();
|
||||
data_result_ok(user_profile)
|
||||
let old_authenticator = manager.cloud_services.get_user_authenticator();
|
||||
match manager.sign_in(params, auth_type).await {
|
||||
Ok(profile) => data_result_ok(UserProfilePB::from(profile)),
|
||||
Err(err) => {
|
||||
manager
|
||||
.cloud_services
|
||||
.set_user_authenticator(&old_authenticator);
|
||||
return Err(err);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(
|
||||
@@ -63,10 +71,18 @@ pub async fn sign_up(
|
||||
) -> DataResult<UserProfilePB, FlowyError> {
|
||||
let manager = upgrade_manager(manager)?;
|
||||
let params: SignUpParams = data.into_inner().try_into()?;
|
||||
let auth_type = params.auth_type.clone();
|
||||
let authenticator = params.auth_type.clone();
|
||||
|
||||
let user_profile = manager.sign_up(auth_type, BoxAny::new(params)).await?;
|
||||
data_result_ok(user_profile.into())
|
||||
let old_authenticator = manager.cloud_services.get_user_authenticator();
|
||||
match manager.sign_up(authenticator, BoxAny::new(params)).await {
|
||||
Ok(profile) => data_result_ok(UserProfilePB::from(profile)),
|
||||
Err(err) => {
|
||||
manager
|
||||
.cloud_services
|
||||
.set_user_authenticator(&old_authenticator);
|
||||
return Err(err);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(manager))]
|
||||
@@ -135,7 +151,6 @@ pub async fn set_appearance_setting(
|
||||
if setting.theme.is_empty() {
|
||||
setting.theme = APPEARANCE_DEFAULT_THEME.to_string();
|
||||
}
|
||||
|
||||
store_preferences.set_object(APPEARANCE_SETTING_CACHE_KEY, setting)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -268,6 +268,11 @@ impl UserManager {
|
||||
.map(|collab_db| Arc::downgrade(&collab_db))
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
pub fn get_collab_backup_list(&self, uid: i64) -> Vec<String> {
|
||||
self.database.get_collab_backup_list(uid)
|
||||
}
|
||||
|
||||
/// Performs a user sign-in, initializing user awareness and sending relevant notifications.
|
||||
///
|
||||
/// This asynchronous function interacts with an external user service to authenticate and sign in a user
|
||||
@@ -282,7 +287,8 @@ impl UserManager {
|
||||
params: SignInParams,
|
||||
authenticator: Authenticator,
|
||||
) -> Result<UserProfile, FlowyError> {
|
||||
self.update_authenticator(&authenticator).await;
|
||||
self.cloud_services.set_user_authenticator(&authenticator);
|
||||
|
||||
let response: AuthResponse = self
|
||||
.cloud_services
|
||||
.get_user_service()?
|
||||
@@ -321,10 +327,6 @@ impl UserManager {
|
||||
Ok(user_profile)
|
||||
}
|
||||
|
||||
pub(crate) async fn update_authenticator(&self, authenticator: &Authenticator) {
|
||||
self.cloud_services.set_authenticator(authenticator.clone());
|
||||
}
|
||||
|
||||
/// Manages the user sign-up process, potentially migrating data if necessary.
|
||||
///
|
||||
/// This asynchronous function interacts with an external authentication service to register and sign up a user
|
||||
@@ -341,7 +343,7 @@ impl UserManager {
|
||||
// sign out the current user if there is one
|
||||
let migration_user = self.get_migration_user(&authenticator).await;
|
||||
|
||||
self.update_authenticator(&authenticator).await;
|
||||
self.cloud_services.set_user_authenticator(&authenticator);
|
||||
let auth_service = self.cloud_services.get_user_service()?;
|
||||
let response: AuthResponse = auth_service.sign_up(params).await?;
|
||||
let new_user_profile = UserProfile::from((&response, &authenticator));
|
||||
@@ -513,15 +515,9 @@ impl UserManager {
|
||||
// users opt for cloud storage, the application should automatically create a backup of the user
|
||||
// data. This backup should be in the form of a zip file and stored locally on the user's disk
|
||||
// for safety and data integrity purposes
|
||||
if self.user_config.is_custom_storage_path() {
|
||||
self
|
||||
.database
|
||||
.backup_or_restore(session.user_id, &session.user_workspace.id);
|
||||
} else {
|
||||
self
|
||||
.database
|
||||
.restore_if_need(session.user_id, &session.user_workspace.id);
|
||||
}
|
||||
self
|
||||
.database
|
||||
.backup_or_restore(session.user_id, &session.user_workspace.id);
|
||||
}
|
||||
|
||||
/// Fetches the user profile for the given user ID.
|
||||
@@ -723,7 +719,7 @@ impl UserManager {
|
||||
authenticator: &Authenticator,
|
||||
email: &str,
|
||||
) -> Result<String, FlowyError> {
|
||||
self.update_authenticator(authenticator).await;
|
||||
self.cloud_services.set_user_authenticator(authenticator);
|
||||
|
||||
let auth_service = self.cloud_services.get_user_service()?;
|
||||
let url = auth_service
|
||||
@@ -738,8 +734,8 @@ impl UserManager {
|
||||
oauth_provider: &str,
|
||||
) -> Result<String, FlowyError> {
|
||||
self
|
||||
.update_authenticator(&Authenticator::AppFlowyCloud)
|
||||
.await;
|
||||
.cloud_services
|
||||
.set_user_authenticator(&Authenticator::AppFlowyCloud);
|
||||
let auth_service = self.cloud_services.get_user_service()?;
|
||||
let url = auth_service
|
||||
.generate_oauth_url_with_provider(oauth_provider)
|
||||
|
||||
@@ -59,9 +59,10 @@ impl UserDataMigration for FavoriteV1AndWorkspaceArrayMigration {
|
||||
&encode.state_vector,
|
||||
)
|
||||
.map_err(internal_error)?;
|
||||
|
||||
write_txn.commit_transaction().map_err(internal_error)?;
|
||||
}
|
||||
|
||||
write_txn.commit_transaction().map_err(internal_error)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -48,9 +48,10 @@ impl UserDataMigration for WorkspaceTrashMapToSectionMigration {
|
||||
&encode.state_vector,
|
||||
)
|
||||
.map_err(internal_error)?;
|
||||
|
||||
write_txn.commit_transaction().map_err(internal_error)?;
|
||||
}
|
||||
|
||||
write_txn.commit_transaction().map_err(internal_error)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ use parking_lot::{Mutex, RwLock};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::Arc;
|
||||
use tracing::info;
|
||||
use tracing::{debug, event, info, instrument};
|
||||
|
||||
pub(crate) struct ImportContext {
|
||||
pub imported_session: Session,
|
||||
@@ -92,15 +92,16 @@ pub(crate) fn import_appflowy_data_folder(
|
||||
let views = collab_db.with_write_txn(|collab_write_txn| {
|
||||
// use the old_to_new_id_map to keep track of the other collab object id and the new collab object id
|
||||
let old_to_new_id_map = Arc::new(Mutex::new(OldToNewIdMap::new()));
|
||||
let mut all_object_ids = imported_collab_read_txn
|
||||
let mut all_imported_object_ids = imported_collab_read_txn
|
||||
.get_all_docs()
|
||||
.map(|iter| iter.collect::<Vec<String>>())
|
||||
.unwrap_or_default();
|
||||
|
||||
// when doing import, we don't want to import the user workspace, database view tracker and the user awareness
|
||||
all_object_ids.retain(|id| id != &imported_session.user_workspace.id);
|
||||
all_object_ids.retain(|id| id != &imported_session.user_workspace.database_view_tracker_id);
|
||||
all_object_ids
|
||||
all_imported_object_ids.retain(|id| id != &imported_session.user_workspace.id);
|
||||
all_imported_object_ids
|
||||
.retain(|id| id != &imported_session.user_workspace.database_view_tracker_id);
|
||||
all_imported_object_ids
|
||||
.retain(|id| id != &awareness_oid_from_user_uuid(&imported_session.user_uuid).to_string());
|
||||
|
||||
// import database view tracker
|
||||
@@ -118,32 +119,36 @@ pub(crate) fn import_appflowy_data_folder(
|
||||
.flatten()
|
||||
.cloned()
|
||||
.collect();
|
||||
all_object_ids.retain(|id| !database_view_ids.contains(id));
|
||||
all_imported_object_ids.retain(|id| !database_view_ids.contains(id));
|
||||
|
||||
// load other collab objects
|
||||
let collab_by_oid = load_collab_by_oid(
|
||||
let imported_collab_by_oid = load_collab_by_oid(
|
||||
imported_session.user_id,
|
||||
&imported_collab_read_txn,
|
||||
&all_object_ids,
|
||||
&all_imported_object_ids,
|
||||
);
|
||||
// import the database
|
||||
migrate_databases(
|
||||
&old_to_new_id_map,
|
||||
session,
|
||||
collab_write_txn,
|
||||
&mut all_object_ids,
|
||||
&collab_by_oid,
|
||||
&mut all_imported_object_ids,
|
||||
&imported_collab_by_oid,
|
||||
&row_object_ids,
|
||||
&document_object_ids,
|
||||
)?;
|
||||
|
||||
// the object ids now only contains the document collab object ids
|
||||
for object_id in &all_object_ids {
|
||||
if let Some(collab) = collab_by_oid.get(object_id) {
|
||||
for object_id in &all_imported_object_ids {
|
||||
if let Some(imported_collab) = imported_collab_by_oid.get(object_id) {
|
||||
let new_object_id = old_to_new_id_map.lock().renew_id(object_id);
|
||||
document_object_ids.lock().insert(new_object_id.clone());
|
||||
tracing::debug!("migrate from: {}, to: {}", object_id, new_object_id,);
|
||||
import_collab_object(collab, session.user_id, &new_object_id, collab_write_txn);
|
||||
debug!("import from: {}, to: {}", object_id, new_object_id,);
|
||||
import_collab_object(
|
||||
imported_collab,
|
||||
session.user_id,
|
||||
&new_object_id,
|
||||
collab_write_txn,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,6 +183,9 @@ pub(crate) fn import_appflowy_data_folder(
|
||||
collab_write_txn,
|
||||
)?;
|
||||
|
||||
document_object_ids
|
||||
.lock()
|
||||
.insert(import_container_view_id.clone());
|
||||
let import_container_view =
|
||||
ViewBuilder::new(session.user_id, session.user_workspace.id.clone())
|
||||
.with_view_id(import_container_view_id)
|
||||
@@ -185,6 +193,7 @@ pub(crate) fn import_appflowy_data_folder(
|
||||
.with_name(name)
|
||||
.with_child_views(child_views)
|
||||
.build();
|
||||
|
||||
Ok(vec![import_container_view])
|
||||
},
|
||||
}
|
||||
@@ -247,10 +256,9 @@ fn migrate_databases<'a, W>(
|
||||
old_to_new_id_map: &Arc<Mutex<OldToNewIdMap>>,
|
||||
session: &Session,
|
||||
collab_write_txn: &'a W,
|
||||
object_ids: &mut Vec<String>,
|
||||
collab_by_oid: &HashMap<String, Collab>,
|
||||
imported_object_ids: &mut Vec<String>,
|
||||
imported_collab_by_oid: &HashMap<String, Collab>,
|
||||
row_object_ids: &Mutex<HashSet<String>>,
|
||||
document_object_ids: &Mutex<HashSet<String>>,
|
||||
) -> Result<(), PersistenceError>
|
||||
where
|
||||
W: YrsDocAction<'a>,
|
||||
@@ -258,20 +266,20 @@ where
|
||||
{
|
||||
// Migrate databases
|
||||
let mut database_object_ids = vec![];
|
||||
let database_row_object_ids = RwLock::new(HashSet::new());
|
||||
let imported_database_row_object_ids = RwLock::new(HashSet::new());
|
||||
|
||||
for object_id in &mut *object_ids {
|
||||
if let Some(collab) = collab_by_oid.get(object_id) {
|
||||
if !is_database_collab(collab) {
|
||||
for object_id in &mut *imported_object_ids {
|
||||
if let Some(database_collab) = imported_collab_by_oid.get(object_id) {
|
||||
if !is_database_collab(database_collab) {
|
||||
continue;
|
||||
}
|
||||
|
||||
database_object_ids.push(object_id.clone());
|
||||
reset_inline_view_id(collab, |old_inline_view_id| {
|
||||
reset_inline_view_id(database_collab, |old_inline_view_id| {
|
||||
old_to_new_id_map.lock().renew_id(&old_inline_view_id)
|
||||
});
|
||||
|
||||
mut_database_views_with_collab(collab, |database_view| {
|
||||
mut_database_views_with_collab(database_collab, |database_view| {
|
||||
let new_view_id = old_to_new_id_map.lock().renew_id(&database_view.id);
|
||||
let new_database_id = old_to_new_id_map
|
||||
.lock()
|
||||
@@ -284,64 +292,72 @@ where
|
||||
let old_row_document_id = database_row_document_id_from_row_id(&old_row_id);
|
||||
let new_row_id = old_to_new_id_map.lock().renew_id(&old_row_id);
|
||||
let new_row_document_id = database_row_document_id_from_row_id(&new_row_id);
|
||||
tracing::debug!("migrate row id: {} to {}", row_order.id, new_row_id);
|
||||
tracing::debug!(
|
||||
"migrate row document id: {} to {}",
|
||||
old_row_document_id,
|
||||
new_row_document_id
|
||||
);
|
||||
|
||||
old_to_new_id_map
|
||||
.lock()
|
||||
.insert(old_row_document_id, new_row_document_id);
|
||||
.insert(old_row_document_id.clone(), new_row_document_id);
|
||||
|
||||
row_order.id = RowId::from(new_row_id);
|
||||
database_row_object_ids.write().insert(old_row_id);
|
||||
imported_database_row_object_ids.write().insert(old_row_id);
|
||||
});
|
||||
|
||||
// collect the ids
|
||||
let row_ids = database_view
|
||||
let new_row_ids = database_view
|
||||
.row_orders
|
||||
.iter()
|
||||
.map(|order| order.id.clone().into_inner())
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
let row_document_ids = row_ids
|
||||
.iter()
|
||||
.map(|id| database_row_document_id_from_row_id(id))
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
row_object_ids.lock().extend(row_ids);
|
||||
document_object_ids.lock().extend(row_document_ids);
|
||||
row_object_ids.lock().extend(new_row_ids);
|
||||
});
|
||||
|
||||
let new_object_id = old_to_new_id_map.lock().renew_id(object_id);
|
||||
tracing::debug!(
|
||||
debug!(
|
||||
"migrate database from: {}, to: {}",
|
||||
object_id,
|
||||
new_object_id,
|
||||
object_id, new_object_id,
|
||||
);
|
||||
import_collab_object(
|
||||
database_collab,
|
||||
session.user_id,
|
||||
&new_object_id,
|
||||
collab_write_txn,
|
||||
);
|
||||
import_collab_object(collab, session.user_id, &new_object_id, collab_write_txn);
|
||||
}
|
||||
}
|
||||
let database_row_object_ids = database_row_object_ids.read();
|
||||
let imported_database_row_object_ids = imported_database_row_object_ids.read();
|
||||
|
||||
// remove the database object ids from the object ids
|
||||
object_ids.retain(|id| !database_object_ids.contains(id));
|
||||
object_ids.retain(|id| !database_row_object_ids.contains(id));
|
||||
imported_object_ids.retain(|id| !database_object_ids.contains(id));
|
||||
imported_object_ids.retain(|id| !imported_database_row_object_ids.contains(id));
|
||||
|
||||
for object_id in &*database_row_object_ids {
|
||||
if let Some(collab) = collab_by_oid.get(object_id) {
|
||||
let new_object_id = old_to_new_id_map.lock().renew_id(object_id);
|
||||
tracing::info!(
|
||||
"migrate database row from: {}, to: {}",
|
||||
object_id,
|
||||
new_object_id,
|
||||
for imported_row_id in &*imported_database_row_object_ids {
|
||||
if let Some(imported_collab) = imported_collab_by_oid.get(imported_row_id) {
|
||||
let new_row_id = old_to_new_id_map.lock().renew_id(imported_row_id);
|
||||
info!(
|
||||
"import database row from: {}, to: {}",
|
||||
imported_row_id, new_row_id,
|
||||
);
|
||||
mut_row_with_collab(collab, |row_update| {
|
||||
row_update.set_row_id(RowId::from(new_object_id.clone()));
|
||||
mut_row_with_collab(imported_collab, |row_update| {
|
||||
row_update.set_row_id(RowId::from(new_row_id.clone()));
|
||||
});
|
||||
import_collab_object(collab, session.user_id, &new_object_id, collab_write_txn);
|
||||
import_collab_object(
|
||||
imported_collab,
|
||||
session.user_id,
|
||||
&new_row_id,
|
||||
collab_write_txn,
|
||||
);
|
||||
}
|
||||
|
||||
let imported_row_document_id = database_row_document_id_from_row_id(imported_row_id);
|
||||
if imported_collab_by_oid
|
||||
.get(&imported_row_document_id)
|
||||
.is_some()
|
||||
{
|
||||
let new_row_document_id = old_to_new_id_map.lock().renew_id(&imported_row_document_id);
|
||||
info!(
|
||||
"map row document from: {}, to: {}",
|
||||
imported_row_document_id, new_row_document_id,
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -354,7 +370,7 @@ where
|
||||
{
|
||||
let txn = collab.transact();
|
||||
if let Err(err) = w_txn.create_new_doc(new_uid, &new_object_id, &txn) {
|
||||
tracing::error!("import collab failed: {:?}", err);
|
||||
tracing::error!("import collab:{} failed: {:?}", new_object_id, err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,6 +535,7 @@ impl DerefMut for OldToNewIdMap {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all)]
|
||||
pub async fn upload_imported_data(
|
||||
uid: i64,
|
||||
user_collab_db: Arc<RocksCollabDB>,
|
||||
@@ -549,16 +566,20 @@ pub async fn upload_imported_data(
|
||||
let object_by_collab_type = tokio::task::spawn_blocking(move || {
|
||||
let collab_read = user_collab_db.read_txn();
|
||||
let mut object_by_collab_type = HashMap::new();
|
||||
|
||||
event!(tracing::Level::DEBUG, "upload database collab data");
|
||||
object_by_collab_type.insert(
|
||||
CollabType::Database,
|
||||
load_and_process_collab_data(uid, &collab_read, &database_object_ids),
|
||||
);
|
||||
|
||||
event!(tracing::Level::DEBUG, "upload document collab data");
|
||||
object_by_collab_type.insert(
|
||||
CollabType::Document,
|
||||
load_and_process_collab_data(uid, &collab_read, &document_object_ids),
|
||||
);
|
||||
|
||||
event!(tracing::Level::DEBUG, "upload database row collab data");
|
||||
object_by_collab_type.insert(
|
||||
CollabType::DatabaseRow,
|
||||
load_and_process_collab_data(uid, &collab_read, &row_object_ids),
|
||||
@@ -573,17 +594,26 @@ pub async fn upload_imported_data(
|
||||
let mut size_counter = 0;
|
||||
let mut objects: Vec<UserCollabParams> = vec![];
|
||||
let upload_size_limit = 2 * 1024 * 1024;
|
||||
for (collab_type, encoded_v1_by_oid) in object_by_collab_type {
|
||||
for (collab_type, encoded_collab_by_oid) in object_by_collab_type {
|
||||
info!(
|
||||
"Batch import collab:{} ids: {:?}",
|
||||
collab_type,
|
||||
encoded_v1_by_oid.keys(),
|
||||
encoded_collab_by_oid.keys(),
|
||||
);
|
||||
for (oid, encoded_v1) in encoded_v1_by_oid {
|
||||
let obj_size = encoded_v1.len();
|
||||
for (oid, encoded_collab) in encoded_collab_by_oid {
|
||||
let obj_size = encoded_collab.len();
|
||||
if size_counter + obj_size > upload_size_limit && !objects.is_empty() {
|
||||
// When the limit is exceeded, batch create with the current list of objects
|
||||
// and reset for the next batch.
|
||||
info!(
|
||||
"Exceeded maximum payload size. Batch creating collab objects: {}, payload size: {}",
|
||||
objects
|
||||
.iter()
|
||||
.map(|o| o.object_id.clone())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
size_counter
|
||||
);
|
||||
user_cloud_service
|
||||
.batch_create_collab_object(workspace_id, objects)
|
||||
.await?;
|
||||
@@ -594,7 +624,7 @@ pub async fn upload_imported_data(
|
||||
// Add the current object to the batch.
|
||||
objects.push(UserCollabParams {
|
||||
object_id: oid,
|
||||
encoded_collab_v1: encoded_v1,
|
||||
encoded_collab,
|
||||
collab_type: collab_type.clone(),
|
||||
});
|
||||
size_counter += obj_size;
|
||||
@@ -619,6 +649,7 @@ pub async fn upload_imported_data(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all)]
|
||||
fn load_and_process_collab_data<'a, R>(
|
||||
uid: i64,
|
||||
collab_read: &R,
|
||||
@@ -635,7 +666,7 @@ where
|
||||
.encode_collab_v1()
|
||||
.encode_to_bytes()
|
||||
.ok()
|
||||
.map(|encoded_v1| (oid, encoded_v1))
|
||||
.map(|encoded_collab| (oid, encoded_collab))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -7,6 +7,7 @@ use crate::services::data_import::ImportContext;
|
||||
use collab::preclude::Collab;
|
||||
use flowy_folder_deps::entities::ImportData;
|
||||
use std::sync::Arc;
|
||||
use tracing::instrument;
|
||||
|
||||
pub enum ImportDataSource {
|
||||
AppFlowyDataFolder {
|
||||
@@ -26,6 +27,7 @@ pub(crate) fn import_data(
|
||||
import_appflowy_data_folder(session, &session.user_workspace.id, &collab_db, context)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all)]
|
||||
pub fn load_collab_by_oid<'a, R>(
|
||||
uid: i64,
|
||||
collab_read_txn: &R,
|
||||
@@ -44,7 +46,7 @@ where
|
||||
Ok(_) => {
|
||||
collab_by_oid.insert(object_id.clone(), collab);
|
||||
},
|
||||
Err(err) => tracing::error!("🔴Initialize migration collab failed: {:?} ", err),
|
||||
Err(err) => tracing::error!("🔴import collab:{} failed: {:?} ", object_id, err),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,17 @@ impl UserDB {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
pub fn get_collab_backup_list(&self, uid: i64) -> Vec<String> {
|
||||
let collab_db_path = self.paths.collab_db_path(uid);
|
||||
if let Ok(history_folder) = self.paths.collab_db_history(uid, true) {
|
||||
return CollabDBZipBackup::new(collab_db_path.clone(), history_folder)
|
||||
.get_backup_list()
|
||||
.unwrap_or_default();
|
||||
}
|
||||
vec![]
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all)]
|
||||
pub fn restore_if_need(&self, uid: i64, workspace_id: &str) {
|
||||
if let Ok(history_folder) = self.paths.collab_db_history(uid, false) {
|
||||
@@ -224,9 +235,16 @@ impl CollabDBZipBackup {
|
||||
|
||||
#[instrument(name = "backup_collab_db", skip_all, err)]
|
||||
pub fn backup(&self) -> io::Result<()> {
|
||||
let today_zip_file = self
|
||||
.history_folder
|
||||
.join(format!("collab_db_{}.zip", today_zip_timestamp()));
|
||||
let file_name = match std::env::var("APP_VERSION") {
|
||||
Ok(version_num) => {
|
||||
format!("collab_db_{}_{}.zip", version_num, today_zip_timestamp())
|
||||
},
|
||||
Err(_) => {
|
||||
format!("collab_db_{}.zip", today_zip_timestamp())
|
||||
},
|
||||
};
|
||||
|
||||
let today_zip_file = self.history_folder.join(file_name);
|
||||
|
||||
// Remove today's existing zip file if it exists
|
||||
if !today_zip_file.exists() {
|
||||
@@ -240,11 +258,29 @@ impl CollabDBZipBackup {
|
||||
}
|
||||
|
||||
// Clean up old backups
|
||||
self.clean_old_backups()?;
|
||||
if let Err(err) = self.clean_old_backups() {
|
||||
error!("Clean up old backups failed: {:?}", err);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
pub fn get_backup_list(&self) -> io::Result<Vec<String>> {
|
||||
let mut backups = Vec::new();
|
||||
for entry in fs::read_dir(&self.history_folder)? {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
if path.is_file() && path.extension().and_then(|s| s.to_str()) == Some("zip") {
|
||||
if let Some(file_name) = path.file_stem().and_then(|s| s.to_str()) {
|
||||
backups.push(file_name.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
backups.sort();
|
||||
Ok(backups)
|
||||
}
|
||||
|
||||
#[instrument(skip_all, err)]
|
||||
pub fn restore_latest_backup(&self) -> io::Result<()> {
|
||||
let mut latest_zip: Option<(String, PathBuf)> = None;
|
||||
@@ -258,7 +294,7 @@ impl CollabDBZipBackup {
|
||||
let path = entry.path();
|
||||
if path.is_file() && path.extension().and_then(|s| s.to_str()) == Some("zip") {
|
||||
if let Some(file_name) = path.file_stem().and_then(|s| s.to_str()) {
|
||||
if let Some(timestamp_str) = file_name.strip_prefix("collab_db_") {
|
||||
if let Some(timestamp_str) = file_name.split('_').last() {
|
||||
match latest_zip {
|
||||
Some((latest_timestamp, _)) if timestamp_str > latest_timestamp.as_str() => {
|
||||
latest_zip = Some((timestamp_str.to_string(), path));
|
||||
@@ -309,6 +345,7 @@ impl CollabDBZipBackup {
|
||||
// Remove backups older than 10 days
|
||||
let threshold_str = threshold_date.format(zip_time_format()).to_string();
|
||||
|
||||
info!("Current backup: {:?}", backups.len());
|
||||
// If there are more than 10 backups, remove the oldest ones
|
||||
while backups.len() > 10 {
|
||||
if let Some((date_str, path)) = backups.first() {
|
||||
|
||||
@@ -9,7 +9,7 @@ edition = "2018"
|
||||
|
||||
tracing-subscriber = { version = "0.3.17", features = ["registry", "env-filter", "ansi", "json"] }
|
||||
tracing-bunyan-formatter = "0.3.9"
|
||||
tracing-appender = "0.2.2"
|
||||
tracing-appender = "0.2.3"
|
||||
tracing-core = "0.1"
|
||||
tracing.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::sync::RwLock;
|
||||
use chrono::Local;
|
||||
use lazy_static::lazy_static;
|
||||
use tracing::subscriber::set_global_default;
|
||||
use tracing_appender::rolling::Rotation;
|
||||
use tracing_appender::{non_blocking::WorkerGuard, rolling::RollingFileAppender};
|
||||
use tracing_bunyan_formatter::JsonStorageLayer;
|
||||
use tracing_subscriber::fmt::format::Writer;
|
||||
@@ -25,10 +26,17 @@ pub struct Builder {
|
||||
|
||||
impl Builder {
|
||||
pub fn new(name: &str, directory: &str) -> Self {
|
||||
let file_appender = RollingFileAppender::builder()
|
||||
.rotation(Rotation::DAILY)
|
||||
.filename_prefix(name)
|
||||
.max_log_files(6)
|
||||
.build(directory)
|
||||
.unwrap_or(tracing_appender::rolling::daily(directory, name));
|
||||
|
||||
Builder {
|
||||
name: name.to_owned(),
|
||||
env_filter: "Info".to_owned(),
|
||||
file_appender: tracing_appender::rolling::daily(directory, name),
|
||||
file_appender,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ run_task = { name = [
|
||||
|
||||
#
|
||||
[tasks.sdk-dev-build]
|
||||
dependencies = ["set-app-version"]
|
||||
private = true
|
||||
script = [
|
||||
"""
|
||||
@@ -58,6 +59,7 @@ script = [
|
||||
script_runner = "@shell"
|
||||
|
||||
[tasks.sdk-dev-build.mac]
|
||||
dependencies = ["set-app-version"]
|
||||
private = true
|
||||
script = [
|
||||
"""
|
||||
@@ -69,6 +71,7 @@ script = [
|
||||
script_runner = "@shell"
|
||||
|
||||
[tasks.sdk-dev-build.windows]
|
||||
dependencies = ["set-app-version"]
|
||||
private = true
|
||||
script = [
|
||||
"""
|
||||
@@ -93,6 +96,7 @@ run_task = { name = [
|
||||
|
||||
#
|
||||
[tasks.sdk-release-build]
|
||||
dependencies = ["set-app-version"]
|
||||
script = [
|
||||
"""
|
||||
cd rust-lib/
|
||||
@@ -103,6 +107,7 @@ script = [
|
||||
script_runner = "@shell"
|
||||
|
||||
[tasks.sdk-release-build.mac]
|
||||
dependencies = ["set-app-version"]
|
||||
script = [
|
||||
"""
|
||||
cd rust-lib/
|
||||
@@ -172,3 +177,13 @@ script = [
|
||||
""",
|
||||
]
|
||||
script_runner = "@duckscript"
|
||||
|
||||
[tasks.set-app-version]
|
||||
script = ["""
|
||||
if is_empty ${APP_VERSION}
|
||||
APP_VERSION = set ${APPFLOWY_VERSION}
|
||||
set_env APP_VERSION ${APPFLOWY_VERSION}
|
||||
end
|
||||
echo APP_VERSION: ${APP_VERSION}
|
||||
"""]
|
||||
script_runner = "@duckscript"
|
||||
@@ -7,7 +7,6 @@ linux_alias = "appflowy-linux"
|
||||
dependencies = ["appflowy-core-release"]
|
||||
run_task = { name = [
|
||||
"code_generation",
|
||||
"set-app-version",
|
||||
"flutter-build",
|
||||
"copy-to-product",
|
||||
] }
|
||||
@@ -16,7 +15,6 @@ script_runner = "@shell"
|
||||
[tasks.appflowy-macos-universal]
|
||||
run_task = { name = [
|
||||
"code_generation",
|
||||
"set-app-version",
|
||||
"flutter-build",
|
||||
"copy-to-product",
|
||||
] }
|
||||
@@ -71,7 +69,6 @@ linux_alias = "appflowy-linux-dev"
|
||||
dependencies = ["appflowy-core-dev-ios"]
|
||||
run_task = { name = [
|
||||
"code_generation",
|
||||
"set-app-version",
|
||||
"flutter-build-ios",
|
||||
] }
|
||||
script_runner = "@shell"
|
||||
@@ -80,7 +77,6 @@ script_runner = "@shell"
|
||||
dependencies = ["appflowy-core-dev-android"]
|
||||
run_task = { name = [
|
||||
"code_generation",
|
||||
"set-app-version",
|
||||
"flutter-build-android",
|
||||
] }
|
||||
script_runner = "@shell"
|
||||
@@ -89,7 +85,6 @@ script_runner = "@shell"
|
||||
dependencies = ["appflowy-core-dev-android"]
|
||||
run_task = { name = [
|
||||
"code_generation",
|
||||
"set-app-version",
|
||||
"flutter-build-android",
|
||||
] }
|
||||
script_runner = "@shell"
|
||||
@@ -98,7 +93,6 @@ script_runner = "@shell"
|
||||
dependencies = ["appflowy-core-dev"]
|
||||
run_task = { name = [
|
||||
"code_generation",
|
||||
"set-app-version",
|
||||
"flutter-build",
|
||||
"copy-to-product",
|
||||
] }
|
||||
@@ -108,7 +102,6 @@ script_runner = "@shell"
|
||||
dependencies = ["appflowy-core-dev"]
|
||||
run_task = { name = [
|
||||
"code_generation",
|
||||
"set-app-version",
|
||||
"flutter-build",
|
||||
"copy-to-product",
|
||||
] }
|
||||
@@ -117,7 +110,6 @@ run_task = { name = [
|
||||
dependencies = ["appflowy-core-dev"]
|
||||
run_task = { name = [
|
||||
"code_generation",
|
||||
"set-app-version",
|
||||
"flutter-build",
|
||||
"copy-to-product",
|
||||
] }
|
||||
@@ -216,15 +208,6 @@ script = [
|
||||
]
|
||||
script_runner = "@duckscript"
|
||||
|
||||
[tasks.set-app-version]
|
||||
script = ["""
|
||||
if is_empty ${APP_VERSION}
|
||||
APP_VERSION = set ${CURRENT_APP_VERSION}
|
||||
set_env APP_VERSION ${CURRENT_APP_VERSION}
|
||||
end
|
||||
echo APP_VERSION: ${APP_VERSION}
|
||||
"""]
|
||||
script_runner = "@duckscript"
|
||||
|
||||
# The following tasks will create an archive that will be used on the GitHub Releases section
|
||||
# The archives are created using different compression programs depending on the target OS
|
||||
|
||||
@@ -12,7 +12,7 @@ condition = { env_set = [
|
||||
|
||||
[tasks.appflowy-core-dev-ios]
|
||||
category = "Build"
|
||||
dependencies = ["env_check"]
|
||||
dependencies = ["env_check", "set-app-version"]
|
||||
run_task = { name = [
|
||||
"setup-crate-type",
|
||||
"sdk-build-ios",
|
||||
@@ -21,6 +21,7 @@ run_task = { name = [
|
||||
] }
|
||||
|
||||
[tasks.sdk-build-ios]
|
||||
dependencies = ["set-app-version"]
|
||||
private = true
|
||||
script = [
|
||||
"""
|
||||
@@ -40,7 +41,7 @@ script_runner = "@shell"
|
||||
|
||||
[tasks.appflowy-core-dev-android]
|
||||
category = "Build"
|
||||
dependencies = ["env_check"]
|
||||
dependencies = ["env_check", "set-app-version"]
|
||||
run_task = { name = [
|
||||
"setup-crate-type",
|
||||
"sdk-build-android",
|
||||
@@ -49,6 +50,7 @@ run_task = { name = [
|
||||
] }
|
||||
|
||||
[tasks.sdk-build-android]
|
||||
dependencies = ["set-app-version"]
|
||||
private = true
|
||||
script = [
|
||||
"""
|
||||
|
||||
Reference in new issue
Block a user