diff --git a/.github/workflows/dart_lint.yml b/.github/workflows/dart_lint.yml
index 2b4a995cce..69cf8e46c7 100644
--- a/.github/workflows/dart_lint.yml
+++ b/.github/workflows/dart_lint.yml
@@ -8,12 +8,8 @@ name: Flutter lint
on:
push:
branches: [ main ]
- paths:
- - 'frontend/app_flowy'
pull_request:
branches: [ main ]
- paths:
- - 'frontend/app_flowy'
env:
CARGO_TERM_COLOR: always
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 69cf3ec788..93dedaa43d 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -66,7 +66,7 @@ jobs:
working-directory: frontend
run: |
flutter config --enable-linux-desktop
- cargo make --profile production-linux-x86 appflowy
+ cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-linux-x86 appflowy
- name: Upload Release Asset
id: upload-release-asset
@@ -111,7 +111,7 @@ jobs:
working-directory: frontend
run: |
flutter config --enable-macos-desktop
- cargo make --profile production-mac-x86 appflowy
+ cargo make --env APP_VERSION=${{ github.ref_name }} --profile production-mac-x86 appflowy
- name: Archive macOS app
working-directory: ${{ env.MACOS_APP_RELEASE_PATH }}
diff --git a/.github/workflows/rust_lint.yml b/.github/workflows/rust_lint.yml
index 9b39f28f2d..ac650b197b 100644
--- a/.github/workflows/rust_lint.yml
+++ b/.github/workflows/rust_lint.yml
@@ -3,14 +3,8 @@ name: Rust lint
on:
push:
branches: [ main ]
- paths:
- - 'frontend/rust-lib'
- - 'shared-lib'
pull_request:
branches: [ main ]
- paths:
- - 'frontend/rust-lib'
- - 'shared-lib'
env:
diff --git a/.github/workflows/rust_test.yml b/.github/workflows/rust_test.yml
index e58db025b4..30b1f15576 100644
--- a/.github/workflows/rust_test.yml
+++ b/.github/workflows/rust_test.yml
@@ -4,15 +4,9 @@ on:
push:
branches:
- 'main'
- paths:
- - 'frontend/rust-lib'
- - 'shared-lib'
pull_request:
branches:
- 'main'
- paths:
- - 'frontend/rust-lib'
- - 'shared-lib'
env:
CARGO_TERM_COLOR: always
@@ -50,8 +44,8 @@ jobs:
- name: Run rust-lib tests
working-directory: frontend/rust-lib
- run: cargo test --no-default-features
+ run: RUST_LOG=info cargo test --no-default-features --features="sync"
- name: Run shared-lib tests
working-directory: shared-lib
- run: cargo test --no-default-features
\ No newline at end of file
+ run: RUST_LOG=info cargo test --no-default-features
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 19540b8ce6..a5ac013c35 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
# Release Notes
+## Version 0.0.4 - beta.1 - 2022-04-08
+v0.0.4 - beta.1 is pre-release
+
+New features
+- Table-view database
+ - supported column types: Text, Checbox, Single-select, Multi-select, Numbers
+ - hide / delete columns
+ - insert rows
+
## Version 0.0.3 - 2022-02-23
v0.0.3 is production ready, available on Linux, macOS, and Windows
diff --git a/frontend/.vscode/launch.json b/frontend/.vscode/launch.json
index 74249d756e..66fc02b1a1 100644
--- a/frontend/.vscode/launch.json
+++ b/frontend/.vscode/launch.json
@@ -11,7 +11,7 @@
"type": "dart",
"preLaunchTask": "build_flowy_sdk",
"env":{
- "RUST_LOG":"info",
+ "RUST_LOG":"info"
},
"cwd": "${workspaceRoot}/app_flowy"
},
@@ -22,7 +22,7 @@
"type": "dart",
"preLaunchTask": "build_flowy_sdk",
"env":{
- "RUST_LOG":"trace",
+ "RUST_LOG":"trace"
},
"cwd": "${workspaceRoot}/app_flowy"
},
diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml
index e661a425b6..7c82e17ba7 100644
--- a/frontend/Makefile.toml
+++ b/frontend/Makefile.toml
@@ -9,24 +9,43 @@ extend = [
{ path = "scripts/makefile/flutter.toml" },
]
+[config]
+on_error_task = "catch"
+
+[tasks.catch]
+run_task = {name = ["restore-crate-type"]}
+
[env]
RUST_LOG = "info"
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
CARGO_MAKE_CRATE_NAME = "dart-ffi"
LIB_NAME = "dart_ffi"
-VERSION = "0.0.3"
+CURRENT_APP_VERSION = "0.0.4"
FEATURES = "flutter"
PRODUCT_NAME = "AppFlowy"
-#CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html
-CRATE_TYPE = "cdylib"
-SDK_EXT = "dylib"
+# CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html
+# If you update the macOS's CRATE_TYPE, don't forget to update the
+# flowy_sdk.podspec
+# for staticlib:
+# s.static_framework = true
+# s.vendored_libraries = "libdart_ffi.a"
+# for cdylib:
+# s.vendored_libraries = "libdart_ffi.dylib"
+#
+# Remember to update the ffi.dart:
+# for staticlib:
+# if (Platform.isMacOS) return DynamicLibrary.open('${prefix}/libdart_ffi.a');
+# for cdylib:
+# if (Platform.isMacOS) return DynamicLibrary.open('${prefix}/libdart_ffi.dylib');
+CRATE_TYPE = "staticlib"
+SDK_EXT = "a"
APP_ENVIRONMENT = "local"
FLUTTER_FLOWY_SDK_PATH="app_flowy/packages/flowy_sdk"
PROTOBUF_DERIVE_CACHE="../shared-lib/flowy-derive/src/derive_cache/derive_cache.rs"
[env.development-mac]
-RUST_LOG = "trace"
+RUST_LOG = "info"
TARGET_OS = "macos"
RUST_COMPILE_TARGET = "x86_64-apple-darwin"
BUILD_FLAG = "debug"
diff --git a/frontend/app_flowy/assets/images/editor/Icons 16/Yen.svg b/frontend/app_flowy/assets/images/editor/Icons 16/Yen.svg
deleted file mode 100644
index b7cf1d361d..0000000000
--- a/frontend/app_flowy/assets/images/editor/Icons 16/Yen.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/frontend/app_flowy/assets/images/grid/checkmark.svg b/frontend/app_flowy/assets/images/grid/checkmark.svg
new file mode 100644
index 0000000000..f9c848f713
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/checkmark.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/delete.svg b/frontend/app_flowy/assets/images/grid/delete.svg
new file mode 100644
index 0000000000..fcfbf2f6dd
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/delete.svg
@@ -0,0 +1,6 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/details.svg b/frontend/app_flowy/assets/images/grid/details.svg
new file mode 100644
index 0000000000..e4c9f58f27
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/details.svg
@@ -0,0 +1,4 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/duplicate.svg b/frontend/app_flowy/assets/images/grid/duplicate.svg
new file mode 100644
index 0000000000..f11048fd2f
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/duplicate.svg
@@ -0,0 +1,4 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/expander.svg b/frontend/app_flowy/assets/images/grid/expander.svg
new file mode 100644
index 0000000000..179bdb1a9e
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/expander.svg
@@ -0,0 +1,6 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/field/checkbox.svg b/frontend/app_flowy/assets/images/grid/field/checkbox.svg
new file mode 100644
index 0000000000..37f52c47ed
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/field/checkbox.svg
@@ -0,0 +1,4 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/field/checklist.svg b/frontend/app_flowy/assets/images/grid/field/checklist.svg
new file mode 100644
index 0000000000..3a88d236a1
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/field/checklist.svg
@@ -0,0 +1,4 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/field/date.svg b/frontend/app_flowy/assets/images/grid/field/date.svg
new file mode 100644
index 0000000000..78243f1e75
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/field/date.svg
@@ -0,0 +1,6 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/field/euro.svg b/frontend/app_flowy/assets/images/grid/field/euro.svg
new file mode 100644
index 0000000000..95f511f687
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/field/euro.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/field/multi_select.svg b/frontend/app_flowy/assets/images/grid/field/multi_select.svg
new file mode 100644
index 0000000000..97a2e9c434
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/field/multi_select.svg
@@ -0,0 +1,8 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/field/number.svg b/frontend/app_flowy/assets/images/grid/field/number.svg
new file mode 100644
index 0000000000..9d8b98d10d
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/field/number.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/field/numbers.svg b/frontend/app_flowy/assets/images/grid/field/numbers.svg
new file mode 100644
index 0000000000..9d8b98d10d
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/field/numbers.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/field/single_select.svg b/frontend/app_flowy/assets/images/grid/field/single_select.svg
new file mode 100644
index 0000000000..8ccbc9a2e3
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/field/single_select.svg
@@ -0,0 +1,4 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/field/text.svg b/frontend/app_flowy/assets/images/grid/field/text.svg
new file mode 100644
index 0000000000..7befa5080f
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/field/text.svg
@@ -0,0 +1,4 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/field/us_dollar.svg b/frontend/app_flowy/assets/images/grid/field/us_dollar.svg
new file mode 100644
index 0000000000..a8485cd6a1
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/field/us_dollar.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/field/yen.svg b/frontend/app_flowy/assets/images/grid/field/yen.svg
new file mode 100644
index 0000000000..8e9bf47c99
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/field/yen.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/hide.svg b/frontend/app_flowy/assets/images/grid/hide.svg
new file mode 100644
index 0000000000..dfb6dbb90c
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/hide.svg
@@ -0,0 +1,4 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/left.svg b/frontend/app_flowy/assets/images/grid/left.svg
new file mode 100644
index 0000000000..0f771a3858
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/left.svg
@@ -0,0 +1,5 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/more.svg b/frontend/app_flowy/assets/images/grid/more.svg
new file mode 100644
index 0000000000..b191e64a10
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/more.svg
@@ -0,0 +1,3 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/right.svg b/frontend/app_flowy/assets/images/grid/right.svg
new file mode 100644
index 0000000000..7d738f4e69
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/right.svg
@@ -0,0 +1,5 @@
+
diff --git a/frontend/app_flowy/assets/images/editor/Icons 16/Sort/Ascending.svg b/frontend/app_flowy/assets/images/grid/setting/ascending.svg
similarity index 100%
rename from frontend/app_flowy/assets/images/editor/Icons 16/Sort/Ascending.svg
rename to frontend/app_flowy/assets/images/grid/setting/ascending.svg
diff --git a/frontend/app_flowy/assets/images/editor/Icons 16/Sort/Descending.svg b/frontend/app_flowy/assets/images/grid/setting/descending.svg
similarity index 100%
rename from frontend/app_flowy/assets/images/editor/Icons 16/Sort/Descending.svg
rename to frontend/app_flowy/assets/images/grid/setting/descending.svg
diff --git a/frontend/app_flowy/assets/images/editor/Icons 16/Filter.svg b/frontend/app_flowy/assets/images/grid/setting/filter.svg
similarity index 100%
rename from frontend/app_flowy/assets/images/editor/Icons 16/Filter.svg
rename to frontend/app_flowy/assets/images/grid/setting/filter.svg
diff --git a/frontend/app_flowy/assets/images/editor/Icons 16/Properties.svg b/frontend/app_flowy/assets/images/grid/setting/properties.svg
similarity index 100%
rename from frontend/app_flowy/assets/images/editor/Icons 16/Properties.svg
rename to frontend/app_flowy/assets/images/grid/setting/properties.svg
diff --git a/frontend/app_flowy/assets/images/grid/setting/setting.svg b/frontend/app_flowy/assets/images/grid/setting/setting.svg
new file mode 100644
index 0000000000..3d632703ab
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/setting/setting.svg
@@ -0,0 +1,4 @@
+
diff --git a/frontend/app_flowy/assets/images/grid/setting/sort.svg b/frontend/app_flowy/assets/images/grid/setting/sort.svg
new file mode 100644
index 0000000000..06e17d62a9
--- /dev/null
+++ b/frontend/app_flowy/assets/images/grid/setting/sort.svg
@@ -0,0 +1,4 @@
+
diff --git a/frontend/app_flowy/assets/translations/en.json b/frontend/app_flowy/assets/translations/en.json
index 7717e71229..a051401446 100644
--- a/frontend/app_flowy/assets/translations/en.json
+++ b/frontend/app_flowy/assets/translations/en.json
@@ -141,5 +141,59 @@
"lightLabel": "Light Mode",
"darkLabel": "Dark Mode"
}
+ },
+ "grid": {
+ "settings": {
+ "filter": "Filter",
+ "sortBy": "Sort by",
+ "Properties": "Properties"
+ },
+ "field": {
+ "hide": "Hide",
+ "insertLeft": "Insert Left",
+ "insertRight": "Insert Right",
+ "duplicate": "Duplicate",
+ "delete": "Delete",
+ "textFieldName": "Text",
+ "checkboxFieldName": "Checkbox",
+ "dateFieldName": "Date",
+ "numberFieldName": "Numbers",
+ "singleSelectFieldName": "Select",
+ "multiSelectFieldName": "Multiselect",
+ "numberFormat": " Number format",
+ "dateFormat": " Date format",
+ "includeTime": " Include time",
+ "dateFormatFriendly": "Month Day,Year",
+ "dateFormatISO": "Year-Month-Day",
+ "dateFormatLocal": "Month/Month/Day",
+ "dateFormatUS": "Month/Month/Day",
+ "timeFormat": " Time format",
+ "timeFormatTwelveHour": "12 hour",
+ "timeFormatTwentyFourHour": "24 hour",
+ "addSelectOption": "Add an option",
+ "optionTitle": "Options",
+ "addOption": "Add option",
+ "editProperty": "Edit property"
+ },
+ "row": {
+ "duplicate": "Duplicate",
+ "delete": "Delete",
+ "textPlaceholder": "Empty"
+ },
+ "selectOption": {
+ "purpleColor": "Purple",
+ "pinkColor": "Pink",
+ "lightPinkColor": "Light Pink",
+ "orangeColor": "Orange",
+ "yellowColor": "Yellow",
+ "limeColor": "Lime",
+ "greenColor": "Green",
+ "aquaColor": "Aqua",
+ "blueColor": "Blue",
+ "deleteTag": "Delete tag",
+ "colorPannelTitle": "Colors",
+ "pannelTitle": "Select an option or create one",
+ "searchOption": "Search for an option"
+ }
}
}
diff --git a/frontend/app_flowy/assets/translations/tr-TR.json b/frontend/app_flowy/assets/translations/tr-TR.json
new file mode 100644
index 0000000000..c83cace0a7
--- /dev/null
+++ b/frontend/app_flowy/assets/translations/tr-TR.json
@@ -0,0 +1,145 @@
+{
+ "appName": "AppFlowy",
+ "defaultUsername": "Ben",
+ "welcomeText": "@:appName'e Hoş Geldiniz!",
+ "githubStarText": "GitHub Yıldızı!",
+ "subscribeNewsletterText": "Bültene Abone Ol",
+ "letsGoButtonText": "Hadi başlayalım.",
+ "title": "Başlık",
+ "signUp": {
+ "buttonText": "Kayıt Ol",
+ "title": "@:appName'e kaydolun.",
+ "getStartedText": "başlayalım",
+ "emptyPasswordError": "Parola boş olamaz",
+ "repeatPasswordEmptyError": "Parola (tekrar) boş olamaz",
+ "unmatchedPasswordError": "Parolalar eşleşmiyor",
+ "alreadyHaveAnAccount": "Zaten hesabınız var mı?",
+ "emailHint": "E-Posta",
+ "passwordHint": "Parola",
+ "repeatPasswordHint": "Tekrar parola"
+ },
+ "signIn": {
+ "loginTitle": "@:appName oturum aç",
+ "loginButtonText": "Giriş",
+ "buttonText": "Oturum Aç",
+ "forgotPassword": "Parolanızı mı Unuttunuz?",
+ "emailHint": "E-Posta",
+ "passwordHint": "Parola",
+ "dontHaveAnAccount": "Hesabınız yok mu?",
+ "repeatPasswordEmptyError": "Parola (tekrar) boş olamaz",
+ "unmatchedPasswordError": "Parolalar eşleşmiyor"
+ },
+ "workspace": {
+ "create": "Çalışma alanı oluştur",
+ "hint": "Çalışma alanı",
+ "notFoundError": "Çalışma alanı bulunamadı"
+ },
+ "shareAction": {
+ "buttonText": "Paylaş",
+ "workInProgress": "Yakında",
+ "markdown": "Markdown",
+ "copyLink": "Link'i Kopyala"
+ },
+ "disclosureAction": {
+ "rename": "Yeniden adlandır",
+ "delete": "Sil",
+ "duplicate": "Çoğalt"
+ },
+ "blankPageTitle": "Boş sayfa",
+ "newPageText": "Yeni sayfa",
+ "trash": {
+ "text": "Çöp",
+ "restoreAll": "Geri Yükle",
+ "deleteAll": "Sil",
+ "pageHeader": {
+ "fileName": "Dosya adı",
+ "lastModified": "Son Değiştirme",
+ "created": "Oluşturuldu"
+ }
+ },
+ "deletePagePrompt": {
+ "text": "Bu sayfa Çöp Kutusu'nda",
+ "restore": "Sayfayı geri yükle",
+ "deletePermanent": "Kalıcı olarak sil"
+ },
+ "dialogCreatePageNameHint": "Sayfa adı",
+ "questionBubble": {
+ "whatsNew": "Yeni ne var?",
+ "help": "Yardım & Destek",
+ "debug": {
+ "name": "Hata Ayıklama",
+ "success": "Hata ayıklama bilgileri panoya kopyalandı!",
+ "fail": "Hata ayıklama bilgileri panoya kopyalanamıyor"
+ }
+ },
+ "menuAppHeader": {
+ "addPageTooltip": "Yeni bir sayfa ekleyin",
+ "defaultNewPageName": "Başlıksız",
+ "renameDialog": "Yeniden adlandır"
+ },
+ "toolbar": {
+ "undo": "Geri",
+ "redo": "İleri",
+ "bold": "Kalın",
+ "italic": "İtalik",
+ "underline": "Altı Çizili",
+ "strike": "Üstü Çizili",
+ "numList": "Numaralı Liste",
+ "bulletList": "Madde İşaretli Liste",
+ "checkList": "Yapılacaklar Listesi",
+ "inlineCode": "Kod",
+ "quote": "Alıntı",
+ "header": "Başlık",
+ "highlight": "Vurgu"
+ },
+ "tooltip": {
+ "lightMode": "Aydınlık Mod'a Geç",
+ "darkMode": "Karanlık Mod'a Geç"
+ },
+ "contactsPage": {
+ "title": "İletişim",
+ "whatsHappening": "Bu hafta neler var?",
+ "addContact": "Kişi Ekle",
+ "editContact": "Kişiyi Düzenle"
+ },
+ "button": {
+ "OK": "TAMAM",
+ "Cancel": "İptal",
+ "signIn": "Oturum Aç",
+ "signOut": "Oturum Kapat",
+ "complete": "Tamamlandı",
+ "save": "Kaydet"
+ },
+ "label": {
+ "welcome": "Merhaba!",
+ "firstName": "Ad",
+ "middleName": "İkinci Ad",
+ "lastName": "Soyad",
+ "stepX": "Aşama {X}"
+ },
+ "oAuth": {
+ "err": {
+ "failedTitle": "Hesabınıza bağlanılamıyor.",
+ "failedMsg": "Lütfen, tarayıcınızda oturum açma işlemini tamamladığınızdan emin olun."
+ },
+ "google": {
+ "title": "GOOGLE OTURUM AÇMA",
+ "instruction1": "Google Kişilerinizi içe aktarmak için web tarayıcınızı kullanarak bu uygulamaya izin vermeniz gerekir.",
+ "instruction2": "Simgeyi tıklayarak veya metni seçerek bu kodu panonuza kopyalayın:",
+ "instruction3": "Web tarayıcınızda aşağıdaki bağlantıyı açın ve yukarıdaki kodu girin:",
+ "instruction4": "Kayıt işlemini tamamladığınızda aşağıdaki düğmeye basın:"
+ }
+ },
+ "settings": {
+ "title": "Ayarlar",
+ "menu": {
+ "appearance": "Görünüm",
+ "language": "Dil",
+ "open": "Ayarları Aç"
+ },
+ "appearance": {
+ "lightLabel": "Aydınlık Mod",
+ "darkLabel": "Karanlık Mod"
+ }
+ }
+}
diff --git a/frontend/app_flowy/lib/core/notification_helper.dart b/frontend/app_flowy/lib/core/notification_helper.dart
index 88b299aa3a..650abc544c 100644
--- a/frontend/app_flowy/lib/core/notification_helper.dart
+++ b/frontend/app_flowy/lib/core/notification_helper.dart
@@ -1,10 +1,14 @@
+import 'dart:async';
import 'dart:typed_data';
import 'package:flowy_sdk/protobuf/dart-notify/protobuf.dart';
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-folder/dart_notification.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pb.dart';
+import 'package:flowy_sdk/rust_stream.dart';
+// User
typedef UserNotificationCallback = void Function(UserNotification, Either);
class UserNotificationParser extends NotificationParser {
@@ -17,10 +21,11 @@ class UserNotificationParser extends NotificationParser);
+// Folder
+typedef FolderNotificationCallback = void Function(FolderNotification, Either);
class FolderNotificationParser extends NotificationParser {
- FolderNotificationParser({String? id, required NotificationCallback callback})
+ FolderNotificationParser({String? id, required FolderNotificationCallback callback})
: super(
id: id,
callback: callback,
@@ -29,6 +34,36 @@ class FolderNotificationParser extends NotificationParser);
+
+class GridNotificationParser extends NotificationParser {
+ GridNotificationParser({String? id, required GridNotificationCallback callback})
+ : super(
+ id: id,
+ callback: callback,
+ tyParser: (ty) => GridNotification.valueOf(ty),
+ errorParser: (bytes) => FlowyError.fromBuffer(bytes),
+ );
+}
+
+typedef GridNotificationHandler = Function(GridNotification ty, Either result);
+
+class GridNotificationListener {
+ StreamSubscription? _subscription;
+ GridNotificationParser? _parser;
+
+ GridNotificationListener({required String objectId, required GridNotificationHandler handler})
+ : _parser = GridNotificationParser(id: objectId, callback: handler) {
+ _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable));
+ }
+
+ Future stop() async {
+ _parser = null;
+ await _subscription?.cancel();
+ }
+}
+
class NotificationParser {
String? id;
void Function(T, Either) callback;
diff --git a/frontend/app_flowy/lib/plugin/plugin.dart b/frontend/app_flowy/lib/plugin/plugin.dart
index d46e14746f..8d30b122ad 100644
--- a/frontend/app_flowy/lib/plugin/plugin.dart
+++ b/frontend/app_flowy/lib/plugin/plugin.dart
@@ -3,27 +3,46 @@ library flowy_plugin;
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
+import 'package:flowy_infra/notifier.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flutter/widgets.dart';
export "./src/sandbox.dart";
+enum DefaultPlugin {
+ quill,
+ blank,
+ trash,
+ grid,
+}
+
+extension FlowyDefaultPluginExt on DefaultPlugin {
+ int type() {
+ switch (this) {
+ case DefaultPlugin.quill:
+ return 0;
+ case DefaultPlugin.blank:
+ return 1;
+ case DefaultPlugin.trash:
+ return 2;
+ case DefaultPlugin.grid:
+ return 3;
+ }
+ }
+}
+
typedef PluginType = int;
-
typedef PluginDataType = ViewDataType;
-
typedef PluginId = String;
abstract class Plugin {
- PluginId get pluginId;
+ PluginId get id;
- PluginDisplay get pluginDisplay;
+ PluginDisplay get display;
- PluginType get pluginType;
+ PluginType get ty;
- ChangeNotifier? get displayNotifier => null;
-
- void dispose();
+ void dispose() {}
}
abstract class PluginBuilder {
@@ -33,22 +52,19 @@ abstract class PluginBuilder {
PluginType get pluginType;
- ViewDataType get dataType => ViewDataType.PlainText;
+ ViewDataType get dataType => ViewDataType.TextBlock;
}
abstract class PluginConfig {
+ // Return false will disable the user to create it. For example, a trash plugin shouldn't be created by the user,
bool get creatable => true;
}
-abstract class PluginDisplay with NavigationItem {
- @override
- Widget get leftBarItem;
-
- @override
- Widget? get rightBarItem;
-
+abstract class PluginDisplay with NavigationItem {
List get navigationItems;
+ PublishNotifier? get notifier => null;
+
Widget buildWidget();
}
diff --git a/frontend/app_flowy/lib/startup/deps_resolver.dart b/frontend/app_flowy/lib/startup/deps_resolver.dart
new file mode 100644
index 0000000000..8f239f1ece
--- /dev/null
+++ b/frontend/app_flowy/lib/startup/deps_resolver.dart
@@ -0,0 +1,217 @@
+import 'package:app_flowy/core/network_monitor.dart';
+import 'package:app_flowy/user/application/user_listener.dart';
+import 'package:app_flowy/user/application/user_service.dart';
+import 'package:app_flowy/workspace/application/app/prelude.dart';
+import 'package:app_flowy/workspace/application/doc/prelude.dart';
+import 'package:app_flowy/workspace/application/grid/prelude.dart';
+import 'package:app_flowy/workspace/application/trash/prelude.dart';
+import 'package:app_flowy/workspace/application/workspace/prelude.dart';
+import 'package:app_flowy/workspace/application/edit_pannel/edit_pannel_bloc.dart';
+import 'package:app_flowy/workspace/application/home/home_bloc.dart';
+import 'package:app_flowy/workspace/application/view/prelude.dart';
+import 'package:app_flowy/workspace/application/home/prelude.dart';
+import 'package:app_flowy/workspace/application/menu/prelude.dart';
+import 'package:app_flowy/user/application/prelude.dart';
+import 'package:app_flowy/user/presentation/router.dart';
+import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
+import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
+import 'package:get_it/get_it.dart';
+
+class DependencyResolver {
+ static Future resolve(GetIt getIt) async {
+ _resolveUserDeps(getIt);
+
+ _resolveHomeDeps(getIt);
+
+ _resolveFolderDeps(getIt);
+
+ _resolveDocDeps(getIt);
+
+ _resolveGridDeps(getIt);
+ }
+}
+
+void _resolveUserDeps(GetIt getIt) {
+ getIt.registerFactory(() => AuthService());
+ getIt.registerFactory(() => AuthRouter());
+
+ getIt.registerFactory(() => SignInBloc(getIt()));
+ getIt.registerFactory(() => SignUpBloc(getIt()));
+
+ getIt.registerFactory(() => SplashRoute());
+ getIt.registerFactory(() => HomeBloc());
+ getIt.registerFactory(() => EditPannelBloc());
+ getIt.registerFactory(() => SplashBloc());
+ getIt.registerLazySingleton(() => NetworkListener());
+}
+
+void _resolveHomeDeps(GetIt getIt) {
+ getIt.registerFactoryParam(
+ (user, _) => UserListener(user: user),
+ );
+
+ getIt.registerFactoryParam(
+ (user, _) => HomeListenBloc(getIt(param1: user)),
+ );
+
+ //
+ getIt.registerLazySingleton(() => HomeStackManager());
+
+ getIt.registerFactoryParam(
+ (user, _) => WelcomeBloc(
+ userService: UserService(),
+ userListener: getIt(param1: user),
+ ),
+ );
+
+ // share
+ getIt.registerLazySingleton(() => ShareService());
+ getIt.registerFactoryParam(
+ (view, _) => DocShareBloc(view: view, service: getIt()));
+}
+
+void _resolveFolderDeps(GetIt getIt) {
+ //workspace
+ getIt.registerFactoryParam((user, workspaceId) =>
+ WorkspaceListener(service: WorkspaceListenerService(user: user, workspaceId: workspaceId)));
+
+ // View
+ getIt.registerFactoryParam(
+ (view, _) => ViewListener(view: view),
+ );
+
+ getIt.registerFactoryParam(
+ (view, _) => ViewBloc(
+ view: view,
+ service: ViewService(),
+ listener: getIt(param1: view),
+ ),
+ );
+
+ //Menu
+ getIt.registerFactoryParam(
+ (user, workspaceId) => MenuBloc(
+ workspaceId: workspaceId,
+ service: WorkspaceService(),
+ listener: getIt(param1: user, param2: workspaceId),
+ ),
+ );
+
+ getIt.registerFactoryParam(
+ (user, _) => MenuUserBloc(
+ user,
+ UserService(),
+ getIt(param1: user),
+ ),
+ );
+
+ // App
+ getIt.registerFactoryParam(
+ (app, _) => AppBloc(
+ app: app,
+ service: AppService(),
+ listener: AppListener(appId: app.id),
+ ),
+ );
+
+ // trash
+ getIt.registerLazySingleton(() => TrashService());
+ getIt.registerLazySingleton(() => TrashListener());
+ getIt.registerFactory(
+ () => TrashBloc(
+ service: getIt(),
+ listener: getIt(),
+ ),
+ );
+}
+
+void _resolveDocDeps(GetIt getIt) {
+// Doc
+ getIt.registerFactoryParam(
+ (view, _) => DocumentBloc(
+ view: view,
+ service: DocumentService(),
+ listener: getIt(param1: view),
+ trashService: getIt(),
+ ),
+ );
+}
+
+void _resolveGridDeps(GetIt getIt) {
+ // Grid
+ getIt.registerFactoryParam(
+ (view, _) => GridBloc(view: view),
+ );
+
+ getIt.registerFactoryParam(
+ (gridId, fieldCache) => GridHeaderBloc(
+ gridId: gridId,
+ fieldCache: fieldCache,
+ ),
+ );
+
+ getIt.registerFactoryParam(
+ (data, _) => FieldActionSheetBloc(
+ field: data.field,
+ service: FieldService(gridId: data.gridId),
+ ),
+ );
+
+ getIt.registerFactoryParam(
+ (gridId, fieldLoader) => FieldEditorBloc(
+ service: FieldService(gridId: gridId),
+ fieldLoader: fieldLoader,
+ ),
+ );
+
+ getIt.registerFactoryParam(
+ (cellData, _) => TextCellBloc(
+ cellData: cellData,
+ ),
+ );
+
+ getIt.registerFactoryParam(
+ (cellData, _) => SelectionCellBloc(
+ cellData: cellData,
+ ),
+ );
+
+ getIt.registerFactoryParam(
+ (cellData, _) => NumberCellBloc(
+ cellData: cellData,
+ ),
+ );
+
+ getIt.registerFactoryParam(
+ (cellData, _) => DateCellBloc(
+ cellData: cellData,
+ ),
+ );
+
+ getIt.registerFactoryParam(
+ (cellData, _) => CheckboxCellBloc(
+ service: CellService(),
+ cellData: cellData,
+ ),
+ );
+
+ getIt.registerFactoryParam(
+ (context, _) => FieldSwitcherBloc(context),
+ );
+
+ getIt.registerFactoryParam(
+ (typeOption, _) => DateTypeOptionBloc(typeOption: typeOption),
+ );
+
+ getIt.registerFactoryParam(
+ (typeOption, _) => NumberTypeOptionBloc(typeOption: typeOption),
+ );
+
+ getIt.registerFactoryParam(
+ (gridId, cache) => GridPropertyBloc(gridId: gridId, fieldCache: cache),
+ );
+}
diff --git a/frontend/app_flowy/lib/startup/home_deps_resolver.dart b/frontend/app_flowy/lib/startup/home_deps_resolver.dart
deleted file mode 100644
index c006c9de88..0000000000
--- a/frontend/app_flowy/lib/startup/home_deps_resolver.dart
+++ /dev/null
@@ -1,115 +0,0 @@
-import 'package:app_flowy/user/application/user_listener.dart';
-import 'package:app_flowy/user/application/user_service.dart';
-import 'package:app_flowy/workspace/application/app/app_bloc.dart';
-import 'package:app_flowy/workspace/application/app/app_listener.dart';
-import 'package:app_flowy/workspace/application/app/app_service.dart';
-import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
-import 'package:app_flowy/workspace/application/doc/doc_service.dart';
-import 'package:app_flowy/workspace/application/doc/share_bloc.dart';
-import 'package:app_flowy/workspace/application/doc/share_service.dart';
-import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart';
-import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
-import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart';
-import 'package:app_flowy/workspace/application/trash/trash_bloc.dart';
-import 'package:app_flowy/workspace/application/trash/trash_listener.dart';
-import 'package:app_flowy/workspace/application/trash/trash_service.dart';
-import 'package:app_flowy/workspace/application/view/view_bloc.dart';
-import 'package:app_flowy/workspace/application/view/view_listener.dart';
-import 'package:app_flowy/workspace/application/view/view_service.dart';
-import 'package:app_flowy/workspace/application/workspace/welcome_bloc.dart';
-import 'package:app_flowy/workspace/application/workspace/workspace_listener.dart';
-import 'package:app_flowy/workspace/application/workspace/workspace_service.dart';
-import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
-import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
-import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
-import 'package:get_it/get_it.dart';
-
-class HomeDepsResolver {
- static Future resolve(GetIt getIt) async {
- getIt.registerFactoryParam(
- (user, _) => UserListener(user: user),
- );
-
- getIt.registerFactoryParam(
- (user, _) => HomeListenBloc(getIt(param1: user)),
- );
-
- //
- getIt.registerLazySingleton(() => HomeStackManager());
- getIt.registerFactoryParam(
- (user, _) => WelcomeBloc(
- userService: UserService(),
- userListener: getIt(param1: user),
- ),
- );
-
- //workspace
- getIt.registerFactoryParam((user, workspaceId) =>
- WorkspaceListener(service: WorkspaceListenerService(user: user, workspaceId: workspaceId)));
-
- // View
- getIt.registerFactoryParam(
- (view, _) => ViewListener(view: view),
- );
-
- getIt.registerFactoryParam(
- (view, _) => ViewBloc(
- view: view,
- service: ViewService(),
- listener: getIt(param1: view),
- ),
- );
-
- //Menu Bloc
- getIt.registerFactoryParam(
- (user, workspaceId) => MenuBloc(
- workspaceId: workspaceId,
- service: WorkspaceService(),
- listener: getIt(param1: user, param2: workspaceId),
- ),
- );
-
- getIt.registerFactoryParam(
- (user, _) => MenuUserBloc(
- user,
- UserService(),
- getIt(param1: user),
- ),
- );
-
- // App
- getIt.registerFactoryParam(
- (app, _) => AppBloc(
- app: app,
- service: AppService(),
- listener: AppListener(appId: app.id),
- ),
- );
-
- // Doc
- getIt.registerFactoryParam(
- (view, _) => DocumentBloc(
- view: view,
- service: DocumentService(),
- listener: getIt(param1: view),
- trashService: getIt(),
- ),
- );
-
- // trash
- getIt.registerLazySingleton(() => TrashService());
- getIt.registerLazySingleton(() => TrashListener());
- getIt.registerFactory(
- () => TrashBloc(
- service: getIt(),
- listener: getIt(),
- ),
- );
-
- // share
- getIt.registerLazySingleton(() => ShareService());
- getIt.registerFactoryParam(
- (view, _) => DocShareBloc(view: view, service: getIt()));
- }
-}
diff --git a/frontend/app_flowy/lib/startup/startup.dart b/frontend/app_flowy/lib/startup/startup.dart
index 0335879f5a..38243afa56 100644
--- a/frontend/app_flowy/lib/startup/startup.dart
+++ b/frontend/app_flowy/lib/startup/startup.dart
@@ -2,8 +2,7 @@ import 'dart:io';
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/tasks/prelude.dart';
-import 'package:app_flowy/startup/home_deps_resolver.dart';
-import 'package:app_flowy/startup/user_deps_resolver.dart';
+import 'package:app_flowy/startup/deps_resolver.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
@@ -62,8 +61,7 @@ Future initGetIt(
getIt.registerLazySingleton(() => AppLauncher(env, getIt));
getIt.registerSingleton(PluginSandbox());
- await UserDepsResolver.resolve(getIt);
- await HomeDepsResolver.resolve(getIt);
+ await DependencyResolver.resolve(getIt);
}
class LaunchContext {
diff --git a/frontend/app_flowy/lib/startup/tasks/app_widget.dart b/frontend/app_flowy/lib/startup/tasks/app_widget.dart
index 23f4109042..1747cfd8ec 100644
--- a/frontend/app_flowy/lib/startup/tasks/app_widget.dart
+++ b/frontend/app_flowy/lib/startup/tasks/app_widget.dart
@@ -39,6 +39,7 @@ class InitAppWidgetTask extends LaunchTask {
Locale('it', 'IT'),
Locale('pt', 'BR'),
Locale('ru', 'RU'),
+ Locale('tr', 'TR'),
Locale('zh', 'CN'),
],
path: 'assets/translations',
@@ -112,7 +113,7 @@ class ApplicationBlocObserver extends BlocObserver {
// ignore: unnecessary_overrides
void onTransition(Bloc bloc, Transition transition) {
// Log.debug("[current]: ${transition.currentState} \n\n[next]: ${transition.nextState}");
- //Log.debug("${transition.nextState}");
+ // Log.debug("${transition.nextState}");
super.onTransition(bloc, transition);
}
@@ -122,9 +123,9 @@ class ApplicationBlocObserver extends BlocObserver {
super.onError(bloc, error, stackTrace);
}
- @override
- void onEvent(Bloc bloc, Object? event) {
- Log.debug("$event");
- super.onEvent(bloc, event);
- }
+ // @override
+ // void onEvent(Bloc bloc, Object? event) {
+ // Log.debug("$event");
+ // super.onEvent(bloc, event);
+ // }
}
diff --git a/frontend/app_flowy/lib/startup/tasks/load_plugin.dart b/frontend/app_flowy/lib/startup/tasks/load_plugin.dart
index 650dd49d22..fd4bb7e2b9 100644
--- a/frontend/app_flowy/lib/startup/tasks/load_plugin.dart
+++ b/frontend/app_flowy/lib/startup/tasks/load_plugin.dart
@@ -2,27 +2,9 @@ import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/presentation/plugins/blank/blank.dart';
import 'package:app_flowy/workspace/presentation/plugins/doc/document.dart';
+import 'package:app_flowy/workspace/presentation/plugins/grid/grid.dart';
import 'package:app_flowy/workspace/presentation/plugins/trash/trash.dart';
-enum DefaultPlugin {
- quillEditor,
- blank,
- trash,
-}
-
-extension FlowyDefaultPluginExt on DefaultPlugin {
- int type() {
- switch (this) {
- case DefaultPlugin.quillEditor:
- return 0;
- case DefaultPlugin.blank:
- return 1;
- case DefaultPlugin.trash:
- return 2;
- }
- }
-}
-
class PluginLoadTask extends LaunchTask {
@override
LaunchTaskType get type => LaunchTaskType.dataProcessing;
@@ -32,5 +14,6 @@ class PluginLoadTask extends LaunchTask {
registerPlugin(builder: BlankPluginBuilder(), config: BlankPluginConfig());
registerPlugin(builder: TrashPluginBuilder(), config: TrashPluginConfig());
registerPlugin(builder: DocumentPluginBuilder());
+ registerPlugin(builder: GridPluginBuilder(), config: GridPluginConfig());
}
}
diff --git a/frontend/app_flowy/lib/startup/user_deps_resolver.dart b/frontend/app_flowy/lib/startup/user_deps_resolver.dart
deleted file mode 100644
index daf67a071a..0000000000
--- a/frontend/app_flowy/lib/startup/user_deps_resolver.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-import 'package:app_flowy/user/application/auth_service.dart';
-import 'package:app_flowy/user/application/sign_in_bloc.dart';
-import 'package:app_flowy/user/application/sign_up_bloc.dart';
-import 'package:app_flowy/user/application/splash_bloc.dart';
-import 'package:app_flowy/user/presentation/router.dart';
-import 'package:app_flowy/workspace/application/edit_pannel/edit_pannel_bloc.dart';
-import 'package:app_flowy/workspace/application/home/home_bloc.dart';
-import 'package:get_it/get_it.dart';
-
-import '../core/network_monitor.dart';
-
-class UserDepsResolver {
- static Future resolve(GetIt getIt) async {
- getIt.registerFactory(() => AuthService());
-
- //Interface implementation
- getIt.registerFactory(() => AuthRouter());
-
- //Bloc
- getIt.registerFactory(() => SignInBloc(getIt()));
- getIt.registerFactory(() => SignUpBloc(getIt()));
-
- getIt.registerFactory(() => SplashRoute());
- getIt.registerFactory(() => HomeBloc());
- getIt.registerFactory(() => EditPannelBloc());
- getIt.registerFactory(() => SplashBloc());
- getIt.registerLazySingleton(() => NetworkListener());
- }
-}
diff --git a/frontend/app_flowy/lib/user/application/prelude.dart b/frontend/app_flowy/lib/user/application/prelude.dart
new file mode 100644
index 0000000000..74b644808e
--- /dev/null
+++ b/frontend/app_flowy/lib/user/application/prelude.dart
@@ -0,0 +1,4 @@
+export './auth_service.dart';
+export './sign_in_bloc.dart';
+export './sign_up_bloc.dart';
+export './splash_bloc.dart';
diff --git a/frontend/app_flowy/lib/user/application/sign_in_bloc.dart b/frontend/app_flowy/lib/user/application/sign_in_bloc.dart
index 25aa66cc50..e0f5bed605 100644
--- a/frontend/app_flowy/lib/user/application/sign_in_bloc.dart
+++ b/frontend/app_flowy/lib/user/application/sign_in_bloc.dart
@@ -54,14 +54,14 @@ class SignInBloc extends Bloc {
}
@freezed
-abstract class SignInEvent with _$SignInEvent {
+class SignInEvent with _$SignInEvent {
const factory SignInEvent.signedInWithUserEmailAndPassword() = SignedInWithUserEmailAndPassword;
const factory SignInEvent.emailChanged(String email) = EmailChanged;
const factory SignInEvent.passwordChanged(String password) = PasswordChanged;
}
@freezed
-abstract class SignInState with _$SignInState {
+class SignInState with _$SignInState {
const factory SignInState({
String? email,
String? password,
diff --git a/frontend/app_flowy/lib/user/application/sign_up_bloc.dart b/frontend/app_flowy/lib/user/application/sign_up_bloc.dart
index 11acd1d385..2efc82d3c7 100644
--- a/frontend/app_flowy/lib/user/application/sign_up_bloc.dart
+++ b/frontend/app_flowy/lib/user/application/sign_up_bloc.dart
@@ -15,11 +15,11 @@ class SignUpBloc extends Bloc {
on((event, emit) async {
await event.map(signUpWithUserEmailAndPassword: (e) async {
await _performActionOnSignUp(emit);
- }, emailChanged: (EmailChanged value) async {
+ }, emailChanged: (_EmailChanged value) async {
emit(state.copyWith(email: value.email, emailError: none(), successOrFail: none()));
- }, passwordChanged: (PasswordChanged value) async {
+ }, passwordChanged: (_PasswordChanged value) async {
emit(state.copyWith(password: value.password, passwordError: none(), successOrFail: none()));
- }, repeatPasswordChanged: (RepeatPasswordChanged value) async {
+ }, repeatPasswordChanged: (_RepeatPasswordChanged value) async {
emit(state.copyWith(repeatedPassword: value.password, repeatPasswordError: none(), successOrFail: none()));
});
});
@@ -104,9 +104,9 @@ class SignUpBloc extends Bloc {
@freezed
class SignUpEvent with _$SignUpEvent {
const factory SignUpEvent.signUpWithUserEmailAndPassword() = SignUpWithUserEmailAndPassword;
- const factory SignUpEvent.emailChanged(String email) = EmailChanged;
- const factory SignUpEvent.passwordChanged(String password) = PasswordChanged;
- const factory SignUpEvent.repeatPasswordChanged(String password) = RepeatPasswordChanged;
+ const factory SignUpEvent.emailChanged(String email) = _EmailChanged;
+ const factory SignUpEvent.passwordChanged(String password) = _PasswordChanged;
+ const factory SignUpEvent.repeatPasswordChanged(String password) = _RepeatPasswordChanged;
}
@freezed
diff --git a/frontend/app_flowy/lib/user/application/user_listener.dart b/frontend/app_flowy/lib/user/application/user_listener.dart
index 993aee60e0..5b212cc2d0 100644
--- a/frontend/app_flowy/lib/user/application/user_listener.dart
+++ b/frontend/app_flowy/lib/user/application/user_listener.dart
@@ -12,7 +12,6 @@ import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-user/dart_notification.pb.dart' as user;
import 'package:flowy_sdk/rust_stream.dart';
-
typedef UserProfileUpdatedNotifierValue = Either;
typedef AuthNotifierValue = Either;
typedef WorkspaceUpdatedNotifierValue = Either, FlowyError>;
@@ -23,8 +22,8 @@ class UserListener {
final authDidChangedNotifier = PublishNotifier();
final workspaceUpdatedNotifier = PublishNotifier();
- late FolderNotificationParser _workspaceParser;
- late UserNotificationParser _userParser;
+ FolderNotificationParser? _workspaceParser;
+ UserNotificationParser? _userParser;
late UserProfile _user;
UserListener({
required UserProfile user,
@@ -36,12 +35,14 @@ class UserListener {
_workspaceParser = FolderNotificationParser(id: _user.token, callback: _notificationCallback);
_userParser = UserNotificationParser(id: _user.token, callback: _userNotificationCallback);
_subscription = RustStreamReceiver.listen((observable) {
- _workspaceParser.parse(observable);
- _userParser.parse(observable);
+ _workspaceParser?.parse(observable);
+ _userParser?.parse(observable);
});
}
Future stop() async {
+ _workspaceParser = null;
+ _userParser = null;
await _subscription?.cancel();
profileUpdatedNotifier.dispose();
authDidChangedNotifier.dispose();
diff --git a/frontend/app_flowy/lib/user/domain/auth_state.dart b/frontend/app_flowy/lib/user/domain/auth_state.dart
index b70383c0aa..96f2036e01 100644
--- a/frontend/app_flowy/lib/user/domain/auth_state.dart
+++ b/frontend/app_flowy/lib/user/domain/auth_state.dart
@@ -4,7 +4,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'auth_state.freezed.dart';
@freezed
-abstract class AuthState with _$AuthState {
+class AuthState with _$AuthState {
const factory AuthState.authenticated(UserProfile userProfile) = Authenticated;
const factory AuthState.unauthenticated(FlowyError error) = Unauthenticated;
const factory AuthState.initial() = _Initial;
diff --git a/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart b/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart
index f7afa0b4d3..9a02863345 100644
--- a/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart
+++ b/frontend/app_flowy/lib/user/presentation/sign_in_screen.dart
@@ -170,11 +170,11 @@ class PasswordTextField extends StatelessWidget {
return RoundedInputField(
obscureText: true,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
- obscureIcon: svg("home/hide"),
- obscureHideIcon: svg("home/show"),
+ obscureIcon: svgWidget("home/hide"),
+ obscureHideIcon: svgWidget("home/show"),
hintText: LocaleKeys.signIn_passwordHint.tr(),
normalBorderColor: theme.shader4,
- highlightBorderColor: theme.red,
+ errorBorderColor: theme.red,
cursorColor: theme.main1,
errorText: context.read().state.passwordError.fold(() => "", (error) => error),
onChanged: (value) => context.read().add(SignInEvent.passwordChanged(value)),
@@ -199,7 +199,7 @@ class EmailTextField extends StatelessWidget {
hintText: LocaleKeys.signIn_emailHint.tr(),
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
normalBorderColor: theme.shader4,
- highlightBorderColor: theme.red,
+ errorBorderColor: theme.red,
cursorColor: theme.main1,
errorText: context.read().state.emailError.fold(() => "", (error) => error),
onChanged: (value) => context.read().add(SignInEvent.emailChanged(value)),
diff --git a/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart b/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart
index 931ccff516..9f95a1db75 100644
--- a/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart
+++ b/frontend/app_flowy/lib/user/presentation/sign_up_screen.dart
@@ -134,12 +134,12 @@ class PasswordTextField extends StatelessWidget {
builder: (context, state) {
return RoundedInputField(
obscureText: true,
- obscureIcon: svg("home/hide"),
- obscureHideIcon: svg("home/show"),
+ obscureIcon: svgWidget("home/hide"),
+ obscureHideIcon: svgWidget("home/show"),
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
hintText: LocaleKeys.signUp_passwordHint.tr(),
normalBorderColor: theme.shader4,
- highlightBorderColor: theme.red,
+ errorBorderColor: theme.red,
cursorColor: theme.main1,
errorText: context.read().state.passwordError.fold(() => "", (error) => error),
onChanged: (value) => context.read().add(SignUpEvent.passwordChanged(value)),
@@ -162,12 +162,12 @@ class RepeatPasswordTextField extends StatelessWidget {
builder: (context, state) {
return RoundedInputField(
obscureText: true,
- obscureIcon: svg("home/hide"),
- obscureHideIcon: svg("home/show"),
+ obscureIcon: svgWidget("home/hide"),
+ obscureHideIcon: svgWidget("home/show"),
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
hintText: LocaleKeys.signUp_repeatPasswordHint.tr(),
normalBorderColor: theme.shader4,
- highlightBorderColor: theme.red,
+ errorBorderColor: theme.red,
cursorColor: theme.main1,
errorText: context.read().state.repeatPasswordError.fold(() => "", (error) => error),
onChanged: (value) => context.read().add(SignUpEvent.repeatPasswordChanged(value)),
@@ -192,7 +192,7 @@ class EmailTextField extends StatelessWidget {
hintText: LocaleKeys.signUp_emailHint.tr(),
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
normalBorderColor: theme.shader4,
- highlightBorderColor: theme.red,
+ errorBorderColor: theme.red,
cursorColor: theme.main1,
errorText: context.read().state.emailError.fold(() => "", (error) => error),
onChanged: (value) => context.read().add(SignUpEvent.emailChanged(value)),
diff --git a/frontend/app_flowy/lib/user/presentation/splash_screen.dart b/frontend/app_flowy/lib/user/presentation/splash_screen.dart
index 5fe302abd0..dd8fdcd180 100644
--- a/frontend/app_flowy/lib/user/presentation/splash_screen.dart
+++ b/frontend/app_flowy/lib/user/presentation/splash_screen.dart
@@ -4,7 +4,7 @@ import 'package:app_flowy/user/domain/auth_state.dart';
import 'package:app_flowy/user/presentation/router.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart';
-import 'package:flowy_sdk/protobuf/flowy-folder-data-model/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/error-code/error_code.pbenum.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/app_flowy/lib/user/presentation/widgets/background.dart b/frontend/app_flowy/lib/user/presentation/widgets/background.dart
index 86dfab7ffe..225f7f0080 100644
--- a/frontend/app_flowy/lib/user/presentation/widgets/background.dart
+++ b/frontend/app_flowy/lib/user/presentation/widgets/background.dart
@@ -44,7 +44,7 @@ class FlowyLogoTitle extends StatelessWidget {
children: [
SizedBox.fromSize(
size: logoSize,
- child: svg("flowy_logo"),
+ child: svgWidget("flowy_logo"),
),
const VSpace(30),
Text(
diff --git a/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart b/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart
index 5175fe2396..73192436bf 100644
--- a/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart
+++ b/frontend/app_flowy/lib/workspace/application/app/app_bloc.dart
@@ -19,7 +19,7 @@ class AppBloc extends Bloc {
AppBloc({required this.app, required this.service, required this.listener}) : super(AppState.initial(app)) {
on((event, emit) async {
await event.map(initial: (e) async {
- listener.startListening(
+ listener.start(
viewsChanged: _handleViewsChanged,
appUpdated: (app) => add(AppEvent.appDidUpdate(app)),
);
diff --git a/frontend/app_flowy/lib/workspace/application/app/app_listener.dart b/frontend/app_flowy/lib/workspace/application/app/app_listener.dart
index 8f0ff7cb23..46b16bb080 100644
--- a/frontend/app_flowy/lib/workspace/application/app/app_listener.dart
+++ b/frontend/app_flowy/lib/workspace/application/app/app_listener.dart
@@ -17,18 +17,18 @@ class AppListener {
StreamSubscription? _subscription;
ViewsDidChangeCallback? _viewsChanged;
AppDidUpdateCallback? _updated;
- late FolderNotificationParser _parser;
+ FolderNotificationParser? _parser;
String appId;
AppListener({
required this.appId,
});
- void startListening({ViewsDidChangeCallback? viewsChanged, AppDidUpdateCallback? appUpdated}) {
+ void start({ViewsDidChangeCallback? viewsChanged, AppDidUpdateCallback? appUpdated}) {
_viewsChanged = viewsChanged;
_updated = appUpdated;
_parser = FolderNotificationParser(id: appId, callback: _bservableCallback);
- _subscription = RustStreamReceiver.listen((observable) => _parser.parse(observable));
+ _subscription = RustStreamReceiver.listen((observable) => _parser?.parse(observable));
}
void _bservableCallback(FolderNotification ty, Either result) {
@@ -61,6 +61,7 @@ class AppListener {
}
Future close() async {
+ _parser = null;
await _subscription?.cancel();
_viewsChanged = null;
_updated = null;
diff --git a/frontend/app_flowy/lib/workspace/application/app/prelude.dart b/frontend/app_flowy/lib/workspace/application/app/prelude.dart
new file mode 100644
index 0000000000..f8477049d3
--- /dev/null
+++ b/frontend/app_flowy/lib/workspace/application/app/prelude.dart
@@ -0,0 +1,3 @@
+export 'app_bloc.dart';
+export 'app_listener.dart';
+export 'app_service.dart';
diff --git a/frontend/app_flowy/lib/workspace/application/appearance.dart b/frontend/app_flowy/lib/workspace/application/appearance.dart
index 87cd7e1af8..06473729a8 100644
--- a/frontend/app_flowy/lib/workspace/application/appearance.dart
+++ b/frontend/app_flowy/lib/workspace/application/appearance.dart
@@ -1,3 +1,5 @@
+import 'dart:async';
+
import 'package:app_flowy/user/application/user_settings_service.dart';
import 'package:equatable/equatable.dart';
import 'package:flowy_infra/theme.dart';
@@ -5,13 +7,12 @@ import 'package:flowy_sdk/log.dart';
import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_setting.pb.dart';
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
-import 'package:async/async.dart';
class AppearanceSettingModel extends ChangeNotifier with EquatableMixin {
AppearanceSettings setting;
AppTheme _theme;
Locale _locale;
- CancelableOperation? _saveOperation;
+ Timer? _saveOperation;
AppearanceSettingModel(this.setting)
: _theme = AppTheme.fromName(name: setting.theme),
@@ -21,12 +22,10 @@ class AppearanceSettingModel extends ChangeNotifier with EquatableMixin {
Locale get locale => _locale;
Future save() async {
- _saveOperation?.cancel;
- _saveOperation = CancelableOperation.fromFuture(
- Future.delayed(const Duration(seconds: 1), () async {
- await UserSettingsService().setAppearanceSettings(setting);
- }),
- );
+ _saveOperation?.cancel();
+ _saveOperation = Timer(const Duration(seconds: 2), () async {
+ await UserSettingsService().setAppearanceSettings(setting);
+ });
}
@override
diff --git a/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart b/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart
index e3dc9c91aa..8d944c34ac 100644
--- a/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart
+++ b/frontend/app_flowy/lib/workspace/application/doc/doc_bloc.dart
@@ -65,7 +65,7 @@ class DocumentBloc extends Bloc {
await _subscription?.cancel();
}
- service.closeDocument(docId: view.id);
+ await service.closeDocument(docId: view.id);
return super.close();
}
@@ -88,7 +88,7 @@ class DocumentBloc extends Bloc {
final result = await service.openDocument(docId: view.id);
result.fold(
(block) {
- document = _decodeJsonToDocument(block.deltaJson);
+ document = _decodeJsonToDocument(block.deltaStr);
_subscription = document.changes.listen((event) {
final delta = event.item2;
final documentDelta = document.toDelta();
@@ -115,7 +115,7 @@ class DocumentBloc extends Bloc {
result.fold((rustDoc) {
// final json = utf8.decode(doc.data);
- final rustDelta = Delta.fromJson(jsonDecode(rustDoc.deltaJson));
+ final rustDelta = Delta.fromJson(jsonDecode(rustDoc.deltaStr));
if (documentDelta != rustDelta) {
Log.error("Receive : $rustDelta");
Log.error("Expected : $documentDelta");
diff --git a/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart b/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart
index e0891ea62c..a0498491f9 100644
--- a/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart
+++ b/frontend/app_flowy/lib/workspace/application/doc/doc_service.dart
@@ -1,20 +1,25 @@
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart';
-import 'package:flowy_sdk/protobuf/flowy-collaboration/document_info.pb.dart';
+
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-sync/text_block_info.pb.dart';
class DocumentService {
- Future> openDocument({required String docId}) {
- final request = ViewId(value: docId);
- return FolderEventOpenView(request).send();
+ Future> openDocument({
+ required String docId,
+ }) async {
+ await FolderEventSetLatestView(ViewId(value: docId)).send();
+
+ final payload = TextBlockId(value: docId);
+ return BlockEventGetBlockData(payload).send();
}
- Future> composeDelta({required String docId, required String data}) {
- final request = BlockDelta.create()
+ Future> composeDelta({required String docId, required String data}) {
+ final payload = TextBlockDelta.create()
..blockId = docId
- ..deltaJson = data;
- return FolderEventApplyDocDelta(request).send();
+ ..deltaStr = data;
+ return BlockEventApplyDelta(payload).send();
}
Future> closeDocument({required String docId}) {
diff --git a/frontend/app_flowy/lib/workspace/application/doc/prelude.dart b/frontend/app_flowy/lib/workspace/application/doc/prelude.dart
new file mode 100644
index 0000000000..f2befe4cf0
--- /dev/null
+++ b/frontend/app_flowy/lib/workspace/application/doc/prelude.dart
@@ -0,0 +1,4 @@
+export 'doc_bloc.dart';
+export 'doc_service.dart';
+export 'share_bloc.dart';
+export 'share_service.dart';
diff --git a/frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart b/frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart
index fe4b2e7f5c..c8fd8a2b96 100644
--- a/frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart
+++ b/frontend/app_flowy/lib/workspace/application/doc/share_bloc.dart
@@ -1,6 +1,6 @@
import 'package:app_flowy/workspace/application/doc/share_service.dart';
import 'package:app_flowy/workspace/application/markdown/delta_markdown.dart';
-import 'package:flowy_sdk/protobuf/flowy-folder-data-model/share.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-text-block/entities.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
diff --git a/frontend/app_flowy/lib/workspace/application/doc/share_service.dart b/frontend/app_flowy/lib/workspace/application/doc/share_service.dart
index eedc0913bb..cc3afe1314 100644
--- a/frontend/app_flowy/lib/workspace/application/doc/share_service.dart
+++ b/frontend/app_flowy/lib/workspace/application/doc/share_service.dart
@@ -1,8 +1,8 @@
import 'dart:async';
import 'package:dartz/dartz.dart';
import 'package:flowy_sdk/dispatch/dispatch.dart';
-import 'package:flowy_sdk/protobuf/flowy-folder-data-model/protobuf.dart';
import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
+import 'package:flowy_sdk/protobuf/flowy-text-block/protobuf.dart';
class ShareService {
Future> export(String docId, ExportType type) {
@@ -10,7 +10,7 @@ class ShareService {
..viewId = docId
..exportType = type;
- return FolderEventExportDocument(request).send();
+ return BlockEventExportDocument(request).send();
}
Future> exportText(String docId) {
diff --git a/frontend/app_flowy/lib/workspace/application/edit_pannel/edit_context.dart b/frontend/app_flowy/lib/workspace/application/edit_pannel/edit_context.dart
index cd52bc7f11..571461b365 100644
--- a/frontend/app_flowy/lib/workspace/application/edit_pannel/edit_context.dart
+++ b/frontend/app_flowy/lib/workspace/application/edit_pannel/edit_context.dart
@@ -5,19 +5,8 @@ abstract class EditPannelContext extends Equatable {
final String identifier;
final String title;
final Widget child;
- const EditPannelContext(
- {required this.child, required this.identifier, required this.title});
+ const EditPannelContext({required this.child, required this.identifier, required this.title});
@override
List