chore: sync chat document when open chat (#7016)

* chore: sync document

* chore: auto create chat title
This commit is contained in:
Nathan.fooo 2024-12-20 00:15:01 +08:00 committed by GitHub
parent ee96a44fef
commit d25a399aba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 425 additions and 184 deletions

View File

@ -6,6 +6,7 @@ import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-ai/entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/code.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-error/code.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_result/appflowy_result.dart'; import 'package:appflowy_result/appflowy_result.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:fixnum/fixnum.dart'; import 'package:fixnum/fixnum.dart';
@ -64,6 +65,9 @@ class ChatBloc extends Bloc<ChatEvent, ChatState> {
Future<void> close() async { Future<void> close() async {
await answerStream?.dispose(); await answerStream?.dispose();
await listener.stop(); await listener.stop();
final request = ViewIdPB(value: chatId);
unawaited(FolderEventCloseView(request).send());
return super.close(); return super.close();
} }

View File

@ -172,7 +172,7 @@ checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7"
[[package]] [[package]]
name = "app-error" name = "app-error"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -192,7 +192,7 @@ dependencies = [
[[package]] [[package]]
name = "appflowy-ai-client" name = "appflowy-ai-client"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -888,7 +888,7 @@ dependencies = [
[[package]] [[package]]
name = "client-api" name = "client-api"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"again", "again",
"anyhow", "anyhow",
@ -944,7 +944,7 @@ dependencies = [
[[package]] [[package]]
name = "client-api-entity" name = "client-api-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"collab-entity", "collab-entity",
"collab-rt-entity", "collab-rt-entity",
@ -957,7 +957,7 @@ dependencies = [
[[package]] [[package]]
name = "client-websocket" name = "client-websocket"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-util", "futures-util",
@ -1257,7 +1257,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-rt-entity" name = "collab-rt-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -1282,7 +1282,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-rt-protocol" name = "collab-rt-protocol"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -1554,7 +1554,7 @@ dependencies = [
"cssparser-macros", "cssparser-macros",
"dtoa-short", "dtoa-short",
"itoa 1.0.6", "itoa 1.0.6",
"phf 0.11.2", "phf 0.8.0",
"smallvec", "smallvec",
] ]
@ -1679,7 +1679,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
[[package]] [[package]]
name = "database-entity" name = "database-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
@ -3268,7 +3268,7 @@ dependencies = [
[[package]] [[package]]
name = "gotrue" name = "gotrue"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"futures-util", "futures-util",
@ -3285,7 +3285,7 @@ dependencies = [
[[package]] [[package]]
name = "gotrue-entity" name = "gotrue-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
@ -3840,7 +3840,7 @@ dependencies = [
[[package]] [[package]]
name = "infra" name = "infra"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -6576,7 +6576,7 @@ dependencies = [
[[package]] [[package]]
name = "shared-entity" name = "shared-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",

View File

@ -59,7 +59,7 @@ collab-importer = { version = "0.1" }
# Run the script: # Run the script:
# scripts/tool/update_client_api_rev.sh new_rev_id # scripts/tool/update_client_api_rev.sh new_rev_id
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "9f57fa63d5ee039f50b0d27b860679deb14fee2e" } client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ea131f0baab67defe7591067357eced490072372" }
[dependencies] [dependencies]
serde_json.workspace = true serde_json.workspace = true

View File

@ -163,7 +163,7 @@ checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7"
[[package]] [[package]]
name = "app-error" name = "app-error"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -183,7 +183,7 @@ dependencies = [
[[package]] [[package]]
name = "appflowy-ai-client" name = "appflowy-ai-client"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -877,7 +877,7 @@ dependencies = [
[[package]] [[package]]
name = "client-api" name = "client-api"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"again", "again",
"anyhow", "anyhow",
@ -933,7 +933,7 @@ dependencies = [
[[package]] [[package]]
name = "client-api-entity" name = "client-api-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"collab-entity", "collab-entity",
"collab-rt-entity", "collab-rt-entity",
@ -946,7 +946,7 @@ dependencies = [
[[package]] [[package]]
name = "client-websocket" name = "client-websocket"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-util", "futures-util",
@ -1255,7 +1255,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-rt-entity" name = "collab-rt-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -1280,7 +1280,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-rt-protocol" name = "collab-rt-protocol"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -1559,7 +1559,7 @@ dependencies = [
"cssparser-macros", "cssparser-macros",
"dtoa-short", "dtoa-short",
"itoa 1.0.10", "itoa 1.0.10",
"phf 0.11.2", "phf 0.8.0",
"smallvec", "smallvec",
] ]
@ -1684,7 +1684,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
[[package]] [[package]]
name = "database-entity" name = "database-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
@ -3350,7 +3350,7 @@ dependencies = [
[[package]] [[package]]
name = "gotrue" name = "gotrue"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"futures-util", "futures-util",
@ -3367,7 +3367,7 @@ dependencies = [
[[package]] [[package]]
name = "gotrue-entity" name = "gotrue-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
@ -3927,7 +3927,7 @@ dependencies = [
[[package]] [[package]]
name = "infra" name = "infra"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -6656,7 +6656,7 @@ dependencies = [
[[package]] [[package]]
name = "shared-entity" name = "shared-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",

View File

@ -58,7 +58,7 @@ collab-importer = { version = "0.1" }
# Run the script: # Run the script:
# scripts/tool/update_client_api_rev.sh new_rev_id # scripts/tool/update_client_api_rev.sh new_rev_id
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "9f57fa63d5ee039f50b0d27b860679deb14fee2e" } client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ea131f0baab67defe7591067357eced490072372" }
[dependencies] [dependencies]
serde_json.workspace = true serde_json.workspace = true

View File

@ -163,7 +163,7 @@ checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7"
[[package]] [[package]]
name = "app-error" name = "app-error"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -183,7 +183,7 @@ dependencies = [
[[package]] [[package]]
name = "appflowy-ai-client" name = "appflowy-ai-client"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -780,7 +780,7 @@ dependencies = [
[[package]] [[package]]
name = "client-api" name = "client-api"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"again", "again",
"anyhow", "anyhow",
@ -836,7 +836,7 @@ dependencies = [
[[package]] [[package]]
name = "client-api-entity" name = "client-api-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"collab-entity", "collab-entity",
"collab-rt-entity", "collab-rt-entity",
@ -849,7 +849,7 @@ dependencies = [
[[package]] [[package]]
name = "client-websocket" name = "client-websocket"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-util", "futures-util",
@ -1118,7 +1118,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-rt-entity" name = "collab-rt-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode", "bincode",
@ -1143,7 +1143,7 @@ dependencies = [
[[package]] [[package]]
name = "collab-rt-protocol" name = "collab-rt-protocol"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -1538,7 +1538,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
[[package]] [[package]]
name = "database-entity" name = "database-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
@ -2982,7 +2982,7 @@ dependencies = [
[[package]] [[package]]
name = "gotrue" name = "gotrue"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"futures-util", "futures-util",
@ -2999,7 +2999,7 @@ dependencies = [
[[package]] [[package]]
name = "gotrue-entity" name = "gotrue-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",
@ -3484,7 +3484,7 @@ dependencies = [
[[package]] [[package]]
name = "infra" name = "infra"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@ -5841,7 +5841,7 @@ dependencies = [
[[package]] [[package]]
name = "shared-entity" name = "shared-entity"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9f57fa63d5ee039f50b0d27b860679deb14fee2e#9f57fa63d5ee039f50b0d27b860679deb14fee2e" source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ea131f0baab67defe7591067357eced490072372#ea131f0baab67defe7591067357eced490072372"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"app-error", "app-error",

View File

@ -107,8 +107,8 @@ dashmap = "6.0.1"
# Run the script.add_workspace_members: # Run the script.add_workspace_members:
# scripts/tool/update_client_api_rev.sh new_rev_id # scripts/tool/update_client_api_rev.sh new_rev_id
# ⚠️⚠️⚠️️ # ⚠️⚠️⚠️️
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "9f57fa63d5ee039f50b0d27b860679deb14fee2e" } client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ea131f0baab67defe7591067357eced490072372" }
client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "9f57fa63d5ee039f50b0d27b860679deb14fee2e" } client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ea131f0baab67defe7591067357eced490072372" }
[profile.dev] [profile.dev]
opt-level = 0 opt-level = 0

View File

@ -1,4 +1,4 @@
use flowy_folder::view_operation::{EncodedCollabType, ViewData}; use flowy_folder::view_operation::{GatherEncodedCollab, ViewData};
use std::sync::Arc; use std::sync::Arc;
use collab_folder::{FolderData, View}; use collab_folder::{FolderData, View};
@ -190,14 +190,14 @@ impl EventIntegrationTest {
payload.unwrap() payload.unwrap()
} }
pub async fn get_encoded_collab_v1_from_disk( pub async fn gather_encode_collab_from_disk(
&self, &self,
view_id: &str, view_id: &str,
layout: ViewLayout, layout: ViewLayout,
) -> EncodedCollabType { ) -> GatherEncodedCollab {
self self
.folder_manager .folder_manager
.get_encode_collab_from_disk(view_id, &layout) .gather_publish_encode_collab(view_id, &layout)
.await .await
.unwrap() .unwrap()
} }

View File

@ -5,7 +5,7 @@ use event_integration_test::EventIntegrationTest;
use flowy_folder::entities::{ use flowy_folder::entities::{
ImportItemPayloadPB, ImportPayloadPB, ImportTypePB, ViewLayoutPB, ViewPB, ImportItemPayloadPB, ImportPayloadPB, ImportTypePB, ViewLayoutPB, ViewPB,
}; };
use flowy_folder::view_operation::EncodedCollabType; use flowy_folder::view_operation::GatherEncodedCollab;
use crate::util::unzip; use crate::util::unzip;
@ -18,11 +18,11 @@ async fn publish_single_database_test() {
let grid = import_csv("publish_grid_primary.csv", &test).await; let grid = import_csv("publish_grid_primary.csv", &test).await;
let grid_encoded_collab = test let grid_encoded_collab = test
.get_encoded_collab_v1_from_disk(&grid.id, ViewLayout::Grid) .gather_encode_collab_from_disk(&grid.id, ViewLayout::Grid)
.await; .await;
match grid_encoded_collab { match grid_encoded_collab {
EncodedCollabType::Database(encoded_collab) => { GatherEncodedCollab::Database(encoded_collab) => {
// the len of row collabs should be the same as the number of rows in the csv file // the len of row collabs should be the same as the number of rows in the csv file
let rows_len = encoded_collab.database_row_encoded_collabs.len(); let rows_len = encoded_collab.database_row_encoded_collabs.len();
assert_eq!(rows_len, 18); assert_eq!(rows_len, 18);
@ -106,11 +106,11 @@ async fn test_publish_encode_collab_result(
test.open_database(&id).await; test.open_database(&id).await;
let encoded_collab = test let encoded_collab = test
.get_encoded_collab_v1_from_disk(&id, layout.into()) .gather_encode_collab_from_disk(&id, layout.into())
.await; .await;
match encoded_collab { match encoded_collab {
EncodedCollabType::Database(encoded_collab) => { GatherEncodedCollab::Database(encoded_collab) => {
if let Some(rows_len) = expectations.get(&view.name.as_str()) { if let Some(rows_len) = expectations.get(&view.name.as_str()) {
assert_eq!(encoded_collab.database_row_encoded_collabs.len(), *rows_len); assert_eq!(encoded_collab.database_row_encoded_collabs.len(), *rows_len);
} }

View File

@ -2,7 +2,7 @@ use collab_folder::ViewLayout;
use event_integration_test::EventIntegrationTest; use event_integration_test::EventIntegrationTest;
use flowy_folder::entities::{ViewLayoutPB, ViewPB}; use flowy_folder::entities::{ViewLayoutPB, ViewPB};
use flowy_folder::publish_util::generate_publish_name; use flowy_folder::publish_util::generate_publish_name;
use flowy_folder::view_operation::EncodedCollabType; use flowy_folder::view_operation::GatherEncodedCollab;
use flowy_folder_pub::entities::{ use flowy_folder_pub::entities::{
PublishDocumentPayload, PublishPayload, PublishViewInfo, PublishViewMeta, PublishViewMetaData, PublishDocumentPayload, PublishPayload, PublishViewInfo, PublishViewMeta, PublishViewMetaData,
}; };
@ -14,7 +14,7 @@ async fn mock_single_document_view_publish_payload(
) -> Vec<PublishPayload> { ) -> Vec<PublishPayload> {
let view_id = &view.id; let view_id = &view.id;
let layout: ViewLayout = view.layout.clone().into(); let layout: ViewLayout = view.layout.clone().into();
let view_encoded_collab = test.get_encoded_collab_v1_from_disk(view_id, layout).await; let view_encoded_collab = test.gather_encode_collab_from_disk(view_id, layout).await;
let publish_view_info = PublishViewInfo { let publish_view_info = PublishViewInfo {
view_id: view_id.to_string(), view_id: view_id.to_string(),
name: view.name.to_string(), name: view.name.to_string(),
@ -29,7 +29,7 @@ async fn mock_single_document_view_publish_payload(
}; };
let data = match view_encoded_collab { let data = match view_encoded_collab {
EncodedCollabType::Document(doc) => doc.document_encoded_collab.doc_state.to_vec(), GatherEncodedCollab::Document(doc) => doc.doc_state.to_vec(),
_ => panic!("Expected document collab"), _ => panic!("Expected document collab"),
}; };
@ -54,7 +54,7 @@ async fn mock_nested_document_view_publish_payload(
) -> Vec<PublishPayload> { ) -> Vec<PublishPayload> {
let view_id = &view.id; let view_id = &view.id;
let layout: ViewLayout = view.layout.clone().into(); let layout: ViewLayout = view.layout.clone().into();
let view_encoded_collab = test.get_encoded_collab_v1_from_disk(view_id, layout).await; let view_encoded_collab = test.gather_encode_collab_from_disk(view_id, layout).await;
let publish_view_info = PublishViewInfo { let publish_view_info = PublishViewInfo {
view_id: view_id.to_string(), view_id: view_id.to_string(),
name: view.name.to_string(), name: view.name.to_string(),
@ -72,7 +72,7 @@ async fn mock_nested_document_view_publish_payload(
let child_view = test.get_view(child_view_id).await; let child_view = test.get_view(child_view_id).await;
let child_layout: ViewLayout = child_view.layout.clone().into(); let child_layout: ViewLayout = child_view.layout.clone().into();
let child_view_encoded_collab = test let child_view_encoded_collab = test
.get_encoded_collab_v1_from_disk(child_view_id, child_layout) .gather_encode_collab_from_disk(child_view_id, child_layout)
.await; .await;
let child_publish_view_info = PublishViewInfo { let child_publish_view_info = PublishViewInfo {
view_id: child_view_id.to_string(), view_id: child_view_id.to_string(),
@ -89,12 +89,12 @@ async fn mock_nested_document_view_publish_payload(
let child_publish_name = generate_publish_name(&child_view.id, &child_view.name); let child_publish_name = generate_publish_name(&child_view.id, &child_view.name);
let data = match view_encoded_collab { let data = match view_encoded_collab {
EncodedCollabType::Document(doc) => doc.document_encoded_collab.doc_state.to_vec(), GatherEncodedCollab::Document(doc) => doc.doc_state.to_vec(),
_ => panic!("Expected document collab"), _ => panic!("Expected document collab"),
}; };
let child_data = match child_view_encoded_collab { let child_data = match child_view_encoded_collab {
EncodedCollabType::Document(doc) => doc.document_encoded_collab.doc_state.to_vec(), GatherEncodedCollab::Document(doc) => doc.doc_state.to_vec(),
_ => panic!("Expected document collab"), _ => panic!("Expected document collab"),
}; };

View File

@ -1,6 +1,6 @@
use crate::chat::Chat; use crate::chat::Chat;
use crate::entities::{ use crate::entities::{
ChatInfoPB, ChatMessageListPB, ChatMessagePB, FilePB, RepeatedRelatedQuestionPB, ChatInfoPB, ChatMessageListPB, ChatMessagePB, ChatSettingsPB, FilePB, RepeatedRelatedQuestionPB,
}; };
use crate::local_ai::local_llm_chat::LocalAIController; use crate::local_ai::local_llm_chat::LocalAIController;
use crate::middleware::chat_service_mw::AICloudServiceMiddleware; use crate::middleware::chat_service_mw::AICloudServiceMiddleware;
@ -9,18 +9,19 @@ use crate::persistence::{insert_chat, read_chat_metadata, ChatTable};
use appflowy_plugin::manager::PluginManager; use appflowy_plugin::manager::PluginManager;
use dashmap::DashMap; use dashmap::DashMap;
use flowy_ai_pub::cloud::{ use flowy_ai_pub::cloud::{
ChatCloudService, ChatMessageMetadata, ChatMessageType, UpdateChatParams, ChatCloudService, ChatMessageMetadata, ChatMessageType, ChatSettings, UpdateChatParams,
}; };
use flowy_error::{FlowyError, FlowyResult}; use flowy_error::{FlowyError, FlowyResult};
use flowy_sqlite::kv::KVStorePreferences; use flowy_sqlite::kv::KVStorePreferences;
use flowy_sqlite::DBConnection; use flowy_sqlite::DBConnection;
use crate::notification::{chat_notification_builder, ChatNotification};
use flowy_storage_pub::storage::StorageService; use flowy_storage_pub::storage::StorageService;
use lib_infra::async_trait::async_trait; use lib_infra::async_trait::async_trait;
use lib_infra::util::timestamp; use lib_infra::util::timestamp;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use tracing::{info, trace}; use tracing::{error, info, trace};
pub trait AIUserService: Send + Sync + 'static { pub trait AIUserService: Send + Sync + 'static {
fn user_id(&self) -> Result<i64, FlowyError>; fn user_id(&self) -> Result<i64, FlowyError>;
@ -31,22 +32,29 @@ pub trait AIUserService: Send + Sync + 'static {
} }
#[async_trait] #[async_trait]
pub trait AIQueryService: Send + Sync + 'static { pub trait AIExternalService: Send + Sync + 'static {
async fn query_chat_rag_ids( async fn query_chat_rag_ids(
&self, &self,
parent_view_id: &str, parent_view_id: &str,
chat_id: &str, chat_id: &str,
) -> Result<Vec<String>, FlowyError>; ) -> Result<Vec<String>, FlowyError>;
async fn sync_rag_documents(&self, rag_ids: Vec<String>) -> Result<(), FlowyError>; async fn sync_rag_documents(
&self,
workspace_id: &str,
rag_ids: Vec<String>,
) -> Result<(), FlowyError>;
async fn notify_did_send_message(&self, chat_id: &str, message: &str) -> Result<(), FlowyError>;
} }
pub struct AIManager { pub struct AIManager {
pub cloud_service_wm: Arc<AICloudServiceMiddleware>, pub cloud_service_wm: Arc<AICloudServiceMiddleware>,
pub user_service: Arc<dyn AIUserService>, pub user_service: Arc<dyn AIUserService>,
pub query_service: Arc<dyn AIQueryService>, pub external_service: Arc<dyn AIExternalService>,
chats: Arc<DashMap<String, Arc<Chat>>>, chats: Arc<DashMap<String, Arc<Chat>>>,
pub local_ai_controller: Arc<LocalAIController>, pub local_ai_controller: Arc<LocalAIController>,
store_preferences: Arc<KVStorePreferences>,
} }
impl AIManager { impl AIManager {
@ -55,7 +63,7 @@ impl AIManager {
user_service: impl AIUserService, user_service: impl AIUserService,
store_preferences: Arc<KVStorePreferences>, store_preferences: Arc<KVStorePreferences>,
storage_service: Weak<dyn StorageService>, storage_service: Weak<dyn StorageService>,
query_service: impl AIQueryService, query_service: impl AIExternalService,
) -> AIManager { ) -> AIManager {
let user_service = Arc::new(user_service); let user_service = Arc::new(user_service);
let plugin_manager = Arc::new(PluginManager::new()); let plugin_manager = Arc::new(PluginManager::new());
@ -65,7 +73,7 @@ impl AIManager {
user_service.clone(), user_service.clone(),
chat_cloud_service.clone(), chat_cloud_service.clone(),
)); ));
let query_service = Arc::new(query_service); let external_service = Arc::new(query_service);
// setup local chat service // setup local chat service
let cloud_service_wm = Arc::new(AICloudServiceMiddleware::new( let cloud_service_wm = Arc::new(AICloudServiceMiddleware::new(
@ -80,7 +88,8 @@ impl AIManager {
user_service, user_service,
chats: Arc::new(DashMap::new()), chats: Arc::new(DashMap::new()),
local_ai_controller, local_ai_controller,
query_service, external_service,
store_preferences,
} }
} }
@ -99,12 +108,41 @@ impl AIManager {
self.cloud_service_wm.clone(), self.cloud_service_wm.clone(),
)) ))
}); });
trace!("[AI Plugin] notify open chat: {}", chat_id); trace!("[AI Plugin] notify open chat: {}", chat_id);
if self.local_ai_controller.is_running() { if self.local_ai_controller.is_running() {
self.local_ai_controller.open_chat(chat_id); self.local_ai_controller.open_chat(chat_id);
} }
let user_service = self.user_service.clone();
let cloud_service_wm = self.cloud_service_wm.clone();
let store_preferences = self.store_preferences.clone();
let external_service = self.external_service.clone();
let chat_id = chat_id.to_string();
tokio::spawn(async move {
match refresh_chat_setting(
&user_service,
&cloud_service_wm,
&store_preferences,
&chat_id,
)
.await
{
Ok(settings) => {
if settings.rag_ids.is_empty() {
return;
}
if let Ok(workspace_id) = user_service.workspace_id() {
let _ = external_service
.sync_rag_documents(&workspace_id, settings.rag_ids)
.await;
}
},
Err(err) => {
error!("failed to refresh chat settings: {}", err);
},
}
});
Ok(()) Ok(())
} }
@ -152,7 +190,7 @@ impl AIManager {
) -> Result<Arc<Chat>, FlowyError> { ) -> Result<Arc<Chat>, FlowyError> {
let workspace_id = self.user_service.workspace_id()?; let workspace_id = self.user_service.workspace_id()?;
let rag_ids = self let rag_ids = self
.query_service .external_service
.query_chat_rag_ids(parent_view_id, chat_id) .query_chat_rag_ids(parent_view_id, chat_id)
.await .await
.unwrap_or_default(); .unwrap_or_default();
@ -193,6 +231,10 @@ impl AIManager {
metadata, metadata,
) )
.await?; .await?;
let _ = self
.external_service
.notify_did_send_message(chat_id, message)
.await;
Ok(question) Ok(question)
} }
@ -302,31 +344,48 @@ impl AIManager {
Ok(()) Ok(())
} }
pub fn local_ai_purchased(&self) {}
pub async fn get_rag_ids(&self, chat_id: &str) -> FlowyResult<Vec<String>> { pub async fn get_rag_ids(&self, chat_id: &str) -> FlowyResult<Vec<String>> {
let workspace_id = self.user_service.workspace_id()?; if let Some(settings) = self
.store_preferences
.get_object::<ChatSettings>(&setting_store_key(chat_id))
{
return Ok(settings.rag_ids);
}
let settings = self let settings = refresh_chat_setting(
.cloud_service_wm &self.user_service,
.get_chat_settings(&workspace_id, chat_id) &self.cloud_service_wm,
&self.store_preferences,
chat_id,
)
.await?; .await?;
Ok(settings.rag_ids) Ok(settings.rag_ids)
} }
pub async fn update_rag_ids(&self, chat_id: &str, rag_ids: Vec<String>) -> FlowyResult<()> { pub async fn update_rag_ids(&self, chat_id: &str, rag_ids: Vec<String>) -> FlowyResult<()> {
info!("[Chat] update chat:{} rag ids: {:?}", chat_id, rag_ids);
if !rag_ids.is_empty() { if !rag_ids.is_empty() {
let workspace_id = self.user_service.workspace_id()?; let workspace_id = self.user_service.workspace_id()?;
let update_setting = UpdateChatParams { let update_setting = UpdateChatParams {
name: None, name: None,
metadata: None, metadata: None,
rag_ids: Some(rag_ids), rag_ids: Some(rag_ids.clone()),
}; };
self self
.cloud_service_wm .cloud_service_wm
.update_chat_settings(&workspace_id, chat_id, update_setting) .update_chat_settings(&workspace_id, chat_id, update_setting)
.await?; .await?;
let user_service = self.user_service.clone();
let external_service = self.external_service.clone();
tokio::spawn(async move {
if let Ok(workspace_id) = user_service.workspace_id() {
let _ = external_service
.sync_rag_documents(&workspace_id, rag_ids)
.await;
}
});
} }
Ok(()) Ok(())
} }
@ -346,3 +405,32 @@ fn save_chat(conn: DBConnection, chat_id: &str) -> FlowyResult<()> {
insert_chat(conn, &row)?; insert_chat(conn, &row)?;
Ok(()) Ok(())
} }
async fn refresh_chat_setting(
user_service: &Arc<dyn AIUserService>,
cloud_service: &Arc<AICloudServiceMiddleware>,
store_preferences: &Arc<KVStorePreferences>,
chat_id: &str,
) -> FlowyResult<ChatSettings> {
info!("[Chat] refresh chat:{} setting", chat_id);
let workspace_id = user_service.workspace_id()?;
let settings = cloud_service
.get_chat_settings(&workspace_id, chat_id)
.await?;
if let Err(err) = store_preferences.set_object(&setting_store_key(chat_id), &settings) {
error!("failed to set chat settings: {}", err);
}
chat_notification_builder(chat_id, ChatNotification::DidUpdateChatSettings)
.payload(ChatSettingsPB {
rag_ids: settings.rag_ids.clone(),
})
.send();
Ok(settings)
}
fn setting_store_key(chat_id: &str) -> String {
format!("chat_settings_{}", chat_id)
}

View File

@ -14,6 +14,7 @@ pub enum ChatNotification {
FinishStreaming = 5, FinishStreaming = 5,
UpdateChatPluginState = 6, UpdateChatPluginState = 6,
UpdateLocalChatAI = 7, UpdateLocalChatAI = 7,
DidUpdateChatSettings = 8,
} }
impl std::convert::From<ChatNotification> for i32 { impl std::convert::From<ChatNotification> for i32 {

View File

@ -1,8 +1,10 @@
use flowy_ai::ai_manager::{AIManager, AIQueryService, AIUserService}; use collab_entity::CollabType;
use flowy_ai::ai_manager::{AIExternalService, AIManager, AIUserService};
use flowy_ai_pub::cloud::ChatCloudService; use flowy_ai_pub::cloud::ChatCloudService;
use flowy_error::FlowyError; use flowy_error::FlowyError;
use flowy_folder::ViewLayout; use flowy_folder::ViewLayout;
use flowy_folder_pub::query::FolderQueryService; use flowy_folder_pub::cloud::{FolderCloudService, FullSyncCollabParams};
use flowy_folder_pub::query::FolderService;
use flowy_sqlite::kv::KVStorePreferences; use flowy_sqlite::kv::KVStorePreferences;
use flowy_sqlite::DBConnection; use flowy_sqlite::DBConnection;
use flowy_storage_pub::storage::StorageService; use flowy_storage_pub::storage::StorageService;
@ -10,6 +12,7 @@ use flowy_user::services::authenticate_user::AuthenticateUser;
use lib_infra::async_trait::async_trait; use lib_infra::async_trait::async_trait;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use tracing::{error, info};
pub struct ChatDepsResolver; pub struct ChatDepsResolver;
@ -19,7 +22,8 @@ impl ChatDepsResolver {
cloud_service: Arc<dyn ChatCloudService>, cloud_service: Arc<dyn ChatCloudService>,
store_preferences: Arc<KVStorePreferences>, store_preferences: Arc<KVStorePreferences>,
storage_service: Weak<dyn StorageService>, storage_service: Weak<dyn StorageService>,
folder_query: impl FolderQueryService, folder_cloud_service: Arc<dyn FolderCloudService>,
folder_service: impl FolderService,
) -> Arc<AIManager> { ) -> Arc<AIManager> {
let user_service = ChatUserServiceImpl(authenticate_user); let user_service = ChatUserServiceImpl(authenticate_user);
Arc::new(AIManager::new( Arc::new(AIManager::new(
@ -28,25 +32,27 @@ impl ChatDepsResolver {
store_preferences, store_preferences,
storage_service, storage_service,
ChatQueryServiceImpl { ChatQueryServiceImpl {
folder_query: Box::new(folder_query), folder_service: Box::new(folder_service),
folder_cloud_service,
}, },
)) ))
} }
} }
struct ChatQueryServiceImpl { struct ChatQueryServiceImpl {
folder_query: Box<dyn FolderQueryService>, folder_service: Box<dyn FolderService>,
folder_cloud_service: Arc<dyn FolderCloudService>,
} }
#[async_trait] #[async_trait]
impl AIQueryService for ChatQueryServiceImpl { impl AIExternalService for ChatQueryServiceImpl {
async fn query_chat_rag_ids( async fn query_chat_rag_ids(
&self, &self,
parent_view_id: &str, parent_view_id: &str,
chat_id: &str, chat_id: &str,
) -> Result<Vec<String>, FlowyError> { ) -> Result<Vec<String>, FlowyError> {
let mut ids = self let mut ids = self
.folder_query .folder_service
.get_sibling_ids_with_view_layout(parent_view_id, ViewLayout::Document) .get_sibling_ids_with_view_layout(parent_view_id, ViewLayout::Document)
.await; .await;
@ -57,12 +63,46 @@ impl AIQueryService for ChatQueryServiceImpl {
Ok(ids) Ok(ids)
} }
async fn sync_rag_documents(&self, rag_ids: Vec<String>) -> Result<(), FlowyError> { async fn sync_rag_documents(
&self,
workspace_id: &str,
rag_ids: Vec<String>,
) -> Result<(), FlowyError> {
info!("sync_rag_documents: {:?}", rag_ids);
for rag_id in rag_ids.iter() { for rag_id in rag_ids.iter() {
if let Some(_query_collab) = self.folder_query.get_collab(rag_id).await { if let Some(query_collab) = self
// TODO(nathan): sync .folder_service
.get_collab(rag_id, CollabType::Document)
.await
{
let params = FullSyncCollabParams {
object_id: rag_id.clone(),
collab_type: CollabType::Document,
encoded_collab: query_collab.encoded_collab,
};
match self
.folder_cloud_service
.full_sync_collab_object(workspace_id, params)
.await
{
Ok(_) => info!("[Chat] full sync rag document: {}", rag_id),
Err(err) => error!("failed to sync rag document:{} error:{}", rag_id, err),
} }
} }
}
Ok(())
}
async fn notify_did_send_message(&self, chat_id: &str, message: &str) -> Result<(), FlowyError> {
info!(
"notify_did_send_message: chat_id: {}, message: {}",
chat_id, message
);
self
.folder_service
.set_view_title_if_empty(chat_id, message)
.await?;
Ok(()) Ok(())
} }
} }

View File

@ -12,13 +12,12 @@ use flowy_database2::DatabaseManager;
use flowy_document::entities::DocumentDataPB; use flowy_document::entities::DocumentDataPB;
use flowy_document::manager::DocumentManager; use flowy_document::manager::DocumentManager;
use flowy_document::parser::json::parser::JsonToDocumentParser; use flowy_document::parser::json::parser::JsonToDocumentParser;
use flowy_error::{FlowyError, FlowyResult}; use flowy_error::{internal_error, FlowyError, FlowyResult};
use flowy_folder::entities::{CreateViewParams, ViewLayoutPB}; use flowy_folder::entities::{CreateViewParams, UpdateViewParams, ViewLayoutPB};
use flowy_folder::manager::{FolderManager, FolderUser}; use flowy_folder::manager::{FolderManager, FolderUser};
use flowy_folder::share::ImportType; use flowy_folder::share::ImportType;
use flowy_folder::view_operation::{ use flowy_folder::view_operation::{
DatabaseEncodedCollab, DocumentEncodedCollab, EncodedCollabType, FolderOperationHandler, DatabaseEncodedCollab, FolderOperationHandler, GatherEncodedCollab, ImportedData, View, ViewData,
ImportedData, View, ViewData,
}; };
use flowy_folder::ViewLayout; use flowy_folder::ViewLayout;
use flowy_search::folder::indexer::FolderIndexManagerImpl; use flowy_search::folder::indexer::FolderIndexManagerImpl;
@ -34,7 +33,7 @@ use tokio::sync::RwLock;
use crate::integrate::server::ServerProvider; use crate::integrate::server::ServerProvider;
use collab_plugins::local_storage::kv::KVTransactionDB; use collab_plugins::local_storage::kv::KVTransactionDB;
use flowy_folder_pub::query::{FolderQueryService, QueryCollab}; use flowy_folder_pub::query::{FolderQueryService, FolderService, FolderViewEdit, QueryCollab};
use lib_infra::async_trait::async_trait; use lib_infra::async_trait::async_trait;
pub struct FolderDepsResolver(); pub struct FolderDepsResolver();
@ -116,6 +115,10 @@ impl FolderUser for FolderUserImpl {
struct DocumentFolderOperation(Arc<DocumentManager>); struct DocumentFolderOperation(Arc<DocumentManager>);
#[async_trait] #[async_trait]
impl FolderOperationHandler for DocumentFolderOperation { impl FolderOperationHandler for DocumentFolderOperation {
fn name(&self) -> &str {
"DocumentFolderOperationHandler"
}
async fn create_workspace_view( async fn create_workspace_view(
&self, &self,
uid: i64, uid: i64,
@ -169,6 +172,16 @@ impl FolderOperationHandler for DocumentFolderOperation {
Ok(data_bytes) Ok(data_bytes)
} }
async fn gather_publish_encode_collab(
&self,
user: &Arc<dyn FolderUser>,
view_id: &str,
) -> Result<GatherEncodedCollab, FlowyError> {
let encoded_collab =
get_encoded_collab_v1_from_disk(user, view_id, CollabType::Document).await?;
Ok(GatherEncodedCollab::Document(encoded_collab))
}
async fn create_view_with_view_data( async fn create_view_with_view_data(
&self, &self,
user_id: i64, user_id: i64,
@ -209,47 +222,6 @@ impl FolderOperationHandler for DocumentFolderOperation {
} }
} }
async fn get_encoded_collab_v1_from_disk(
&self,
user: &Arc<dyn FolderUser>,
view_id: &str,
) -> Result<EncodedCollabType, FlowyError> {
// get the collab_object_id for the document.
// the collab_object_id for the document is the view_id.
let workspace_id = user.workspace_id()?;
let uid = user
.user_id()
.map_err(|e| e.with_context("unable to get the uid: {}"))?;
// get the collab db
let collab_db = user
.collab_db(uid)
.map_err(|e| e.with_context("unable to get the collab"))?;
let collab_db = collab_db.upgrade().ok_or_else(|| {
FlowyError::internal().with_context(
"The collab db has been dropped, indicating that the user has switched to a new account",
)
})?;
let collab_read_txn = collab_db.read_txn();
// read the collab from the db
let collab =
load_collab_by_object_id(uid, &collab_read_txn, &workspace_id, view_id).map_err(|e| {
FlowyError::internal().with_context(format!("load document collab failed: {}", e))
})?;
let encoded_collab = collab
// encode the collab and check the integrity of the collab
.encode_collab_v1(|collab| CollabType::Document.validate_require_data(collab))
.map_err(|e| {
FlowyError::internal().with_context(format!("encode document collab failed: {}", e))
})?;
Ok(EncodedCollabType::Document(DocumentEncodedCollab {
document_encoded_collab: encoded_collab,
}))
}
async fn import_from_bytes( async fn import_from_bytes(
&self, &self,
uid: i64, uid: i64,
@ -279,10 +251,6 @@ impl FolderOperationHandler for DocumentFolderOperation {
// TODO(lucas): import file from local markdown file // TODO(lucas): import file from local markdown file
Ok(()) Ok(())
} }
fn name(&self) -> &str {
"DocumentFolderOperationHandler"
}
} }
struct DatabaseFolderOperation(Arc<DatabaseManager>); struct DatabaseFolderOperation(Arc<DatabaseManager>);
@ -307,11 +275,11 @@ impl FolderOperationHandler for DatabaseFolderOperation {
Ok(()) Ok(())
} }
async fn get_encoded_collab_v1_from_disk( async fn gather_publish_encode_collab(
&self, &self,
user: &Arc<dyn FolderUser>, user: &Arc<dyn FolderUser>,
view_id: &str, view_id: &str,
) -> Result<EncodedCollabType, FlowyError> { ) -> Result<GatherEncodedCollab, FlowyError> {
let workspace_id = user.workspace_id()?; let workspace_id = user.workspace_id()?;
// get the collab_object_id for the database. // get the collab_object_id for the database.
// //
@ -349,7 +317,6 @@ impl FolderOperationHandler for DatabaseFolderOperation {
tokio::task::spawn_blocking(move || { tokio::task::spawn_blocking(move || {
let collab_read_txn = collab_db.read_txn(); let collab_read_txn = collab_db.read_txn();
let database_collab = load_collab_by_object_id(uid, &collab_read_txn, &workspace_id, &oid) let database_collab = load_collab_by_object_id(uid, &collab_read_txn, &workspace_id, &oid)
.map_err(|e| { .map_err(|e| {
FlowyError::internal().with_context(format!("load database collab failed: {}", e)) FlowyError::internal().with_context(format!("load database collab failed: {}", e))
@ -403,7 +370,7 @@ impl FolderOperationHandler for DatabaseFolderOperation {
}) })
.collect::<Result<HashMap<_, _>, FlowyError>>()?; .collect::<Result<HashMap<_, _>, FlowyError>>()?;
Ok(EncodedCollabType::Database(DatabaseEncodedCollab { Ok(GatherEncodedCollab::Database(DatabaseEncodedCollab {
database_encoded_collab, database_encoded_collab,
database_row_encoded_collabs, database_row_encoded_collabs,
database_row_document_encoded_collabs, database_row_document_encoded_collabs,
@ -663,19 +630,62 @@ impl FolderOperationHandler for ChatFolderOperation {
} }
} }
#[derive(Clone, Debug)] #[derive(Clone)]
pub struct FolderQueryServiceImpl { pub struct FolderServiceImpl {
folder_manager: Weak<FolderManager>, folder_manager: Weak<FolderManager>,
user: Arc<dyn FolderUser>,
} }
impl FolderService for FolderServiceImpl {}
impl FolderQueryServiceImpl { impl FolderServiceImpl {
pub fn new(folder_manager: Weak<FolderManager>) -> Self { pub fn new(
Self { folder_manager } folder_manager: Weak<FolderManager>,
authenticate_user: Weak<AuthenticateUser>,
) -> Self {
let user: Arc<dyn FolderUser> = Arc::new(FolderUserImpl { authenticate_user });
Self {
folder_manager,
user,
}
} }
} }
#[async_trait] #[async_trait]
impl FolderQueryService for FolderQueryServiceImpl { impl FolderViewEdit for FolderServiceImpl {
async fn set_view_title_if_empty(&self, view_id: &str, title: &str) -> FlowyResult<()> {
if title.is_empty() {
return Ok(());
}
if let Some(folder_manager) = self.folder_manager.upgrade() {
if let Ok(view) = folder_manager.get_view(view_id).await {
if view.name.is_empty() {
let title = if title.len() > 50 {
title.chars().take(50).collect()
} else {
title.to_string()
};
folder_manager
.update_view_with_params(UpdateViewParams {
view_id: view_id.to_string(),
name: Some(title),
desc: None,
thumbnail: None,
layout: None,
is_favorite: None,
extra: None,
})
.await?;
}
}
}
Ok(())
}
}
#[async_trait]
impl FolderQueryService for FolderServiceImpl {
async fn get_sibling_ids_with_view_layout( async fn get_sibling_ids_with_view_layout(
&self, &self,
parent_view_id: &str, parent_view_id: &str,
@ -708,8 +718,52 @@ impl FolderQueryService for FolderQueryServiceImpl {
} }
} }
async fn get_collab(&self, _object_id: &str) -> Option<QueryCollab> { async fn get_collab(&self, object_id: &str, collab_type: CollabType) -> Option<QueryCollab> {
// TODO(nathan): return query collab let encode_collab = get_encoded_collab_v1_from_disk(&self.user, object_id, collab_type.clone())
None .await
.ok();
encode_collab.map(|encoded_collab| QueryCollab {
collab_type,
encoded_collab,
})
} }
} }
#[inline]
async fn get_encoded_collab_v1_from_disk(
user: &Arc<dyn FolderUser>,
view_id: &str,
collab_type: CollabType,
) -> Result<EncodedCollab, FlowyError> {
let workspace_id = user.workspace_id()?;
let uid = user
.user_id()
.map_err(|e| e.with_context("unable to get the uid: {}"))?;
// get the collab db
let collab_db = user
.collab_db(uid)
.map_err(|e| e.with_context("unable to get the collab"))?;
let collab_db = collab_db.upgrade().ok_or_else(|| {
FlowyError::internal().with_context(
"The collab db has been dropped, indicating that the user has switched to a new account",
)
})?;
let collab_read_txn = collab_db.read_txn();
let collab =
load_collab_by_object_id(uid, &collab_read_txn, &workspace_id, view_id).map_err(|e| {
FlowyError::internal().with_context(format!("load document collab failed: {}", e))
})?;
tokio::task::spawn_blocking(move || {
let data = collab
.encode_collab_v1(|collab| collab_type.validate_require_data(collab))
.map_err(|e| {
FlowyError::internal().with_context(format!("encode document collab failed: {}", e))
})?;
Ok::<_, FlowyError>(data)
})
.await
.map_err(internal_error)?
}

View File

@ -33,7 +33,8 @@ use flowy_document::deps::DocumentData;
use flowy_document_pub::cloud::{DocumentCloudService, DocumentSnapshot}; use flowy_document_pub::cloud::{DocumentCloudService, DocumentSnapshot};
use flowy_error::{FlowyError, FlowyResult}; use flowy_error::{FlowyError, FlowyResult};
use flowy_folder_pub::cloud::{ use flowy_folder_pub::cloud::{
FolderCloudService, FolderCollabParams, FolderData, FolderSnapshot, Workspace, WorkspaceRecord, FolderCloudService, FolderCollabParams, FolderData, FolderSnapshot, FullSyncCollabParams,
Workspace, WorkspaceRecord,
}; };
use flowy_folder_pub::entities::PublishPayload; use flowy_folder_pub::entities::PublishPayload;
use flowy_server_pub::af_cloud_config::AFCloudConfiguration; use flowy_server_pub::af_cloud_config::AFCloudConfiguration;
@ -417,6 +418,18 @@ impl FolderCloudService for ServerProvider {
.import_zip(file_path) .import_zip(file_path)
.await .await
} }
async fn full_sync_collab_object(
&self,
workspace_id: &str,
params: FullSyncCollabParams,
) -> Result<(), FlowyError> {
self
.get_server()?
.folder_service()
.full_sync_collab_object(workspace_id, params)
.await
}
} }
#[async_trait] #[async_trait]

View File

@ -211,21 +211,15 @@ impl UserStatusCallback for UserStatusCallbackImpl {
fn did_update_plans(&self, plans: Vec<SubscriptionPlan>) { fn did_update_plans(&self, plans: Vec<SubscriptionPlan>) {
let mut storage_plan_changed = false; let mut storage_plan_changed = false;
let mut local_ai_enabled = false;
for plan in &plans { for plan in &plans {
match plan { match plan {
SubscriptionPlan::Pro | SubscriptionPlan::Team => storage_plan_changed = true, SubscriptionPlan::Pro | SubscriptionPlan::Team => storage_plan_changed = true,
SubscriptionPlan::AiLocal => local_ai_enabled = true,
_ => {}, _ => {},
} }
} }
if storage_plan_changed { if storage_plan_changed {
self.storage_manager.enable_storage_write_access(); self.storage_manager.enable_storage_write_access();
} }
if local_ai_enabled {
self.ai_manager.local_ai_purchased();
}
} }
fn did_update_storage_limitation(&self, can_write: bool) { fn did_update_storage_limitation(&self, can_write: bool) {

View File

@ -174,13 +174,17 @@ impl AppFlowyCore {
) )
.await; .await;
let folder_query_service = FolderQueryServiceImpl::new(Arc::downgrade(&folder_manager)); let folder_query_service = FolderServiceImpl::new(
Arc::downgrade(&folder_manager),
Arc::downgrade(&authenticate_user),
);
let ai_manager = ChatDepsResolver::resolve( let ai_manager = ChatDepsResolver::resolve(
Arc::downgrade(&authenticate_user), Arc::downgrade(&authenticate_user),
server_provider.clone(), server_provider.clone(),
store_preference.clone(), store_preference.clone(),
Arc::downgrade(&storage_manager.storage_service), Arc::downgrade(&storage_manager.storage_service),
server_provider.clone(),
folder_query_service.clone(), folder_query_service.clone(),
); );

View File

@ -1,6 +1,7 @@
use crate::entities::PublishPayload; use crate::entities::PublishPayload;
pub use anyhow::Error; pub use anyhow::Error;
use client_api::entity::{workspace_dto::PublishInfoView, PublishInfo}; use client_api::entity::{workspace_dto::PublishInfoView, PublishInfo};
use collab::entity::EncodedCollab;
use collab_entity::CollabType; use collab_entity::CollabType;
pub use collab_folder::{Folder, FolderData, Workspace}; pub use collab_folder::{Folder, FolderData, Workspace};
use flowy_error::FlowyError; use flowy_error::FlowyError;
@ -40,6 +41,12 @@ pub trait FolderCloudService: Send + Sync + 'static {
object_id: &str, object_id: &str,
) -> Result<Vec<u8>, FlowyError>; ) -> Result<Vec<u8>, FlowyError>;
async fn full_sync_collab_object(
&self,
workspace_id: &str,
params: FullSyncCollabParams,
) -> Result<(), FlowyError>;
async fn batch_create_folder_collab_objects( async fn batch_create_folder_collab_objects(
&self, &self,
workspace_id: &str, workspace_id: &str,
@ -105,6 +112,13 @@ pub struct FolderCollabParams {
pub collab_type: CollabType, pub collab_type: CollabType,
} }
#[derive(Debug)]
pub struct FullSyncCollabParams {
pub object_id: String,
pub encoded_collab: EncodedCollab,
pub collab_type: CollabType,
}
pub struct FolderSnapshot { pub struct FolderSnapshot {
pub snapshot_id: i64, pub snapshot_id: i64,
pub database_id: String, pub database_id: String,

View File

@ -1,14 +1,16 @@
use collab::entity::EncodedCollab; use collab::entity::EncodedCollab;
use collab_entity::CollabType; use collab_entity::CollabType;
use collab_folder::ViewLayout; use collab_folder::ViewLayout;
use flowy_error::FlowyResult;
use lib_infra::async_trait::async_trait; use lib_infra::async_trait::async_trait;
pub struct QueryCollab { pub struct QueryCollab {
pub name: String,
pub collab_type: CollabType, pub collab_type: CollabType,
pub encoded_collab: EncodedCollab, pub encoded_collab: EncodedCollab,
} }
pub trait FolderService: FolderQueryService + FolderViewEdit {}
#[async_trait] #[async_trait]
pub trait FolderQueryService: Send + Sync + 'static { pub trait FolderQueryService: Send + Sync + 'static {
async fn get_sibling_ids_with_view_layout( async fn get_sibling_ids_with_view_layout(
@ -17,5 +19,10 @@ pub trait FolderQueryService: Send + Sync + 'static {
view_layout: ViewLayout, view_layout: ViewLayout,
) -> Vec<String>; ) -> Vec<String>;
async fn get_collab(&self, object_id: &str) -> Option<QueryCollab>; async fn get_collab(&self, object_id: &str, collab_type: CollabType) -> Option<QueryCollab>;
}
#[async_trait]
pub trait FolderViewEdit: Send + Sync + 'static {
async fn set_view_title_if_empty(&self, view_id: &str, title: &str) -> FlowyResult<()>;
} }

View File

@ -16,7 +16,7 @@ use crate::publish_util::{generate_publish_name, view_pb_to_publish_view};
use crate::share::{ImportData, ImportItem, ImportParams}; use crate::share::{ImportData, ImportItem, ImportParams};
use crate::util::{folder_not_init_error, workspace_data_not_sync_error}; use crate::util::{folder_not_init_error, workspace_data_not_sync_error};
use crate::view_operation::{ use crate::view_operation::{
create_view, EncodedCollabType, FolderOperationHandler, FolderOperationHandlers, ViewData, create_view, FolderOperationHandler, FolderOperationHandlers, GatherEncodedCollab, ViewData,
}; };
use arc_swap::ArcSwapOption; use arc_swap::ArcSwapOption;
use client_api::entity::workspace_dto::PublishInfoView; use client_api::entity::workspace_dto::PublishInfoView;
@ -132,14 +132,14 @@ impl FolderManager {
Ok(data) Ok(data)
} }
pub async fn get_encode_collab_from_disk( pub async fn gather_publish_encode_collab(
&self, &self,
view_id: &str, view_id: &str,
layout: &ViewLayout, layout: &ViewLayout,
) -> FlowyResult<EncodedCollabType> { ) -> FlowyResult<GatherEncodedCollab> {
let handler = self.get_handler(layout)?; let handler = self.get_handler(layout)?;
let encoded_collab = handler let encoded_collab = handler
.get_encoded_collab_v1_from_disk(&self.user, view_id) .gather_publish_encode_collab(&self.user, view_id)
.await?; .await?;
Ok(encoded_collab) Ok(encoded_collab)
} }
@ -1524,8 +1524,8 @@ impl FolderManager {
layout: ViewLayout, layout: ViewLayout,
) -> FlowyResult<PublishPayload> { ) -> FlowyResult<PublishPayload> {
let handler = self.get_handler(&layout)?; let handler = self.get_handler(&layout)?;
let encoded_collab_wrapper: EncodedCollabType = handler let encoded_collab_wrapper: GatherEncodedCollab = handler
.get_encoded_collab_v1_from_disk(&self.user, view_id) .gather_publish_encode_collab(&self.user, view_id)
.await?; .await?;
let view = self.get_view_pb(view_id).await?; let view = self.get_view_pb(view_id).await?;
@ -1556,7 +1556,7 @@ impl FolderManager {
}; };
let payload = match encoded_collab_wrapper { let payload = match encoded_collab_wrapper {
EncodedCollabType::Database(v) => { GatherEncodedCollab::Database(v) => {
let database_collab = v.database_encoded_collab.doc_state.to_vec(); let database_collab = v.database_encoded_collab.doc_state.to_vec();
let database_relations = v.database_relations; let database_relations = v.database_relations;
let database_row_collabs = v let database_row_collabs = v
@ -1579,11 +1579,11 @@ impl FolderManager {
}; };
PublishPayload::Database(PublishDatabasePayload { meta, data }) PublishPayload::Database(PublishDatabasePayload { meta, data })
}, },
EncodedCollabType::Document(v) => { GatherEncodedCollab::Document(v) => {
let data = v.document_encoded_collab.doc_state.to_vec(); let data = v.doc_state.to_vec();
PublishPayload::Document(PublishDocumentPayload { meta, data }) PublishPayload::Document(PublishDocumentPayload { meta, data })
}, },
EncodedCollabType::Unknown => PublishPayload::Unknown, GatherEncodedCollab::Unknown => PublishPayload::Unknown,
}; };
Ok(payload) Ok(payload)

View File

@ -19,17 +19,12 @@ use crate::manager::FolderUser;
use crate::share::ImportType; use crate::share::ImportType;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum EncodedCollabType { pub enum GatherEncodedCollab {
Document(DocumentEncodedCollab), Document(EncodedCollab),
Database(DatabaseEncodedCollab), Database(DatabaseEncodedCollab),
Unknown, Unknown,
} }
#[derive(Debug, Clone)]
pub struct DocumentEncodedCollab {
pub document_encoded_collab: EncodedCollab,
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DatabaseEncodedCollab { pub struct DatabaseEncodedCollab {
pub database_encoded_collab: EncodedCollab, pub database_encoded_collab: EncodedCollab,
@ -69,11 +64,11 @@ pub trait FolderOperationHandler: Send + Sync {
async fn duplicate_view(&self, view_id: &str) -> Result<Bytes, FlowyError>; async fn duplicate_view(&self, view_id: &str) -> Result<Bytes, FlowyError>;
/// get the encoded collab data from the disk. /// get the encoded collab data from the disk.
async fn get_encoded_collab_v1_from_disk( async fn gather_publish_encode_collab(
&self, &self,
_user: &Arc<dyn FolderUser>, _user: &Arc<dyn FolderUser>,
_view_id: &str, _view_id: &str,
) -> Result<EncodedCollabType, FlowyError> { ) -> Result<GatherEncodedCollab, FlowyError> {
Err(FlowyError::not_support()) Err(FlowyError::not_support())
} }

View File

@ -16,8 +16,8 @@ use uuid::Uuid;
use flowy_error::{ErrorCode, FlowyError}; use flowy_error::{ErrorCode, FlowyError};
use flowy_folder_pub::cloud::{ use flowy_folder_pub::cloud::{
Folder, FolderCloudService, FolderCollabParams, FolderData, FolderSnapshot, Workspace, Folder, FolderCloudService, FolderCollabParams, FolderData, FolderSnapshot, FullSyncCollabParams,
WorkspaceRecord, Workspace, WorkspaceRecord,
}; };
use flowy_folder_pub::entities::PublishPayload; use flowy_folder_pub::entities::PublishPayload;
use lib_infra::async_trait::async_trait; use lib_infra::async_trait::async_trait;
@ -152,6 +152,25 @@ where
Ok(doc_state) Ok(doc_state)
} }
async fn full_sync_collab_object(
&self,
workspace_id: &str,
params: FullSyncCollabParams,
) -> Result<(), FlowyError> {
let workspace_id = workspace_id.to_string();
let try_get_client = self.inner.try_get_client();
try_get_client?
.collab_full_sync(
&workspace_id,
&params.object_id,
params.collab_type,
params.encoded_collab.doc_state.to_vec(),
params.encoded_collab.state_vector.to_vec(),
)
.await?;
Ok(())
}
async fn batch_create_folder_collab_objects( async fn batch_create_folder_collab_objects(
&self, &self,
workspace_id: &str, workspace_id: &str,

View File

@ -7,8 +7,8 @@ use collab_entity::CollabType;
use crate::local_server::LocalServerDB; use crate::local_server::LocalServerDB;
use flowy_error::FlowyError; use flowy_error::FlowyError;
use flowy_folder_pub::cloud::{ use flowy_folder_pub::cloud::{
gen_workspace_id, FolderCloudService, FolderCollabParams, FolderData, FolderSnapshot, Workspace, gen_workspace_id, FolderCloudService, FolderCollabParams, FolderData, FolderSnapshot,
WorkspaceRecord, FullSyncCollabParams, Workspace, WorkspaceRecord,
}; };
use flowy_folder_pub::entities::PublishPayload; use flowy_folder_pub::entities::PublishPayload;
use lib_infra::async_trait::async_trait; use lib_infra::async_trait::async_trait;
@ -145,4 +145,12 @@ impl FolderCloudService for LocalServerFolderCloudServiceImpl {
async fn import_zip(&self, _file_path: &str) -> Result<(), FlowyError> { async fn import_zip(&self, _file_path: &str) -> Result<(), FlowyError> {
Err(FlowyError::local_version_not_support()) Err(FlowyError::local_version_not_support())
} }
async fn full_sync_collab_object(
&self,
_workspace_id: &str,
_params: FullSyncCollabParams,
) -> Result<(), FlowyError> {
Ok(())
}
} }