mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-16 22:50:29 +03:00
fix: search launch review (#5169)
* fix: support filtering results by workspace * feat: add search button to sidebar * fix: reduce view/recent view fetching across application * feat: add channel to search listener * feat: clean + localization * chore: remove redundant code * fix: disable search * chore: trigger ci * chore: disable search in backend * test: disable search tests for now * feat: temp disable reliance on folder search * fix: add debounce to inline actions * chore: complete future if disposed * fix: clean code * chore: disable unused bloc with feature flag * fix: recent views lazy read * chore: revert podilfe change * chore: update logs * chore: update client api and collab * chore: fix tst * chore: fix test & update collab commit * chore: update collab commit * test: fix unit tests * chore: update rust toolchain 1.77 * chore: use opt-level 1 * fix: code review * chore: clippy --------- Co-authored-by: nathan <nathan@appflowy.io> Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
This commit is contained in:
parent
bf64b0d2fa
commit
275d0b2ac4
2
.github/workflows/android_ci.yaml.bak
vendored
2
.github/workflows/android_ci.yaml.bak
vendored
@ -20,7 +20,7 @@
|
||||
# env:
|
||||
# CARGO_TERM_COLOR: always
|
||||
# FLUTTER_VERSION: "3.19.0"
|
||||
# RUST_TOOLCHAIN: "1.75"
|
||||
# RUST_TOOLCHAIN: "1.77.2"
|
||||
# CARGO_MAKE_VERSION: "0.36.6"
|
||||
|
||||
# concurrency:
|
||||
|
28
.github/workflows/flutter_ci.yaml
vendored
28
.github/workflows/flutter_ci.yaml
vendored
@ -26,7 +26,7 @@ on:
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
FLUTTER_VERSION: "3.19.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
RUST_TOOLCHAIN: "1.77.2"
|
||||
CARGO_MAKE_VERSION: "0.36.6"
|
||||
|
||||
concurrency:
|
||||
@ -39,7 +39,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
os: [ ubuntu-latest ]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
flutter_profile: development-linux-x86_64
|
||||
@ -73,7 +73,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [windows-latest]
|
||||
os: [ windows-latest ]
|
||||
include:
|
||||
- os: windows-latest
|
||||
flutter_profile: development-windows-x86
|
||||
@ -99,7 +99,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [macos-latest]
|
||||
os: [ macos-latest ]
|
||||
include:
|
||||
- os: macos-latest
|
||||
flutter_profile: development-mac-x86_64
|
||||
@ -121,12 +121,12 @@ jobs:
|
||||
flutter_profile: ${{ matrix.flutter_profile }}
|
||||
|
||||
unit_test:
|
||||
needs: [prepare-linux]
|
||||
needs: [ prepare-linux ]
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
os: [ ubuntu-latest ]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
flutter_profile: development-linux-x86_64
|
||||
@ -212,11 +212,11 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
cloud_integration_test:
|
||||
needs: [prepare-linux]
|
||||
needs: [ prepare-linux ]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
os: [ ubuntu-latest ]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
flutter_profile: development-linux-x86_64
|
||||
@ -301,12 +301,12 @@ jobs:
|
||||
|
||||
# split the integration tests into different machines to minimize the time
|
||||
integration_test_1:
|
||||
needs: [prepare-linux]
|
||||
needs: [ prepare-linux ]
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
os: [ ubuntu-latest ]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: 'x86_64-unknown-linux-gnu'
|
||||
@ -325,12 +325,12 @@ jobs:
|
||||
rust_target: ${{ matrix.target }}
|
||||
|
||||
integration_test_2:
|
||||
needs: [prepare-linux]
|
||||
needs: [ prepare-linux ]
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
os: [ ubuntu-latest ]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: 'x86_64-unknown-linux-gnu'
|
||||
@ -349,12 +349,12 @@ jobs:
|
||||
rust_target: ${{ matrix.target }}
|
||||
|
||||
integration_test_3:
|
||||
needs: [prepare-linux]
|
||||
needs: [ prepare-linux ]
|
||||
if: github.event.pull_request.draft != true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
os: [ ubuntu-latest ]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
target: 'x86_64-unknown-linux-gnu'
|
||||
|
10
.github/workflows/ios_ci.yaml
vendored
10
.github/workflows/ios_ci.yaml
vendored
@ -19,7 +19,7 @@ on:
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.19.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
RUST_TOOLCHAIN: "1.77.2"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
@ -31,7 +31,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [macos-14]
|
||||
os: [ macos-14 ]
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
@ -86,7 +86,7 @@ jobs:
|
||||
model: 'iPhone 15'
|
||||
shutdown_after_job: false
|
||||
|
||||
# enable it again if the 12 mins timeout is fixed
|
||||
# - name: Run integration tests
|
||||
# working-directory: frontend/appflowy_flutter
|
||||
# enable it again if the 12 mins timeout is fixed
|
||||
# - name: Run integration tests
|
||||
# working-directory: frontend/appflowy_flutter
|
||||
# run: flutter test integration_test/runner.dart -d ${{ steps.simulator-action.outputs.udid }}
|
||||
|
22
.github/workflows/release.yml
vendored
22
.github/workflows/release.yml
vendored
@ -7,7 +7,7 @@ on:
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.19.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
RUST_TOOLCHAIN: "1.77.2"
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
@ -232,10 +232,10 @@ jobs:
|
||||
matrix:
|
||||
job:
|
||||
- {
|
||||
targets: "aarch64-apple-darwin,x86_64-apple-darwin",
|
||||
os: macos-11,
|
||||
extra-build-args: "",
|
||||
}
|
||||
targets: "aarch64-apple-darwin,x86_64-apple-darwin",
|
||||
os: macos-11,
|
||||
extra-build-args: "",
|
||||
}
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
@ -336,12 +336,12 @@ jobs:
|
||||
matrix:
|
||||
job:
|
||||
- {
|
||||
arch: x86_64,
|
||||
target: x86_64-unknown-linux-gnu,
|
||||
os: ubuntu-20.04,
|
||||
extra-build-args: "",
|
||||
flutter_profile: production-linux-x86_64,
|
||||
}
|
||||
arch: x86_64,
|
||||
target: x86_64-unknown-linux-gnu,
|
||||
os: ubuntu-20.04,
|
||||
extra-build-args: "",
|
||||
flutter_profile: production-linux-x86_64,
|
||||
}
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
|
2
.github/workflows/rust_ci.yaml
vendored
2
.github/workflows/rust_ci.yaml
vendored
@ -19,7 +19,7 @@ on:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
RUST_TOOLCHAIN: "1.77.2"
|
||||
|
||||
jobs:
|
||||
test-on-ubuntu:
|
||||
|
2
.github/workflows/rust_coverage.yml
vendored
2
.github/workflows/rust_coverage.yml
vendored
@ -11,7 +11,7 @@ on:
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
FLUTTER_VERSION: "3.19.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
RUST_TOOLCHAIN: "1.77.2"
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
|
2
.github/workflows/tauri2_ci.yaml
vendored
2
.github/workflows/tauri2_ci.yaml
vendored
@ -10,7 +10,7 @@ on:
|
||||
env:
|
||||
NODE_VERSION: "18.16.0"
|
||||
PNPM_VERSION: "8.5.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
RUST_TOOLCHAIN: "1.77.2"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
|
4
.github/workflows/tauri_ci.yaml
vendored
4
.github/workflows/tauri_ci.yaml
vendored
@ -10,7 +10,7 @@ on:
|
||||
env:
|
||||
NODE_VERSION: "18.16.0"
|
||||
PNPM_VERSION: "8.5.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
RUST_TOOLCHAIN: "1.77.2"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
@ -22,7 +22,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [ubuntu-20.04]
|
||||
platform: [ ubuntu-20.04 ]
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
|
2
.github/workflows/tauri_release.yml
vendored
2
.github/workflows/tauri_release.yml
vendored
@ -14,7 +14,7 @@ on:
|
||||
env:
|
||||
NODE_VERSION: "18.16.0"
|
||||
PNPM_VERSION: "8.5.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
RUST_TOOLCHAIN: "1.77.2"
|
||||
|
||||
jobs:
|
||||
|
||||
|
2
.github/workflows/web_ci.yaml
vendored
2
.github/workflows/web_ci.yaml
vendored
@ -12,7 +12,7 @@ env:
|
||||
CARGO_TERM_COLOR: always
|
||||
NODE_VERSION: "18.16.0"
|
||||
PNPM_VERSION: "8.5.0"
|
||||
RUST_TOOLCHAIN: "1.75"
|
||||
RUST_TOOLCHAIN: "1.77.2"
|
||||
CARGO_MAKE_VERSION: "0.36.6"
|
||||
|
||||
jobs:
|
||||
|
@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-notification/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/entities.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/notification.pbenum.dart';
|
||||
import 'package:appflowy_backend/rust_stream.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
|
||||
@ -23,9 +23,11 @@ class SearchNotificationParser
|
||||
SearchNotificationParser({
|
||||
super.id,
|
||||
required super.callback,
|
||||
String? channel,
|
||||
}) : super(
|
||||
tyParser: (ty, source) =>
|
||||
source == _source ? SearchNotification.valueOf(ty) : null,
|
||||
tyParser: (ty, source) => source == "$_source$channel"
|
||||
? SearchNotification.valueOf(ty)
|
||||
: null,
|
||||
errorParser: (bytes) => FlowyError.fromBuffer(bytes),
|
||||
);
|
||||
}
|
||||
@ -39,7 +41,12 @@ class SearchNotificationListener {
|
||||
SearchNotificationListener({
|
||||
required String objectId,
|
||||
required SearchNotificationHandler handler,
|
||||
}) : _parser = SearchNotificationParser(id: objectId, callback: handler) {
|
||||
String? channel,
|
||||
}) : _parser = SearchNotificationParser(
|
||||
id: objectId,
|
||||
callback: handler,
|
||||
channel: channel,
|
||||
) {
|
||||
_subscription =
|
||||
RustStreamReceiver.listen((observable) => _parser?.parse(observable));
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/mobile/presentation/database/board/mobile_board_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/mobile_calendar_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/mobile_grid_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/presentation.dart';
|
||||
import 'package:appflowy/workspace/application/recent/recent_service.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/workspace/application/recent/cached_recent_service.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
extension MobileRouter on BuildContext {
|
||||
@ -17,7 +19,7 @@ extension MobileRouter on BuildContext {
|
||||
queryParameters: view.queryParameters(arguments),
|
||||
).toString(),
|
||||
).then((value) {
|
||||
RecentService().updateRecentViews([view.id], true);
|
||||
getIt<CachedRecentService>().updateRecentViews([view.id], true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||
@ -8,7 +10,6 @@ import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
|
@ -102,10 +102,7 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
||||
late final InlineActionsService inlineActionsService = InlineActionsService(
|
||||
context: context,
|
||||
handlers: [
|
||||
InlinePageReferenceService(
|
||||
currentViewId: documentBloc.view.id,
|
||||
limitResults: 5,
|
||||
),
|
||||
InlinePageReferenceService(currentViewId: documentBloc.view.id),
|
||||
DateReferenceService(context),
|
||||
ReminderReferenceService(context),
|
||||
],
|
||||
|
@ -11,28 +11,27 @@ import 'package:appflowy/plugins/inline_actions/inline_actions_menu.dart';
|
||||
import 'package:appflowy/plugins/inline_actions/inline_actions_result.dart';
|
||||
import 'package:appflowy/plugins/inline_actions/service_handler.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/user/application/auth/auth_service.dart';
|
||||
import 'package:appflowy/workspace/application/recent/cached_recent_service.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_service.dart';
|
||||
import 'package:appflowy/workspace/application/workspace/workspace_listener.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/widget/dialog/styled_dialogs.dart';
|
||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||
|
||||
// const _channel = "InlinePageReference";
|
||||
|
||||
// TODO(Mathias): Clean up and use folder search instead
|
||||
class InlinePageReferenceService extends InlineActionsDelegate {
|
||||
InlinePageReferenceService({
|
||||
required this.currentViewId,
|
||||
this.viewLayout,
|
||||
this.customTitle,
|
||||
this.insertPage = false,
|
||||
this.limitResults = 0,
|
||||
}) {
|
||||
this.limitResults = 5,
|
||||
}) : assert(limitResults > 0, 'limitResults must be greater than 0') {
|
||||
init();
|
||||
}
|
||||
|
||||
@ -48,147 +47,102 @@ class InlinePageReferenceService extends InlineActionsDelegate {
|
||||
///
|
||||
final bool insertPage;
|
||||
|
||||
/// Defaults to 0 where there are no limits
|
||||
/// Anything above 0 will limit the page reference results
|
||||
/// Defaults to 5
|
||||
/// Will limit the page reference results
|
||||
/// to [limitResults].
|
||||
///
|
||||
final int limitResults;
|
||||
|
||||
final ViewBackendService service = ViewBackendService();
|
||||
List<InlineActionsMenuItem> _items = [];
|
||||
List<InlineActionsMenuItem> _filtered = [];
|
||||
late final CachedRecentService _recentService;
|
||||
|
||||
UserProfilePB? _user;
|
||||
String? _workspaceId;
|
||||
WorkspaceListener? _listener;
|
||||
bool _recentViewsInitialized = false;
|
||||
late final List<InlineActionsMenuItem> _recentViews;
|
||||
|
||||
Future<void> init() async {
|
||||
_items = await _generatePageItems(currentViewId, viewLayout);
|
||||
_filtered = limitResults > 0 ? _items.take(limitResults).toList() : _items;
|
||||
Future<List<InlineActionsMenuItem>> _getRecentViews() async {
|
||||
if (_recentViewsInitialized) {
|
||||
return _recentViews;
|
||||
}
|
||||
|
||||
await _initWorkspaceListener();
|
||||
_recentViewsInitialized = true;
|
||||
|
||||
_initCompleter.complete();
|
||||
}
|
||||
final views =
|
||||
(await _recentService.recentViews()).reversed.toSet().toList();
|
||||
|
||||
Future<void> _initWorkspaceListener() async {
|
||||
final snapshot = await Future.wait([
|
||||
FolderEventGetCurrentWorkspaceSetting().send(),
|
||||
getIt<AuthService>().getUser(),
|
||||
]);
|
||||
|
||||
final (workspaceSettings, userProfile) = (snapshot.first, snapshot.last);
|
||||
_workspaceId = workspaceSettings.fold(
|
||||
(s) => (s as WorkspaceSettingPB).workspaceId,
|
||||
(e) => null,
|
||||
// Filter by viewLayout
|
||||
views.retainWhere(
|
||||
(i) =>
|
||||
currentViewId != i.id &&
|
||||
(viewLayout == null || i.layout == viewLayout),
|
||||
);
|
||||
|
||||
_user = userProfile.fold((s) => s as UserProfilePB, (e) => null);
|
||||
// Map to InlineActionsMenuItem, then take 5 items
|
||||
return _recentViews = views.map(_fromView).take(5).toList();
|
||||
}
|
||||
|
||||
if (_user != null && _workspaceId != null) {
|
||||
_listener = WorkspaceListener(
|
||||
user: _user!,
|
||||
workspaceId: _workspaceId!,
|
||||
);
|
||||
_listener!.start(
|
||||
appsChanged: (_) async {
|
||||
_items = await _generatePageItems(currentViewId, viewLayout);
|
||||
_filtered =
|
||||
limitResults > 0 ? _items.take(limitResults).toList() : _items;
|
||||
},
|
||||
);
|
||||
bool _viewsInitialized = false;
|
||||
late final List<ViewPB> _allViews;
|
||||
|
||||
Future<List<ViewPB>> _getViews() async {
|
||||
if (_viewsInitialized) {
|
||||
return _allViews;
|
||||
}
|
||||
|
||||
_viewsInitialized = true;
|
||||
|
||||
final viewResult = await ViewBackendService.getAllViews();
|
||||
return _allViews = viewResult
|
||||
.toNullable()
|
||||
?.items
|
||||
.where((v) => viewLayout == null || v.layout == viewLayout)
|
||||
.toList() ??
|
||||
const [];
|
||||
}
|
||||
|
||||
Future<void> init() async {
|
||||
_recentService = getIt<CachedRecentService>();
|
||||
// _searchListener.start(onResultsClosed: _onResults);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
if (!_initCompleter.isCompleted) {
|
||||
_initCompleter.complete();
|
||||
}
|
||||
|
||||
await super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<InlineActionsResult> search([
|
||||
String? search,
|
||||
]) async {
|
||||
_filtered = await _filterItems(search);
|
||||
final isSearching = search != null && search.isNotEmpty;
|
||||
|
||||
late List<InlineActionsMenuItem> items;
|
||||
if (isSearching) {
|
||||
final allViews = await _getViews();
|
||||
|
||||
items = allViews
|
||||
.where(
|
||||
(view) => view.name.toLowerCase().contains(search.toLowerCase()),
|
||||
)
|
||||
.take(limitResults)
|
||||
.map((view) => _fromView(view))
|
||||
.toList();
|
||||
} else {
|
||||
items = await _getRecentViews();
|
||||
}
|
||||
|
||||
return InlineActionsResult(
|
||||
title: customTitle?.isNotEmpty == true
|
||||
? customTitle!
|
||||
: LocaleKeys.inlineActions_pageReference.tr(),
|
||||
results: _filtered,
|
||||
: isSearching
|
||||
? LocaleKeys.inlineActions_pageReference.tr()
|
||||
: LocaleKeys.inlineActions_recentPages.tr(),
|
||||
results: items,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
await _listener?.stop();
|
||||
}
|
||||
|
||||
Future<List<InlineActionsMenuItem>> _filterItems(String? search) async {
|
||||
await _initCompleter.future;
|
||||
|
||||
final items = (search == null || search.isEmpty)
|
||||
? _items
|
||||
: _items.where(
|
||||
(item) =>
|
||||
item.keywords != null &&
|
||||
item.keywords!.isNotEmpty &&
|
||||
item.keywords!.any(
|
||||
(keyword) => keyword.contains(search.toLowerCase()),
|
||||
),
|
||||
);
|
||||
|
||||
return limitResults > 0
|
||||
? items.take(limitResults).toList()
|
||||
: items.toList();
|
||||
}
|
||||
|
||||
Future<List<InlineActionsMenuItem>> _generatePageItems(
|
||||
String currentViewId,
|
||||
ViewLayoutPB? viewLayout,
|
||||
) async {
|
||||
late List<ViewPB> views;
|
||||
if (viewLayout != null) {
|
||||
views = await service.fetchViewsWithLayoutType(viewLayout);
|
||||
} else {
|
||||
views = await service.fetchViews();
|
||||
}
|
||||
|
||||
if (views.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
final List<InlineActionsMenuItem> pages = [];
|
||||
views.sort((a, b) => b.createTime.compareTo(a.createTime));
|
||||
|
||||
for (final view in views) {
|
||||
if (view.id == currentViewId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final pageSelectionMenuItem = InlineActionsMenuItem(
|
||||
keywords: [view.name.toLowerCase()],
|
||||
label: view.name,
|
||||
icon: (onSelected) => view.icon.value.isNotEmpty
|
||||
? EmojiText(
|
||||
emoji: view.icon.value,
|
||||
fontSize: 12,
|
||||
textAlign: TextAlign.center,
|
||||
lineHeight: 1.3,
|
||||
)
|
||||
: view.defaultIcon(),
|
||||
onSelected: (context, editorState, menuService, replace) => insertPage
|
||||
? _onInsertPageRef(view, context, editorState, replace)
|
||||
: _onInsertLinkRef(
|
||||
view,
|
||||
context,
|
||||
editorState,
|
||||
menuService,
|
||||
replace,
|
||||
),
|
||||
);
|
||||
|
||||
pages.add(pageSelectionMenuItem);
|
||||
}
|
||||
|
||||
return pages;
|
||||
}
|
||||
|
||||
Future<void> _onInsertPageRef(
|
||||
ViewPB view,
|
||||
BuildContext context,
|
||||
@ -268,4 +222,32 @@ class InlinePageReferenceService extends InlineActionsDelegate {
|
||||
|
||||
await editorState.apply(transaction);
|
||||
}
|
||||
|
||||
InlineActionsMenuItem _fromView(ViewPB view) => InlineActionsMenuItem(
|
||||
keywords: [view.name.toLowerCase()],
|
||||
label: view.name,
|
||||
icon: (onSelected) => view.icon.value.isNotEmpty
|
||||
? EmojiText(
|
||||
emoji: view.icon.value,
|
||||
fontSize: 12,
|
||||
textAlign: TextAlign.center,
|
||||
lineHeight: 1.3,
|
||||
)
|
||||
: view.defaultIcon(),
|
||||
onSelected: (context, editorState, menu, replace) => insertPage
|
||||
? _onInsertPageRef(view, context, editorState, replace)
|
||||
: _onInsertLinkRef(view, context, editorState, menu, replace),
|
||||
);
|
||||
|
||||
// Future<InlineActionsMenuItem?> _fromSearchResult(
|
||||
// SearchResultPB result,
|
||||
// ) async {
|
||||
// final viewRes = await ViewBackendService.getView(result.viewId);
|
||||
// final view = viewRes.toNullable();
|
||||
// if (view == null) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// return _fromView(view);
|
||||
// }
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
@ -79,6 +81,8 @@ class _InlineActionsHandlerState extends State<InlineActionsHandler> {
|
||||
final _focusNode = FocusNode(debugLabel: 'inline_actions_menu_handler');
|
||||
final _scrollController = ScrollController();
|
||||
|
||||
Timer? _debounce;
|
||||
|
||||
late List<InlineActionsResult> results = widget.results;
|
||||
int invalidCounter = 0;
|
||||
late int startOffset;
|
||||
@ -86,7 +90,8 @@ class _InlineActionsHandlerState extends State<InlineActionsHandler> {
|
||||
String _search = '';
|
||||
set search(String search) {
|
||||
_search = search;
|
||||
_doSearch();
|
||||
_debounce?.cancel();
|
||||
_debounce = Timer(const Duration(milliseconds: 200), _doSearch);
|
||||
}
|
||||
|
||||
Future<void> _doSearch() async {
|
||||
@ -138,6 +143,7 @@ class _InlineActionsHandlerState extends State<InlineActionsHandler> {
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
_focusNode.dispose();
|
||||
_debounce?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,9 @@ enum FeatureFlag {
|
||||
// if it's on, the collaborators will show in the database
|
||||
syncDatabase,
|
||||
|
||||
// used for the search feature
|
||||
search,
|
||||
|
||||
// used for ignore the conflicted feature flag
|
||||
unknown;
|
||||
|
||||
@ -98,15 +101,13 @@ enum FeatureFlag {
|
||||
|
||||
switch (this) {
|
||||
case FeatureFlag.collaborativeWorkspace:
|
||||
return false;
|
||||
case FeatureFlag.membersSettings:
|
||||
return false;
|
||||
case FeatureFlag.syncDocument:
|
||||
return true;
|
||||
case FeatureFlag.syncDatabase:
|
||||
return true;
|
||||
case FeatureFlag.search:
|
||||
case FeatureFlag.unknown:
|
||||
return false;
|
||||
case FeatureFlag.syncDocument:
|
||||
case FeatureFlag.syncDatabase:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,6 +121,8 @@ enum FeatureFlag {
|
||||
return 'if it\'s on, the document will be synced in real-time';
|
||||
case FeatureFlag.syncDatabase:
|
||||
return 'if it\'s on, the collaborators will show in the database';
|
||||
case FeatureFlag.search:
|
||||
return 'if it\'s on, the command palette and search button will be available';
|
||||
case FeatureFlag.unknown:
|
||||
return '';
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import 'package:appflowy/user/presentation/router.dart';
|
||||
import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/edit_panel/edit_panel_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/recent/cached_recent_service.dart';
|
||||
import 'package:appflowy/workspace/application/settings/appearance/base_appearance.dart';
|
||||
import 'package:appflowy/workspace/application/settings/appearance/desktop_appearance.dart';
|
||||
import 'package:appflowy/workspace/application/settings/appearance/mobile_appearance.dart';
|
||||
@ -171,6 +172,7 @@ void _resolveUserDeps(GetIt getIt, IntegrationMode mode) {
|
||||
getIt.registerFactory<EditPanelBloc>(() => EditPanelBloc());
|
||||
getIt.registerFactory<SplashBloc>(() => SplashBloc());
|
||||
getIt.registerLazySingleton<NetworkListener>(() => NetworkListener());
|
||||
getIt.registerLazySingleton<CachedRecentService>(() => CachedRecentService());
|
||||
}
|
||||
|
||||
void _resolveHomeDeps(GetIt getIt) {
|
||||
@ -203,12 +205,10 @@ void _resolveHomeDeps(GetIt getIt) {
|
||||
}
|
||||
|
||||
void _resolveFolderDeps(GetIt getIt) {
|
||||
//workspace
|
||||
// Workspace
|
||||
getIt.registerFactoryParam<WorkspaceListener, UserProfilePB, String>(
|
||||
(user, workspaceId) => WorkspaceListener(
|
||||
user: user,
|
||||
workspaceId: workspaceId,
|
||||
),
|
||||
(user, workspaceId) =>
|
||||
WorkspaceListener(user: user, workspaceId: workspaceId),
|
||||
);
|
||||
|
||||
getIt.registerFactoryParam<ViewBloc, ViewPB, void>(
|
||||
@ -217,21 +217,23 @@ void _resolveFolderDeps(GetIt getIt) {
|
||||
),
|
||||
);
|
||||
|
||||
//Settings
|
||||
// Settings
|
||||
getIt.registerFactoryParam<SettingsDialogBloc, UserProfilePB, void>(
|
||||
(user, _) => SettingsDialogBloc(user),
|
||||
);
|
||||
|
||||
//User
|
||||
// User
|
||||
getIt.registerFactoryParam<SettingsUserViewBloc, UserProfilePB, void>(
|
||||
(user, _) => SettingsUserViewBloc(user),
|
||||
);
|
||||
|
||||
// trash
|
||||
// Trash
|
||||
getIt.registerLazySingleton<TrashService>(() => TrashService());
|
||||
getIt.registerLazySingleton<TrashListener>(() => TrashListener());
|
||||
getIt.registerFactory<TrashBloc>(
|
||||
() => TrashBloc(),
|
||||
);
|
||||
|
||||
// Favorite
|
||||
getIt.registerFactory<FavoriteBloc>(() => FavoriteBloc());
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/startup/tasks/feature_flag_task.dart';
|
||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||
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';
|
||||
|
||||
@ -136,6 +137,7 @@ class FlowyRunner {
|
||||
if (isAppFlowyCloudEnabled) InitAppFlowyCloudTask(),
|
||||
const InitAppWidgetTask(),
|
||||
const InitPlatformServiceTask(),
|
||||
const RecentServiceTask(),
|
||||
],
|
||||
],
|
||||
);
|
||||
|
@ -5,11 +5,13 @@ import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:appflowy/mobile/application/mobile_router.dart';
|
||||
import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart';
|
||||
import 'package:appflowy/shared/feature_flags.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/user/application/reminder/reminder_bloc.dart';
|
||||
import 'package:appflowy/user/application/user_settings_service.dart';
|
||||
import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart';
|
||||
import 'package:appflowy/workspace/application/command_palette/command_palette_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/notification/notification_service.dart';
|
||||
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||
import 'package:appflowy/workspace/application/settings/notifications/notification_settings_cubit.dart';
|
||||
@ -126,18 +128,27 @@ class ApplicationWidget extends StatefulWidget {
|
||||
class _ApplicationWidgetState extends State<ApplicationWidget> {
|
||||
late final GoRouter routerConfig;
|
||||
|
||||
final _commandPaletteNotifier = ValueNotifier<bool>(false);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
// avoid rebuild routerConfig when the appTheme is changed.
|
||||
// Avoid rebuild routerConfig when the appTheme is changed.
|
||||
routerConfig = generateRouter(widget.child);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_commandPaletteNotifier.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
if (FeatureFlag.search.isOn)
|
||||
BlocProvider<CommandPaletteBloc>(create: (_) => CommandPaletteBloc()),
|
||||
BlocProvider<AppearanceSettingsCubit>(
|
||||
create: (_) => AppearanceSettingsCubit(
|
||||
widget.appearanceSetting,
|
||||
@ -152,10 +163,7 @@ class _ApplicationWidgetState extends State<ApplicationWidget> {
|
||||
create: (_) => DocumentAppearanceCubit()..fetch(),
|
||||
),
|
||||
BlocProvider.value(value: getIt<RenameViewBloc>()),
|
||||
BlocProvider.value(
|
||||
value: getIt<ActionNavigationBloc>()
|
||||
..add(const ActionNavigationEvent.initialize()),
|
||||
),
|
||||
BlocProvider.value(value: getIt<ActionNavigationBloc>()),
|
||||
BlocProvider.value(
|
||||
value: getIt<ReminderBloc>()..add(const ReminderEvent.started()),
|
||||
),
|
||||
@ -196,10 +204,12 @@ class _ApplicationWidgetState extends State<ApplicationWidget> {
|
||||
),
|
||||
child: overlayManagerBuilder(
|
||||
context,
|
||||
CommandPalette(
|
||||
toggleNotifier: ValueNotifier<bool>(false),
|
||||
child: child,
|
||||
),
|
||||
FeatureFlag.search.isOn
|
||||
? CommandPalette(
|
||||
toggleNotifier: _commandPaletteNotifier,
|
||||
child: child,
|
||||
)
|
||||
: child,
|
||||
),
|
||||
),
|
||||
debugShowCheckedModeBanner: false,
|
||||
|
@ -12,3 +12,4 @@ export 'platform_service.dart';
|
||||
export 'rust_sdk.dart';
|
||||
export 'supabase_task.dart';
|
||||
export 'windows.dart';
|
||||
export 'recent_service_task.dart';
|
||||
|
@ -0,0 +1,14 @@
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/workspace/application/recent/prelude.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
|
||||
class RecentServiceTask extends LaunchTask {
|
||||
const RecentServiceTask();
|
||||
|
||||
@override
|
||||
Future<void> initialize(LaunchContext context) async =>
|
||||
Log.info('[CachedRecentService] Initialized');
|
||||
|
||||
@override
|
||||
Future<void> dispose() async => getIt<CachedRecentService>().dispose();
|
||||
}
|
@ -1,10 +1,5 @@
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/user/application/auth/auth_service.dart';
|
||||
import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_service.dart';
|
||||
import 'package:appflowy/workspace/application/workspace/workspace_listener.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
@ -15,15 +10,21 @@ class ActionNavigationBloc
|
||||
ActionNavigationBloc() : super(const ActionNavigationState.initial()) {
|
||||
on<ActionNavigationEvent>((event, emit) async {
|
||||
await event.when(
|
||||
initialize: () async {
|
||||
final views = await ViewBackendService().fetchViews();
|
||||
emit(state.copyWith(views: views));
|
||||
await initializeListeners();
|
||||
},
|
||||
viewsChanged: (views) {
|
||||
emit(state.copyWith(views: views));
|
||||
},
|
||||
performAction: (action, nextActions) {
|
||||
performAction: (action, nextActions) async {
|
||||
NavigationAction currentAction = action;
|
||||
if (currentAction.arguments?[ActionArgumentKeys.view] == null &&
|
||||
action.type == ActionType.openView) {
|
||||
final result = await ViewBackendService.getView(action.objectId);
|
||||
final view = result.toNullable();
|
||||
if (view != null) {
|
||||
if (currentAction.arguments == null) {
|
||||
currentAction = currentAction.copyWith(arguments: {});
|
||||
}
|
||||
|
||||
action.arguments?.addAll({ActionArgumentKeys.view: view});
|
||||
}
|
||||
}
|
||||
|
||||
emit(state.copyWith(action: action, nextActions: nextActions));
|
||||
|
||||
if (nextActions.isNotEmpty) {
|
||||
@ -43,92 +44,38 @@ class ActionNavigationBloc
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
WorkspaceListener? _workspaceListener;
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _workspaceListener?.stop();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
Future<void> initializeListeners() async {
|
||||
if (_workspaceListener != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final userOrFailure = await getIt<AuthService>().getUser();
|
||||
final user = userOrFailure.fold((s) => s, (f) => null);
|
||||
if (user == null) {
|
||||
_workspaceListener = null;
|
||||
return;
|
||||
}
|
||||
|
||||
final workspaceSettingsOrFailure =
|
||||
await FolderEventGetCurrentWorkspaceSetting().send();
|
||||
final workspaceId = workspaceSettingsOrFailure.fold(
|
||||
(s) => s.workspaceId,
|
||||
(f) => null,
|
||||
);
|
||||
if (workspaceId == null) {
|
||||
_workspaceListener = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_workspaceListener = WorkspaceListener(
|
||||
user: user,
|
||||
workspaceId: workspaceId,
|
||||
);
|
||||
|
||||
_workspaceListener?.start(
|
||||
appsChanged: (_) async {
|
||||
final views = await ViewBackendService().fetchViews();
|
||||
add(ActionNavigationEvent.viewsChanged(views));
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ActionNavigationEvent with _$ActionNavigationEvent {
|
||||
const factory ActionNavigationEvent.initialize() = _Initialize;
|
||||
|
||||
const factory ActionNavigationEvent.performAction({
|
||||
required NavigationAction action,
|
||||
@Default([]) List<NavigationAction> nextActions,
|
||||
}) = _PerformAction;
|
||||
|
||||
const factory ActionNavigationEvent.viewsChanged(List<ViewPB> views) =
|
||||
_ViewsChanged;
|
||||
}
|
||||
|
||||
class ActionNavigationState {
|
||||
const ActionNavigationState.initial()
|
||||
: action = null,
|
||||
nextActions = const [],
|
||||
views = const [];
|
||||
nextActions = const [];
|
||||
|
||||
const ActionNavigationState({
|
||||
required this.action,
|
||||
this.nextActions = const [],
|
||||
this.views = const [],
|
||||
});
|
||||
|
||||
final NavigationAction? action;
|
||||
final List<NavigationAction> nextActions;
|
||||
final List<ViewPB> views;
|
||||
|
||||
ActionNavigationState copyWith({
|
||||
NavigationAction? action,
|
||||
List<NavigationAction>? nextActions,
|
||||
List<ViewPB>? views,
|
||||
}) =>
|
||||
ActionNavigationState(
|
||||
action: action ?? this.action,
|
||||
nextActions: nextActions ?? this.nextActions,
|
||||
views: views ?? this.views,
|
||||
);
|
||||
|
||||
ActionNavigationState setNoAction() =>
|
||||
ActionNavigationState(action: null, nextActions: [], views: views);
|
||||
const ActionNavigationState(action: null);
|
||||
}
|
||||
|
@ -7,12 +7,14 @@ import 'package:appflowy/plugins/trash/application/trash_service.dart';
|
||||
import 'package:appflowy/workspace/application/command_palette/search_listener.dart';
|
||||
import 'package:appflowy/workspace/application/command_palette/search_service.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/trash.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/result.pb.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'command_palette_bloc.freezed.dart';
|
||||
|
||||
const _searchChannel = 'CommandPalette';
|
||||
|
||||
class CommandPaletteBloc
|
||||
extends Bloc<CommandPaletteEvent, CommandPaletteState> {
|
||||
CommandPaletteBloc() : super(CommandPaletteState.initial()) {
|
||||
@ -27,9 +29,12 @@ class CommandPaletteBloc
|
||||
|
||||
Timer? _debounceOnChanged;
|
||||
final TrashService _trashService = TrashService();
|
||||
final SearchListener _searchListener = SearchListener();
|
||||
final SearchListener _searchListener = SearchListener(
|
||||
channel: _searchChannel,
|
||||
);
|
||||
final TrashListener _trashListener = TrashListener();
|
||||
String? _oldQuery;
|
||||
String? _workspaceId;
|
||||
|
||||
@override
|
||||
Future<void> close() {
|
||||
@ -44,8 +49,7 @@ class CommandPaletteBloc
|
||||
searchChanged: _debounceOnSearchChanged,
|
||||
trashChanged: (trash) async {
|
||||
if (trash != null) {
|
||||
emit(state.copyWith(trash: trash));
|
||||
return;
|
||||
return emit(state.copyWith(trash: trash));
|
||||
}
|
||||
|
||||
final trashOrFailure = await _trashService.readTrash();
|
||||
@ -59,10 +63,14 @@ class CommandPaletteBloc
|
||||
}
|
||||
},
|
||||
performSearch: (search) async {
|
||||
if (search.isNotEmpty) {
|
||||
if (search.isNotEmpty && search != state.query) {
|
||||
_oldQuery = state.query;
|
||||
emit(state.copyWith(query: search, isLoading: true));
|
||||
await SearchBackendService.performSearch(search);
|
||||
await SearchBackendService.performSearch(
|
||||
search,
|
||||
workspaceId: _workspaceId,
|
||||
channel: _searchChannel,
|
||||
);
|
||||
} else {
|
||||
emit(state.copyWith(query: null, isLoading: false, results: []));
|
||||
}
|
||||
@ -82,6 +90,10 @@ class CommandPaletteBloc
|
||||
),
|
||||
);
|
||||
},
|
||||
workspaceChanged: (workspaceId) {
|
||||
_workspaceId = workspaceId;
|
||||
emit(state.copyWith(results: [], query: '', isLoading: false));
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
@ -162,6 +174,10 @@ class CommandPaletteEvent with _$CommandPaletteEvent {
|
||||
const factory CommandPaletteEvent.trashChanged({
|
||||
@Default(null) List<TrashPB>? trash,
|
||||
}) = _TrashChanged;
|
||||
|
||||
const factory CommandPaletteEvent.workspaceChanged({
|
||||
@Default(null) String? workspaceId,
|
||||
}) = _WorkspaceChanged;
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
@ -4,7 +4,8 @@ import 'dart:typed_data';
|
||||
import 'package:appflowy/core/notification/search_notification.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/notification.pbenum.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/result.pb.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
|
||||
@ -12,7 +13,15 @@ import 'package:flowy_infra/notifier.dart';
|
||||
const _searchObjectId = "SEARCH_IDENTIFIER";
|
||||
|
||||
class SearchListener {
|
||||
SearchListener();
|
||||
SearchListener({this.channel});
|
||||
|
||||
/// Use this to filter out search results from other channels.
|
||||
///
|
||||
/// If null, it will receive search results from all
|
||||
/// channels, otherwise it will only receive search results from the specified
|
||||
/// channel.
|
||||
///
|
||||
final String? channel;
|
||||
|
||||
PublishNotifier<RepeatedSearchResultPB>? _updateNotifier = PublishNotifier();
|
||||
PublishNotifier<RepeatedSearchResultPB>? _updateDidCloseNotifier =
|
||||
@ -20,14 +29,21 @@ class SearchListener {
|
||||
SearchNotificationListener? _listener;
|
||||
|
||||
void start({
|
||||
required void Function(RepeatedSearchResultPB) onResultsChanged,
|
||||
required void Function(RepeatedSearchResultPB) onResultsClosed,
|
||||
void Function(RepeatedSearchResultPB)? onResultsChanged,
|
||||
void Function(RepeatedSearchResultPB)? onResultsClosed,
|
||||
}) {
|
||||
_updateNotifier?.addPublishListener(onResultsChanged);
|
||||
_updateDidCloseNotifier?.addPublishListener(onResultsClosed);
|
||||
if (onResultsChanged != null) {
|
||||
_updateNotifier?.addPublishListener(onResultsChanged);
|
||||
}
|
||||
|
||||
if (onResultsClosed != null) {
|
||||
_updateDidCloseNotifier?.addPublishListener(onResultsClosed);
|
||||
}
|
||||
|
||||
_listener = SearchNotificationListener(
|
||||
objectId: _searchObjectId,
|
||||
handler: _handler,
|
||||
channel: channel,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/result.pb.dart';
|
||||
|
||||
extension GetIcon on SearchResultPB {
|
||||
Widget? getIcon() {
|
||||
|
@ -1,13 +1,21 @@
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/query.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/search_filter.pb.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
|
||||
class SearchBackendService {
|
||||
static Future<FlowyResult<void, FlowyError>> performSearch(
|
||||
String keyword,
|
||||
) async {
|
||||
final request = SearchQueryPB(search: keyword);
|
||||
String keyword, {
|
||||
String? workspaceId,
|
||||
String? channel,
|
||||
}) async {
|
||||
final filter = SearchFilterPB(workspaceId: workspaceId);
|
||||
final request = SearchQueryPB(
|
||||
search: keyword,
|
||||
filter: filter,
|
||||
channel: channel,
|
||||
);
|
||||
|
||||
return SearchEventSearch(request).send();
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
|
||||
class HomeService {
|
||||
static Future<FlowyResult<ViewPB, FlowyError>> readApp({
|
||||
required String appId,
|
||||
}) {
|
||||
final payload = ViewIdPB.create()..value = appId;
|
||||
return FolderEventGetView(payload).send();
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/workspace/application/recent/recent_listener.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
|
||||
/// This is a lazy-singleton to share recent views across the application.
|
||||
///
|
||||
/// Use-cases:
|
||||
/// - Desktop: Command Palette recent view history
|
||||
/// - Desktop: (Documents) Inline-page reference recent view history
|
||||
/// - Mobile: Recent view history on home screen
|
||||
///
|
||||
/// See the related [LaunchTask] in [RecentServiceTask].
|
||||
///
|
||||
class CachedRecentService {
|
||||
CachedRecentService();
|
||||
|
||||
Completer<void> _completer = Completer();
|
||||
|
||||
ValueNotifier<List<ViewPB>> notifier = ValueNotifier(const []);
|
||||
List<ViewPB> _recentViews = const [];
|
||||
final _listener = RecentViewsListener();
|
||||
|
||||
Future<List<ViewPB>> recentViews() async {
|
||||
if (_isInitialized) return _recentViews;
|
||||
|
||||
_isInitialized = true;
|
||||
|
||||
_listener.start(recentViewsUpdated: _recentViewsUpdated);
|
||||
final result = await _readRecentViews();
|
||||
_recentViews = result.toNullable()?.items ?? const [];
|
||||
notifier.value = _recentViews;
|
||||
_completer.complete();
|
||||
|
||||
return _recentViews;
|
||||
}
|
||||
|
||||
/// Updates the recent views history
|
||||
Future<FlowyResult<void, FlowyError>> updateRecentViews(
|
||||
List<String> viewIds,
|
||||
bool addInRecent,
|
||||
) async {
|
||||
return FolderEventUpdateRecentViews(
|
||||
UpdateRecentViewPayloadPB(viewIds: viewIds, addInRecent: addInRecent),
|
||||
).send();
|
||||
}
|
||||
|
||||
Future<FlowyResult<RepeatedViewPB, FlowyError>> _readRecentViews() =>
|
||||
FolderEventReadRecentViews().send();
|
||||
|
||||
bool _isInitialized = false;
|
||||
|
||||
Future<void> reset() async {
|
||||
await _listener.stop();
|
||||
_resetCompleter();
|
||||
_isInitialized = false;
|
||||
_recentViews = const [];
|
||||
}
|
||||
|
||||
Future<void> dispose() async {
|
||||
await _listener.stop();
|
||||
}
|
||||
|
||||
void _recentViewsUpdated(
|
||||
FlowyResult<RepeatedViewIdPB, FlowyError> result,
|
||||
) {
|
||||
final viewIds = result.toNullable();
|
||||
if (viewIds != null) {
|
||||
_readRecentViews().then(
|
||||
(views) => _recentViews = views.toNullable()?.items ?? const [],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _resetCompleter() {
|
||||
if (!_completer.isCompleted) {
|
||||
_completer.complete();
|
||||
}
|
||||
_completer = Completer<void>();
|
||||
}
|
||||
}
|
@ -1,2 +1,2 @@
|
||||
export 'recent_service.dart';
|
||||
export 'cached_recent_service.dart';
|
||||
export 'recent_views_bloc.dart';
|
||||
|
@ -1,19 +0,0 @@
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
|
||||
class RecentService {
|
||||
Future<FlowyResult<void, FlowyError>> updateRecentViews(
|
||||
List<String> viewIds,
|
||||
bool addInRecent,
|
||||
) async {
|
||||
return FolderEventUpdateRecentViews(
|
||||
UpdateRecentViewPayloadPB(viewIds: viewIds, addInRecent: addInRecent),
|
||||
).send();
|
||||
}
|
||||
|
||||
Future<FlowyResult<RepeatedViewPB, FlowyError>> readRecentViews() {
|
||||
return FolderEventReadRecentViews().send();
|
||||
}
|
||||
}
|
@ -1,9 +1,6 @@
|
||||
import 'package:appflowy/workspace/application/recent/recent_listener.dart';
|
||||
import 'package:appflowy/workspace/application/recent/recent_service.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/workspace/application/recent/cached_recent_service.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
@ -11,15 +8,15 @@ part 'recent_views_bloc.freezed.dart';
|
||||
|
||||
class RecentViewsBloc extends Bloc<RecentViewsEvent, RecentViewsState> {
|
||||
RecentViewsBloc() : super(RecentViewsState.initial()) {
|
||||
_service = getIt<CachedRecentService>();
|
||||
_dispatch();
|
||||
}
|
||||
|
||||
final _service = RecentService();
|
||||
final _listener = RecentViewsListener();
|
||||
late final CachedRecentService _service;
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _listener.stop();
|
||||
_service.notifier.removeListener(_onRecentViewsUpdated);
|
||||
return super.close();
|
||||
}
|
||||
|
||||
@ -28,9 +25,7 @@ class RecentViewsBloc extends Bloc<RecentViewsEvent, RecentViewsState> {
|
||||
(event, emit) async {
|
||||
await event.map(
|
||||
initial: (e) async {
|
||||
_listener.start(
|
||||
recentViewsUpdated: (result) => _onRecentViewsUpdated(result),
|
||||
);
|
||||
_service.notifier.addListener(_onRecentViewsUpdated);
|
||||
add(const RecentViewsEvent.fetchRecentViews());
|
||||
},
|
||||
addRecentViews: (e) async {
|
||||
@ -40,22 +35,15 @@ class RecentViewsBloc extends Bloc<RecentViewsEvent, RecentViewsState> {
|
||||
await _service.updateRecentViews(e.viewIds, false);
|
||||
},
|
||||
fetchRecentViews: (e) async {
|
||||
final result = await _service.readRecentViews();
|
||||
result.fold(
|
||||
(views) => emit(state.copyWith(views: views.items)),
|
||||
(error) => Log.error(error),
|
||||
);
|
||||
emit(state.copyWith(views: await _service.recentViews()));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _onRecentViewsUpdated(
|
||||
FlowyResult<RepeatedViewIdPB, FlowyError> result,
|
||||
) {
|
||||
add(const RecentViewsEvent.fetchRecentViews());
|
||||
}
|
||||
void _onRecentViewsUpdated() =>
|
||||
add(const RecentViewsEvent.fetchRecentViews());
|
||||
}
|
||||
|
||||
@freezed
|
||||
@ -74,7 +62,5 @@ class RecentViewsState with _$RecentViewsState {
|
||||
required List<ViewPB> views,
|
||||
}) = _RecentViewsState;
|
||||
|
||||
factory RecentViewsState.initial() => const RecentViewsState(
|
||||
views: [],
|
||||
);
|
||||
factory RecentViewsState.initial() => const RecentViewsState(views: []);
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:appflowy/plugins/util.dart';
|
||||
import 'package:appflowy/startup/plugin/plugin.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/workspace/application/recent/cached_recent_service.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'tabs_bloc.freezed.dart';
|
||||
@ -81,11 +83,15 @@ class TabsBloc extends Bloc<TabsEvent, TabsState> {
|
||||
void openPlugin(
|
||||
ViewPB view, {
|
||||
Map<String, dynamic> arguments = const {},
|
||||
}) =>
|
||||
add(
|
||||
TabsEvent.openPlugin(
|
||||
plugin: view.plugin(arguments: arguments),
|
||||
view: view,
|
||||
),
|
||||
);
|
||||
}) {
|
||||
add(
|
||||
TabsEvent.openPlugin(
|
||||
plugin: view.plugin(arguments: arguments),
|
||||
view: view,
|
||||
),
|
||||
);
|
||||
|
||||
// Update recent views
|
||||
getIt<CachedRecentService>().updateRecentViews([view.id], true);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import 'package:appflowy/core/config/kv.dart';
|
||||
import 'package:appflowy/core/config/kv_keys.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/workspace/application/favorite/favorite_listener.dart';
|
||||
import 'package:appflowy/workspace/application/recent/recent_service.dart';
|
||||
import 'package:appflowy/workspace/application/recent/cached_recent_service.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_listener.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_service.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
@ -88,9 +88,7 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
|
||||
await _setViewIsExpanded(view, e.isExpanded);
|
||||
},
|
||||
viewDidUpdate: (e) async {
|
||||
final result = await ViewBackendService.getView(
|
||||
view.id,
|
||||
);
|
||||
final result = await ViewBackendService.getView(view.id);
|
||||
final view_ = result.fold((l) => l, (r) => null);
|
||||
e.result.fold(
|
||||
(view) async {
|
||||
@ -146,7 +144,10 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
|
||||
),
|
||||
),
|
||||
);
|
||||
await RecentService().updateRecentViews([view.id], false);
|
||||
await getIt<CachedRecentService>().updateRecentViews(
|
||||
[view.id],
|
||||
false,
|
||||
);
|
||||
},
|
||||
duplicate: (e) async {
|
||||
final result = await ViewBackendService.duplicate(view: view);
|
||||
@ -313,9 +314,7 @@ class ViewBloc extends Bloc<ViewEvent, ViewState> {
|
||||
}
|
||||
|
||||
if (update.updateChildViews.isNotEmpty) {
|
||||
final view = await ViewBackendService.getView(
|
||||
update.parentViewId,
|
||||
);
|
||||
final view = await ViewBackendService.getView(update.parentViewId);
|
||||
final childViews = view.fold((l) => l.childViews, (r) => []);
|
||||
bool isSameOrder = true;
|
||||
if (childViews.length == update.updateChildViews.length) {
|
||||
|
@ -99,9 +99,7 @@ class ViewBackendService {
|
||||
layoutType: layoutType,
|
||||
parentViewId: parentViewId,
|
||||
name: name,
|
||||
ext: {
|
||||
'database_id': databaseId,
|
||||
},
|
||||
ext: {'database_id': databaseId},
|
||||
);
|
||||
}
|
||||
|
||||
@ -215,49 +213,13 @@ class ViewBackendService {
|
||||
return FolderEventMoveNestedView(payload).send();
|
||||
}
|
||||
|
||||
Future<List<ViewPB>> fetchViewsWithLayoutType(
|
||||
ViewLayoutPB? layoutType,
|
||||
) async {
|
||||
final views = await fetchViews();
|
||||
if (layoutType == null) {
|
||||
return views;
|
||||
}
|
||||
return views
|
||||
.where(
|
||||
(element) => layoutType == element.layout,
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<List<ViewPB>> fetchViews() async {
|
||||
final result = <ViewPB>[];
|
||||
return FolderEventReadCurrentWorkspace().send().then((value) async {
|
||||
final workspace = value.toNullable();
|
||||
if (workspace != null) {
|
||||
final views = workspace.views;
|
||||
for (final view in views) {
|
||||
result.add(view);
|
||||
final childViews = await getAllViews(view);
|
||||
result.addAll(childViews);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
Future<List<ViewPB>> getAllViews(ViewPB view) async {
|
||||
final result = <ViewPB>[];
|
||||
final childViews = await getChildViews(viewId: view.id).then(
|
||||
(value) => value.toNullable(),
|
||||
);
|
||||
if (childViews != null && childViews.isNotEmpty) {
|
||||
result.addAll(childViews);
|
||||
final views = await Future.wait(
|
||||
childViews.map((e) async => getAllViews(e)),
|
||||
);
|
||||
result.addAll(views.expand((element) => element));
|
||||
}
|
||||
return result;
|
||||
/// Fetches a flattened list of all Views.
|
||||
///
|
||||
/// Views do not contain their children in this list, as they all exist
|
||||
/// in the same level in this version.
|
||||
///
|
||||
static Future<FlowyResult<RepeatedViewPB, FlowyError>> getAllViews() async {
|
||||
return FolderEventGetAllViews().send();
|
||||
}
|
||||
|
||||
static Future<FlowyResult<ViewPB, FlowyError>> getView(
|
||||
|
@ -61,7 +61,6 @@ class _CommandPaletteController extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _CommandPaletteControllerState extends State<_CommandPaletteController> {
|
||||
late final CommandPaletteBloc _commandPaletteBloc;
|
||||
late ValueNotifier<bool> _toggleNotifier = widget.toggleNotifier;
|
||||
bool _isOpen = false;
|
||||
|
||||
@ -86,31 +85,28 @@ class _CommandPaletteControllerState extends State<_CommandPaletteController> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
_toggleNotifier.addListener(_onToggle);
|
||||
_commandPaletteBloc = CommandPaletteBloc();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_toggleNotifier.removeListener(_onToggle);
|
||||
_toggleNotifier.dispose();
|
||||
_commandPaletteBloc.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onToggle() {
|
||||
if (widget.toggleNotifier.value && !_isOpen) {
|
||||
if (_toggleNotifier.value && !_isOpen) {
|
||||
_isOpen = true;
|
||||
FlowyOverlay.show(
|
||||
context: context,
|
||||
builder: (_) => BlocProvider.value(
|
||||
value: _commandPaletteBloc,
|
||||
value: context.read<CommandPaletteBloc>(),
|
||||
child: CommandPaletteModal(shortcutBuilder: _buildShortcut),
|
||||
),
|
||||
).then((_) {
|
||||
_isOpen = false;
|
||||
widget.toggleNotifier.value = false;
|
||||
_toggleNotifier.value = false;
|
||||
});
|
||||
} else if (!widget.toggleNotifier.value && _isOpen) {
|
||||
} else if (!_toggleNotifier.value && _isOpen) {
|
||||
FlowyOverlay.pop(context);
|
||||
_isOpen = false;
|
||||
}
|
||||
@ -148,52 +144,48 @@ class CommandPaletteModal extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<CommandPaletteBloc, CommandPaletteState>(
|
||||
builder: (context, state) {
|
||||
return FlowyDialog(
|
||||
alignment: Alignment.topCenter,
|
||||
insetPadding: const EdgeInsets.only(top: 100),
|
||||
constraints: const BoxConstraints(maxHeight: 420, maxWidth: 510),
|
||||
expandHeight: false,
|
||||
child: shortcutBuilder(
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SearchField(query: state.query, isLoading: state.isLoading),
|
||||
if ((state.query?.isEmpty ?? true) ||
|
||||
state.isLoading && state.results.isEmpty) ...[
|
||||
const Divider(height: 0),
|
||||
Flexible(
|
||||
child: RecentViewsList(
|
||||
onSelected: () => FlowyOverlay.pop(context),
|
||||
),
|
||||
builder: (context, state) => FlowyDialog(
|
||||
alignment: Alignment.topCenter,
|
||||
insetPadding: const EdgeInsets.only(top: 100),
|
||||
constraints: const BoxConstraints(maxHeight: 420, maxWidth: 510),
|
||||
expandHeight: false,
|
||||
child: shortcutBuilder(
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SearchField(query: state.query, isLoading: state.isLoading),
|
||||
if ((state.query?.isEmpty ?? true) ||
|
||||
state.isLoading && state.results.isEmpty) ...[
|
||||
const Divider(height: 0),
|
||||
Flexible(
|
||||
child: RecentViewsList(
|
||||
onSelected: () => FlowyOverlay.pop(context),
|
||||
),
|
||||
],
|
||||
if (state.results.isNotEmpty) ...[
|
||||
const Divider(height: 0),
|
||||
Flexible(
|
||||
child: SearchResultsList(
|
||||
trash: state.trash,
|
||||
results: state.results,
|
||||
),
|
||||
),
|
||||
],
|
||||
_CommandPaletteFooter(
|
||||
shouldShow: state.results.isNotEmpty &&
|
||||
(state.query?.isNotEmpty ?? false),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (state.results.isNotEmpty) ...[
|
||||
const Divider(height: 0),
|
||||
Flexible(
|
||||
child: SearchResultsList(
|
||||
trash: state.trash,
|
||||
results: state.results,
|
||||
),
|
||||
),
|
||||
],
|
||||
_CommandPaletteFooter(
|
||||
shouldShow: state.results.isNotEmpty &&
|
||||
(state.query?.isNotEmpty ?? false),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _CommandPaletteFooter extends StatelessWidget {
|
||||
const _CommandPaletteFooter({
|
||||
required this.shouldShow,
|
||||
});
|
||||
const _CommandPaletteFooter({required this.shouldShow});
|
||||
|
||||
final bool shouldShow;
|
||||
|
||||
@ -204,38 +196,22 @@ class _CommandPaletteFooter extends StatelessWidget {
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 4,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
),
|
||||
border: Border(top: BorderSide(color: Theme.of(context).dividerColor)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 5,
|
||||
vertical: 1,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 1),
|
||||
decoration: BoxDecoration(
|
||||
color: AFThemeExtension.of(context).lightGreyHover,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: const FlowyText.semibold(
|
||||
'TAB',
|
||||
fontSize: 10,
|
||||
),
|
||||
child: const FlowyText.semibold('TAB', fontSize: 10),
|
||||
),
|
||||
const HSpace(4),
|
||||
FlowyText(
|
||||
LocaleKeys.commandPalette_navigateHint.tr(),
|
||||
fontSize: 11,
|
||||
),
|
||||
FlowyText(LocaleKeys.commandPalette_navigateHint.tr(), fontSize: 11),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -5,7 +5,7 @@ import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart';
|
||||
import 'package:appflowy/workspace/application/command_palette/search_result_ext.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/result.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
|
@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/workspace/presentation/command_palette/widgets/search_result_tile.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/trash.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/result.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
|
||||
|
@ -6,12 +6,12 @@ import 'package:appflowy/user/application/auth/auth_service.dart';
|
||||
import 'package:appflowy/user/application/reminder/reminder_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/home/home_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/home/home_service.dart';
|
||||
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_service.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/errors/workspace_failed_screen.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/hotkeys.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar.dart';
|
||||
@ -298,8 +298,8 @@ class DesktopHomeScreenStackAdaptor extends HomeStackDelegate {
|
||||
|
||||
@override
|
||||
void didDeleteStackWidget(ViewPB view, int? index) {
|
||||
HomeService.readApp(appId: view.parentViewId).then((result) {
|
||||
result.fold(
|
||||
ViewBackendService.getView(view.parentViewId).then(
|
||||
(result) => result.fold(
|
||||
(parentView) {
|
||||
final List<ViewPB> views = parentView.childViews;
|
||||
if (views.isNotEmpty) {
|
||||
@ -316,7 +316,7 @@ class DesktopHomeScreenStackAdaptor extends HomeStackDelegate {
|
||||
.add(TabsEvent.openPlugin(plugin: BlankPagePlugin()));
|
||||
},
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
});
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,22 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/shared/feature_flags.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/action_navigation/navigation_action.dart';
|
||||
import 'package:appflowy/workspace/application/command_palette/command_palette_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/favorite/prelude.dart';
|
||||
import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/recent/cached_recent_service.dart';
|
||||
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||
import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_folder.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_new_page_button.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/sidebar_top_menu.dart';
|
||||
@ -19,8 +27,10 @@ import 'package:appflowy_backend/protobuf/flowy-folder/workspace.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
|
||||
show UserProfilePB;
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
/// Home Sidebar is the left side bar of the home page.
|
||||
@ -58,7 +68,23 @@ class HomeSideBar extends StatelessWidget {
|
||||
// +-- Public Or Private Section: control the sections of the workspace
|
||||
// |
|
||||
// +-- Trash Section
|
||||
return BlocBuilder<UserWorkspaceBloc, UserWorkspaceState>(
|
||||
return BlocConsumer<UserWorkspaceBloc, UserWorkspaceState>(
|
||||
listenWhen: (previous, current) =>
|
||||
previous.currentWorkspace?.workspaceId !=
|
||||
current.currentWorkspace?.workspaceId,
|
||||
listener: (context, state) {
|
||||
if (FeatureFlag.search.isOn) {
|
||||
// Notify command palette that workspace has changed
|
||||
context.read<CommandPaletteBloc>().add(
|
||||
CommandPaletteEvent.workspaceChanged(
|
||||
workspaceId: state.currentWorkspace?.workspaceId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Re-initialize workspace-specific services
|
||||
getIt<CachedRecentService>().reset();
|
||||
},
|
||||
// Rebuild the whole sidebar when the current workspace changes
|
||||
buildWhen: (previous, current) =>
|
||||
previous.currentWorkspace?.workspaceId !=
|
||||
@ -130,11 +156,9 @@ class HomeSideBar extends StatelessWidget {
|
||||
) {
|
||||
final action = state.action;
|
||||
if (action?.type == ActionType.openView) {
|
||||
final view = state.views.findView(action!.objectId);
|
||||
|
||||
final view = action!.arguments?[ActionArgumentKeys.view];
|
||||
if (view != null) {
|
||||
final Map<String, dynamic> arguments = {};
|
||||
|
||||
final nodePath = action.arguments?[ActionArgumentKeys.nodePath];
|
||||
if (nodePath != null) {
|
||||
arguments[PluginArgumentKeys.selection] = Selection.collapsed(
|
||||
@ -186,6 +210,7 @@ class _SidebarState extends State<_Sidebar> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const menuHorizontalInset = EdgeInsets.symmetric(horizontal: 12);
|
||||
final userState = context.read<UserWorkspaceBloc>().state;
|
||||
return DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceVariant,
|
||||
@ -206,21 +231,17 @@ class _SidebarState extends State<_Sidebar> {
|
||||
padding: menuHorizontalInset,
|
||||
child:
|
||||
// if the workspaces are empty, show the user profile instead
|
||||
context.read<UserWorkspaceBloc>().state.isCollabWorkspaceOn &&
|
||||
context
|
||||
.read<UserWorkspaceBloc>()
|
||||
.state
|
||||
.workspaces
|
||||
.isNotEmpty
|
||||
? SidebarWorkspace(
|
||||
userProfile: widget.userProfile,
|
||||
)
|
||||
: SidebarUser(
|
||||
userProfile: widget.userProfile,
|
||||
),
|
||||
userState.isCollabWorkspaceOn && userState.workspaces.isNotEmpty
|
||||
? SidebarWorkspace(userProfile: widget.userProfile)
|
||||
: SidebarUser(userProfile: widget.userProfile),
|
||||
),
|
||||
|
||||
const VSpace(20),
|
||||
if (FeatureFlag.search.isOn) ...[
|
||||
const VSpace(8),
|
||||
const Padding(
|
||||
padding: menuHorizontalInset,
|
||||
child: _SidebarSearchButton(),
|
||||
),
|
||||
],
|
||||
// scrollable document list
|
||||
Expanded(
|
||||
child: Padding(
|
||||
@ -263,3 +284,16 @@ class _SidebarState extends State<_Sidebar> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _SidebarSearchButton extends StatelessWidget {
|
||||
const _SidebarSearchButton();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FlowyButton(
|
||||
onTap: () => CommandPalette.of(context).toggle(),
|
||||
leftIcon: const FlowySvg(FlowySvgs.search_s),
|
||||
text: FlowyText(LocaleKeys.search_label.tr()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/widgets/loading.dart';
|
||||
@ -14,7 +16,6 @@ import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class SidebarWorkspace extends StatefulWidget {
|
||||
@ -147,7 +148,7 @@ class _SidebarWorkspaceState extends State<SidebarWorkspace> {
|
||||
}
|
||||
}
|
||||
|
||||
class SidebarSwitchWorkspaceButton extends StatefulWidget {
|
||||
class SidebarSwitchWorkspaceButton extends StatelessWidget {
|
||||
const SidebarSwitchWorkspaceButton({
|
||||
super.key,
|
||||
required this.userProfile,
|
||||
@ -157,26 +158,15 @@ class SidebarSwitchWorkspaceButton extends StatefulWidget {
|
||||
final UserWorkspacePB currentWorkspace;
|
||||
final UserProfilePB userProfile;
|
||||
|
||||
@override
|
||||
State<SidebarSwitchWorkspaceButton> createState() =>
|
||||
_SidebarSwitchWorkspaceButtonState();
|
||||
}
|
||||
|
||||
class _SidebarSwitchWorkspaceButtonState
|
||||
extends State<SidebarSwitchWorkspaceButton> {
|
||||
final controller = PopoverController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppFlowyPopover(
|
||||
direction: PopoverDirection.bottomWithCenterAligned,
|
||||
offset: const Offset(0, 10),
|
||||
constraints: const BoxConstraints(maxWidth: 260, maxHeight: 600),
|
||||
onOpen: () {
|
||||
context.read<UserWorkspaceBloc>().add(
|
||||
const UserWorkspaceEvent.fetchWorkspaces(),
|
||||
);
|
||||
},
|
||||
onOpen: () => context
|
||||
.read<UserWorkspaceBloc>()
|
||||
.add(const UserWorkspaceEvent.fetchWorkspaces()),
|
||||
popupBuilder: (_) {
|
||||
return BlocProvider<UserWorkspaceBloc>.value(
|
||||
value: context.read<UserWorkspaceBloc>(),
|
||||
@ -188,7 +178,7 @@ class _SidebarSwitchWorkspaceButtonState
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return WorkspacesMenu(
|
||||
userProfile: widget.userProfile,
|
||||
userProfile: userProfile,
|
||||
currentWorkspace: currentWorkspace,
|
||||
workspaces: workspaces,
|
||||
);
|
||||
@ -197,8 +187,6 @@ class _SidebarSwitchWorkspaceButtonState
|
||||
);
|
||||
},
|
||||
child: FlowyButton(
|
||||
onTap: () => controller.show(),
|
||||
useIntrinsicWidth: true,
|
||||
margin: const EdgeInsets.symmetric(vertical: 8),
|
||||
text: Row(
|
||||
children: [
|
||||
@ -206,7 +194,7 @@ class _SidebarSwitchWorkspaceButtonState
|
||||
SizedBox.square(
|
||||
dimension: 30.0,
|
||||
child: WorkspaceIcon(
|
||||
workspace: widget.currentWorkspace,
|
||||
workspace: currentWorkspace,
|
||||
iconSize: 20,
|
||||
enableEdit: false,
|
||||
),
|
||||
@ -214,7 +202,7 @@ class _SidebarSwitchWorkspaceButtonState
|
||||
const HSpace(6),
|
||||
Expanded(
|
||||
child: FlowyText.medium(
|
||||
widget.currentWorkspace.name,
|
||||
currentWorkspace.name,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
withTooltip: true,
|
||||
),
|
||||
|
@ -14,6 +14,7 @@ import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-search/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
import 'package:ffi/ffi.dart';
|
||||
@ -25,8 +26,6 @@ import '../protobuf/flowy-config/entities.pb.dart';
|
||||
import '../protobuf/flowy-config/event_map.pb.dart';
|
||||
import '../protobuf/flowy-date/entities.pb.dart';
|
||||
import '../protobuf/flowy-date/event_map.pb.dart';
|
||||
import '../protobuf/flowy-search/entities.pb.dart';
|
||||
import '../protobuf/flowy-search/event_map.pb.dart';
|
||||
|
||||
import 'error.dart';
|
||||
|
||||
|
@ -75,14 +75,14 @@ void main() {
|
||||
..add(const ViewEvent.initial());
|
||||
await blocResponseFuture();
|
||||
deleteViewBloc.add(const ViewEvent.delete());
|
||||
await blocResponseFuture();
|
||||
await blocResponseFuture(millisecond: 1000);
|
||||
assert(context.viewBloc.state.view.childViews.length == 2);
|
||||
assert(trashBloc.state.objects.length == 1);
|
||||
assert(trashBloc.state.objects.first.id == deletedView.id);
|
||||
|
||||
// put back
|
||||
trashBloc.add(TrashEvent.putback(deletedView.id));
|
||||
await blocResponseFuture();
|
||||
await blocResponseFuture(millisecond: 1000);
|
||||
assert(context.viewBloc.state.view.childViews.length == 3);
|
||||
assert(trashBloc.state.objects.isEmpty);
|
||||
|
||||
@ -92,8 +92,7 @@ void main() {
|
||||
..add(const ViewEvent.initial());
|
||||
await blocResponseFuture();
|
||||
deleteViewBloc.add(const ViewEvent.delete());
|
||||
await blocResponseFuture();
|
||||
await blocResponseFuture();
|
||||
await blocResponseFuture(millisecond: 1000);
|
||||
}
|
||||
expect(trashBloc.state.objects[0].id, context.allViews[0].id);
|
||||
expect(trashBloc.state.objects[1].id, context.allViews[1].id);
|
||||
@ -101,12 +100,12 @@ void main() {
|
||||
|
||||
// delete a view permanently
|
||||
trashBloc.add(TrashEvent.delete(trashBloc.state.objects[0]));
|
||||
await blocResponseFuture();
|
||||
await blocResponseFuture(millisecond: 1000);
|
||||
expect(trashBloc.state.objects.length, 2);
|
||||
|
||||
// delete all view permanently
|
||||
trashBloc.add(const TrashEvent.deleteAll());
|
||||
await blocResponseFuture();
|
||||
await blocResponseFuture(millisecond: 1000);
|
||||
assert(
|
||||
trashBloc.state.objects.isEmpty,
|
||||
"but receive ${trashBloc.state.objects.length}",
|
||||
|
@ -49,7 +49,7 @@ void main() {
|
||||
const ViewEvent.initial(),
|
||||
);
|
||||
childViewBloc.add(const ViewEvent.duplicate());
|
||||
await blocResponseFuture();
|
||||
await blocResponseFuture(millisecond: 1000);
|
||||
expect(viewBloc.state.view.childViews.length, 2);
|
||||
});
|
||||
|
||||
@ -220,7 +220,7 @@ void main() {
|
||||
section: ViewSectionPB.Public,
|
||||
),
|
||||
);
|
||||
await blocResponseFuture();
|
||||
await blocResponseFuture(millisecond: 1000);
|
||||
expect(viewBloc.state.view.childViews.length, i + 1);
|
||||
expect(viewBloc.state.view.childViews.last.name, 'Test $layout');
|
||||
expect(viewBloc.state.view.childViews.last.layout, layout);
|
||||
|
97
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
97
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
@ -134,9 +134,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.18"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
@ -162,7 +162,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
|
||||
[[package]]
|
||||
name = "app-error"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -191,6 +191,7 @@ dependencies = [
|
||||
"flowy-document",
|
||||
"flowy-error",
|
||||
"flowy-notification",
|
||||
"flowy-search",
|
||||
"flowy-user",
|
||||
"lib-dispatch",
|
||||
"serde",
|
||||
@ -205,9 +206,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "1.7.1"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
|
||||
checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
@ -739,7 +740,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"again",
|
||||
"anyhow",
|
||||
@ -785,7 +786,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-websocket"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
@ -859,7 +860,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -883,7 +884,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-database"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -913,7 +914,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-document"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -932,7 +933,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -947,7 +948,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-folder"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -985,7 +986,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-plugins"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@ -1024,7 +1025,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -1049,7 +1050,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-protocol"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -1063,7 +1064,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-user"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -1403,7 +1404,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -1583,9 +1584,9 @@ checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "1.2.1"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
|
||||
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
@ -1721,9 +1722,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fastdivide"
|
||||
version = "0.4.1"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59668941c55e5c186b8b58c391629af56774ec768f73c08bbcd56f09348eb00b"
|
||||
checksum = "25c7df09945d65ea8d70b3321547ed414bbc540aad5bac6883d021b970f35b04"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
@ -2134,8 +2135,8 @@ dependencies = [
|
||||
"protobuf",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strsim 0.11.1",
|
||||
"strum_macros 0.26.2",
|
||||
"strsim 0.11.0",
|
||||
"strum_macros 0.26.1",
|
||||
"tantivy",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
@ -2769,7 +2770,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@ -2786,7 +2787,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -3218,7 +3219,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@ -3493,9 +3494,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
version = "0.2.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@ -3608,9 +3609,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lz4_flex"
|
||||
version = "0.11.3"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5"
|
||||
checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15"
|
||||
|
||||
[[package]]
|
||||
name = "mac"
|
||||
@ -3838,9 +3839,9 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
|
||||
|
||||
[[package]]
|
||||
name = "murmurhash32"
|
||||
version = "0.3.1"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2195bf6aa996a481483b29d62a7663eed3fe39600c460e323f8ff41e90bdd89b"
|
||||
checksum = "d9380db4c04d219ac5c51d14996bbf2c2e9a15229771b53f8671eb6c83cf44df"
|
||||
|
||||
[[package]]
|
||||
name = "nanoid"
|
||||
@ -4721,7 +4722,7 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"heck 0.4.1",
|
||||
"itertools 0.10.5",
|
||||
"itertools 0.11.0",
|
||||
"log",
|
||||
"multimap",
|
||||
"once_cell",
|
||||
@ -4742,7 +4743,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.10.5",
|
||||
"itertools 0.11.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.47",
|
||||
@ -5046,6 +5047,15 @@ dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.3"
|
||||
@ -5285,9 +5295,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.33"
|
||||
version = "0.38.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3cc72858054fcff6d7dea32df2aeaee6a7c24227366d7ea429aada2f26b16ad"
|
||||
checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca"
|
||||
dependencies = [
|
||||
"bitflags 2.4.0",
|
||||
"errno",
|
||||
@ -5697,7 +5707,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -5915,9 +5925,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
@ -5952,9 +5962,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.26.2"
|
||||
version = "0.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946"
|
||||
checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18"
|
||||
dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
@ -6486,12 +6496,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.10.1"
|
||||
version = "3.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
|
||||
checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"redox_syscall 0.4.1",
|
||||
"rustix",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
@ -60,6 +60,7 @@ flowy-error = { path = "../../rust-lib/flowy-error", features = [
|
||||
"impl_from_serde",
|
||||
"tauri_ts",
|
||||
] }
|
||||
flowy-search = { path = "../../rust-lib/flowy-search", features = ["tauri_ts"] }
|
||||
flowy-document = { path = "../../rust-lib/flowy-document", features = [
|
||||
"tauri_ts",
|
||||
] }
|
||||
@ -87,7 +88,7 @@ yrs = { git = "https://github.com/appflowy/y-crdt", rev = "3f25bb510ca5274e7657d
|
||||
# Run the script:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ca70c426311fc6fb87ecccfa66e3927b36e96795" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "1019b8c5b6ffb548253dc2c7819afb84d242ab7b" }
|
||||
# Please use the following script to update collab.
|
||||
# Working directory: frontend
|
||||
#
|
||||
@ -97,10 +98,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ca7
|
||||
# To switch to the local path, run:
|
||||
# scripts/tool/update_collab_source.sh
|
||||
# ⚠️⚠️⚠️️
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
|
@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "1.75"
|
||||
channel = "1.77.2"
|
||||
|
34
frontend/appflowy_web/wasm-libs/Cargo.lock
generated
34
frontend/appflowy_web/wasm-libs/Cargo.lock
generated
@ -215,7 +215,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
|
||||
[[package]]
|
||||
name = "app-error"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -541,7 +541,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"again",
|
||||
"anyhow",
|
||||
@ -587,7 +587,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-websocket"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
@ -631,7 +631,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -655,7 +655,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-document"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -674,7 +674,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -689,7 +689,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-folder"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -727,7 +727,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-plugins"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@ -765,7 +765,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -790,7 +790,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-protocol"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -804,7 +804,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-user"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -1001,7 +1001,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -1774,7 +1774,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@ -1791,7 +1791,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -2092,7 +2092,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@ -3732,7 +3732,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -4994,4 +4994,4 @@ dependencies = [
|
||||
[[patch.unused]]
|
||||
name = "collab-database"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
|
@ -55,7 +55,7 @@ codegen-units = 1
|
||||
# Run the script:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ca70c426311fc6fb87ecccfa66e3927b36e96795" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "1019b8c5b6ffb548253dc2c7819afb84d242ab7b" }
|
||||
# Please use the following script to update collab.
|
||||
# Working directory: frontend
|
||||
#
|
||||
@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ca7
|
||||
# To switch to the local path, run:
|
||||
# scripts/tool/update_collab_source.sh
|
||||
# ⚠️⚠️⚠️️
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
|
@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "1.75"
|
||||
channel = "1.77.2"
|
||||
|
40
frontend/appflowy_web_app/src-tauri/Cargo.lock
generated
40
frontend/appflowy_web_app/src-tauri/Cargo.lock
generated
@ -153,7 +153,7 @@ checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
|
||||
[[package]]
|
||||
name = "app-error"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -714,7 +714,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"again",
|
||||
"anyhow",
|
||||
@ -760,7 +760,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-websocket"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
@ -843,7 +843,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -867,7 +867,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-database"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -897,7 +897,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-document"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -916,7 +916,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -931,7 +931,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-folder"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -969,7 +969,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-plugins"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@ -1008,7 +1008,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -1033,7 +1033,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-protocol"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -1047,7 +1047,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-user"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -1280,7 +1280,7 @@ dependencies = [
|
||||
"cssparser-macros",
|
||||
"dtoa-short",
|
||||
"itoa 1.0.10",
|
||||
"phf 0.8.0",
|
||||
"phf 0.11.2",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
@ -1391,7 +1391,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -2844,7 +2844,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@ -2861,7 +2861,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -3298,7 +3298,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@ -4803,7 +4803,7 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"heck 0.4.1",
|
||||
"itertools 0.11.0",
|
||||
"itertools 0.10.5",
|
||||
"log",
|
||||
"multimap",
|
||||
"once_cell",
|
||||
@ -4824,7 +4824,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.11.0",
|
||||
"itertools 0.10.5",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.55",
|
||||
@ -5802,7 +5802,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
|
@ -87,7 +87,7 @@ yrs = { git = "https://github.com/appflowy/y-crdt", rev = "3f25bb510ca5274e7657d
|
||||
# Run the script:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ca70c426311fc6fb87ecccfa66e3927b36e96795" }
|
||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "1019b8c5b6ffb548253dc2c7819afb84d242ab7b" }
|
||||
# Please use the following script to update collab.
|
||||
# Working directory: frontend
|
||||
#
|
||||
@ -97,10 +97,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ca7
|
||||
# To switch to the local path, run:
|
||||
# scripts/tool/update_collab_source.sh
|
||||
# ⚠️⚠️⚠️️
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
|
@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "1.75"
|
||||
channel = "1.77.2"
|
||||
|
@ -1193,6 +1193,7 @@
|
||||
},
|
||||
"inlineActions": {
|
||||
"noResults": "No results",
|
||||
"recentPages": "Recent pages",
|
||||
"pageReference": "Page reference",
|
||||
"docReference": "Document reference",
|
||||
"boardReference": "Board reference",
|
||||
|
106
frontend/rust-lib/Cargo.lock
generated
106
frontend/rust-lib/Cargo.lock
generated
@ -135,9 +135,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.18"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
@ -163,7 +163,7 @@ checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
|
||||
[[package]]
|
||||
name = "app-error"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -182,9 +182,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "1.7.1"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
|
||||
checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
@ -696,7 +696,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-api"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"again",
|
||||
"anyhow",
|
||||
@ -742,7 +742,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "client-websocket"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
@ -785,7 +785,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -809,7 +809,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-database"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -839,7 +839,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-document"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -858,7 +858,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@ -873,7 +873,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-folder"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -911,7 +911,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-plugins"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@ -950,7 +950,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -975,7 +975,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-rt-protocol"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@ -989,7 +989,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "collab-user"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=5e32057ac8e6939368a8e75df91bcbce2ac143e7#5e32057ac8e6939368a8e75df91bcbce2ac143e7"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=66bc02f87ba73b3f1095424a2ec053c1fac72c36#66bc02f87ba73b3f1095424a2ec053c1fac72c36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"collab",
|
||||
@ -1326,7 +1326,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||
[[package]]
|
||||
name = "database-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -1432,6 +1432,12 @@ version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d95203a6a50906215a502507c0f879a0ce7ff205a6111e2db2a5ef8e4bb92e43"
|
||||
|
||||
[[package]]
|
||||
name = "deunicode"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6e854126756c496b8c81dec88f9a706b15b875c5849d4097a3854476b9fdf94"
|
||||
|
||||
[[package]]
|
||||
name = "diesel"
|
||||
version = "2.1.4"
|
||||
@ -1496,9 +1502,9 @@ checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "1.2.1"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
|
||||
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
@ -1647,12 +1653,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fake"
|
||||
version = "2.8.0"
|
||||
version = "2.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9af7b0c58ac9d03169e27f080616ce9f64004edca3d2ef4147a811c21b23b319"
|
||||
checksum = "1c25829bde82205da46e1823b2259db6273379f626fc211f126f65654a2669be"
|
||||
dependencies = [
|
||||
"deunicode 1.4.3",
|
||||
"rand 0.8.5",
|
||||
"unidecode",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1695,15 +1701,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fastdivide"
|
||||
version = "0.4.1"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59668941c55e5c186b8b58c391629af56774ec768f73c08bbcd56f09348eb00b"
|
||||
checksum = "25c7df09945d65ea8d70b3321547ed414bbc540aad5bac6883d021b970f35b04"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.0.2"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
|
||||
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
|
||||
|
||||
[[package]]
|
||||
name = "finl_unicode"
|
||||
@ -2102,8 +2108,8 @@ dependencies = [
|
||||
"protobuf",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strsim 0.11.1",
|
||||
"strum_macros 0.26.2",
|
||||
"strsim 0.11.0",
|
||||
"strum_macros 0.26.1",
|
||||
"tantivy",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
@ -2589,7 +2595,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
@ -2606,7 +2612,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "gotrue-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -2977,7 +2983,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "infra"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"reqwest",
|
||||
@ -3156,9 +3162,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
version = "0.2.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@ -3259,9 +3265,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lz4_flex"
|
||||
version = "0.11.3"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5"
|
||||
checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15"
|
||||
|
||||
[[package]]
|
||||
name = "mac"
|
||||
@ -3465,9 +3471,9 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
|
||||
|
||||
[[package]]
|
||||
name = "murmurhash32"
|
||||
version = "0.3.1"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2195bf6aa996a481483b29d62a7663eed3fe39600c460e323f8ff41e90bdd89b"
|
||||
checksum = "d9380db4c04d219ac5c51d14996bbf2c2e9a15229771b53f8671eb6c83cf44df"
|
||||
|
||||
[[package]]
|
||||
name = "nanoid"
|
||||
@ -4741,9 +4747,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.33"
|
||||
version = "0.38.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3cc72858054fcff6d7dea32df2aeaee6a7c24227366d7ea429aada2f26b16ad"
|
||||
checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
|
||||
dependencies = [
|
||||
"bitflags 2.4.0",
|
||||
"errno",
|
||||
@ -5089,7 +5095,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "shared-entity"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=ca70c426311fc6fb87ecccfa66e3927b36e96795#ca70c426311fc6fb87ecccfa66e3927b36e96795"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=1019b8c5b6ffb548253dc2c7819afb84d242ab7b#1019b8c5b6ffb548253dc2c7819afb84d242ab7b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"app-error",
|
||||
@ -5180,7 +5186,7 @@ version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373"
|
||||
dependencies = [
|
||||
"deunicode",
|
||||
"deunicode 0.4.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5275,9 +5281,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
@ -5312,9 +5318,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.26.2"
|
||||
version = "0.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946"
|
||||
checksum = "7a3417fc93d76740d974a01654a09777cb500428cc874ca9f45edfe0c4d4cd18"
|
||||
dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
@ -5551,9 +5557,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.10.1"
|
||||
version = "3.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
|
||||
checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
@ -6210,12 +6216,6 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "unidecode"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "402bb19d8e03f1d1a7450e2bd613980869438e0666331be3e073089124aa1adc"
|
||||
|
||||
[[package]]
|
||||
name = "universal-hash"
|
||||
version = "0.5.1"
|
||||
|
@ -81,7 +81,7 @@ chrono = { version = "0.4.31", default-features = false, features = ["clock"] }
|
||||
yrs = { version = "0.17.2" }
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 0
|
||||
opt-level = 1
|
||||
lto = false
|
||||
codegen-units = 16
|
||||
|
||||
@ -115,7 +115,7 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1
|
||||
# Run the script.add_workspace_members:
|
||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||
# ⚠️⚠️⚠️️
|
||||
client-api = { git = " https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ca70c426311fc6fb87ecccfa66e3927b36e96795" }
|
||||
client-api = { git = " https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "1019b8c5b6ffb548253dc2c7819afb84d242ab7b" }
|
||||
# Please use the following script to update collab.
|
||||
# Working directory: frontend
|
||||
#
|
||||
@ -125,10 +125,10 @@ client-api = { git = " https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ca
|
||||
# To switch to the local path, run:
|
||||
# scripts/tool/update_collab_source.sh
|
||||
# ⚠️⚠️⚠️️
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "5e32057ac8e6939368a8e75df91bcbce2ac143e7" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "66bc02f87ba73b3f1095424a2ec053c1fac72c36" }
|
||||
|
@ -197,7 +197,7 @@ fn generate_ts_protobuf_files(
|
||||
.write(true)
|
||||
.append(false)
|
||||
.truncate(true)
|
||||
.open(&ts_index)
|
||||
.open(ts_index)
|
||||
{
|
||||
Ok(ref mut file) => {
|
||||
let mut export = String::new();
|
||||
|
@ -77,7 +77,7 @@ pub fn gen(dest_folder_name: &str, project: Project) {
|
||||
.write(true)
|
||||
.append(false)
|
||||
.truncate(true)
|
||||
.open(&ts_index)
|
||||
.open(ts_index)
|
||||
{
|
||||
Ok(ref mut file) => {
|
||||
let mut export = String::new();
|
||||
|
@ -46,6 +46,7 @@ pub fn save_content_to_file_with_diff_prompt(content: &str, output_file: &str) {
|
||||
} else {
|
||||
match OpenOptions::new()
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.write(true)
|
||||
.open(output_file)
|
||||
{
|
||||
|
@ -8,7 +8,7 @@ edition = "2021"
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
collab = { version = "0.1.0" }
|
||||
collab = { version = "0.1.0", features = ["trace_transact"] }
|
||||
collab-plugins = { version = "0.1.0" }
|
||||
collab-entity = { version = "0.1.0" }
|
||||
serde.workspace = true
|
||||
|
@ -177,6 +177,7 @@ pub extern "C" fn link_me_please() {}
|
||||
#[inline(always)]
|
||||
async fn post_to_flutter(response: AFPluginEventResponse, port: i64) {
|
||||
let isolate = allo_isolate::Isolate::new(port);
|
||||
#[allow(clippy::blocks_in_conditions)]
|
||||
match isolate
|
||||
.catch_unwind(async {
|
||||
let ffi_resp = FFIResponse::from(response);
|
||||
|
@ -141,7 +141,7 @@ impl EventIntegrationTest {
|
||||
|
||||
pub fn get_folder_data(&self) -> FolderData {
|
||||
let mutex_folder = self.appflowy_core.folder_manager.get_mutex_folder().clone();
|
||||
let folder_lock_guard = mutex_folder.lock();
|
||||
let folder_lock_guard = mutex_folder.read();
|
||||
let folder = folder_lock_guard.as_ref().unwrap();
|
||||
folder.get_folder_data().clone().unwrap()
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
mod database;
|
||||
mod document;
|
||||
mod folder;
|
||||
mod search;
|
||||
|
||||
// TODO(Mathias): Enable tests for search
|
||||
// mod search;
|
||||
mod user;
|
||||
pub mod util;
|
||||
|
@ -79,7 +79,7 @@ async fn test_folder_index_create_view() {
|
||||
// Wait for the index to be updated
|
||||
sleep(Duration::from_millis(500)).await;
|
||||
|
||||
let results = folder_search_manager.perform_search(view.name.clone());
|
||||
let results = folder_search_manager.perform_search(view.name.clone(), None);
|
||||
if let Err(e) = results {
|
||||
panic!("Error performing search: {:?}", e);
|
||||
}
|
||||
@ -114,12 +114,12 @@ async fn test_folder_index_rename_view() {
|
||||
// Wait for the index to be updated
|
||||
sleep(Duration::from_millis(500)).await;
|
||||
|
||||
let first = folder_search_manager.perform_search(view.name);
|
||||
let first = folder_search_manager.perform_search(view.name, None);
|
||||
if let Err(e) = first {
|
||||
panic!("Error performing search: {:?}", e);
|
||||
}
|
||||
|
||||
let second = folder_search_manager.perform_search(new_view_name.clone());
|
||||
let second = folder_search_manager.perform_search(new_view_name.clone(), None);
|
||||
if let Err(e) = second {
|
||||
panic!("Error performing search: {:?}", e);
|
||||
}
|
||||
|
@ -162,9 +162,7 @@ impl AppFlowyCore {
|
||||
Arc::downgrade(&(server_provider.clone() as Arc<dyn ObjectStorageService>)),
|
||||
);
|
||||
|
||||
let folder_indexer = Arc::new(FolderIndexManagerImpl::new(Arc::downgrade(
|
||||
&authenticate_user,
|
||||
)));
|
||||
let folder_indexer = Arc::new(FolderIndexManagerImpl::new(None));
|
||||
let folder_manager = FolderDepsResolver::resolve(
|
||||
Arc::downgrade(&authenticate_user),
|
||||
&document_manager,
|
||||
|
@ -293,7 +293,7 @@ async fn according_to_select_option_is_filter_test() {
|
||||
let multi_select_field = test.get_first_field(FieldType::MultiSelect);
|
||||
let options = test.get_multi_select_type_option(&multi_select_field.id);
|
||||
|
||||
let filtering_options = vec![options[1].clone(), options[2].clone()];
|
||||
let filtering_options = [options[1].clone(), options[2].clone()];
|
||||
let ids = filtering_options
|
||||
.iter()
|
||||
.map(|option| option.id.clone())
|
||||
@ -346,7 +346,7 @@ async fn according_to_select_option_contains_filter_test() {
|
||||
let multi_select_field = test.get_first_field(FieldType::MultiSelect);
|
||||
let options = test.get_multi_select_type_option(&multi_select_field.id);
|
||||
|
||||
let filtering_options = vec![options[1].clone(), options[2].clone()];
|
||||
let filtering_options = [options[1].clone(), options[2].clone()];
|
||||
let ids = filtering_options
|
||||
.iter()
|
||||
.map(|option| option.id.clone())
|
||||
|
@ -344,6 +344,7 @@ impl DocumentManager {
|
||||
// create file if not exist
|
||||
let mut file = tokio::fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.write(true)
|
||||
.open(&local_file_path)
|
||||
.await?;
|
||||
|
@ -72,6 +72,19 @@ pub fn view_pb_without_child_views(view: View) -> ViewPB {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view_pb_without_child_views_from_arc(view: Arc<View>) -> ViewPB {
|
||||
ViewPB {
|
||||
id: view.id.clone(),
|
||||
parent_view_id: view.parent_view_id.clone(),
|
||||
name: view.name.clone(),
|
||||
create_time: view.created_at,
|
||||
child_views: Default::default(),
|
||||
layout: view.layout.clone().into(),
|
||||
icon: view.icon.clone().map(|icon| icon.into()),
|
||||
is_favorite: view.is_favorite,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a ViewPB with child views. Only the first level of child views are included.
|
||||
pub fn view_pb_with_child_views(view: Arc<View>, child_views: Vec<Arc<View>>) -> ViewPB {
|
||||
ViewPB {
|
||||
|
@ -138,6 +138,16 @@ pub(crate) async fn get_view_handler(
|
||||
data_result_ok(view_pb)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(folder), err)]
|
||||
pub(crate) async fn get_all_views_handler(
|
||||
folder: AFPluginState<Weak<FolderManager>>,
|
||||
) -> DataResult<RepeatedViewPB, FlowyError> {
|
||||
let folder = upgrade_folder(folder)?;
|
||||
let view_pbs = folder.get_all_views_pb().await?;
|
||||
|
||||
data_result_ok(RepeatedViewPB::from(view_pbs))
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(data, folder), err)]
|
||||
pub(crate) async fn get_view_ancestors_handler(
|
||||
data: AFPluginData<ViewIdPB>,
|
||||
|
@ -18,6 +18,7 @@ pub fn init(folder: Weak<FolderManager>) -> AFPlugin {
|
||||
.event(FolderEvent::CreateView, create_view_handler)
|
||||
.event(FolderEvent::CreateOrphanView, create_orphan_view_handler)
|
||||
.event(FolderEvent::GetView, get_view_handler)
|
||||
.event(FolderEvent::GetAllViews, get_all_views_handler)
|
||||
.event(FolderEvent::UpdateView, update_view_handler)
|
||||
.event(FolderEvent::DeleteView, delete_view_handler)
|
||||
.event(FolderEvent::DuplicateView, duplicate_view_handler)
|
||||
@ -97,6 +98,10 @@ pub enum FolderEvent {
|
||||
#[event(input = "CreateOrphanViewPayloadPB", output = "ViewPB")]
|
||||
CreateOrphanView = 16,
|
||||
|
||||
/// Return the view info
|
||||
#[event(output = "RepeatedViewPB")]
|
||||
GetAllViews = 17,
|
||||
|
||||
#[event()]
|
||||
CopyLink = 20,
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
use crate::entities::icon::UpdateViewIconParams;
|
||||
use crate::entities::{
|
||||
view_pb_with_child_views, view_pb_without_child_views, CreateViewParams, CreateWorkspaceParams,
|
||||
DeletedViewPB, FolderSnapshotPB, MoveNestedViewParams, RepeatedTrashPB, RepeatedViewIdPB,
|
||||
RepeatedViewPB, UpdateViewParams, ViewPB, ViewSectionPB, WorkspacePB, WorkspaceSettingPB,
|
||||
view_pb_with_child_views, view_pb_without_child_views, view_pb_without_child_views_from_arc,
|
||||
CreateViewParams, CreateWorkspaceParams, DeletedViewPB, FolderSnapshotPB, MoveNestedViewParams,
|
||||
RepeatedTrashPB, RepeatedViewIdPB, RepeatedViewPB, UpdateViewParams, ViewPB, ViewSectionPB,
|
||||
WorkspacePB, WorkspaceSettingPB,
|
||||
};
|
||||
use crate::manager_observer::{
|
||||
notify_child_views_changed, notify_did_update_workspace, notify_parent_view_did_change,
|
||||
@ -30,11 +31,11 @@ use flowy_folder_pub::cloud::{gen_view_id, FolderCloudService};
|
||||
use flowy_folder_pub::folder_builder::ParentChildViews;
|
||||
use flowy_search_pub::entities::FolderIndexManager;
|
||||
use lib_infra::conditional_send_sync_trait;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use parking_lot::RwLock;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::ops::Deref;
|
||||
use std::sync::{Arc, Weak};
|
||||
use tracing::{error, info, instrument};
|
||||
use tracing::{error, info, instrument, trace};
|
||||
|
||||
conditional_send_sync_trait! {
|
||||
"[crate::manager::FolderUser] represents the user for folder.";
|
||||
@ -134,7 +135,7 @@ impl FolderManager {
|
||||
pub async fn get_current_workspace_public_views(&self) -> FlowyResult<Vec<ViewPB>> {
|
||||
let workspace_id = self
|
||||
.mutex_folder
|
||||
.lock()
|
||||
.read()
|
||||
.as_ref()
|
||||
.map(|folder| folder.get_workspace_id());
|
||||
|
||||
@ -367,7 +368,7 @@ impl FolderManager {
|
||||
|
||||
pub async fn get_workspace_pb(&self) -> FlowyResult<WorkspacePB> {
|
||||
let workspace_pb = {
|
||||
let guard = self.mutex_folder.lock();
|
||||
let guard = self.mutex_folder.read();
|
||||
let folder = guard
|
||||
.as_ref()
|
||||
.ok_or(FlowyError::internal().with_context("folder is not initialized"))?;
|
||||
@ -396,7 +397,7 @@ impl FolderManager {
|
||||
async fn get_current_workspace_id(&self) -> FlowyResult<String> {
|
||||
self
|
||||
.mutex_folder
|
||||
.lock()
|
||||
.read()
|
||||
.as_ref()
|
||||
.map(|folder| folder.get_workspace_id())
|
||||
.ok_or(FlowyError::internal().with_context("Unexpected empty workspace id"))
|
||||
@ -409,12 +410,13 @@ impl FolderManager {
|
||||
///
|
||||
/// * `none_callback`: A callback function that is invoked when `mutex_folder` contains `None`.
|
||||
/// * `f2`: A callback function that is invoked when `mutex_folder` contains a `Some` value. The contained folder is passed as an argument to this callback.
|
||||
#[instrument(level = "debug", skip_all)]
|
||||
fn with_folder<F1, F2, Output>(&self, none_callback: F1, f2: F2) -> Output
|
||||
where
|
||||
F1: FnOnce() -> Output,
|
||||
F2: FnOnce(&Folder) -> Output,
|
||||
{
|
||||
let folder = self.mutex_folder.lock();
|
||||
let folder = self.mutex_folder.read();
|
||||
match &*folder {
|
||||
None => none_callback(),
|
||||
Some(folder) => f2(folder),
|
||||
@ -471,7 +473,7 @@ impl FolderManager {
|
||||
);
|
||||
|
||||
if let Ok(workspace_id) = self.get_current_workspace_id().await {
|
||||
let folder = &self.mutex_folder.lock();
|
||||
let folder = &self.mutex_folder.read();
|
||||
if let Some(folder) = folder.as_ref() {
|
||||
notify_did_update_workspace(&workspace_id, folder);
|
||||
}
|
||||
@ -523,8 +525,10 @@ impl FolderManager {
|
||||
/// again using the ID of the child view you wish to access.
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
pub async fn get_view_pb(&self, view_id: &str) -> FlowyResult<ViewPB> {
|
||||
trace!("Get view pb with id: {}", view_id);
|
||||
let view_id = view_id.to_string();
|
||||
let folder = self.mutex_folder.lock();
|
||||
|
||||
let folder = self.mutex_folder.read();
|
||||
let folder = folder.as_ref().ok_or_else(folder_not_init_error)?;
|
||||
|
||||
// trash views and other private views should not be accessed
|
||||
@ -555,6 +559,30 @@ impl FolderManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves all views.
|
||||
///
|
||||
/// It is important to note that this will return a flat map of all views,
|
||||
/// excluding all child views themselves, as they are all at the same level in this
|
||||
/// map.
|
||||
///
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
pub async fn get_all_views_pb(&self) -> FlowyResult<Vec<ViewPB>> {
|
||||
let folder = self.mutex_folder.read();
|
||||
let folder = folder.as_ref().ok_or_else(folder_not_init_error)?;
|
||||
|
||||
// trash views and other private views should not be accessed
|
||||
let view_ids_should_be_filtered = self.get_view_ids_should_be_filtered(folder);
|
||||
|
||||
let all_views = folder.views.get_all_views();
|
||||
let views = all_views
|
||||
.into_iter()
|
||||
.filter(|view| !view_ids_should_be_filtered.contains(&view.id))
|
||||
.map(view_pb_without_child_views_from_arc)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Ok(views)
|
||||
}
|
||||
|
||||
/// Retrieves the ancestors of the view corresponding to the specified view ID, including the view itself.
|
||||
///
|
||||
/// For example, if the view hierarchy is as follows:
|
||||
@ -1063,7 +1091,7 @@ impl FolderManager {
|
||||
.send();
|
||||
|
||||
if let Ok(workspace_id) = self.get_current_workspace_id().await {
|
||||
let folder = &self.mutex_folder.lock();
|
||||
let folder = &self.mutex_folder.read();
|
||||
if let Some(folder) = folder.as_ref() {
|
||||
notify_did_update_workspace(&workspace_id, folder);
|
||||
}
|
||||
@ -1318,9 +1346,9 @@ pub(crate) fn get_workspace_private_view_pbs(_workspace_id: &str, folder: &Folde
|
||||
/// The MutexFolder is a wrapper of the [Folder] that is used to share the folder between different
|
||||
/// threads.
|
||||
#[derive(Clone, Default)]
|
||||
pub struct MutexFolder(Arc<Mutex<Option<Folder>>>);
|
||||
pub struct MutexFolder(Arc<RwLock<Option<Folder>>>);
|
||||
impl Deref for MutexFolder {
|
||||
type Target = Arc<Mutex<Option<Folder>>>;
|
||||
type Target = Arc<RwLock<Option<Folder>>>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ impl FolderManager {
|
||||
let index_content_rx = folder.subscribe_index_content();
|
||||
self
|
||||
.folder_indexer
|
||||
.set_index_content_receiver(index_content_rx);
|
||||
.set_index_content_receiver(index_content_rx, workspace_id.clone());
|
||||
|
||||
// Index all views in the folder if needed
|
||||
if !self.folder_indexer.is_indexed() {
|
||||
@ -141,12 +141,13 @@ impl FolderManager {
|
||||
let folder_indexer = self.folder_indexer.clone();
|
||||
|
||||
// We spawn a blocking task to index all views in the folder
|
||||
let wid = workspace_id.clone();
|
||||
spawn_blocking(move || {
|
||||
folder_indexer.index_all_views(views);
|
||||
folder_indexer.index_all_views(views, wid);
|
||||
});
|
||||
}
|
||||
|
||||
*self.mutex_folder.lock() = Some(folder);
|
||||
*self.mutex_folder.write() = Some(folder);
|
||||
|
||||
let weak_mutex_folder = Arc::downgrade(&self.mutex_folder);
|
||||
subscribe_folder_sync_state_changed(workspace_id.clone(), folder_state_rx, &weak_mutex_folder);
|
||||
|
@ -67,7 +67,7 @@ pub(crate) fn subscribe_folder_snapshot_state_changed(
|
||||
af_spawn(async move {
|
||||
if let Some(mutex_folder) = weak_mutex_folder.upgrade() {
|
||||
let stream = mutex_folder
|
||||
.lock()
|
||||
.read()
|
||||
.as_ref()
|
||||
.map(|folder| folder.subscribe_snapshot_state());
|
||||
if let Some(mut state_stream) = stream {
|
||||
@ -119,7 +119,7 @@ pub(crate) fn subscribe_folder_trash_changed(
|
||||
TrashSectionChange::TrashItemAdded { ids } => ids,
|
||||
TrashSectionChange::TrashItemRemoved { ids } => ids,
|
||||
};
|
||||
if let Some(folder) = folder.lock().as_ref() {
|
||||
if let Some(folder) = folder.read().as_ref() {
|
||||
let views = folder.views.get_views(&ids);
|
||||
for view in views {
|
||||
unique_ids.insert(view.parent_view_id.clone());
|
||||
@ -146,7 +146,7 @@ pub(crate) fn notify_parent_view_did_change<T: AsRef<str>>(
|
||||
folder: Arc<MutexFolder>,
|
||||
parent_view_ids: Vec<T>,
|
||||
) -> Option<()> {
|
||||
let folder = folder.lock();
|
||||
let folder = folder.read();
|
||||
let folder = folder.as_ref()?;
|
||||
let workspace_id = folder.get_workspace_id();
|
||||
let trash_ids = folder
|
||||
|
@ -9,10 +9,11 @@ pub struct IndexableData {
|
||||
pub data: String,
|
||||
pub icon: Option<ViewIcon>,
|
||||
pub layout: ViewLayout,
|
||||
pub workspace_id: String,
|
||||
}
|
||||
|
||||
pub trait IndexManager: Send + Sync {
|
||||
fn set_index_content_receiver(&self, rx: IndexContentReceiver);
|
||||
fn set_index_content_receiver(&self, rx: IndexContentReceiver, workspace_id: String);
|
||||
fn add_index(&self, data: IndexableData) -> Result<(), FlowyError>;
|
||||
fn update_index(&self, data: IndexableData) -> Result<(), FlowyError>;
|
||||
fn remove_indices(&self, ids: Vec<String>) -> Result<(), FlowyError>;
|
||||
@ -22,5 +23,5 @@ pub trait IndexManager: Send + Sync {
|
||||
}
|
||||
|
||||
pub trait FolderIndexManager: IndexManager {
|
||||
fn index_all_views(&self, views: Vec<View>);
|
||||
fn index_all_views(&self, views: Vec<View>, workspace_id: String);
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
proto_input = ["src/event_map.rs", "src/entities.rs"]
|
||||
proto_input = ["src/event_map.rs", "src/entities"]
|
||||
event_files = ["src/event_map.rs"]
|
||||
|
30
frontend/rust-lib/flowy-search/src/entities/index_type.rs
Normal file
30
frontend/rust-lib/flowy-search/src/entities/index_type.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use flowy_derive::ProtoBuf_Enum;
|
||||
|
||||
#[derive(ProtoBuf_Enum, Eq, PartialEq, Debug, Clone)]
|
||||
pub enum IndexTypePB {
|
||||
View = 0,
|
||||
DocumentBlock = 1,
|
||||
DatabaseRow = 2,
|
||||
}
|
||||
|
||||
impl Default for IndexTypePB {
|
||||
fn default() -> Self {
|
||||
Self::View
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<IndexTypePB> for i32 {
|
||||
fn from(notification: IndexTypePB) -> Self {
|
||||
notification as i32
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<i32> for IndexTypePB {
|
||||
fn from(notification: i32) -> Self {
|
||||
match notification {
|
||||
1 => IndexTypePB::View,
|
||||
2 => IndexTypePB::DocumentBlock,
|
||||
_ => IndexTypePB::DatabaseRow,
|
||||
}
|
||||
}
|
||||
}
|
11
frontend/rust-lib/flowy-search/src/entities/mod.rs
Normal file
11
frontend/rust-lib/flowy-search/src/entities/mod.rs
Normal file
@ -0,0 +1,11 @@
|
||||
mod index_type;
|
||||
mod notification;
|
||||
mod query;
|
||||
mod result;
|
||||
mod search_filter;
|
||||
|
||||
pub use index_type::*;
|
||||
pub use notification::*;
|
||||
pub use query::*;
|
||||
pub use result::*;
|
||||
pub use search_filter::*;
|
39
frontend/rust-lib/flowy-search/src/entities/notification.rs
Normal file
39
frontend/rust-lib/flowy-search/src/entities/notification.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
|
||||
use super::SearchResultPB;
|
||||
|
||||
#[derive(ProtoBuf, Default, Debug, Clone)]
|
||||
pub struct SearchResultNotificationPB {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<SearchResultPB>,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub closed: bool,
|
||||
|
||||
#[pb(index = 3, one_of)]
|
||||
pub channel: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf_Enum, Debug, Default)]
|
||||
pub enum SearchNotification {
|
||||
#[default]
|
||||
Unknown = 0,
|
||||
DidUpdateResults = 1,
|
||||
DidCloseResults = 2,
|
||||
}
|
||||
|
||||
impl std::convert::From<SearchNotification> for i32 {
|
||||
fn from(notification: SearchNotification) -> Self {
|
||||
notification as i32
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<i32> for SearchNotification {
|
||||
fn from(notification: i32) -> Self {
|
||||
match notification {
|
||||
1 => SearchNotification::DidUpdateResults,
|
||||
2 => SearchNotification::DidCloseResults,
|
||||
_ => SearchNotification::Unknown,
|
||||
}
|
||||
}
|
||||
}
|
25
frontend/rust-lib/flowy-search/src/entities/query.rs
Normal file
25
frontend/rust-lib/flowy-search/src/entities/query.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use flowy_derive::ProtoBuf;
|
||||
|
||||
use super::SearchFilterPB;
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Default, Debug, Clone)]
|
||||
pub struct SearchQueryPB {
|
||||
#[pb(index = 1)]
|
||||
pub search: String,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub limit: Option<i64>,
|
||||
|
||||
#[pb(index = 3, one_of)]
|
||||
pub filter: Option<SearchFilterPB>,
|
||||
|
||||
/// Used to identify the channel of the search
|
||||
///
|
||||
/// This can be used to have multiple search notification listeners in place.
|
||||
/// It is up to the client to decide how to handle this.
|
||||
///
|
||||
/// If not set, then no channel is used.
|
||||
///
|
||||
#[pb(index = 4, one_of)]
|
||||
pub channel: Option<String>,
|
||||
}
|
@ -1,14 +1,7 @@
|
||||
use collab_folder::{IconType, ViewIcon};
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Default, Debug, Clone)]
|
||||
pub struct SearchQueryPB {
|
||||
#[pb(index = 1)]
|
||||
pub search: String,
|
||||
|
||||
#[pb(index = 2, one_of)]
|
||||
pub limit: Option<i64>,
|
||||
}
|
||||
use super::IndexTypePB;
|
||||
|
||||
#[derive(Debug, Default, ProtoBuf, Clone)]
|
||||
pub struct RepeatedSearchResultPB {
|
||||
@ -35,6 +28,9 @@ pub struct SearchResultPB {
|
||||
|
||||
#[pb(index = 6)]
|
||||
pub score: f64,
|
||||
|
||||
#[pb(index = 7)]
|
||||
pub workspace_id: String,
|
||||
}
|
||||
|
||||
impl SearchResultPB {
|
||||
@ -46,6 +42,7 @@ impl SearchResultPB {
|
||||
data: self.data.clone(),
|
||||
icon: self.icon.clone(),
|
||||
score,
|
||||
workspace_id: self.workspace_id.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -125,65 +122,3 @@ impl From<ViewIcon> for ResultIconPB {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf_Enum, Eq, PartialEq, Debug, Clone)]
|
||||
pub enum IndexTypePB {
|
||||
View = 0,
|
||||
DocumentBlock = 1,
|
||||
DatabaseRow = 2,
|
||||
}
|
||||
|
||||
impl Default for IndexTypePB {
|
||||
fn default() -> Self {
|
||||
Self::View
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<IndexTypePB> for i32 {
|
||||
fn from(notification: IndexTypePB) -> Self {
|
||||
notification as i32
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<i32> for IndexTypePB {
|
||||
fn from(notification: i32) -> Self {
|
||||
match notification {
|
||||
1 => IndexTypePB::View,
|
||||
2 => IndexTypePB::DocumentBlock,
|
||||
_ => IndexTypePB::DatabaseRow,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf, Default, Debug, Clone)]
|
||||
pub struct SearchResultNotificationPB {
|
||||
#[pb(index = 1)]
|
||||
pub items: Vec<SearchResultPB>,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub closed: bool,
|
||||
}
|
||||
|
||||
#[derive(ProtoBuf_Enum, Debug, Default)]
|
||||
pub enum SearchNotification {
|
||||
#[default]
|
||||
Unknown = 0,
|
||||
DidUpdateResults = 1,
|
||||
DidCloseResults = 2,
|
||||
}
|
||||
|
||||
impl std::convert::From<SearchNotification> for i32 {
|
||||
fn from(notification: SearchNotification) -> Self {
|
||||
notification as i32
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<i32> for SearchNotification {
|
||||
fn from(notification: i32) -> Self {
|
||||
match notification {
|
||||
1 => SearchNotification::DidUpdateResults,
|
||||
2 => SearchNotification::DidCloseResults,
|
||||
_ => SearchNotification::Unknown,
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
use flowy_derive::ProtoBuf;
|
||||
|
||||
#[derive(Eq, PartialEq, ProtoBuf, Default, Debug, Clone)]
|
||||
pub struct SearchFilterPB {
|
||||
#[pb(index = 1, one_of)]
|
||||
pub workspace_id: Option<String>,
|
||||
}
|
@ -21,7 +21,7 @@ pub(crate) async fn search_handler(
|
||||
) -> Result<(), FlowyError> {
|
||||
let query = data.into_inner();
|
||||
let manager = upgrade_manager(manager)?;
|
||||
manager.perform_search(query.search);
|
||||
manager.perform_search(query.search, query.filter, query.channel);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ pub struct FolderIndexData {
|
||||
pub title: String,
|
||||
pub icon: String,
|
||||
pub icon_ty: i64,
|
||||
pub workspace_id: String,
|
||||
}
|
||||
|
||||
impl From<FolderIndexData> for SearchResultPB {
|
||||
@ -28,6 +29,7 @@ impl From<FolderIndexData> for SearchResultPB {
|
||||
data: data.title,
|
||||
score: 0.0,
|
||||
icon,
|
||||
workspace_id: data.workspace_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
use crate::entities::SearchResultPB;
|
||||
use crate::services::manager::{SearchHandler, SearchType};
|
||||
use crate::{
|
||||
entities::{SearchFilterPB, SearchResultPB},
|
||||
services::manager::{SearchHandler, SearchType},
|
||||
};
|
||||
use flowy_error::FlowyResult;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -20,8 +22,20 @@ impl SearchHandler for FolderSearchHandler {
|
||||
SearchType::Folder
|
||||
}
|
||||
|
||||
fn perform_search(&self, query: String) -> FlowyResult<Vec<SearchResultPB>> {
|
||||
self.index_manager.search(query)
|
||||
fn perform_search(
|
||||
&self,
|
||||
query: String,
|
||||
filter: Option<SearchFilterPB>,
|
||||
) -> FlowyResult<Vec<SearchResultPB>> {
|
||||
let mut results = self.index_manager.search(query, filter.clone())?;
|
||||
if let Some(filter) = filter {
|
||||
if let Some(workspace_id) = filter.workspace_id {
|
||||
// Filter results by workspace ID
|
||||
results.retain(|result| result.workspace_id == workspace_id);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
fn index_count(&self) -> u64 {
|
||||
|
@ -8,8 +8,11 @@ use std::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
entities::ResultIconTypePB,
|
||||
folder::schema::{FolderSchema, FOLDER_ICON_FIELD_NAME, FOLDER_TITLE_FIELD_NAME},
|
||||
entities::{ResultIconTypePB, SearchFilterPB, SearchResultPB},
|
||||
folder::schema::{
|
||||
FolderSchema, FOLDER_ICON_FIELD_NAME, FOLDER_ICON_TY_FIELD_NAME, FOLDER_ID_FIELD_NAME,
|
||||
FOLDER_TITLE_FIELD_NAME, FOLDER_WORKSPACE_ID_FIELD_NAME,
|
||||
},
|
||||
};
|
||||
use collab::core::collab::{IndexContent, IndexContentReceiver};
|
||||
use collab_folder::{View, ViewIcon, ViewIndexContent, ViewLayout};
|
||||
@ -23,12 +26,7 @@ use tantivy::{
|
||||
IndexWriter, Term,
|
||||
};
|
||||
|
||||
use crate::entities::SearchResultPB;
|
||||
|
||||
use super::{
|
||||
entities::FolderIndexData,
|
||||
schema::{FOLDER_ICON_TY_FIELD_NAME, FOLDER_ID_FIELD_NAME},
|
||||
};
|
||||
use super::entities::FolderIndexData;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FolderIndexManagerImpl {
|
||||
@ -41,7 +39,15 @@ pub struct FolderIndexManagerImpl {
|
||||
const FOLDER_INDEX_DIR: &str = "folder_index";
|
||||
|
||||
impl FolderIndexManagerImpl {
|
||||
pub fn new(auth_user: Weak<AuthenticateUser>) -> Self {
|
||||
pub fn new(auth_user: Option<Weak<AuthenticateUser>>) -> Self {
|
||||
// TODO(Mathias): Temporarily disable seaerch
|
||||
let auth_user = match auth_user {
|
||||
Some(auth_user) => auth_user,
|
||||
None => {
|
||||
return FolderIndexManagerImpl::empty();
|
||||
},
|
||||
};
|
||||
|
||||
// AuthenticateUser is required to get the index path
|
||||
let authenticate_user = auth_user.upgrade();
|
||||
|
||||
@ -130,15 +136,19 @@ impl FolderIndexManagerImpl {
|
||||
let title_field = folder_schema.schema.get_field(FOLDER_TITLE_FIELD_NAME)?;
|
||||
let icon_field = folder_schema.schema.get_field(FOLDER_ICON_FIELD_NAME)?;
|
||||
let icon_ty_field = folder_schema.schema.get_field(FOLDER_ICON_TY_FIELD_NAME)?;
|
||||
let workspace_id_field = folder_schema
|
||||
.schema
|
||||
.get_field(FOLDER_WORKSPACE_ID_FIELD_NAME)?;
|
||||
|
||||
for data in indexes {
|
||||
let (icon, icon_ty) = self.extract_icon(data.icon, data.layout);
|
||||
|
||||
let _ = index_writer.add_document(doc![
|
||||
id_field => data.id.clone(),
|
||||
title_field => data.data.clone(),
|
||||
icon_field => icon.unwrap_or_default(),
|
||||
icon_ty_field => icon_ty,
|
||||
id_field => data.id.clone(),
|
||||
title_field => data.data.clone(),
|
||||
icon_field => icon.unwrap_or_default(),
|
||||
icon_ty_field => icon_ty,
|
||||
workspace_id_field => data.workspace_id.clone(),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -206,7 +216,11 @@ impl FolderIndexManagerImpl {
|
||||
(icon, icon_ty)
|
||||
}
|
||||
|
||||
pub fn search(&self, query: String) -> Result<Vec<SearchResultPB>, FlowyError> {
|
||||
pub fn search(
|
||||
&self,
|
||||
query: String,
|
||||
_filter: Option<SearchFilterPB>,
|
||||
) -> Result<Vec<SearchResultPB>, FlowyError> {
|
||||
let folder_schema = self.get_folder_schema()?;
|
||||
|
||||
let index = match &self.index {
|
||||
@ -222,11 +236,7 @@ impl FolderIndexManagerImpl {
|
||||
let title_field = folder_schema.schema.get_field(FOLDER_TITLE_FIELD_NAME)?;
|
||||
|
||||
let length = query.len();
|
||||
let distance: u8 = match length {
|
||||
_ if length > 4 => 2,
|
||||
_ if length > 2 => 1,
|
||||
_ => 0,
|
||||
};
|
||||
let distance: u8 = if length >= 2 { 2 } else { 1 };
|
||||
|
||||
let mut query_parser = QueryParser::for_index(&index.clone(), vec![title_field]);
|
||||
query_parser.set_field_fuzzy(title_field, true, distance, true);
|
||||
@ -273,8 +283,9 @@ impl IndexManager for FolderIndexManagerImpl {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn set_index_content_receiver(&self, mut rx: IndexContentReceiver) {
|
||||
fn set_index_content_receiver(&self, mut rx: IndexContentReceiver, workspace_id: String) {
|
||||
let indexer = self.clone();
|
||||
let wid = workspace_id.clone();
|
||||
af_spawn(async move {
|
||||
while let Ok(msg) = rx.recv().await {
|
||||
match msg {
|
||||
@ -285,6 +296,7 @@ impl IndexManager for FolderIndexManagerImpl {
|
||||
data: view.name,
|
||||
icon: view.icon,
|
||||
layout: view.layout,
|
||||
workspace_id: wid.clone(),
|
||||
});
|
||||
},
|
||||
Err(err) => tracing::error!("FolderIndexManager error deserialize: {:?}", err),
|
||||
@ -296,6 +308,7 @@ impl IndexManager for FolderIndexManagerImpl {
|
||||
data: view.name,
|
||||
icon: view.icon,
|
||||
layout: view.layout,
|
||||
workspace_id: wid.clone(),
|
||||
});
|
||||
},
|
||||
Err(err) => tracing::error!("FolderIndexManager error deserialize: {:?}", err),
|
||||
@ -317,7 +330,11 @@ impl IndexManager for FolderIndexManagerImpl {
|
||||
let id_field = folder_schema.schema.get_field(FOLDER_ID_FIELD_NAME)?;
|
||||
let title_field = folder_schema.schema.get_field(FOLDER_TITLE_FIELD_NAME)?;
|
||||
let icon_field = folder_schema.schema.get_field(FOLDER_ICON_FIELD_NAME)?;
|
||||
let icon_ty_field = folder_schema.schema.get_field(FOLDER_ICON_TY_FIELD_NAME)?;
|
||||
let icon_ty_field: tantivy::schema::Field =
|
||||
folder_schema.schema.get_field(FOLDER_ICON_TY_FIELD_NAME)?;
|
||||
let workspace_id_field = folder_schema
|
||||
.schema
|
||||
.get_field(FOLDER_WORKSPACE_ID_FIELD_NAME)?;
|
||||
|
||||
let delete_term = Term::from_field_text(id_field, &data.id.clone());
|
||||
|
||||
@ -332,6 +349,7 @@ impl IndexManager for FolderIndexManagerImpl {
|
||||
title_field => data.data,
|
||||
icon_field => icon.unwrap_or_default(),
|
||||
icon_ty_field => icon_ty,
|
||||
workspace_id_field => data.workspace_id.clone(),
|
||||
]);
|
||||
|
||||
index_writer.commit()?;
|
||||
@ -364,6 +382,9 @@ impl IndexManager for FolderIndexManagerImpl {
|
||||
let title_field = folder_schema.schema.get_field(FOLDER_TITLE_FIELD_NAME)?;
|
||||
let icon_field = folder_schema.schema.get_field(FOLDER_ICON_FIELD_NAME)?;
|
||||
let icon_ty_field = folder_schema.schema.get_field(FOLDER_ICON_TY_FIELD_NAME)?;
|
||||
let workspace_id_field = folder_schema
|
||||
.schema
|
||||
.get_field(FOLDER_WORKSPACE_ID_FIELD_NAME)?;
|
||||
|
||||
let (icon, icon_ty) = self.extract_icon(data.icon, data.layout);
|
||||
|
||||
@ -373,6 +394,7 @@ impl IndexManager for FolderIndexManagerImpl {
|
||||
title_field => data.data,
|
||||
icon_field => icon.unwrap_or_default(),
|
||||
icon_ty_field => icon_ty,
|
||||
workspace_id_field => data.workspace_id,
|
||||
]);
|
||||
|
||||
index_writer.commit()?;
|
||||
@ -386,7 +408,7 @@ impl IndexManager for FolderIndexManagerImpl {
|
||||
}
|
||||
|
||||
impl FolderIndexManager for FolderIndexManagerImpl {
|
||||
fn index_all_views(&self, views: Vec<View>) {
|
||||
fn index_all_views(&self, views: Vec<View>, workspace_id: String) {
|
||||
let indexable_data = views
|
||||
.into_iter()
|
||||
.map(|view| IndexableData {
|
||||
@ -394,6 +416,7 @@ impl FolderIndexManager for FolderIndexManagerImpl {
|
||||
data: view.name,
|
||||
icon: view.icon,
|
||||
layout: view.layout,
|
||||
workspace_id: workspace_id.clone(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
@ -4,6 +4,7 @@ pub const FOLDER_ID_FIELD_NAME: &str = "id";
|
||||
pub const FOLDER_TITLE_FIELD_NAME: &str = "title";
|
||||
pub const FOLDER_ICON_FIELD_NAME: &str = "icon";
|
||||
pub const FOLDER_ICON_TY_FIELD_NAME: &str = "icon_ty";
|
||||
pub const FOLDER_WORKSPACE_ID_FIELD_NAME: &str = "workspace_id";
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FolderSchema {
|
||||
@ -33,6 +34,10 @@ impl FolderSchema {
|
||||
tantivy::schema::TEXT | tantivy::schema::STORED,
|
||||
);
|
||||
schema_builder.add_i64_field(FOLDER_ICON_TY_FIELD_NAME, tantivy::schema::STORED);
|
||||
schema_builder.add_text_field(
|
||||
FOLDER_WORKSPACE_ID_FIELD_NAME,
|
||||
tantivy::schema::TEXT | tantivy::schema::STORED,
|
||||
);
|
||||
|
||||
let schema = schema_builder.build();
|
||||
|
||||
|
@ -5,7 +5,7 @@ use flowy_error::FlowyResult;
|
||||
use lib_dispatch::prelude::af_spawn;
|
||||
use tokio::{sync::broadcast, task::spawn_blocking};
|
||||
|
||||
use crate::entities::{SearchResultNotificationPB, SearchResultPB};
|
||||
use crate::entities::{SearchFilterPB, SearchResultNotificationPB, SearchResultPB};
|
||||
|
||||
use super::notifier::{SearchNotifier, SearchResultChanged, SearchResultReceiverRunner};
|
||||
|
||||
@ -18,7 +18,11 @@ pub trait SearchHandler: Send + Sync + 'static {
|
||||
/// returns the type of search this handler is responsible for
|
||||
fn search_type(&self) -> SearchType;
|
||||
/// performs a search and returns the results
|
||||
fn perform_search(&self, query: String) -> FlowyResult<Vec<SearchResultPB>>;
|
||||
fn perform_search(
|
||||
&self,
|
||||
query: String,
|
||||
filter: Option<SearchFilterPB>,
|
||||
) -> FlowyResult<Vec<SearchResultPB>>;
|
||||
/// returns the number of indexed objects
|
||||
fn index_count(&self) -> u64;
|
||||
}
|
||||
@ -50,17 +54,24 @@ impl SearchManager {
|
||||
self.handlers.get(&search_type)
|
||||
}
|
||||
|
||||
pub fn perform_search(&self, query: String) {
|
||||
pub fn perform_search(
|
||||
&self,
|
||||
query: String,
|
||||
filter: Option<SearchFilterPB>,
|
||||
channel: Option<String>,
|
||||
) {
|
||||
let mut sends: usize = 0;
|
||||
let max: usize = self.handlers.len();
|
||||
let handlers = self.handlers.clone();
|
||||
|
||||
for (_, handler) in handlers {
|
||||
let q = query.clone();
|
||||
let f = filter.clone();
|
||||
let ch = channel.clone();
|
||||
let notifier = self.notifier.clone();
|
||||
|
||||
spawn_blocking(move || {
|
||||
let res = handler.perform_search(q);
|
||||
let res = handler.perform_search(q, f);
|
||||
sends += 1;
|
||||
|
||||
let close = sends == max;
|
||||
@ -68,6 +79,7 @@ impl SearchManager {
|
||||
let notification = SearchResultNotificationPB {
|
||||
items,
|
||||
closed: close,
|
||||
channel: ch,
|
||||
};
|
||||
|
||||
let _ = notifier.send(SearchResultChanged::SearchResultUpdate(notification));
|
||||
|
@ -37,7 +37,7 @@ impl SearchResultReceiverRunner {
|
||||
SearchNotification::DidUpdateResults
|
||||
};
|
||||
|
||||
send_notification(SEARCH_ID, ty)
|
||||
send_notification(SEARCH_ID, ty, notification.channel.clone())
|
||||
.payload(notification)
|
||||
.send();
|
||||
},
|
||||
@ -48,6 +48,16 @@ impl SearchResultReceiverRunner {
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "trace")]
|
||||
pub fn send_notification(id: &str, ty: SearchNotification) -> NotificationBuilder {
|
||||
NotificationBuilder::new(id, ty, SEARCH_OBSERVABLE_SOURCE)
|
||||
pub fn send_notification(
|
||||
id: &str,
|
||||
ty: SearchNotification,
|
||||
channel: Option<String>,
|
||||
) -> NotificationBuilder {
|
||||
let observable_source = &format!(
|
||||
"{}{}",
|
||||
SEARCH_OBSERVABLE_SOURCE,
|
||||
channel.unwrap_or_default()
|
||||
);
|
||||
|
||||
NotificationBuilder::new(id, ty, observable_source)
|
||||
}
|
||||
|
@ -32,9 +32,6 @@ pub(crate) struct UserProfileResponse {
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub(crate) struct UserProfileResponseList(pub Vec<UserProfileResponse>);
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
pub(crate) struct UidResponse {
|
||||
#[allow(dead_code)]
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use chrono::Local;
|
||||
@ -88,8 +90,8 @@ impl Builder {
|
||||
.pretty()
|
||||
.with_env_filter(env_filter)
|
||||
.finish()
|
||||
.with(FlowyFormattingLayer::new(StdoutWriter))
|
||||
.with(JsonStorageLayer)
|
||||
.with(FlowyFormattingLayer::new(DebugStdoutWriter))
|
||||
.with(file_layer);
|
||||
set_global_default(subscriber).map_err(|e| format!("{:?}", e))?;
|
||||
};
|
||||
@ -106,12 +108,19 @@ impl tracing_subscriber::fmt::time::FormatTime for CustomTime {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StdoutWriter;
|
||||
pub struct DebugStdoutWriter;
|
||||
|
||||
impl<'a> MakeWriter<'a> for StdoutWriter {
|
||||
type Writer = std::io::Stdout;
|
||||
impl<'a> MakeWriter<'a> for DebugStdoutWriter {
|
||||
type Writer = Box<dyn Write>;
|
||||
|
||||
fn make_writer(&'a self) -> Self::Writer {
|
||||
std::io::stdout()
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
Box::new(io::sink())
|
||||
}
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
Box::new(io::stdout())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "1.75"
|
||||
channel = "1.77.2"
|
||||
|
Loading…
Reference in New Issue
Block a user