diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2ecf0dab86..e784801bca 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -324,6 +324,7 @@ jobs: with: upload_url: ${{ needs.create-release.outputs.upload_url }} asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_NAME }} + asset_name: ${{ env.LINUX_PACKAGE_NAME }} asset_content_type: application/octet-stream @@ -352,3 +353,12 @@ jobs: tags: ${{ secrets.DOCKER_HUB_USERNAME }}/appflowy_client:${{ github.ref_name }} cache-from: type=registry,ref=${{ secrets.DOCKER_HUB_USERNAME }}/af_build_cache:buildcache cache-to: type=registry,ref=${{ secrets.DOCKER_HUB_USERNAME }}/af_build_cache:buildcache,mode=max + + notify-discord: + runs-on: ubuntu-latest + needs: [build-for-linux, build-for-windows, build-for-macOS] + steps: + - name: Notify Discord + run: | + curl -H "Content-Type: application/json" -d '{"username": "release@appflowy", "content": "🎉 AppFlowy ${{ github.ref_name }} is available. https://github.com/AppFlowy-IO/AppFlowy/releases/tag/'${{ github.ref_name }}'"}' "https://discord.com/api/webhooks/${{ secrets.DISCORD }}" + shell: bash \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 25eef12f1c..fcacaed6c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Release Notes +## Version 0.1.2 - 03/28/2023 + +### Bug Fixes + +- Fix: update calendar selected range. +- Fix: duplicate view. + ## Version 0.1.1 - 03/21/2023 ### New features diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index 1fc240a42a..c7ac53e5c3 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -23,7 +23,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true CARGO_MAKE_CRATE_FS_NAME = "dart_ffi" CARGO_MAKE_CRATE_NAME = "dart-ffi" LIB_NAME = "dart_ffi" -CURRENT_APP_VERSION = "0.1.1" +CURRENT_APP_VERSION = "0.1.2" FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite" PRODUCT_NAME = "AppFlowy" # CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html diff --git a/frontend/appflowy_flutter/assets/images/home/new_app_dark.svg b/frontend/appflowy_flutter/assets/images/home/new_app_dark.svg new file mode 100644 index 0000000000..f1ab9c8cd3 --- /dev/null +++ b/frontend/appflowy_flutter/assets/images/home/new_app_dark.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/appflowy_flutter/assets/translations/en.json b/frontend/appflowy_flutter/assets/translations/en.json index bcca185f4e..a00a49ceb8 100644 --- a/frontend/appflowy_flutter/assets/translations/en.json +++ b/frontend/appflowy_flutter/assets/translations/en.json @@ -188,10 +188,10 @@ "exportDatabase": "Export database", "selectFiles": "Select the files that need to be export", "createNewFolder": "Create a new folder", - "createNewFolderDesc": "Tell us where you want to store your data ...", + "createNewFolderDesc": "Tell us where you want to store your data", "open": "Open", "openFolder": "Open an existing folder", - "openFolderDesc": "Read and write it to your existing AppFlowy folder ...", + "openFolderDesc": "Read and write it to your existing AppFlowy folder", "folderHintText": "folder name", "location": "Creating a new folder", "locationDesc": "Pick a name for your AppFlowy data folder", @@ -366,6 +366,7 @@ "changeCover": "Change Cover", "colors": "Colors", "images": "Images", + "clearAll": "Clear All", "abstract": "Abstract", "addCover": "Add Cover", "addLocalImage": "Add local image", @@ -383,7 +384,6 @@ "imageSavingFailed": "Image Saving Failed", "addIcon": "Add Icon" } - } }, "board": { diff --git a/frontend/appflowy_flutter/assets/translations/zh-TW.json b/frontend/appflowy_flutter/assets/translations/zh-TW.json index 9498df9f54..c1d31944c7 100644 --- a/frontend/appflowy_flutter/assets/translations/zh-TW.json +++ b/frontend/appflowy_flutter/assets/translations/zh-TW.json @@ -40,6 +40,13 @@ "markdown": "Markdown", "copyLink": "複製連結" }, + "moreAction": { + "small": "小", + "medium": "中", + "large": "大", + "fontSize": "字體大小", + "import": "匯入" + }, "disclosureAction": { "rename": "重新命名", "delete": "刪除", @@ -64,6 +71,7 @@ }, "dialogCreatePageNameHint": "頁面名稱", "questionBubble": { + "shortcuts": "快捷鍵", "whatsNew": "新功能", "help": "幫助 & 支援", "debug": { @@ -90,11 +98,21 @@ "inlineCode": "程式碼", "quote": "區塊引言", "header": "標題", - "highlight": "反白" + "highlight": "反白", + "color": "顏色" }, "tooltip": { "lightMode": "切換至亮色模式", - "darkMode": "切換至暗色模式" + "darkMode": "切換至暗色模式", + "openAsPage": "以頁面開啓", + "addNewRow": "新增列表", + "openMenu": "點擊開啓選單", + "viewDataBase": "查看資料庫", + "referencePage": "這個 {name} 已參照" + }, + "sideBar": { + "closeSidebar": "關閉側邊欄", + "openSidebar": "開啓側邊欄" }, "notifications": { "export": { @@ -114,7 +132,14 @@ "signIn": "登入", "signOut": "登出", "complete": "完成", - "save": "儲存" + "save": "儲存", + "generate": "產生", + "esc": "離開", + "keep": "保存", + "tryAgain": "再試一次", + "discard": "放棄變更", + "replace": "取代", + "insertBelow": "在下面插入" }, "label": { "welcome": "歡迎!", @@ -142,22 +167,99 @@ "appearance": "外觀", "language": "語言", "user": "使用者", + "files": "檔案", "open": "開啟設定" }, "appearance": { "themeMode": { - "label": "Theme Mode", + "label": "主題模式", "light": "亮色模式", "dark": "暗色模式", - "system": "Adapt to System" - } + "system": "系統設定" + }, + "theme": "主題" + }, + "files": { + "defaultLocation": "Appflowy 資料儲存位置", + "doubleTapToCopy": "雙擊以複製路徑", + "restoreLocation": "回復 Appflowy 預設路徑", + "customizeLocation": "開啓其他資料夾", + "restartApp": "請重新啓動以讓更動生效", + "exportDatabase": "匯出資料庫", + "selectFiles": "選擇需要匯出的檔案", + "createNewFolder": "建立新檔案", + "createNewFolderDesc": "選擇你想儲存資料的位置", + "open": "打開", + "openFolder": "開啓一個已經存在的資料夾", + "openFolderDesc": "讀寫已存在的 AppFlowy 資料夾", + "folderHintText": "資料夾名稱", + "location": "建立新資料夾", + "locationDesc": "命名 Appflowy 資料夾", + "browser": "瀏覽", + "create": "建立", + "folderPath": "儲存資料夾的路徑", + "locationCannotBeEmpty": "路徑不能爲空", + "pathCopiedSnackbar": "檔案儲存空間的路徑已被複製到剪貼簿!" + }, + "user": { + "name": "名稱", + "icon": "圖標", + "selectAnIcon": "選擇圖標", + "pleaseInputYourOpenAIKey": "請輸入你的 OpenAI 密鑰" } }, "grid": { "settings": { "filter": "篩選", + "sort": "排序", "sortBy": "排序方式", - "Properties": "內容" + "Properties": "內容", + "group": "群組", + "addFilter": "增加", + "deleteFilter": "刪除篩選器", + "filterBy": "以...篩選", + "typeAValue": "輸入一個值...", + "layout": "佈局" + }, + "textFilter": { + "contains": "包含", + "doesNotContain": "不包含", + "endsWith": "以...結尾", + "startWith": "以...開頭", + "is": "是", + "isNot": "不是", + "isEmpty": "爲空", + "isNotEmpty": "不爲空", + "choicechipPrefix": { + "isNot": "不是", + "startWith": "以...開頭", + "endWith": "以...結尾", + "isEmpty": "爲空", + "isNotEmpty": "不爲空" + } + }, + "checkboxFilter": { + "isChecked": "已核取", + "isUnchecked": "未核取", + "choicechipPrefix": { + "is": "是" + } + }, + "checklistFilter": { + "isComplete": "已完成", + "isIncomplted": "未完成" + }, + "singleSelectOptionFilter": { + "is": "是", + "isNot": "不是", + "isEmpty": "爲空", + "isNotEmpty": "不爲空" + }, + "multiSelectOptionFilter": { + "contains": "包含", + "doesNotContain": "不包含", + "isEmpty": "爲空", + "isNotEmpty": "不爲空" }, "field": { "hide": "隱藏", @@ -172,6 +274,7 @@ "singleSelectFieldName": "單選", "multiSelectFieldName": "多選", "urlFieldName": "網址", + "checklistFieldName": "核取列表", "numberFormat": "數字格式", "dateFormat": "日期格式", "includeTime": "包含時間", @@ -186,13 +289,23 @@ "addSelectOption": "新增選項", "optionTitle": "選項", "addOption": "新增選項", - "editProperty": "編輯內容" + "editProperty": "編輯內容", + "newColumn": "新欄位", + "deleteFieldPromptMessage": "你確定嗎?這個內容將被刪除" + }, + "sort": { + "ascending": "升冪排序", + "descending": "降冪排序", + "deleteSort": "刪除排序", + "addSort": "新增排序" }, "row": { "duplicate": "複製", "delete": "刪除", "textPlaceholder": "空", - "copyProperty": "已將內容複製至剪貼簿" + "copyProperty": "已將內容複製至剪貼簿", + "count": "Count", + "newRow": "新列表" }, "selectOption": { "create": "建立", @@ -210,6 +323,9 @@ "panelTitle": "搜尋或建立選項", "searchOption": "搜尋選項" }, + "checklist": { + "panelTitle": "新增物件" + }, "menuName": "網格" }, "document": { @@ -217,10 +333,78 @@ "date": { "timeHintTextInTwelveHour": "01:00 PM", "timeHintTextInTwentyFourHour": "13:00" + }, + "slashMenu": { + "board": { + "selectABoardToLinkTo": "選擇要連結的看板", + "createANewBoard": "建立新的看板" + }, + "grid": { + "selectAGridToLinkTo": "選擇要連結的網格", + "createANewGrid": "建立新網格" + } + }, + "plugins": { + "referencedBoard": "已參照的看板", + "referencedGrid": "已參照的網格", + "autoGeneratorMenuItemName": "OpenAI 寫手", + "autoGeneratorTitleName": "OpenAI: 叫人工智慧寫下任何事情...", + "autoGeneratorLearnMore": "Learn more", + "autoGeneratorGenerate": "產生", + "autoGeneratorHintText": "問 OpenAI ...", + "autoGeneratorCantGetOpenAIKey": "無法取得 OpenAI 密鑰", + "smartEdit": "人工智慧助理", + "openAI": "OpenAI", + "smartEditFixSpelling": "修正拼寫", + "warning": "⚠️ AI 的回答可能不精確或是存在誤導", + "smartEditSummarize": "總結", + "smartEditCouldNotFetchResult": "無法取得 OpenAI 的結果", + "smartEditCouldNotFetchKey": "無法取得 OpenAI 密鑰", + "smartEditDisabled": "在設定連結 OpenAI ", + "discardResponse": "你確定放棄人工智慧的回覆?", + "cover": { + "changeCover": "更換封面", + "colors": "顏色", + "images": "圖片", + "abstract": "摘要", + "addCover": "新增封面", + "addLocalImage": "新增本機圖片", + "invalidImageUrl": "無效的圖片網址", + "failedToAddImageToGallery": "新增圖片到圖庫失敗", + "enterImageUrl": "輸入圖片網址", + "add": "Add", + "back": "Back", + "saveToGallery": "儲存到", + "removeIcon": "移除圖標", + "pasteImageUrl": "複製圖片網址", + "or": "或", + "pickFromFiles": "挑選檔案", + "couldNotFetchImage": "無法截取圖片", + "imageSavingFailed": "圖片儲存失敗", + "addIcon": "新增圖標" + } } }, - "sideBar": { - "openSidebar": "Open sidebar", - "closeSidebar": "Close sidebar" + "board": { + "column": { + "create_new_card": "建立" + }, + "menuName": "看板" + }, + "calendar": { + "menuName": "日曆", + "defaultNewCalendarTitle": "未命名的", + "navigation": { + "today": "今天", + "jumpToday": "跳至今天", + "previousMonth": "上個月", + "nextMonth": "下個月" + }, + "settings": { + "showWeekNumbers": "顯示星期", + "showWeekends": "顯示週末", + "firstDayOfWeek": "一週的第一天", + "layoutDateField": "排列方式" + } } } \ No newline at end of file diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart b/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart index cbd85594a0..24c30a0cd3 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart @@ -184,7 +184,7 @@ class _BoardContentState extends State { width: 20, child: svgWidget( "home/add", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), onAddButtonClick: () { @@ -207,7 +207,7 @@ class _BoardContentState extends State { width: 20, child: svgWidget( "home/add", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), title: FlowyText.medium( diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/toolbar/board_setting.dart b/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/toolbar/board_setting.dart index 5e97c9875f..97118c8e32 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/toolbar/board_setting.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/toolbar/board_setting.dart @@ -113,7 +113,7 @@ class _SettingItem extends StatelessWidget { }, leftIcon: svgWidget( action.iconName(), - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/calendar/presentation/calendar_day.dart b/frontend/appflowy_flutter/lib/plugins/database_view/calendar/presentation/calendar_day.dart index 3a71c2c4ff..0b835f8a39 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/calendar/presentation/calendar_day.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/calendar/presentation/calendar_day.dart @@ -203,7 +203,7 @@ class _NewEventButton extends StatelessWidget { iconPadding: EdgeInsets.zero, icon: svgWidget( "home/add", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), width: 22, ); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/choicechip/choicechip.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/choicechip/choicechip.dart index 8aa9892d41..6900f472e0 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/choicechip/choicechip.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/choicechip/choicechip.dart @@ -43,7 +43,7 @@ class ChoiceChipButton extends StatelessWidget { radius: const BorderRadius.all(Radius.circular(14)), leftIcon: svgWidget( filterInfo.fieldInfo.fieldType.iconName(), - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), rightIcon: _ChoicechipFilterDesc(filterDesc: filterDesc), hoverColor: AFThemeExtension.of(context).lightGreyHover, diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/create_filter_list.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/create_filter_list.dart index e473034fb3..3c8c6b4ba9 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/create_filter_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/create_filter_list.dart @@ -162,7 +162,7 @@ class _FilterPropertyCell extends StatelessWidget { onTap: () => onTap(fieldInfo), leftIcon: svgWidget( fieldInfo.fieldType.iconName(), - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/disclosure_button.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/disclosure_button.dart index 7bab27b745..0f70d7be9d 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/disclosure_button.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/disclosure_button.dart @@ -34,7 +34,7 @@ class _DisclosureButtonState extends State { width: 20, icon: svgWidget( "editor/details", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), onPressed: () => controller.show(), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/filter_menu.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/filter_menu.dart index a7f17b1e8a..ec8c47dc6f 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/filter_menu.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/filter/filter_menu.dart @@ -76,7 +76,7 @@ class _AddFilterButtonState extends State { hoverColor: AFThemeExtension.of(context).lightGreyHover, leftIcon: svgWidget( "home/add", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), onTap: () => popoverController.show(), ), diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/footer/grid_footer.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/footer/grid_footer.dart index 9e4eeb1a4a..44f1d3fb7d 100755 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/footer/grid_footer.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/footer/grid_footer.dart @@ -19,7 +19,7 @@ class GridAddRowButton extends StatelessWidget { onTap: () => context.read().add(const GridEvent.createRow()), leftIcon: svgWidget( "home/add", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_cell.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_cell.dart index 91d5368286..3af13c93a2 100755 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_cell.dart @@ -168,7 +168,7 @@ class FieldCellButton extends StatelessWidget { onTap: onTap, leftIcon: svgWidget( field.fieldType.iconName(), - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), radius: BorderRadius.zero, text: FlowyText.medium( diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_type_list.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_type_list.dart index da6c28d606..f94b46cbee 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_type_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_type_list.dart @@ -61,7 +61,7 @@ class FieldTypeCell extends StatelessWidget { onTap: () => onSelectField(fieldType), leftIcon: svgWidget( fieldType.iconName(), - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_type_option_editor.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_type_option_editor.dart index 4974490642..5f2364571c 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_type_option_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/field_type_option_editor.dart @@ -116,11 +116,11 @@ class _SwitchFieldButton extends StatelessWidget { margin: GridSize.typeOptionContentInsets, leftIcon: svgWidget( bloc.state.field.fieldType.iconName(), - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), rightIcon: svgWidget( "grid/more", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/grid_header.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/grid_header.dart index 0e4c6e28f5..986a91daa2 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/grid_header.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/grid_header.dart @@ -182,7 +182,7 @@ class CreateFieldButton extends StatelessWidget { onTap: () {}, leftIcon: svgWidget( "home/add", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), popupBuilder: (BuildContext popover) { diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/date.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/date.dart index a92ba48fd8..3da0aadd93 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/date.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/date.dart @@ -153,7 +153,7 @@ class DateFormatButton extends StatelessWidget { onHover: onHover, rightIcon: svgWidget( "grid/more", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ); @@ -184,7 +184,7 @@ class TimeFormatButton extends StatelessWidget { onHover: onHover, rightIcon: svgWidget( "grid/more", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/number.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/number.dart index fd5824a0d1..45479046c5 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/number.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/number.dart @@ -61,7 +61,7 @@ class NumberTypeOptionWidget extends TypeOptionWidget { margin: GridSize.typeOptionContentInsets, rightIcon: svgWidget( "grid/more", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), text: Row( children: [ diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/select_option.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/select_option.dart index e30f460c16..cac4f1f0f0 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/select_option.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/select_option.dart @@ -194,7 +194,7 @@ class _OptionCellState extends State<_OptionCell> { padding: const EdgeInsets.symmetric(horizontal: 6.0), child: svgWidget( "grid/details", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ], @@ -251,7 +251,7 @@ class _AddOptionButton extends StatelessWidget { }, leftIcon: svgWidget( "home/add", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ), diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/select_option_editor.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/select_option_editor.dart index c248ec01df..b0d6338ae3 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/select_option_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/header/type_option/select_option_editor.dart @@ -106,7 +106,7 @@ class _DeleteTag extends StatelessWidget { text: FlowyText.medium(LocaleKeys.grid_selectOption_deleteTag.tr()), leftIcon: svgWidget( "grid/delete", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), onTap: () { context diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/row/action.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/row/action.dart index 2aecd5f868..9ecaaf055b 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/row/action.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/row/action.dart @@ -67,7 +67,7 @@ class _ActionCell extends StatelessWidget { }, leftIcon: svgWidget( action.iconName(), - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/sort/create_sort_list.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/sort/create_sort_list.dart index 22f3403a4d..531d781aee 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/sort/create_sort_list.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/sort/create_sort_list.dart @@ -161,7 +161,7 @@ class _SortPropertyCell extends StatelessWidget { onTap: () => onTap(fieldInfo), leftIcon: svgWidget( fieldInfo.fieldType.iconName(), - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/sort/sort_editor.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/sort/sort_editor.dart index 4bd72caa07..8789a6829a 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/sort/sort_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/sort/sort_editor.dart @@ -125,7 +125,7 @@ class _SortItem extends StatelessWidget { hoverColor: AFThemeExtension.of(context).lightGreyHover, icon: svgWidget( "home/close", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ); @@ -187,7 +187,7 @@ class _AddSortButtonState extends State<_AddSortButton> { onTap: () => _popoverController.show(), leftIcon: svgWidget( "home/add", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ), @@ -222,7 +222,7 @@ class _DeleteSortButton extends StatelessWidget { }, leftIcon: svgWidget( "editor/delete", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/sort/sort_menu.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/sort/sort_menu.dart index 19b9b1a569..81a07844cf 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/sort/sort_menu.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/sort/sort_menu.dart @@ -61,7 +61,7 @@ class SortChoiceChip extends StatelessWidget { final text = LocaleKeys.grid_settings_sort.tr(); final leftIcon = svgWidget( "grid/setting/sort", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ); return SizedBox( diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/toolbar/grid_group.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/toolbar/grid_group.dart index 127cb63247..c12ac5613a 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/toolbar/grid_group.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/toolbar/grid_group.dart @@ -82,7 +82,7 @@ class _GridGroupCell extends StatelessWidget { text: FlowyText.medium(fieldInfo.name), leftIcon: svgWidget( fieldInfo.fieldType.iconName(), - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), rightIcon: rightIcon, onTap: () { diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/toolbar/grid_property.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/toolbar/grid_property.dart index 9b65628f4f..0b6f67a6f3 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/toolbar/grid_property.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/toolbar/grid_property.dart @@ -96,7 +96,7 @@ class _GridPropertyCellState extends State<_GridPropertyCell> { Widget build(BuildContext context) { final checkmark = svgWidget( widget.fieldInfo.visibility ? 'home/show' : 'home/hide', - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ); return SizedBox( @@ -118,7 +118,7 @@ class _GridPropertyCellState extends State<_GridPropertyCell> { text: FlowyText.medium(widget.fieldInfo.name), leftIcon: svgWidget( widget.fieldInfo.fieldType.iconName(), - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), rightIcon: FlowyIconButton( hoverColor: Colors.transparent, diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/toolbar/grid_setting.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/toolbar/grid_setting.dart index 25b742b6fc..e41d75ce69 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/toolbar/grid_setting.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/widgets/toolbar/grid_setting.dart @@ -78,7 +78,7 @@ class _SettingItem extends StatelessWidget { onTap: () => onAction(action), leftIcon: svgWidget( action.iconName(), - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart index 196b4b40ec..1227ef8e3c 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart @@ -232,7 +232,7 @@ class _CardMoreOption extends StatelessWidget with CardAccessory { padding: const EdgeInsets.all(3.0), child: svgWidget( 'grid/details', - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ); } @@ -254,7 +254,7 @@ class _CardEditOption extends StatelessWidget with CardAccessory { padding: const EdgeInsets.all(3.0), child: svgWidget( 'editor/edit', - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/accessory/cell_accessory.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/accessory/cell_accessory.dart index 39a8bd41f6..4433c9f43b 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/accessory/cell_accessory.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/accessory/cell_accessory.dart @@ -3,11 +3,9 @@ import 'package:flowy_infra/image.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:flowy_infra/size.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:textstyle_extensions/textstyle_extensions.dart'; import '../cell_builder.dart'; @@ -69,7 +67,6 @@ class _PrimaryCellAccessoryState extends State Widget build(BuildContext context) { return Tooltip( message: LocaleKeys.tooltip_openAsPage.tr(), - textStyle: AFThemeExtension.of(context).caption.textColor(Colors.white), child: svgWidget( "grid/expander", color: Theme.of(context).colorScheme.primary, @@ -125,7 +122,6 @@ class _AccessoryHoverState extends State { @override Widget build(BuildContext context) { List children = [ - const _Background(), Padding(padding: widget.contentPadding, child: widget.child), ]; @@ -173,28 +169,6 @@ class AccessoryHoverState extends ChangeNotifier { bool get onHover => _onHover; } -class _Background extends StatelessWidget { - const _Background({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Consumer( - builder: (context, state, child) { - if (state.onHover) { - return FlowyHoverContainer( - style: HoverStyle( - borderRadius: Corners.s6Border, - hoverColor: AFThemeExtension.of(context).lightGreyHover, - ), - ); - } else { - return const SizedBox(); - } - }, - ); - } -} - class CellAccessoryContainer extends StatelessWidget { final List accessories; const CellAccessoryContainer({required this.accessories, Key? key}) diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/checklist_cell/checklist_cell_editor.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/checklist_cell/checklist_cell_editor.dart index 3e5d744e1e..891e3e7c05 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/checklist_cell/checklist_cell_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/checklist_cell/checklist_cell_editor.dart @@ -137,7 +137,7 @@ class _ChecklistOptionCellState extends State<_ChecklistOptionCell> { iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2), icon: svgWidget( "editor/details", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/date_cell/date_editor.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/date_cell/date_editor.dart index be6674b5bc..3b338d5355 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/date_cell/date_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/date_cell/date_editor.dart @@ -173,13 +173,13 @@ class _CellCalendarWidgetState extends State<_CellCalendarWidget> { leftChevronPadding: EdgeInsets.zero, leftChevronIcon: svgWidget( "home/arrow_left", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), rightChevronPadding: EdgeInsets.zero, rightChevronMargin: EdgeInsets.zero, rightChevronIcon: svgWidget( "home/arrow_right", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), headerMargin: const EdgeInsets.only(bottom: 8.0), ), @@ -254,7 +254,7 @@ class _IncludeTimeButton extends StatelessWidget { children: [ svgWidget( "grid/clock", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), const HSpace(4), FlowyText.medium(LocaleKeys.grid_field_includeTime.tr()), @@ -387,7 +387,7 @@ class _DateTypeOptionButton extends StatelessWidget { margin: GridSize.typeOptionContentInsets, rightIcon: svgWidget( "grid/more", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ), diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart index c83b8ade30..29b0d9b96e 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart @@ -116,7 +116,7 @@ class SelectOptionTag extends StatelessWidget { hoverColor: Colors.transparent, icon: svgWidget( 'home/close', - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ], diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/select_option_cell/select_option_editor.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/select_option_cell/select_option_editor.dart index 024e88405c..e3ba894373 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/select_option_cell/select_option_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/select_option_cell/select_option_editor.dart @@ -277,7 +277,7 @@ class _SelectOptionCellState extends State<_SelectOptionCell> { iconPadding: const EdgeInsets.symmetric(horizontal: 6.0), icon: svgWidget( "editor/details", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ], diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/url_cell/url_cell.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/url_cell/url_cell.dart index 9ab086e356..30cd9ae807 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/url_cell/url_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/cells/url_cell/url_cell.dart @@ -213,7 +213,7 @@ class _EditURLAccessoryState extends State<_EditURLAccessory> offset: const Offset(0, 8), child: svgWidget( "editor/edit", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), popupBuilder: (BuildContext popoverContext) { return URLEditorPopover( @@ -246,7 +246,7 @@ class _CopyURLAccessoryState extends State<_CopyURLAccessory> Widget build(BuildContext context) { return svgWidget( "editor/copy", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/row_detail.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/row_detail.dart index b92f993382..8579a7e17a 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/row_detail.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/row/row_detail.dart @@ -103,7 +103,7 @@ class _CloseButton extends StatelessWidget { iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2), icon: svgWidget( "home/close", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/banner.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/banner.dart index 0e85ff85db..8cd8e4decc 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/banner.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/banner.dart @@ -34,7 +34,8 @@ class DocumentBanner extends StatelessWidget { contentPadding: EdgeInsets.zero, bgColor: Colors.transparent, hoverColor: Theme.of(context).colorScheme.primary, - downColor: Theme.of(context).colorScheme.primaryContainer, + highlightColor: + Theme.of(context).colorScheme.primaryContainer, outlineColor: Colors.white, borderRadius: Corners.s8Border, onPressed: onRestore, @@ -50,7 +51,7 @@ class DocumentBanner extends StatelessWidget { contentPadding: EdgeInsets.zero, bgColor: Colors.transparent, hoverColor: Theme.of(context).colorScheme.primaryContainer, - downColor: Theme.of(context).colorScheme.primary, + highlightColor: Theme.of(context).colorScheme.primary, outlineColor: Colors.white, borderRadius: Corners.s8Border, onPressed: onDelete, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/more/font_size_switcher.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/more/font_size_switcher.dart index 37d6434e4d..13814ac186 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/more/font_size_switcher.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/more/font_size_switcher.dart @@ -32,6 +32,7 @@ class _FontSizeSwitcherState extends State { FlowyText.semibold( LocaleKeys.moreAction_fontSize.tr(), fontSize: 12, + color: Theme.of(context).colorScheme.tertiary, ), const SizedBox( height: 5, @@ -43,9 +44,8 @@ class _FontSizeSwitcherState extends State { _updateSelectedFontSize(_fontSizes[index].item2); }, borderRadius: const BorderRadius.all(Radius.circular(5)), - selectedBorderColor: Theme.of(context).colorScheme.primaryContainer, - selectedColor: Theme.of(context).colorScheme.onSurface, - fillColor: Theme.of(context).colorScheme.primaryContainer, + selectedColor: Theme.of(context).colorScheme.tertiary, + fillColor: Theme.of(context).colorScheme.primary, color: Theme.of(context).hintColor, constraints: const BoxConstraints( minHeight: 40.0, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/more/more_button.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/more/more_button.dart index 5ed6219319..23c5895d52 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/more/more_button.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/more/more_button.dart @@ -28,7 +28,7 @@ class DocumentMoreButton extends StatelessWidget { child: svgWidget( 'editor/details', size: const Size(18, 18), - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/base/built_in_page_widget.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/base/built_in_page_widget.dart index 3aa729d051..0df834c355 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/base/built_in_page_widget.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/base/built_in_page_widget.dart @@ -119,7 +119,7 @@ class _BuiltInPageWidgetState extends State { iconPadding: const EdgeInsets.all(3), icon: svgWidget( 'common/information', - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), // Name @@ -143,7 +143,7 @@ class _BuiltInPageWidgetState extends State { iconPadding: const EdgeInsets.all(3), icon: svgWidget( 'common/settings', - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), onPressed: () => controller.show(), ); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/base/link_to_page_widget.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/base/link_to_page_widget.dart index 73cfbeecb4..46c8298b49 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/base/link_to_page_widget.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/base/link_to_page_widget.dart @@ -149,7 +149,7 @@ class _LinkToPageMenuState extends State { FlowyButton( leftIcon: svgWidget( _iconName(value), - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), text: FlowyText.regular(value.name), onTap: () => widget.onSelected(app.value1, value), diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/board/board_menu_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/board/board_menu_item.dart index c81efbb279..c81d394f7d 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/board/board_menu_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/board/board_menu_item.dart @@ -18,7 +18,7 @@ SelectionMenuItem boardMenuItem = SelectionMenuItem( ); }, // TODO(a-wallen): Translate keywords - keywords: ['referenced board', 'referenced kanban'], + keywords: ['referenced', 'board', 'kanban'], handler: (editorState, menuService, context) { showLinkToPageMenu( editorState, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/cover/change_cover_popover.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/cover/change_cover_popover.dart index 9aa338b0bc..95a33a04da 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/cover/change_cover_popover.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/cover/change_cover_popover.dart @@ -2,17 +2,20 @@ import 'dart:io'; import 'dart:ui'; import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/document/presentation/plugins/cover/change_cover_popover_bloc.dart'; import 'package:appflowy/plugins/document/presentation/plugins/cover/cover_image_picker.dart'; import 'package:appflowy/plugins/document/presentation/plugins/cover/cover_node_widget.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra/theme_extension.dart'; +import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; -import 'package:shared_preferences/shared_preferences.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; const String kLocalImagesKey = 'local_images'; @@ -71,31 +74,35 @@ class CoverColorPicker extends StatefulWidget { } class _ChangeCoverPopoverState extends State { - late Future>? fileImages; bool isAddingImage = false; - @override - void initState() { - super.initState(); - fileImages = _getPreviouslyPickedImagePaths(); - } - @override Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.all(15), - child: SingleChildScrollView( - child: isAddingImage - ? CoverImagePicker( - onBackPressed: () => setState(() { - isAddingImage = false; - }), - onFileSubmit: (List path) { - setState(() { - isAddingImage = false; - }); - }) - : _buildCoverSelection(), + return BlocProvider( + create: (context) => ChangeCoverPopoverBloc() + ..add(const ChangeCoverPopoverEvent.fetchPickedImagePaths()), + child: BlocBuilder( + builder: (context, state) { + return Padding( + padding: const EdgeInsets.all(15), + child: SingleChildScrollView( + child: isAddingImage + ? CoverImagePicker( + onBackPressed: () => setState(() { + isAddingImage = false; + }), + onFileSubmit: (List path) { + context.read().add( + const ChangeCoverPopoverEvent + .fetchPickedImagePaths()); + setState(() { + isAddingImage = false; + }); + }) + : _buildCoverSelection(), + ), + ); + }, ), ); } @@ -104,21 +111,55 @@ class _ChangeCoverPopoverState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - FlowyText.semibold(LocaleKeys.document_plugins_cover_colors.tr()), + FlowyText.semibold( + LocaleKeys.document_plugins_cover_colors.tr(), + color: Theme.of(context).colorScheme.tertiary, + ), const SizedBox(height: 10), _buildColorPickerList(), const SizedBox(height: 10), - FlowyText.semibold(LocaleKeys.document_plugins_cover_images.tr()), + _buildImageHeader(), const SizedBox(height: 10), _buildFileImagePicker(), const SizedBox(height: 10), - FlowyText.semibold(LocaleKeys.document_plugins_cover_abstract.tr()), + FlowyText.semibold( + LocaleKeys.document_plugins_cover_abstract.tr(), + color: Theme.of(context).colorScheme.tertiary, + ), const SizedBox(height: 10), _buildAbstractImagePicker(), ], ); } + Widget _buildImageHeader() { + return BlocBuilder( + builder: (context, state) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + FlowyText.semibold( + LocaleKeys.document_plugins_cover_images.tr(), + color: Theme.of(context).colorScheme.tertiary, + ), + FlowyTextButton( + fillColor: Theme.of(context).cardColor, + hoverColor: Theme.of(context).colorScheme.secondaryContainer, + LocaleKeys.document_plugins_cover_clearAll.tr(), + fontColor: Theme.of(context).colorScheme.tertiary, + onPressed: () { + context + .read() + .add(const ChangeCoverPopoverEvent.clearAllImages()); + }, + mainAxisAlignment: MainAxisAlignment.end, + ), + ], + ); + }, + ); + } + Widget _buildAbstractImagePicker() { return GridView.builder( shrinkWrap: true, @@ -173,71 +214,59 @@ class _ChangeCoverPopoverState extends State { } Widget _buildFileImagePicker() { - return FutureBuilder>( - future: _getPreviouslyPickedImagePaths(), - builder: (context, snapshot) { - if (snapshot.hasData) { - List images = snapshot.data!; - return GridView.builder( - shrinkWrap: true, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - childAspectRatio: 1 / 0.65, - crossAxisSpacing: 7, - mainAxisSpacing: 7, - ), - itemCount: images.length + 1, - itemBuilder: (BuildContext ctx, index) { - if (index == 0) { - return Container( - decoration: BoxDecoration( - color: Theme.of(context) - .colorScheme - .primary - .withOpacity(0.15), - border: Border.all( - color: Theme.of(context).colorScheme.primary, - ), - borderRadius: Corners.s8Border, - ), - child: FlowyIconButton( - iconPadding: EdgeInsets.zero, - icon: Icon( - Icons.add, - color: Theme.of(context).colorScheme.primary, - ), - width: 20, - onPressed: () { - setState(() { - isAddingImage = true; - }); - }, - ), - ); - } - return InkWell( - onTap: () { - widget.onCoverChanged( - CoverSelectionType.file, - images[index - 1], - ); - }, - child: Container( - decoration: BoxDecoration( - image: DecorationImage( - image: FileImage(File(images[index - 1])), - fit: BoxFit.cover, - ), - borderRadius: Corners.s8Border, - ), + return BlocBuilder( + builder: (context, state) { + if (state is Loaded) { + List images = state.imageNames; + return GridView.builder( + shrinkWrap: true, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + childAspectRatio: 1 / 0.65, + crossAxisSpacing: 7, + mainAxisSpacing: 7, + ), + itemCount: images.length + 1, + itemBuilder: (BuildContext ctx, index) { + if (index == 0) { + return Container( + decoration: BoxDecoration( + color: + Theme.of(context).colorScheme.primary.withOpacity(0.15), + border: Border.all( + color: Theme.of(context).colorScheme.primary, ), + borderRadius: Corners.s8Border, + ), + child: FlowyIconButton( + iconPadding: EdgeInsets.zero, + icon: Icon( + Icons.add, + color: Theme.of(context).colorScheme.primary, + ), + width: 20, + onPressed: () { + setState(() { + isAddingImage = true; + }); + }, + ), + ); + } + return ImageGridItem( + onImageSelect: () { + widget.onCoverChanged( + CoverSelectionType.file, + images[index - 1], ); }, + imagePath: images[index - 1], ); - } else { - return Container(); - } - }); + }, + ); + } + return Container(); + }); } List _generateBackgroundColorOptions(EditorState editorState) { @@ -248,19 +277,75 @@ class _ChangeCoverPopoverState extends State { )) .toList(); } +} - Future> _getPreviouslyPickedImagePaths() async { - SharedPreferences prefs = await SharedPreferences.getInstance(); - final imageNames = prefs.getStringList(kLocalImagesKey) ?? []; - final removeNames = []; - for (final name in imageNames) { - if (!File(name).existsSync()) { - removeNames.add(name); - } - } - imageNames.removeWhere((element) => removeNames.contains(element)); - prefs.setStringList(kLocalImagesKey, imageNames); - return imageNames; +class ImageGridItem extends StatefulWidget { + const ImageGridItem({ + Key? key, + required this.onImageSelect, + required this.imagePath, + }) : super(key: key); + + final Function() onImageSelect; + final String imagePath; + + @override + State createState() => _ImageGridItemState(); +} + +class _ImageGridItemState extends State { + bool showDeleteButton = false; + @override + Widget build(BuildContext context) { + return MouseRegion( + onEnter: (_) { + setState(() { + showDeleteButton = true; + }); + }, + onExit: (_) { + setState(() { + showDeleteButton = false; + }); + }, + child: Stack( + children: [ + InkWell( + onTap: widget.onImageSelect, + child: Container( + decoration: BoxDecoration( + image: DecorationImage( + image: FileImage(File(widget.imagePath)), + fit: BoxFit.cover, + ), + borderRadius: Corners.s8Border, + ), + ), + ), + if (showDeleteButton) + Positioned( + right: 2, + top: 2, + child: FlowyIconButton( + fillColor: + Theme.of(context).colorScheme.surface.withOpacity(0.8), + hoverColor: + Theme.of(context).colorScheme.surface.withOpacity(0.8), + iconPadding: const EdgeInsets.all(5), + width: 28, + icon: svgWidget( + 'editor/delete', + color: Theme.of(context).colorScheme.tertiary, + ), + onPressed: () { + context.read().add( + ChangeCoverPopoverEvent.deleteImage(widget.imagePath)); + }, + ), + ), + ], + ), + ); } } diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/cover/change_cover_popover_bloc.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/cover/change_cover_popover_bloc.dart new file mode 100644 index 0000000000..aee98a8e0b --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/cover/change_cover_popover_bloc.dart @@ -0,0 +1,90 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:appflowy/plugins/document/presentation/plugins/cover/change_cover_popover.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +part 'change_cover_popover_bloc.freezed.dart'; + +class ChangeCoverPopoverBloc + extends Bloc { + late final SharedPreferences _prefs; + final _initCompleter = Completer(); + ChangeCoverPopoverBloc() : super(const ChangeCoverPopoverState.initial()) { + SharedPreferences.getInstance().then((prefs) { + _prefs = prefs; + _initCompleter.complete(); + }); + on((event, emit) async { + await event.map( + fetchPickedImagePaths: + (FetchPickedImagePaths fetchPickedImagePaths) async { + final imageNames = await _getPreviouslyPickedImagePaths(); + emit(ChangeCoverPopoverState.loaded(imageNames)); + }, + deleteImage: (DeleteImage deleteImage) async { + final currentState = state; + if (currentState is Loaded) { + await _deleteImageInStorage(deleteImage.path); + final updateImageList = currentState.imageNames + .where((path) => path != deleteImage.path) + .toList(); + await _updateImagePathsInStorage(updateImageList); + emit(Loaded(updateImageList)); + } + }, + clearAllImages: (ClearAllImages clearAllImages) async { + final currentState = state; + if (currentState is Loaded) { + for (final image in currentState.imageNames) { + await _deleteImageInStorage(image); + } + await _updateImagePathsInStorage([]); + emit(const Loaded([])); + } + }, + ); + }); + } + + Future> _getPreviouslyPickedImagePaths() async { + await _initCompleter.future; + final imageNames = _prefs.getStringList(kLocalImagesKey) ?? []; + if (imageNames.isEmpty) { + return imageNames; + } + imageNames.removeWhere((name) => !File(name).existsSync()); + return imageNames; + } + + Future _updateImagePathsInStorage(List imagePaths) async { + await _initCompleter.future; + _prefs.setStringList(kLocalImagesKey, imagePaths); + return; + } + + Future _deleteImageInStorage(String path) async { + final imageFile = File(path); + await imageFile.delete(); + } +} + +@freezed +class ChangeCoverPopoverEvent with _$ChangeCoverPopoverEvent { + const factory ChangeCoverPopoverEvent.fetchPickedImagePaths() = + FetchPickedImagePaths; + + const factory ChangeCoverPopoverEvent.deleteImage(String path) = DeleteImage; + const factory ChangeCoverPopoverEvent.clearAllImages() = ClearAllImages; +} + +@freezed +class ChangeCoverPopoverState with _$ChangeCoverPopoverState { + const factory ChangeCoverPopoverState.initial() = Initial; + const factory ChangeCoverPopoverState.loading() = Loading; + const factory ChangeCoverPopoverState.loaded( + List imageNames, + ) = Loaded; +} diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/cover/cover_node_widget.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/cover/cover_node_widget.dart index 808962e019..8a7ac2807a 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/cover/cover_node_widget.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/cover/cover_node_widget.dart @@ -156,10 +156,7 @@ class _AddCoverButtonState extends State<_AddCoverButton> { leftIconSize: const Size.square(18), onTap: widget.onTap, useIntrinsicWidth: true, - leftIcon: svgWidget( - 'editor/image', - color: Theme.of(context).colorScheme.onSurface, - ), + leftIcon: const FlowySvg(name: 'editor/image'), text: FlowyText.regular( LocaleKeys.document_plugins_cover_addCover.tr(), ), @@ -174,7 +171,7 @@ class _AddCoverButtonState extends State<_AddCoverButton> { useIntrinsicWidth: true, leftIcon: Icon( Icons.emoji_emotions_outlined, - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, size: 18, ), text: FlowyText.regular(LocaleKeys @@ -197,8 +194,7 @@ class _AddCoverButtonState extends State<_AddCoverButton> { child: FlowyButton( leftIconSize: const Size.square(18), useIntrinsicWidth: true, - leftIcon: Icon(Icons.emoji_emotions_outlined, - color: Theme.of(context).colorScheme.onSurface, + leftIcon: const Icon(Icons.emoji_emotions_outlined, size: 18), text: FlowyText.regular( LocaleKeys.document_plugins_cover_addIcon.tr()), @@ -400,7 +396,7 @@ class _CoverImageState extends State<_CoverImage> { popoverController.show(); }, hoverColor: Theme.of(context).colorScheme.surface, - textColor: Theme.of(context).colorScheme.onSurface, + textColor: Theme.of(context).colorScheme.tertiary, fillColor: Theme.of(context).colorScheme.surface.withOpacity(0.8), width: 120, height: 28, @@ -422,7 +418,7 @@ class _CoverImageState extends State<_CoverImage> { width: 28, icon: svgWidget( 'editor/delete', - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).colorScheme.tertiary, ), onPressed: () { widget.onCoverChanged(CoverSelectionType.initial, null); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/grid/grid_menu_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/grid/grid_menu_item.dart index b2775543e9..b79162027b 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/grid/grid_menu_item.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/grid/grid_menu_item.dart @@ -17,7 +17,7 @@ SelectionMenuItem gridMenuItem = SelectionMenuItem( : editorState.editorStyle.selectionMenuItemIconColor, ); }, - keywords: ['referenced grid'], + keywords: ['referenced', 'grid'], handler: (editorState, menuService, context) { showLinkToPageMenu( editorState, diff --git a/frontend/appflowy_flutter/lib/plugins/trash/menu.dart b/frontend/appflowy_flutter/lib/plugins/trash/menu.dart index f3b73e5404..8708aa7563 100644 --- a/frontend/appflowy_flutter/lib/plugins/trash/menu.dart +++ b/frontend/appflowy_flutter/lib/plugins/trash/menu.dart @@ -45,13 +45,9 @@ class MenuTrash extends StatelessWidget { Widget _render(BuildContext context) { return Row( children: [ - SizedBox( - width: 16, - height: 16, - child: svgWidget( - "home/trash", - color: Theme.of(context).colorScheme.onSurface, - ), + const FlowySvg( + size: Size(16, 16), + name: 'home/trash', ), const HSpace(6), FlowyText.medium(LocaleKeys.trash_text.tr()), diff --git a/frontend/appflowy_flutter/lib/plugins/trash/src/trash_cell.dart b/frontend/appflowy_flutter/lib/plugins/trash/src/trash_cell.dart index 058f6f842a..a46cca2a3b 100644 --- a/frontend/appflowy_flutter/lib/plugins/trash/src/trash_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/trash/src/trash_cell.dart @@ -43,7 +43,7 @@ class TrashCell extends StatelessWidget { iconPadding: const EdgeInsets.all(5), icon: svgWidget( "editor/restore", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), const HSpace(20), @@ -53,7 +53,7 @@ class TrashCell extends StatelessWidget { iconPadding: const EdgeInsets.all(5), icon: svgWidget( "editor/delete", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ], diff --git a/frontend/appflowy_flutter/lib/plugins/trash/trash_page.dart b/frontend/appflowy_flutter/lib/plugins/trash/trash_page.dart index a0947a2de3..28460e9c59 100644 --- a/frontend/appflowy_flutter/lib/plugins/trash/trash_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/trash/trash_page.dart @@ -90,6 +90,7 @@ class _TrashPageState extends State { FlowyText.semibold( LocaleKeys.trash_text.tr(), fontSize: FontSizes.s16, + color: Theme.of(context).colorScheme.tertiary, ), const Spacer(), IntrinsicWidth( @@ -97,7 +98,7 @@ class _TrashPageState extends State { text: FlowyText.medium(LocaleKeys.trash_restoreAll.tr()), leftIcon: svgWidget( 'editor/restore', - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), onTap: () => context.read().add( const TrashEvent.restoreAll(), @@ -110,7 +111,7 @@ class _TrashPageState extends State { text: FlowyText.medium(LocaleKeys.trash_deleteAll.tr()), leftIcon: svgWidget( 'editor/delete', - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), onTap: () => context.read().add(const TrashEvent.deleteAll()), diff --git a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart index 9def64f8a5..d38f12e84b 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart @@ -46,6 +46,7 @@ class InitAppWidgetTask extends LaunchTask { Locale('sv'), Locale('tr', 'TR'), Locale('zh', 'CN'), + Locale('zh', 'TW'), ], path: 'assets/translations', fallbackLocale: const Locale('en'), diff --git a/frontend/appflowy_flutter/lib/user/presentation/folder/folder_widget.dart b/frontend/appflowy_flutter/lib/user/presentation/folder/folder_widget.dart index 8a34c04b14..50de6ad88d 100644 --- a/frontend/appflowy_flutter/lib/user/presentation/folder/folder_widget.dart +++ b/frontend/appflowy_flutter/lib/user/presentation/folder/folder_widget.dart @@ -2,9 +2,7 @@ import 'dart:io'; import 'package:appflowy/util/file_picker/file_picker_service.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_infra_ui/style_widget/text_field.dart'; -import 'package:flowy_infra_ui/widget/rounded_button.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; @@ -36,10 +34,7 @@ class _FolderWidgetState extends State { @override Widget build(BuildContext context) { - return SizedBox( - height: 250, - child: _mapIndexToWidget(context), - ); + return _mapIndexToWidget(context); } Widget _mapIndexToWidget(BuildContext context) { @@ -86,37 +81,24 @@ class FolderOptionsWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return ListView( - shrinkWrap: true, - children: [ - Card( - child: ListTile( - title: FlowyText.medium( - LocaleKeys.settings_files_createNewFolder.tr(), - ), - subtitle: FlowyText.regular( - LocaleKeys.settings_files_createNewFolderDesc.tr(), - ), - trailing: _buildTextButton( - context, - LocaleKeys.settings_files_create.tr(), - onPressedCreate, - ), + return Column( + children: [ + _FolderCard( + title: LocaleKeys.settings_files_createNewFolder.tr(), + subtitle: LocaleKeys.settings_files_createNewFolderDesc.tr(), + trailing: _buildTextButton( + context, + LocaleKeys.settings_files_create.tr(), + onPressedCreate, ), ), - Card( - child: ListTile( - title: FlowyText.medium( - LocaleKeys.settings_files_openFolder.tr(), - ), - subtitle: FlowyText.regular( - LocaleKeys.settings_files_openFolderDesc.tr(), - ), - trailing: _buildTextButton( - context, - LocaleKeys.settings_files_open.tr(), - onPressedOpen, - ), + _FolderCard( + title: LocaleKeys.settings_files_openFolder.tr(), + subtitle: LocaleKeys.settings_files_openFolderDesc.tr(), + trailing: _buildTextButton( + context, + LocaleKeys.settings_files_open.tr(), + onPressedOpen, ), ), ], @@ -164,56 +146,55 @@ class CreateFolderWidgetState extends State { label: const Text('Back'), ), ), - Card( - child: ListTile( - title: FlowyText.medium( - LocaleKeys.settings_files_location.tr(), - ), - subtitle: FlowyText.regular( - LocaleKeys.settings_files_locationDesc.tr(), - ), - trailing: SizedBox( - width: 100, - height: 36, - child: FlowyTextField( - hintText: LocaleKeys.settings_files_folderHintText.tr(), - onChanged: (name) { - _folderName = name; - }, - onSubmitted: (name) { - setState(() { - _folderName = name; - }); - }, + _FolderCard( + title: LocaleKeys.settings_files_location.tr(), + subtitle: LocaleKeys.settings_files_locationDesc.tr(), + trailing: SizedBox( + width: 120, + child: FlowyTextField( + hintText: LocaleKeys.settings_files_folderHintText.tr(), + onChanged: (name) => _folderName = name, + onSubmitted: (name) => setState( + () => _folderName = name, ), ), ), ), - Card( - child: ListTile( - title: FlowyText.medium(LocaleKeys.settings_files_folderPath.tr()), - subtitle: FlowyText.regular(_path), - trailing: _buildTextButton( - context, LocaleKeys.settings_files_browser.tr(), () async { + _FolderCard( + title: LocaleKeys.settings_files_folderPath.tr(), + subtitle: _path, + trailing: _buildTextButton( + context, + LocaleKeys.settings_files_browser.tr(), + () async { final dir = await getIt().getDirectoryPath(); if (dir != null) { - setState(() { - directory = dir; - }); + setState(() => directory = dir); } - }), + }, ), ), - Card( - child: _buildTextButton( - context, LocaleKeys.settings_files_create.tr(), () async { - if (_path.isEmpty) { - _showToast(LocaleKeys.settings_files_locationCannotBeEmpty.tr()); - } else { - await getIt().setLocation(_path); - await widget.onPressedCreate(); - } - }), + const VSpace(4.0), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 4.0), + child: Row( + children: [ + _buildTextButton( + context, + LocaleKeys.settings_files_create.tr(), + () async { + if (_path.isEmpty) { + _showToast( + LocaleKeys.settings_files_locationCannotBeEmpty.tr(), + ); + } else { + await getIt().setLocation(_path); + await widget.onPressedCreate(); + } + }, + ), + ], + ), ) ], ); @@ -240,12 +221,70 @@ class CreateFolderWidgetState extends State { Widget _buildTextButton( BuildContext context, String title, VoidCallback onPressed) { - return SizedBox( - width: 70, - height: 36, - child: RoundedTextButton( - title: title, - onPressed: onPressed, - ), + return FlowyTextButton( + title, + onPressed: onPressed, + fillColor: Theme.of(context).colorScheme.primary, + fontColor: Theme.of(context).colorScheme.onPrimary, + hoverColor: Theme.of(context).colorScheme.primaryContainer, ); } + +class _FolderCard extends StatelessWidget { + const _FolderCard({ + Key? key, + required this.title, + required this.subtitle, + this.trailing, + }) : super(key: key); + + final String title; + + final String subtitle; + + final Widget? trailing; + + @override + Widget build(BuildContext context) { + return Card( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 4.0, + horizontal: 16.0, + ), + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + FlowyText.medium( + title, + ), + Row( + children: [ + Flexible( + child: Text( + subtitle, + overflow: TextOverflow.ellipsis, + style: + Theme.of(context).textTheme.bodyMedium!.copyWith( + fontWeight: FontWeight.w400, + ), + ), + ), + ], + ), + ], + ), + ), + if (trailing != null) ...[ + const HSpace(40), + trailing!, + ], + ], + ), + ), + ); + } +} diff --git a/frontend/appflowy_flutter/lib/user/presentation/skip_log_in_screen.dart b/frontend/appflowy_flutter/lib/user/presentation/skip_log_in_screen.dart index e394f98fe1..84f9fa441f 100644 --- a/frontend/appflowy_flutter/lib/user/presentation/skip_log_in_screen.dart +++ b/frontend/appflowy_flutter/lib/user/presentation/skip_log_in_screen.dart @@ -1,9 +1,8 @@ +import 'package:appflowy/core/frameless_window.dart'; import 'package:dartz/dartz.dart' as dartz; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/size.dart'; -import 'package:flowy_infra_ui/style_widget/button.dart'; -import 'package:flowy_infra_ui/widget/rounded_button.dart'; -import 'package:flowy_infra_ui/widget/spacing.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/log.dart'; import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; @@ -39,6 +38,7 @@ class _SkipLogInScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( + appBar: const _SkipLoginMoveWindow(), body: Center( child: _renderBody(context), ), @@ -54,9 +54,13 @@ class _SkipLogInScreenState extends State { logoSize: const Size.square(60), ), const VSpace(40), - SizedBox( - width: 250, - child: GoButton(onPressed: () => _autoRegister(context)), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + GoButton( + onPressed: () => _autoRegister(context), + ), + ], ), const VSpace(20), SizedBox( @@ -72,18 +76,15 @@ class _SkipLogInScreenState extends State { }, ), ), - const VSpace(20), - SizedBox( - width: 400, - child: _buildSubscribeButtons(context), - ), + const Spacer(), + _buildSubscribeButtons(context), ], ); } Row _buildSubscribeButtons(BuildContext context) { return Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisAlignment: MainAxisAlignment.center, children: [ FlowyTextButton( LocaleKeys.githubStarText.tr(), @@ -95,6 +96,7 @@ class _SkipLogInScreenState extends State { onPressed: () => _launchURL('https://github.com/AppFlowy-IO/appflowy'), ), + const HSpace(20), FlowyTextButton( LocaleKeys.subscribeNewsletterText.tr(), fontWeight: FontWeight.w500, @@ -149,19 +151,41 @@ class _SkipLogInScreenState extends State { class GoButton extends StatelessWidget { final VoidCallback onPressed; + const GoButton({ - Key? key, + super.key, required this.onPressed, - }) : super(key: key); + }); @override Widget build(BuildContext context) { - return RoundedTextButton( - title: LocaleKeys.letsGoButtonText.tr(), + return FlowyTextButton( + LocaleKeys.letsGoButtonText.tr(), fontSize: FontSizes.s16, - height: 50, - borderRadius: Corners.s10Border, + padding: const EdgeInsets.symmetric(horizontal: 80, vertical: 12.0), onPressed: onPressed, + fillColor: Theme.of(context).colorScheme.primary, + fontColor: Theme.of(context).colorScheme.onPrimary, + hoverColor: Theme.of(context).colorScheme.primaryContainer, ); } } + +class _SkipLoginMoveWindow extends StatelessWidget + implements PreferredSizeWidget { + const _SkipLoginMoveWindow(); + + @override + Widget build(BuildContext context) { + return Row( + children: const [ + Expanded( + child: MoveWindowDetector(), + ), + ], + ); + } + + @override + Size get preferredSize => const Size.fromHeight(55.0); +} diff --git a/frontend/appflowy_flutter/lib/user/presentation/widgets/background.dart b/frontend/appflowy_flutter/lib/user/presentation/widgets/background.dart index fe3bdd2a15..f7353ebd5a 100644 --- a/frontend/appflowy_flutter/lib/user/presentation/widgets/background.dart +++ b/frontend/appflowy_flutter/lib/user/presentation/widgets/background.dart @@ -49,6 +49,7 @@ class FlowyLogoTitle extends StatelessWidget { FlowyText.semibold( title, fontSize: FontSizes.s24, + color: Theme.of(context).colorScheme.tertiary, ), ], ), diff --git a/frontend/appflowy_flutter/lib/workspace/application/appearance.dart b/frontend/appflowy_flutter/lib/workspace/application/appearance.dart index 9cadf7f5ce..b340b8612e 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/appearance.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/appearance.dart @@ -212,14 +212,20 @@ class AppearanceSettingsState with _$AppearanceSettingsState { return ThemeData( brightness: brightness, - textTheme: - _getTextTheme(fontFamily: fontFamily, fontColor: theme.shader1), + textTheme: _getTextTheme(fontFamily: fontFamily, fontColor: theme.text), textSelectionTheme: TextSelectionThemeData( cursorColor: theme.main2, selectionHandleColor: theme.main2, ), - primaryIconTheme: IconThemeData(color: theme.hover), - iconTheme: IconThemeData(color: theme.shader1), + iconTheme: IconThemeData(color: theme.icon), + tooltipTheme: TooltipThemeData( + textStyle: _getFontStyle( + fontFamily: fontFamily, + fontSize: FontSizes.s11, + fontWeight: FontWeight.w400, + fontColor: theme.surface, + ), + ), scrollbarTheme: ScrollbarThemeData( thumbColor: MaterialStateProperty.all(theme.shader3), thickness: MaterialStateProperty.resolveWith((states) { @@ -239,30 +245,38 @@ class AppearanceSettingsState with _$AppearanceSettingsState { ), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, canvasColor: theme.shader6, - dividerColor: theme.shader6, - hintColor: theme.shader3, + dividerColor: theme.divider, + hintColor: theme.hint, + //action item hover color + hoverColor: theme.hoverBG2, disabledColor: theme.shader4, highlightColor: theme.main1, indicatorColor: theme.main1, toggleableActiveColor: theme.main1, + cardColor: theme.input, colorScheme: ColorScheme( brightness: brightness, - primary: theme.main1, - onPrimary: _white, + primary: theme.primary, + onPrimary: theme.onPrimary, primaryContainer: theme.main2, onPrimaryContainer: _white, - secondary: theme.hover, + // page title hover color + secondary: theme.hoverBG1, onSecondary: theme.shader1, + // setting value hover color secondaryContainer: theme.selector, - onSecondaryContainer: theme.shader1, + onSecondaryContainer: theme.topbarBg, + tertiary: theme.shader7, + tertiaryContainer: theme.questionBubbleBG, background: theme.surface, - onBackground: theme.shader1, + onBackground: theme.text, surface: theme.surface, - onSurface: theme.shader1, + // text&icon color when it is hovered + onSurface: theme.hoverFG, onError: theme.shader7, error: theme.red, outline: theme.shader4, - surfaceVariant: theme.bg1, + surfaceVariant: theme.sidebarBg, shadow: theme.shadow, ), extensions: [ @@ -278,7 +292,7 @@ class AppearanceSettingsState with _$AppearanceSettingsState { tint7: theme.tint7, tint8: theme.tint8, tint9: theme.tint9, - greyHover: theme.bg2, + greyHover: theme.hoverBG1, greySelect: theme.bg3, lightGreyHover: theme.shader6, toggleOffFill: theme.shader5, diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart index c666d77b2d..200ce23686 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart @@ -36,7 +36,7 @@ extension ViewExtension on ViewPB { Widget renderThumbnail({Color? iconColor}) { String thumbnail = "file_icon"; - final Widget widget = svgWidget(thumbnail, color: iconColor); + final Widget widget = FlowySvg(name: thumbnail); return widget; } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart index 6a5bc0e1d4..e73577d818 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart @@ -199,7 +199,7 @@ class HomeTopBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - color: Theme.of(context).colorScheme.surface, + color: Theme.of(context).colorScheme.onSecondaryContainer, height: HomeSizes.topBarHeight, child: Row( crossAxisAlignment: CrossAxisAlignment.center, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/create_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/create_button.dart index d5584173bd..be6fddf37a 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/create_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/create_button.dart @@ -18,9 +18,14 @@ class NewAppButton extends StatelessWidget { LocaleKeys.newPageText.tr(), fillColor: Colors.transparent, hoverColor: Colors.transparent, - fontColor: Theme.of(context).colorScheme.onSurfaceVariant, + fontColor: Theme.of(context).colorScheme.tertiary, onPressed: () async => await _showCreateAppDialog(context), - heading: svgWidget("home/new_app", size: const Size(16, 16)), + heading: Theme.of(context).brightness == Brightness.light + ? svgWidget("home/new_app", size: const Size(16, 16)) + : svgWidget( + "home/new_app_dark", + size: const Size(16, 16), + ), padding: EdgeInsets.symmetric(horizontal: Insets.l, vertical: 20), ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/add_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/add_button.dart index 351012bc38..2b55fd736d 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/add_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/add_button.dart @@ -6,9 +6,9 @@ import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart'; import 'package:appflowy_editor/appflowy_editor.dart' show Document; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:flowy_infra/image.dart'; -import 'package:flowy_infra_ui/style_widget/icon_button.dart'; +import 'package:flowy_infra/theme_extension.dart'; +import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flutter/material.dart'; -import 'package:styled_widget/styled_widget.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -50,13 +50,19 @@ class AddButton extends StatelessWidget { actions: actions, offset: const Offset(0, 8), buildChild: (controller) { - return FlowyIconButton( + return SizedBox( width: 22, - onPressed: () => controller.show(), - icon: svgWidget( - "home/add", - color: Theme.of(context).colorScheme.onSurface, - ).padding(horizontal: 3, vertical: 3), + child: InkWell( + onTap: () => controller.show(), + child: FlowyHover( + style: HoverStyle( + hoverColor: AFThemeExtension.of(context).greySelect, + ), + builder: (context, onHover) => const FlowySvg( + name: 'home/add', + ), + ), + ), ); }, onSelected: (action, controller) { @@ -83,8 +89,7 @@ class AddButtonActionWrapper extends ActionCell { AddButtonActionWrapper({required this.pluginBuilder}); @override - Widget? leftIcon(Color iconColor) => - svgWidget(pluginBuilder.menuIcon, color: iconColor); + Widget? leftIcon(Color iconColor) => FlowySvg(name: pluginBuilder.menuIcon); @override String get name => pluginBuilder.menuName; @@ -100,9 +105,8 @@ class ImportActionWrapper extends ActionCell { }); @override - Widget? leftIcon(Color iconColor) => svgWidget( - 'editor/import', - color: iconColor, + Widget? leftIcon(Color iconColor) => const FlowySvg( + name: 'editor/import', ); @override diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/header.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/header.dart index e94f7380ea..c2161066c9 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/header.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/header.dart @@ -5,7 +5,6 @@ import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:expandable/expandable.dart'; -import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra/icon_data.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/app.pb.dart'; @@ -15,7 +14,6 @@ import 'package:appflowy/workspace/application/app/app_bloc.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:flowy_infra/image.dart'; -import 'package:textstyle_extensions/textstyle_extensions.dart'; import '../menu_app.dart'; import 'add_button.dart'; @@ -58,7 +56,7 @@ class MenuAppHeader extends StatelessWidget { theme: ExpandableThemeData( expandIcon: FlowyIconData.drop_down_show, collapseIcon: FlowyIconData.drop_down_hide, - iconColor: Theme.of(context).colorScheme.onSurface, + iconColor: Theme.of(context).colorScheme.tertiary, iconSize: MenuAppSizes.iconSize, iconPadding: const EdgeInsets.fromLTRB(0, 0, 10, 0), hasIcon: false, @@ -104,7 +102,6 @@ class MenuAppHeader extends StatelessWidget { Widget _renderCreateViewButton(BuildContext context) { return Tooltip( message: LocaleKeys.menuAppHeader_addPageTooltip.tr(), - textStyle: AFThemeExtension.of(context).caption.textColor(Colors.white), child: AddButton( onSelected: (pluginBuilder, document) { context.read().add( @@ -139,9 +136,9 @@ extension AppDisclosureExtension on AppDisclosureAction { Widget icon(Color iconColor) { switch (this) { case AppDisclosureAction.rename: - return svgWidget('editor/edit', color: iconColor); + return const FlowySvg(name: 'editor/edit'); case AppDisclosureAction.delete: - return svgWidget('editor/delete', color: iconColor); + return const FlowySvg(name: 'editor/delete'); } } } @@ -174,6 +171,7 @@ class AppActionList extends StatelessWidget { builder: (context, app) => FlowyText.medium( app.name, overflow: TextOverflow.ellipsis, + color: Theme.of(context).colorScheme.tertiary, ), ), ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/import/import_panel.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/import/import_panel.dart index 0250f443d0..f1996af8f8 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/import/import_panel.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/import/import_panel.dart @@ -24,6 +24,7 @@ Future showImportPanel( title: FlowyText.semibold( LocaleKeys.moreAction_import.tr(), fontSize: 20, + color: Theme.of(context).colorScheme.tertiary, ), content: _ImportPanel(importCallback: callback), contentPadding: const EdgeInsets.symmetric( diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/section/item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/section/item.dart index f261a946a9..e6d328d797 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/section/item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/section/item.dart @@ -4,7 +4,6 @@ import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy/workspace/presentation/home/menu/menu.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; @@ -51,7 +50,7 @@ class ViewSectionItem extends StatelessWidget { onTap: () => onSelected(blocContext.read().state.view), child: FlowyHover( style: HoverStyle( - hoverColor: AFThemeExtension.of(context).greySelect, + hoverColor: Theme.of(context).colorScheme.secondary, ), // If current state.isEditing is true, the hover should not // rebuild when onEnter/onExit events happened. @@ -60,7 +59,6 @@ class ViewSectionItem extends StatelessWidget { blocContext, onHover, state, - Theme.of(context).colorScheme.onSurface, ), isSelected: () => state.isEditing || isSelected, ), @@ -75,13 +73,12 @@ class ViewSectionItem extends StatelessWidget { BuildContext blocContext, bool onHover, ViewState state, - Color iconColor, ) { List children = [ SizedBox( width: 16, height: 16, - child: state.view.renderThumbnail(iconColor: iconColor), + child: state.view.renderThumbnail(), ), const HSpace(2), Expanded( @@ -154,11 +151,11 @@ extension ViewDisclosureExtension on ViewDisclosureAction { Widget icon(Color iconColor) { switch (this) { case ViewDisclosureAction.rename: - return svgWidget('editor/edit', color: iconColor); + return const FlowySvg(name: 'editor/edit'); case ViewDisclosureAction.delete: - return svgWidget('editor/delete', color: iconColor); + return const FlowySvg(name: 'editor/delete'); case ViewDisclosureAction.duplicate: - return svgWidget('editor/copy', color: iconColor); + return const FlowySvg(name: 'editor/copy'); } } } @@ -186,7 +183,7 @@ class ViewDisclosureButton extends StatelessWidget { width: 26, icon: svgWidget( "editor/details", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), onPressed: () { onEdit(true); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu.dart index 92f5f4621b..11cfa05042 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu.dart @@ -229,7 +229,7 @@ class MenuTopBar extends StatelessWidget { iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4), icon: svgWidget( "home/hide_menu", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), ), ) diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu_user.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu_user.dart index 21cc90a04e..236dd60479 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu_user.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/menu_user.dart @@ -2,7 +2,6 @@ import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/menu/menu_user_bloc.dart'; import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.dart'; -import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; @@ -13,7 +12,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:textstyle_extensions/textstyle_extensions.dart'; class MenuUser extends StatelessWidget { final UserProfilePB user; @@ -69,6 +67,7 @@ class MenuUser extends StatelessWidget { return FlowyText.medium( name, overflow: TextOverflow.ellipsis, + color: Theme.of(context).colorScheme.tertiary, ); } @@ -76,7 +75,6 @@ class MenuUser extends StatelessWidget { final userProfile = context.read().state.userProfile; return Tooltip( message: LocaleKeys.settings_menu_open.tr(), - textStyle: AFThemeExtension.of(context).caption.textColor(Colors.white), child: IconButton( onPressed: () { showDialog( @@ -90,7 +88,7 @@ class MenuUser extends StatelessWidget { dimension: 20, child: svgWidget( "home/settings", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).colorScheme.tertiary, ), ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/navigation.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/navigation.dart index f1818fc162..8fcc3b2f19 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/navigation.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/navigation.dart @@ -6,14 +6,12 @@ import 'package:appflowy/workspace/presentation/home/home_stack.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/size.dart'; -import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; import 'package:styled_widget/styled_widget.dart'; -import 'package:textstyle_extensions/textstyle_extensions.dart'; typedef NaviAction = void Function(); @@ -87,7 +85,7 @@ class FlowyNavigation extends StatelessWidget { iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2), icon: svgWidget( "home/hide_menu", - color: Theme.of(context).colorScheme.onSurface, + color: Theme.of(context).iconTheme.color, ), )), ); @@ -180,11 +178,9 @@ TextSpan sidebarTooltipTextSpan(BuildContext context, String hintText) => children: [ TextSpan( text: "$hintText\n", - style: AFThemeExtension.of(context).callout.textColor(Colors.white), ), TextSpan( text: Platform.isMacOS ? "⌘+\\" : "Ctrl+\\", - style: AFThemeExtension.of(context).caption.textColor(Colors.white60), ), ], ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/settings_dialog.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/settings_dialog.dart index d7b3f35a17..09e719c2e4 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/settings_dialog.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/settings_dialog.dart @@ -32,6 +32,7 @@ class SettingsDialog extends StatelessWidget { LocaleKeys.settings_title.tr(), fontSize: 20, fontWeight: FontWeight.w700, + color: Theme.of(context).colorScheme.tertiary, ), ), child: ScaffoldMessenger( @@ -54,7 +55,9 @@ class SettingsDialog extends StatelessWidget { context.read().state.page, ), ), - const VerticalDivider(), + VerticalDivider( + color: Theme.of(context).dividerColor, + ), const SizedBox(width: 10), Expanded( child: getSettingsView( diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart index d4e93b3548..81149f9f34 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart @@ -50,8 +50,8 @@ class ThemeSetting extends StatelessWidget { direction: PopoverDirection.bottomWithRightAligned, child: FlowyTextButton( currentTheme, + fontColor: Theme.of(context).colorScheme.onBackground, fillColor: Colors.transparent, - hoverColor: Theme.of(context).colorScheme.secondary, onPressed: () {}, ), popupBuilder: (BuildContext context) { @@ -107,8 +107,8 @@ class ThemeModeSetting extends StatelessWidget { direction: PopoverDirection.bottomWithRightAligned, child: FlowyTextButton( _themeModeLabelText(currentThemeMode), + fontColor: Theme.of(context).colorScheme.onBackground, fillColor: Colors.transparent, - hoverColor: Theme.of(context).colorScheme.secondary, onPressed: () {}, ), popupBuilder: (BuildContext context) { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_language_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_language_view.dart index 7b76aa6157..2807554195 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_language_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_language_view.dart @@ -47,7 +47,7 @@ class _LanguageSelectorDropdownState extends State { void hoverEnterLanguage() { setState(() { - currHoverColor = Theme.of(context).colorScheme.primary; + currHoverColor = Theme.of(context).colorScheme.secondaryContainer; }); } @@ -67,6 +67,7 @@ class _LanguageSelectorDropdownState extends State { padding: const EdgeInsets.symmetric(horizontal: 6), child: DropdownButton( value: context.locale, + dropdownColor: Theme.of(context).cardColor, onChanged: (locale) { context .read() @@ -80,7 +81,10 @@ class _LanguageSelectorDropdownState extends State { value: locale, child: Padding( padding: const EdgeInsets.all(12.0), - child: FlowyText.medium(languageFromLocale(locale)), + child: FlowyText.medium( + languageFromLocale(locale), + color: Theme.of(context).colorScheme.tertiary, + ), ), ); }).toList(), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu_element.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu_element.dart index 7e6f4e7060..207b03c78f 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu_element.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_menu_element.dart @@ -1,5 +1,6 @@ import 'package:appflowy/workspace/application/settings/settings_dialog_bloc.dart'; import 'package:flowy_infra/size.dart'; +import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; @@ -21,29 +22,32 @@ class SettingsMenuElement extends StatelessWidget { @override Widget build(BuildContext context) { - return ListTile( - leading: Icon( - icon, - size: 16, - color: page == selectedPage - ? Theme.of(context).colorScheme.onSurface - : Theme.of(context).colorScheme.onSurface, + return FlowyHover( + style: HoverStyle( + hoverColor: Theme.of(context).colorScheme.primary, ), - onTap: () { - changeSelectedPage(page); - }, - selected: page == selectedPage, - selectedColor: Theme.of(context).colorScheme.onSurface, - selectedTileColor: Theme.of(context).colorScheme.primaryContainer, - hoverColor: Theme.of(context).colorScheme.primary, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5), - ), - minLeadingWidth: 0, - title: FlowyText.semibold( - label, - fontSize: FontSizes.s14, - overflow: TextOverflow.ellipsis, + child: ListTile( + leading: Icon(icon, + size: 16, + color: page == selectedPage + ? Theme.of(context).colorScheme.onSurface + : null), + onTap: () { + changeSelectedPage(page); + }, + selected: page == selectedPage, + selectedColor: Theme.of(context).colorScheme.onSurface, + selectedTileColor: Theme.of(context).colorScheme.primary, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), + ), + minLeadingWidth: 0, + title: FlowyText.semibold(label, + fontSize: FontSizes.s14, + overflow: TextOverflow.ellipsis, + color: page == selectedPage + ? Theme.of(context).colorScheme.onSurface + : null), ), ); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart index c6bb7f3ca0..aae2882d3c 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart @@ -48,6 +48,9 @@ class BubbleActionList extends StatelessWidget { '?', tooltip: LocaleKeys.questionBubble_help.tr(), fontWeight: FontWeight.w600, + fontColor: Theme.of(context).colorScheme.tertiary, + fillColor: Theme.of(context).colorScheme.tertiaryContainer, + hoverColor: Theme.of(context).colorScheme.tertiaryContainer, mainAxisAlignment: MainAxisAlignment.center, radius: Corners.s10Border, onPressed: () => controller.show(), @@ -200,7 +203,7 @@ extension QuestionBubbleExtension on BubbleAction { case BubbleAction.debug: return '🐛'; case BubbleAction.shortcuts: - return '⌨️'; + return '📋'; } } } diff --git a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/render/toolbar/toolbar_item.dart b/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/render/toolbar/toolbar_item.dart index 844ab4b2b6..b4df31fca3 100644 --- a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/render/toolbar/toolbar_item.dart +++ b/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/render/toolbar/toolbar_item.dart @@ -8,6 +8,7 @@ import 'package:appflowy_editor/src/render/link_menu/link_menu.dart'; import 'package:appflowy_editor/src/extensions/text_node_extensions.dart'; import 'package:appflowy_editor/src/extensions/editor_state_extensions.dart'; import 'package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart'; +import 'dart:io' show Platform; import 'package:flutter/material.dart' hide Overlay, OverlayEntry; @@ -127,7 +128,9 @@ List defaultToolbarItems = [ ToolbarItem( id: 'appflowy.toolbar.bold', type: 2, - tooltipsMessage: AppFlowyEditorLocalizations.current.bold, + tooltipsMessage: AppFlowyEditorLocalizations.current.bold + + "\n" + + (Platform.isMacOS ? "⌘ + B" : "CTRL + B"), iconBuilder: (isHighlight) => FlowySvg( name: 'toolbar/bold', color: isHighlight ? Colors.lightBlue : null, @@ -143,7 +146,9 @@ List defaultToolbarItems = [ ToolbarItem( id: 'appflowy.toolbar.italic', type: 2, - tooltipsMessage: AppFlowyEditorLocalizations.current.italic, + tooltipsMessage: AppFlowyEditorLocalizations.current.italic + + "\n" + + (Platform.isMacOS ? "⌘ + I" : "CTRL + I"), iconBuilder: (isHighlight) => FlowySvg( name: 'toolbar/italic', color: isHighlight ? Colors.lightBlue : null, @@ -159,7 +164,9 @@ List defaultToolbarItems = [ ToolbarItem( id: 'appflowy.toolbar.underline', type: 2, - tooltipsMessage: AppFlowyEditorLocalizations.current.underline, + tooltipsMessage: AppFlowyEditorLocalizations.current.underline + + "\n" + + (Platform.isMacOS ? "⌘ + U" : "CTRL + U"), iconBuilder: (isHighlight) => FlowySvg( name: 'toolbar/underline', color: isHighlight ? Colors.lightBlue : null, @@ -175,7 +182,9 @@ List defaultToolbarItems = [ ToolbarItem( id: 'appflowy.toolbar.strikethrough', type: 2, - tooltipsMessage: AppFlowyEditorLocalizations.current.strikethrough, + tooltipsMessage: AppFlowyEditorLocalizations.current.strikethrough + + "\n" + + (Platform.isMacOS ? "⌘ + SHIFT + S" : "CTRL + SHIFT + S"), iconBuilder: (isHighlight) => FlowySvg( name: 'toolbar/strikethrough', color: isHighlight ? Colors.lightBlue : null, @@ -191,7 +200,9 @@ List defaultToolbarItems = [ ToolbarItem( id: 'appflowy.toolbar.code', type: 2, - tooltipsMessage: AppFlowyEditorLocalizations.current.embedCode, + tooltipsMessage: AppFlowyEditorLocalizations.current.embedCode + + "\n" + + (Platform.isMacOS ? "⌘ + E" : "CTRL + E"), iconBuilder: (isHighlight) => FlowySvg( name: 'toolbar/code', color: isHighlight ? Colors.lightBlue : null, @@ -238,10 +249,28 @@ List defaultToolbarItems = [ ), handler: (editorState, context) => formatBulletedList(editorState), ), + ToolbarItem( + id: 'appflowy.toolbar.number_list', + type: 3, + tooltipsMessage: AppFlowyEditorLocalizations.current.numberedList, + iconBuilder: (isHighlight) => FlowySvg( + name: 'toolbar/number_list', + color: isHighlight ? Colors.lightBlue : null, + ), + validator: _onlyShowInSingleTextSelection, + highlightCallback: (editorState) => _allSatisfy( + editorState, + BuiltInAttributeKey.subtype, + (value) => value == BuiltInAttributeKey.numberList, + ), + handler: (editorState, context) => formatNumberedList(editorState), + ), ToolbarItem( id: 'appflowy.toolbar.link', type: 4, - tooltipsMessage: AppFlowyEditorLocalizations.current.link, + tooltipsMessage: AppFlowyEditorLocalizations.current.link + + "\n" + + (Platform.isMacOS ? "⌘ + K" : "CTRL + K"), iconBuilder: (isHighlight) => FlowySvg( name: 'toolbar/link', color: isHighlight ? Colors.lightBlue : null, @@ -257,7 +286,9 @@ List defaultToolbarItems = [ ToolbarItem( id: 'appflowy.toolbar.highlight', type: 4, - tooltipsMessage: AppFlowyEditorLocalizations.current.highlight, + tooltipsMessage: AppFlowyEditorLocalizations.current.highlight + + "\n" + + (Platform.isMacOS ? "⌘ + SHIFT + H" : "CTRL + SHIFT + H"), iconBuilder: (isHighlight) => FlowySvg( name: 'toolbar/highlight', color: isHighlight ? Colors.lightBlue : null, diff --git a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/render/toolbar/toolbar_item_widget.dart b/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/render/toolbar/toolbar_item_widget.dart index 85b1597564..22bcfab54e 100644 --- a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/render/toolbar/toolbar_item_widget.dart +++ b/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/render/toolbar/toolbar_item_widget.dart @@ -21,6 +21,7 @@ class ToolbarItemWidget extends StatelessWidget { width: 28, height: 28, child: Tooltip( + textAlign: TextAlign.center, preferBelow: false, message: item.tooltipsMessage, child: MouseRegion( diff --git a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart b/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart index adb0e7db3d..0141637b1c 100644 --- a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart +++ b/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart @@ -91,6 +91,13 @@ void formatBulletedList(EditorState editorState) { }); } +void formatNumberedList(EditorState editorState) { + formatTextNodes(editorState, { + BuiltInAttributeKey.subtype: BuiltInAttributeKey.numberList, + BuiltInAttributeKey.number: 1, + }); +} + /// Format the current selection with the given attributes. /// /// If the selected nodes are not text nodes, this method will do nothing. diff --git a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart b/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart index 1f798f4114..ae2c354389 100644 --- a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart +++ b/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart @@ -310,6 +310,47 @@ ShortcutEventHandler underscoreToItalicHandler = (editorState, event) { return KeyEventResult.handled; }; +//Same functionality implemented via Asterisk - for italics +ShortcutEventHandler asteriskToItalicHandler = (editorState, event) { + final selectionService = editorState.service.selectionService; + final selection = selectionService.currentSelection.value; + final textNodes = selectionService.currentSelectedNodes.whereType(); + if (selection == null || !selection.isSingle || textNodes.length != 1) { + return KeyEventResult.ignored; + } + + final textNode = textNodes.first; + final text = textNode.toPlainText(); + // Determine if an 'asterisk' already exists in the text node and only once. + final firstAsterisk = text.indexOf('*'); + final lastAsterisk = text.lastIndexOf('*'); + if (firstAsterisk == -1 || + firstAsterisk != lastAsterisk || + firstAsterisk == selection.start.offset - 1) { + return KeyEventResult.ignored; + } + + final transaction = editorState.transaction + ..deleteText(textNode, firstAsterisk, 1) + ..formatText( + textNode, + firstAsterisk, + selection.end.offset - firstAsterisk - 1, + { + BuiltInAttributeKey.italic: true, + }, + ) + ..afterSelection = Selection.collapsed( + Position( + path: textNode.path, + offset: selection.end.offset - 1, + ), + ); + editorState.apply(transaction); + + return KeyEventResult.handled; +}; + ShortcutEventHandler doubleAsteriskToBoldHandler = (editorState, event) { final selectionService = editorState.service.selectionService; final selection = selectionService.currentSelection.value; diff --git a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart b/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart index 3d8fa6839d..222b412e7c 100644 --- a/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart +++ b/frontend/appflowy_flutter/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart @@ -307,6 +307,11 @@ List builtInShortcutEvents = [ character: '_', handler: underscoreToItalicHandler, ), + ShortcutEvent( + key: 'Asterisk to italic', + character: '*', + handler: asteriskToItalicHandler, + ), ShortcutEvent( key: 'Double asterisk to bold', character: '*', diff --git a/frontend/appflowy_flutter/packages/appflowy_editor/test/render/rich_text/toolbar_rich_text_test.dart b/frontend/appflowy_flutter/packages/appflowy_editor/test/render/rich_text/toolbar_rich_text_test.dart index 54f9ed0455..f0710223c1 100644 --- a/frontend/appflowy_flutter/packages/appflowy_editor/test/render/rich_text/toolbar_rich_text_test.dart +++ b/frontend/appflowy_flutter/packages/appflowy_editor/test/render/rich_text/toolbar_rich_text_test.dart @@ -302,6 +302,33 @@ void main() async { }); })); + group('toolbar, number list' , (() { + testWidgets('Select Text, Click Toolbar and set style for number list', + (tester) async { + final editor = tester.editor..insertTextNode(singleLineText); + await editor.startTesting(); + + final numberList = Selection( + start: Position(path: [0],offset: 0), + end: Position(path: [0], offset: singleLineText.length)); + + await editor.updateSelection(numberList); + await tester.pumpAndSettle(const Duration(milliseconds: 500)); + expect(find.byType(ToolbarWidget), findsOneWidget); + final numberListButton = find.byWidgetPredicate((widget) { + if (widget is ToolbarItemWidget) { + return widget.item.id == 'appflowy.toolbar.number_list'; + } + return false; + }); + expect(numberListButton, findsOneWidget); + await tester.tap(numberListButton); + await tester.pumpAndSettle(); + final node = editor.nodeAtPath([0]) as TextNode; + expect(node.subtype, 'number-list'); + }); + })); + group('toolbar, highlight', (() { testWidgets('Select Text, Click Toolbar and set style for highlighted text', (tester) async { diff --git a/frontend/appflowy_flutter/packages/appflowy_editor/test/service/internal_key_event_handlers/markdown_syntax_to_styled_text_test.dart b/frontend/appflowy_flutter/packages/appflowy_editor/test/service/internal_key_event_handlers/markdown_syntax_to_styled_text_test.dart index c7bb897034..28b27a1c29 100644 --- a/frontend/appflowy_flutter/packages/appflowy_editor/test/service/internal_key_event_handlers/markdown_syntax_to_styled_text_test.dart +++ b/frontend/appflowy_flutter/packages/appflowy_editor/test/service/internal_key_event_handlers/markdown_syntax_to_styled_text_test.dart @@ -441,4 +441,53 @@ void main() async { expect(textNode.toPlainText(), text); })); }); + + group('Convert single asterisk to italic', () { + testWidgets('Test Single Asterisk for Italics', (tester) async { + const text = '*Hello World'; + final editor = tester.editor..insertTextNode(text); + await editor.startTesting(); + + await editor.updateSelection( + Selection.single(path: [0], startOffset: text.length), + ); + + await editor.pressLogicKey(character: '*'); + + final textNode = editor.nodeAtPath([0]) as TextNode; + final allItalic = textNode.allSatisfyItalicInSelection( + Selection.single( + path: [0], + startOffset: 0, + endOffset: text.length - 1, // delete the first * + ), + ); + expect(allItalic, true); + }); + + testWidgets( + 'nothing happens if there\'re more than one * precede the current position', + (tester) async { + const text = '**Hello World'; + final editor = tester.editor..insertTextNode(text); + await editor.startTesting(); + + await editor.updateSelection( + Selection.single(path: [0], startOffset: text.length), + ); + + await editor.pressLogicKey(character: '*'); + await tester.pumpAndSettle(); + + final textNode = editor.nodeAtPath([0]) as TextNode; + final allItalic = textNode.allSatisfyItalicInSelection( + Selection.single( + path: [0], + startOffset: 0, + endOffset: text.length, // insert a new * + ), + ); + expect(allItalic, false); + }); + }); } diff --git a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/colorscheme.dart b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/colorscheme.dart index 76d274f4c8..b109dbad8d 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/colorscheme.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/colorscheme.dart @@ -56,6 +56,22 @@ abstract class FlowyColorScheme { final Color main1; final Color main2; final Color shadow; + final Color sidebarBg; + final Color divider; + final Color topbarBg; + final Color icon; + final Color text; + final Color input; + final Color hint; + final Color primary; + final Color onPrimary; + //page title hover effect + final Color hoverBG1; + //action item hover effect + final Color hoverBG2; + //the text color when it is hovered + final Color hoverFG; + final Color questionBubbleBG; const FlowyColorScheme({ required this.surface, @@ -87,6 +103,19 @@ abstract class FlowyColorScheme { required this.main1, required this.main2, required this.shadow, + required this.sidebarBg, + required this.divider, + required this.topbarBg, + required this.icon, + required this.text, + required this.input, + required this.hint, + required this.primary, + required this.onPrimary, + required this.hoverBG1, + required this.hoverBG2, + required this.hoverFG, + required this.questionBubbleBG, }); factory FlowyColorScheme.builtIn(String themeName, Brightness brightness) { diff --git a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/dandelion.dart b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/dandelion.dart index 21492f43b4..00655eef21 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/dandelion.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/dandelion.dart @@ -4,6 +4,21 @@ import 'colorscheme.dart'; const _black = Color(0xff000000); const _white = Color(0xFFFFFFFF); +const _lightHover = Color(0xFFe0f8ff); +const _lightSelector = Color(0xfff2fcff); +const _lightBg1 = Color(0xFFFFD13E); +const _lightBg2 = Color(0xffedeef2); +const _lightShader1 = Color(0xff333333); +const _lightShader3 = Color(0xff828282); +const _lightShader6 = Color(0xfff2f2f2); +const _lightMain1 = Color(0xffe21f74); + +const _darkShader1 = Color(0xff131720); +const _darkShader2 = Color(0xff1A202C); +const _darkShader3 = Color(0xff363D49); +const _darkShader5 = Color(0xffBBC3CD); +const _darkShader6 = Color(0xffF2F2F2); +const _darkMain1 = Color(0xffe21f74); class DandelionColorScheme extends FlowyColorScheme { const DandelionColorScheme.light() @@ -20,8 +35,8 @@ class DandelionColorScheme extends FlowyColorScheme { shader4: const Color(0xffbdbdbd), shader5: const Color(0xffe0e0e0), shader6: const Color(0xfff2f2f2), - shader7: const Color(0xffffffff), - bg1: const Color(0xFFFFD13E), + shader7: _black, + bg1: _lightBg1, bg2: const Color(0xffedeef2), bg3: const Color(0xffe2e4eb), bg4: const Color(0xff2c144b), @@ -34,9 +49,22 @@ class DandelionColorScheme extends FlowyColorScheme { tint7: const Color(0xffddffd6), tint8: const Color(0xffdefff1), tint9: const Color(0xffe1fbff), - main1: const Color(0xffe21f74), + main1: _lightMain1, main2: const Color.fromARGB(255, 224, 25, 111), shadow: _black, + sidebarBg: _lightBg1, + divider: _lightShader6, + topbarBg: _white, + icon: _lightShader1, + text: _lightShader1, + input: _white, + hint: _lightShader3, + primary: _lightMain1, + onPrimary: _white, + hoverBG1: _lightBg2, + hoverBG2: _lightHover, + hoverFG: _lightShader1, + questionBubbleBG: _lightSelector, ); const DandelionColorScheme.dark() @@ -48,12 +76,12 @@ class DandelionColorScheme extends FlowyColorScheme { yellow: const Color(0xffffd667), green: const Color(0xff66cf80), shader1: _white, - shader2: const Color(0xffffffff), + shader2: _darkShader2, shader3: const Color(0xff828282), shader4: const Color(0xffbdbdbd), - shader5: _white, - shader6: _black, - shader7: _black, + shader5: _darkShader5, + shader6: _darkShader6, + shader7: _white, bg1: const Color(0xFFD5A200), bg2: _black, bg3: const Color(0xff4f4f4f), @@ -67,8 +95,21 @@ class DandelionColorScheme extends FlowyColorScheme { tint7: const Color(0xffbcffad), tint8: const Color(0xffadffe2), tint9: const Color(0xffade4ff), - main1: const Color(0xffe21f74), + main1: _darkMain1, main2: const Color.fromARGB(255, 224, 25, 111), shadow: _black, + sidebarBg: const Color(0xff232B38), + divider: _darkShader3, + topbarBg: _darkShader1, + icon: _darkShader5, + text: _darkShader5, + input: const Color(0xff282E3A), + hint: _darkShader5, + primary: _darkMain1, + onPrimary: _darkShader1, + hoverBG1: _darkMain1, + hoverBG2: _darkMain1, + hoverFG: _darkShader1, + questionBubbleBG: _darkShader3, ); } diff --git a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart index accd81a07e..590b5c7bc6 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart @@ -4,25 +4,39 @@ import 'colorscheme.dart'; const _black = Color(0xff000000); const _white = Color(0xFFFFFFFF); +const _lightHover = Color(0xFFe0f8ff); +const _lightSelector = Color(0xfff2fcff); +const _lightBg1 = Color(0xfff7f8fc); +const _lightBg2 = Color(0xffedeef2); +const _lightShader1 = Color(0xff333333); +const _lightShader3 = Color(0xff828282); +const _lightShader6 = Color(0xfff2f2f2); +const _lightMain1 = Color(0xff00bcf0); +const _darkShader1 = Color(0xff131720); +const _darkShader2 = Color(0xff1A202C); +const _darkShader3 = Color(0xff363D49); +const _darkShader5 = Color(0xffBBC3CD); +const _darkShader6 = Color(0xffF2F2F2); +const _darkMain1 = Color(0xff00BCF0); class DefaultColorScheme extends FlowyColorScheme { const DefaultColorScheme.light() : super( - surface: Colors.white, - hover: const Color(0xFFe0f8ff), - selector: const Color(0xfff2fcff), + surface: _white, + hover: _lightHover, + selector: _lightSelector, red: const Color(0xfffb006d), yellow: const Color(0xffffd667), green: const Color(0xff66cf80), - shader1: const Color(0xff333333), + shader1: _lightShader1, shader2: const Color(0xff4f4f4f), - shader3: const Color(0xff828282), + shader3: _lightShader3, shader4: const Color(0xffbdbdbd), shader5: const Color(0xffe0e0e0), - shader6: const Color(0xfff2f2f2), - shader7: const Color(0xffffffff), - bg1: const Color(0xfff7f8fc), - bg2: const Color(0xffedeef2), + shader6: _lightShader6, + shader7: _lightShader1, + bg1: _lightBg1, + bg2: _lightBg2, bg3: const Color(0xffe2e4eb), bg4: const Color(0xff2c144b), tint1: const Color(0xffe8e0ff), @@ -34,41 +48,67 @@ class DefaultColorScheme extends FlowyColorScheme { tint7: const Color(0xffddffd6), tint8: const Color(0xffdefff1), tint9: const Color(0xffe1fbff), - main1: const Color(0xff00bcf0), + main1: _lightMain1, main2: const Color(0xff00b7ea), shadow: _black, + sidebarBg: _lightBg1, + divider: _lightShader6, + topbarBg: _white, + icon: _lightShader1, + text: _lightShader1, + input: _white, + hint: _lightShader3, + primary: _lightMain1, + onPrimary: _white, + hoverBG1: _lightBg2, + hoverBG2: _lightHover, + hoverFG: _lightShader1, + questionBubbleBG: _lightSelector, ); const DefaultColorScheme.dark() : super( - surface: const Color(0xff292929), - hover: const Color(0xff1f1f1f), - selector: const Color(0xff333333), + surface: _darkShader2, + hover: _darkMain1, + selector: _darkShader2, red: const Color(0xfffb006d), - yellow: const Color(0xffffd667), - green: const Color(0xff66cf80), - shader1: _white, - shader2: const Color(0xffffffff), - shader3: const Color(0xff828282), - shader4: const Color(0xffbdbdbd), - shader5: _white, - shader6: _black, - shader7: _black, - bg1: _black, - bg2: _black, - bg3: const Color(0xff4f4f4f), - bg4: const Color(0xff2c144b), - tint1: const Color(0xffc3adff), - tint2: const Color(0xffffadf9), - tint3: const Color(0xffffadad), - tint4: const Color(0xffffcfad), - tint5: const Color(0xfffffead), - tint6: const Color(0xffe6ffa3), - tint7: const Color(0xffbcffad), - tint8: const Color(0xffadffe2), - tint9: const Color(0xffade4ff), - main1: const Color(0xff00bcf0), - main2: const Color(0xff009cc7), - shadow: _black, + yellow: const Color(0xffF7CF46), + green: const Color(0xff66CF80), + shader1: _darkShader1, + shader2: _darkShader2, + shader3: _darkShader3, + shader4: const Color(0xff7C8CA5), + shader5: _darkShader5, + shader6: _darkShader6, + shader7: _white, + bg1: const Color(0xffF7F8FC), + bg2: const Color(0xffEDEEF2), + bg3: _darkMain1, + bg4: const Color(0xff2C144B), + tint1: const Color(0xff8738F5), + tint2: const Color(0xffE6336E), + tint3: const Color(0xffFF2D9E), + tint4: const Color(0xffE9973E), + tint5: const Color(0xffFBF000), + tint6: const Color(0xffC0F000), + tint7: const Color(0xff15F74E), + tint8: const Color(0xff00F0E2), + tint9: const Color(0xff00BCF0), + main1: _darkMain1, + main2: const Color(0xff00B7EA), + shadow: const Color(0xff0F131C), + sidebarBg: const Color(0xff232B38), + divider: _darkShader3, + topbarBg: _darkShader1, + icon: _darkShader5, + text: _darkShader5, + input: const Color(0xff282E3A), + hint: _darkShader5, + primary: _darkMain1, + onPrimary: _darkShader1, + hoverBG1: _darkMain1, + hoverBG2: _darkMain1, + hoverFG: _darkShader1, + questionBubbleBG: _darkShader3, ); } diff --git a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/lavender.dart b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/lavender.dart index 7012077250..83f0557349 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/lavender.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/lavender.dart @@ -5,6 +5,22 @@ import 'colorscheme.dart'; const _black = Color(0xff000000); const _white = Color(0xFFFFFFFF); +const _lightHover = Color(0xFFe0f8ff); +const _lightSelector = Color(0xfff2fcff); +const _lightBg1 = Color(0xfff7f8fc); +const _lightBg2 = Color(0xffedeef2); +const _lightShader1 = Color(0xff333333); +const _lightShader3 = Color(0xff828282); +const _lightShader6 = Color(0xfff2f2f2); +const _lightMain1 = Color(0xffA652FB); + +const _darkShader1 = Color(0xff131720); +const _darkShader2 = Color(0xff1A202C); +const _darkShader3 = Color(0xff363D49); +const _darkShader5 = Color(0xffBBC3CD); +const _darkShader6 = Color(0xffF2F2F2); +const _darkMain1 = Color(0xffA652FB); + class LavenderColorScheme extends FlowyColorScheme { const LavenderColorScheme.light() : super( @@ -20,7 +36,7 @@ class LavenderColorScheme extends FlowyColorScheme { shader4: const Color(0xffbdbdbd), shader5: const Color(0xffe0e0e0), shader6: const Color(0xfff2f2f2), - shader7: const Color(0xffffffff), + shader7: _black, bg1: const Color(0xffAC59FF), bg2: const Color(0xffedeef2), bg3: const Color(0xffe2e4eb), @@ -34,9 +50,22 @@ class LavenderColorScheme extends FlowyColorScheme { tint7: const Color(0xffddffd6), tint8: const Color(0xffdefff1), tint9: const Color(0xffe1fbff), - main1: const Color(0xffA652FB), + main1: _lightMain1, main2: const Color(0xff9327FF), shadow: _black, + sidebarBg: _lightBg1, + divider: _lightShader6, + topbarBg: _white, + icon: _lightShader1, + text: _lightShader1, + input: _white, + hint: _lightShader3, + primary: _lightMain1, + onPrimary: _white, + hoverBG1: _lightBg2, + hoverBG2: _lightHover, + hoverFG: _lightShader1, + questionBubbleBG: _lightSelector, ); const LavenderColorScheme.dark() @@ -48,12 +77,12 @@ class LavenderColorScheme extends FlowyColorScheme { yellow: const Color(0xffffd667), green: const Color(0xff66cf80), shader1: _white, - shader2: const Color(0xffffffff), + shader2: _darkShader2, shader3: const Color(0xff828282), shader4: const Color(0xffbdbdbd), shader5: _white, - shader6: _black, - shader7: _black, + shader6: _darkShader6, + shader7: _white, bg1: const Color(0xff8C23F6), bg2: _black, bg3: const Color(0xff4f4f4f), @@ -67,8 +96,21 @@ class LavenderColorScheme extends FlowyColorScheme { tint7: const Color(0xffbcffad), tint8: const Color(0xffadffe2), tint9: const Color(0xffade4ff), - main1: const Color(0xffA652FB), + main1: _darkMain1, main2: const Color(0xff9327FF), shadow: _black, + sidebarBg: const Color(0xff232B38), + divider: _darkShader3, + topbarBg: _darkShader1, + icon: _darkShader5, + text: _darkShader5, + input: const Color(0xff282E3A), + hint: _darkShader5, + primary: _darkMain1, + onPrimary: _darkShader1, + hoverBG1: _darkMain1, + hoverBG2: _darkMain1, + hoverFG: _darkShader1, + questionBubbleBG: _darkShader3, ); } diff --git a/frontend/appflowy_flutter/packages/flowy_infra/lib/image.dart b/frontend/appflowy_flutter/packages/flowy_infra/lib/image.dart index 4ed4da10bf..577e3c182a 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra/lib/image.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra/lib/image.dart @@ -1,6 +1,30 @@ -import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter/material.dart'; + +/// For icon that needs to change color when it is on hovered +/// +/// Get the hover color from ThemeData +class FlowySvg extends StatelessWidget { + const FlowySvg({super.key, this.size, required this.name}); + final String name; + final Size? size; + + @override + Widget build(BuildContext context) { + if (size != null) { + return SizedBox.fromSize( + size: size, + child: SvgPicture.asset('assets/images/$name.svg', + color: Theme.of(context).iconTheme.color), + ); + } else { + return SvgPicture.asset('assets/images/$name.svg', + color: Theme.of(context).iconTheme.color); + } + } +} + Widget svgWidget(String name, {Size? size, Color? color}) { if (size != null) { return SizedBox.fromSize( diff --git a/frontend/appflowy_flutter/packages/flowy_infra/lib/language.dart b/frontend/appflowy_flutter/packages/flowy_infra/lib/language.dart index 7cfc9ddc8b..daeba5a95b 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra/lib/language.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra/lib/language.dart @@ -6,7 +6,14 @@ String languageFromLocale(Locale locale) { case "en": return "English"; case "zh": - return "简体中文"; + switch (locale.countryCode) { + case "CN": + return "简体中文"; + case "TW": + return "繁體中文"; + default: + return locale.languageCode; + } // Then in alphabetical order case "ca": diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/appflowy_popover.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/appflowy_popover.dart index 3673720220..1fcc19fb11 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/appflowy_popover.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/appflowy_popover.dart @@ -81,7 +81,7 @@ class _PopoverContainer extends StatelessWidget { Widget build(BuildContext context) { final decoration = this.decoration ?? FlowyDecoration.decoration( - Theme.of(context).colorScheme.surface, + Theme.of(context).cardColor, Theme.of(context).colorScheme.shadow.withOpacity(0.15), ); diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart index f8cc85938b..033f5d2a5d 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/src/flowy_overlay/flowy_dialog.dart @@ -26,6 +26,7 @@ class FlowyDialog extends StatelessWidget { final size = windowSize * 0.7; return SimpleDialog( contentPadding: EdgeInsets.zero, + backgroundColor: Theme.of(context).cardColor, title: title, shape: shape ?? RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/button.dart index 3c958a160a..22b1ff81e8 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -1,11 +1,9 @@ -import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/ignore_parent_gesture.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flutter/material.dart'; -import 'package:textstyle_extensions/textstyle_extensions.dart'; class FlowyButton extends StatelessWidget { final Widget text; @@ -177,7 +175,8 @@ class FlowyTextButton extends StatelessWidget { highlightElevation: 0, shape: RoundedRectangleBorder(borderRadius: radius ?? Corners.s6Border), fillColor: fillColor ?? Theme.of(context).colorScheme.secondaryContainer, - hoverColor: hoverColor ?? Theme.of(context).colorScheme.secondary, + hoverColor: + hoverColor ?? Theme.of(context).colorScheme.secondaryContainer, focusColor: Colors.transparent, splashColor: Colors.transparent, highlightColor: Colors.transparent, @@ -195,7 +194,6 @@ class FlowyTextButton extends StatelessWidget { if (tooltip != null) { child = Tooltip( message: tooltip!, - textStyle: AFThemeExtension.of(context).caption.textColor(Colors.white), child: child, ); } @@ -285,7 +283,6 @@ class FlowyRichTextButton extends StatelessWidget { if (tooltip != null) { child = Tooltip( message: tooltip!, - textStyle: AFThemeExtension.of(context).caption.textColor(Colors.white), child: child, ); } diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/hover.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/hover.dart index 8d8b64dcf3..687c62a4d9 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/hover.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/hover.dart @@ -115,11 +115,11 @@ class HoverStyle { class FlowyHoverContainer extends StatelessWidget { final HoverStyle style; - final Widget? child; + final Widget child; const FlowyHoverContainer({ Key? key, - this.child, + required this.child, required this.style, }) : super(key: key); @@ -137,7 +137,22 @@ class FlowyHoverContainer extends StatelessWidget { color: style.hoverColor ?? Theme.of(context).colorScheme.secondary, borderRadius: style.borderRadius, ), - child: child, + child: + //override text's theme with new color when it is hovered + Theme( + data: Theme.of(context).copyWith( + textTheme: Theme.of(context).textTheme.copyWith( + bodyMedium: Theme.of(context) + .textTheme + .bodyMedium + ?.copyWith(color: Theme.of(context).colorScheme.onSurface), + ), + iconTheme: Theme.of(context) + .iconTheme + .copyWith(color: Theme.of(context).colorScheme.onSurface), + ), + child: child, + ), ); } } diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/buttons/base_styled_button.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/buttons/base_styled_button.dart index 4aefb7dd55..b9c5894b3a 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/buttons/base_styled_button.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/buttons/base_styled_button.dart @@ -9,7 +9,7 @@ class BaseStyledButton extends StatefulWidget { final Color? bgColor; final Color? focusColor; final Color? hoverColor; - final Color? downColor; + final Color? highlightColor; final EdgeInsets? contentPadding; final double? minWidth; final double? minHeight; @@ -34,7 +34,7 @@ class BaseStyledButton extends StatefulWidget { this.minHeight, this.borderRadius, this.hoverColor, - this.downColor, + this.highlightColor, this.shape, this.useBtnText = true, this.autoFocus = false, @@ -116,10 +116,8 @@ class BaseStyledBtnState extends State { highlightElevation: 0, focusElevation: 0, fillColor: Colors.transparent, - hoverColor: - widget.hoverColor ?? Theme.of(context).colorScheme.secondary, - highlightColor: - widget.downColor ?? Theme.of(context).colorScheme.primary, + hoverColor: widget.hoverColor ?? Colors.transparent, + highlightColor: widget.highlightColor ?? Colors.transparent, focusColor: widget.focusColor ?? Colors.grey.withOpacity(0.35), constraints: BoxConstraints( minHeight: widget.minHeight ?? 0, minWidth: widget.minWidth ?? 0), diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/buttons/primary_button.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/buttons/primary_button.dart index 1f7491f133..e67a7a15df 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/buttons/primary_button.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/buttons/primary_button.dart @@ -42,7 +42,6 @@ class PrimaryButton extends StatelessWidget { contentPadding: EdgeInsets.zero, bgColor: Theme.of(context).colorScheme.primary, hoverColor: Theme.of(context).colorScheme.primaryContainer, - downColor: Theme.of(context).colorScheme.primary, borderRadius: bigMode ? Corners.s12Border : Corners.s8Border, onPressed: onPressed, child: child, diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/buttons/secondary_button.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/buttons/secondary_button.dart index 8caa135463..eae3c58a2a 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/buttons/secondary_button.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/buttons/secondary_button.dart @@ -42,8 +42,6 @@ class SecondaryButton extends StatelessWidget { minHeight: bigMode ? 40 : 38, contentPadding: EdgeInsets.zero, bgColor: Theme.of(context).colorScheme.surface, - hoverColor: Theme.of(context).colorScheme.secondary, - downColor: Theme.of(context).colorScheme.primary, outlineColor: Theme.of(context).colorScheme.primary, borderRadius: bigMode ? Corners.s12Border : Corners.s8Border, onPressed: onPressed, diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml index b9d5b4a875..05d84a4d4c 100644 --- a/frontend/appflowy_flutter/pubspec.yaml +++ b/frontend/appflowy_flutter/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.1.1 +version: 0.1.2 environment: sdk: ">=2.18.0 <3.0.0" @@ -89,7 +89,6 @@ dependencies: google_fonts: ^3.0.1 file_picker: <=5.0.0 percent_indicator: ^4.0.1 - appflowy_editor_plugins: path: packages/appflowy_editor_plugins calendar_view: ^1.0.1 diff --git a/frontend/appflowy_tauri/src-tauri/src/init.rs b/frontend/appflowy_tauri/src-tauri/src/init.rs index a09c80c875..c2fdddf85c 100644 --- a/frontend/appflowy_tauri/src-tauri/src/init.rs +++ b/frontend/appflowy_tauri/src-tauri/src/init.rs @@ -10,7 +10,7 @@ pub fn init_flowy_core() -> AppFlowyCore { } data_path.push("data"); - std::env::set_var("RUST_LOG", "debug"); + std::env::set_var("RUST_LOG", "trace"); let server_config = get_client_server_configuration().unwrap(); let config = AppFlowyCoreConfig::new( data_path.to_str().unwrap(), diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/DatePickerPopup.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/DatePickerPopup.tsx index d7af34ec23..03389eb4a3 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/DatePickerPopup.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/DatePickerPopup.tsx @@ -10,6 +10,8 @@ import { ClockSvg } from '$app/components/_shared/svg/ClockSvg'; import { MoreSvg } from '$app/components/_shared/svg/MoreSvg'; import { EditorUncheckSvg } from '$app/components/_shared/svg/EditorUncheckSvg'; import { useCell } from '$app/components/_shared/database-hooks/useCell'; +import { CalendarData } from '$app/stores/effects/database/cell/controller_builder'; +import { DateCellDataPB } from '@/services/backend'; export const DatePickerPopup = ({ left, @@ -29,7 +31,6 @@ export const DatePickerPopup = ({ const { data, cellController } = useCell(cellIdentifier, cellCache, fieldController); const ref = useRef(null); const [adjustedTop, setAdjustedTop] = useState(-100); - // const [value, setValue] = useState(); const { t } = useTranslation(''); const [selectedDate, setSelectedDate] = useState(new Date()); @@ -48,15 +49,18 @@ export const DatePickerPopup = ({ }); useEffect(() => { - // console.log((data as DateCellDataPB).date); - // setSelectedDate(new Date((data as DateCellDataPB).date)); + const date_pb = data as DateCellDataPB | undefined; + if (!date_pb || !date_pb?.date.length) return; + + // should be changed after we can modify date format + setSelectedDate(dayjs(date_pb.date, 'MMM DD, YYYY').toDate()); }, [data]); - const onChange = (v: Date | null | (Date | null)[]) => { + const onChange = async (v: Date | null | (Date | null)[]) => { if (v instanceof Date) { - console.log(dayjs(v).format('YYYY-MM-DD')); setSelectedDate(v); - // void cellController?.saveCellData(new DateCellDataPB({ date: dayjs(v).format('YYYY-MM-DD') })); + const date = new CalendarData(dayjs(v).add(dayjs().utcOffset(), 'minutes').toDate(), false); + await cellController?.saveCellData(date); } }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditCellWrapper.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditCellWrapper.tsx index 64dcebf98a..3e50839f77 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditCellWrapper.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditCellWrapper.tsx @@ -76,7 +76,10 @@ export const EditCellWrapper = ({ )} {cellIdentifier.fieldType === FieldType.Checkbox && cellController && ( - + )} {cellIdentifier.fieldType === FieldType.DateTime && ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditCheckboxCell.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditCheckboxCell.tsx index 25b3a50ff5..6ea688af54 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditCheckboxCell.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditCheckboxCell.tsx @@ -1,22 +1,26 @@ import { EditorCheckSvg } from '$app/components/_shared/svg/EditorCheckSvg'; import { EditorUncheckSvg } from '$app/components/_shared/svg/EditorUncheckSvg'; -import { CellController } from '$app/stores/effects/database/cell/cell_controller'; +import { CheckboxCellController } from '$app/stores/effects/database/cell/controller_builder'; export const EditCheckboxCell = ({ data, cellController, }: { - data: boolean | undefined; - cellController: CellController; + data: 'Yes' | 'No' | undefined; + cellController: CheckboxCellController; }) => { const toggleValue = async () => { - await cellController?.saveCellData(!data); + if (data === 'Yes') { + await cellController?.saveCellData('No'); + } else { + await cellController?.saveCellData('Yes'); + } }; return (
toggleValue()} className={'block px-4 py-2'}>
); diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditRow.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditRow.tsx index abf0b714e7..780120164e 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditRow.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditRow.tsx @@ -108,7 +108,11 @@ export const EditRow = ({ const onDragEnd: OnDragEndResponder = (result) => { if (!result.destination?.index) return; - void controller.moveField(result.source.droppableId, result.source.index, result.destination.index); + void controller.moveField({ + fieldId: result.source.droppableId, + fromIndex: result.source.index, + toIndex: result.destination.index, + }); }; return ( diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardCell.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardCell.tsx index 45222f4a56..5ba97345dd 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardCell.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/board/BoardCell.tsx @@ -1,13 +1,12 @@ import { CellIdentifier } from '../../stores/effects/database/cell/cell_bd_svc'; import { CellCache } from '../../stores/effects/database/cell/cell_cache'; import { FieldController } from '../../stores/effects/database/field/field_controller'; -import { FieldType, SelectOptionCellDataPB } from '../../../services/backend'; +import { FieldType } from '../../../services/backend'; import { BoardOptionsCell } from './BoardOptionsCell'; import { BoardDateCell } from './BoardDateCell'; import { BoardTextCell } from './BoardTextCell'; import { BoardUrlCell } from '$app/components/board/BoardUrlCell'; -import { useCell } from '../_shared/database-hooks/useCell'; -import { CellOptions } from '../_shared/EditRow/CellOptions'; +import { BoardCheckboxCell } from '$app/components/board/BoardCheckboxCell'; export const BoardCell = ({ cellIdentifier, @@ -18,19 +17,16 @@ export const BoardCell = ({ cellCache: CellCache; fieldController: FieldController; }) => { - const { data, cellController } = useCell(cellIdentifier, cellCache, fieldController); - return ( <> {cellIdentifier.fieldType === FieldType.SingleSelect || cellIdentifier.fieldType === FieldType.MultiSelect || cellIdentifier.fieldType === FieldType.Checklist ? ( - { - console.log(top, left); - }} - /> + ) : cellIdentifier.fieldType === FieldType.DateTime ? ( + ) : cellIdentifier.fieldType === FieldType.Checkbox ? ( + ) : ( { + const { data } = useCell(cellIdentifier, cellCache, fieldController); + return ( + + {data === 'Yes' ? : } + + ); +}; diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/tests/DatabaseTestHelper.ts b/frontend/appflowy_tauri/src/appflowy_app/components/tests/DatabaseTestHelper.ts index f3b0f175e4..7ab6cdd5ce 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/tests/DatabaseTestHelper.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/components/tests/DatabaseTestHelper.ts @@ -12,6 +12,7 @@ import { RowInfo } from '../../stores/effects/database/row/row_cache'; import { RowController } from '../../stores/effects/database/row/row_controller'; import { CellControllerBuilder, + CheckboxCellController, DateCellController, NumberCellController, SelectOptionCellController, @@ -126,6 +127,17 @@ export async function makeDateCellController( return Some(builder.build() as DateCellController); } +export async function makeCheckboxCellController( + fieldId: string, + rowInfo: RowInfo, + databaseController: DatabaseController +): Promise> { + const builder = await makeCellControllerBuilder(fieldId, rowInfo, FieldType.Checkbox, databaseController).then( + (result) => result.unwrap() + ); + return Some(builder.build() as CheckboxCellController); +} + export async function makeURLCellController( fieldId: string, rowInfo: RowInfo, diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/tests/TestAPI.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/tests/TestAPI.tsx index a45d82fa38..62daf865d1 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/tests/TestAPI.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/tests/TestAPI.tsx @@ -8,10 +8,13 @@ import { TestDeleteField, TestDeleteRow, TestEditCell, + TestEditCheckboxCell, + TestEditDateCell, TestEditField, TestEditTextCell, TestEditURLCell, TestGetSingleSelectFieldData, + TestMoveField, TestSwitchFromMultiSelectToText, TestSwitchFromSingleSelectToNumber, } from './TestGrid'; @@ -37,9 +40,12 @@ export const TestAPI = () => { + + + diff --git a/frontend/appflowy_tauri/src/appflowy_app/components/tests/TestGrid.tsx b/frontend/appflowy_tauri/src/appflowy_app/components/tests/TestGrid.tsx index 3f7cf70341..1a3925c82c 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/components/tests/TestGrid.tsx +++ b/frontend/appflowy_tauri/src/appflowy_app/components/tests/TestGrid.tsx @@ -8,6 +8,7 @@ import { } from '@/services/backend'; import { Log } from '$app/utils/log'; import { + assert, assertFieldName, assertNumberOfFields, assertNumberOfRows, @@ -16,6 +17,8 @@ import { createTestDatabaseView, editTextCell, findFirstFieldInfoWithFieldType, + makeCheckboxCellController, + makeDateCellController, makeMultiSelectCellController, makeSingleSelectCellController, makeTextCellController, @@ -27,6 +30,8 @@ import { TypeOptionController } from '$app/stores/effects/database/field/type_op import { None, Some } from 'ts-results'; import { RowBackendService } from '$app/stores/effects/database/row/row_bd_svc'; import { makeNumberTypeOptionContext } from '$app/stores/effects/database/field/type_option/type_option_context'; +import { CalendarData } from '$app/stores/effects/database/cell/controller_builder'; +import { DatabaseEventMoveField } from '@/services/backend/events/flowy-database'; export const RunAllGridTests = () => { async function run() { @@ -138,6 +143,57 @@ async function testEditURLCell() { await new Promise((resolve) => setTimeout(resolve, 200)); } +async function testEditDateCell() { + const view = await createTestDatabaseView(ViewLayoutTypePB.Grid); + const databaseController = await openTestDatabase(view.id); + await databaseController.open().then((result) => result.unwrap()); + + const typeOptionController = new TypeOptionController(view.id, None, FieldType.DateTime); + await typeOptionController.initialize(); + + const row = databaseController.databaseViewCache.rowInfos[0]; + const dateCellController = await makeDateCellController(typeOptionController.fieldId, row, databaseController).then( + (result) => result.unwrap() + ); + + dateCellController.subscribeChanged({ + onCellChanged: (content) => { + const pb = content.unwrap(); + Log.info('Receive date data:', pb.date, pb.time); + }, + }); + + const date = new CalendarData(new Date(), true, '13:00'); + await dateCellController.saveCellData(date); + await new Promise((resolve) => setTimeout(resolve, 200)); +} + +async function testCheckboxCell() { + const view = await createTestDatabaseView(ViewLayoutTypePB.Grid); + const databaseController = await openTestDatabase(view.id); + await databaseController.open().then((result) => result.unwrap()); + + const typeOptionController = new TypeOptionController(view.id, None, FieldType.Checkbox); + await typeOptionController.initialize(); + + const row = databaseController.databaseViewCache.rowInfos[0]; + const checkboxCellController = await makeCheckboxCellController( + typeOptionController.fieldId, + row, + databaseController + ).then((result) => result.unwrap()); + + checkboxCellController.subscribeChanged({ + onCellChanged: (content) => { + const pb = content.unwrap(); + Log.info('Receive checkbox data:', pb); + }, + }); + + await checkboxCellController.saveCellData('true'); + await new Promise((resolve) => setTimeout(resolve, 200)); +} + async function testCreateRow() { const view = await createTestDatabaseView(ViewLayoutTypePB.Grid); const databaseController = await openTestDatabase(view.id); @@ -196,6 +252,24 @@ async function testCreateOptionInCell() { await databaseController.dispose(); } +async function testMoveField() { + const view = await createTestDatabaseView(ViewLayoutTypePB.Grid); + const databaseController = await openTestDatabase(view.id); + await databaseController.open().then((result) => result.unwrap()); + + databaseController.subscribe({ + onFieldsChanged: (value) => { + Log.info('Receive fields data:', value); + }, + }); + + const fieldInfos = [...databaseController.fieldController.fieldInfos]; + const field_id = fieldInfos[0].field.id; + await databaseController.moveField({ fieldId: field_id, fromIndex: 0, toIndex: 1 }); + await new Promise((resolve) => setTimeout(resolve, 200)); + assert(databaseController.fieldController.fieldInfos[1].field.id === field_id); +} + async function testGetSingleSelectFieldData() { const view = await createTestDatabaseView(ViewLayoutTypePB.Grid); const databaseController = await openTestDatabase(view.id); @@ -360,6 +434,12 @@ export const TestEditTextCell = () => { export const TestEditURLCell = () => { return TestButton('Test editing URL cell', testEditURLCell); }; +export const TestEditDateCell = () => { + return TestButton('Test editing date cell', testEditDateCell); +}; +export const TestEditCheckboxCell = () => { + return TestButton('Test editing checkbox cell', testCheckboxCell); +}; export const TestCreateRow = () => { return TestButton('Test create row', testCreateRow); }; @@ -382,6 +462,9 @@ export const TestSwitchFromMultiSelectToText = () => { return TestButton('Test switch from multi-select to text column', testSwitchFromMultiSelectToRichText); }; +export const TestMoveField = () => { + return TestButton('Test move field', testMoveField); +}; export const TestEditField = () => { return TestButton('Test edit the column name', testEditField); }; diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/controller_builder.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/controller_builder.ts index 7858f5a938..83f8bcd9ae 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/controller_builder.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/controller_builder.ts @@ -23,7 +23,7 @@ export type SelectOptionCellController = CellController; export class CalendarData { - constructor(public readonly date: Date, public readonly time?: string) {} + constructor(public readonly date: Date, public readonly includeTime: boolean, public readonly time?: string) {} } export type URLCellController = CellController; diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/data_persistence.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/data_persistence.ts index c6eb7288ec..affa40c7f5 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/data_persistence.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/cell/data_persistence.ts @@ -25,11 +25,12 @@ export class DateCellDataPersistence extends CellDataPersistence { save(data: CalendarData): Promise> { const payload = DateChangesetPB.fromObject({ cell_path: _makeCellPath(this.cellIdentifier) }); - payload.date = data.date.getUTCMilliseconds.toString(); + payload.date = ((data.date.getTime() / 1000) | 0).toString(); payload.is_utc = true; if (data.time !== undefined) { payload.time = data.time; } + payload.include_time = data.includeTime; return DatabaseEventUpdateDateCell(payload); } } diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_bd_svc.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_bd_svc.ts index 005aceee99..bce7783ddc 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_bd_svc.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_bd_svc.ts @@ -98,16 +98,6 @@ export class DatabaseBackendService { return DatabaseEventMoveGroup(payload); }; - moveField = (fieldId: string, fromIndex: number, toIndex: number) => { - const payload = MoveFieldPayloadPB.fromObject({ - view_id: this.viewId, - field_id: fieldId, - from_index: fromIndex, - to_index: toIndex, - }); - return DatabaseEventMoveField(payload); - }; - /// Get all fields in database getFields = async (fieldIds?: FieldIdPB[]) => { const payload = GetFieldPayloadPB.fromObject({ view_id: this.viewId }); @@ -125,6 +115,16 @@ export class DatabaseBackendService { return DatabaseEventGetGroup(payload); }; + moveField = (params: { fieldId: string; fromIndex: number; toIndex: number }) => { + const payload = MoveFieldPayloadPB.fromObject({ + view_id: this.viewId, + field_id: params.fieldId, + from_index: params.fromIndex, + to_index: params.toIndex, + }); + return DatabaseEventMoveField(payload); + }; + /// Get all groups in database /// It should only call once after the board open loadGroups = () => { diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_controller.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_controller.ts index fb856c2ccc..918be53b65 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_controller.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_controller.ts @@ -1,7 +1,7 @@ import { DatabaseBackendService } from './database_bd_svc'; import { FieldController, FieldInfo } from './field/field_controller'; import { DatabaseViewCache } from './view/database_view_cache'; -import { DatabasePB, FlowyError, GroupPB } from '@/services/backend'; +import { DatabasePB, GroupPB, FlowyError } from '@/services/backend'; import { RowChangedReason, RowInfo } from './row/row_cache'; import { Err, Ok } from 'ts-results'; import { DatabaseGroupController } from './group/group_controller'; @@ -65,9 +65,7 @@ export class DatabaseController { this.databaseViewCache.initializeWithRows(database.rows); this._callback?.onViewChanged?.(database); - - // temporary fix for grid rows misfire issue - return Ok(database.rows); + return loadGroupResult; } else { return Err(openDatabaseResult.val); } @@ -104,8 +102,8 @@ export class DatabaseController { return this.backendService.moveGroup(fromGroupId, toGroupId); }; - moveField = (fieldId: string, fromIndex: number, toIndex: number) => { - return this.backendService.moveField(fieldId, fromIndex, toIndex); + moveField = (params: { fieldId: string; fromIndex: number; toIndex: number }) => { + return this.backendService.moveField(params); }; private loadGroup = async () => { diff --git a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/field_controller.ts b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/field_controller.ts index 24ee55b968..c1e126e7d9 100644 --- a/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/field_controller.ts +++ b/frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/field/field_controller.ts @@ -36,8 +36,8 @@ export class FieldController { } }; - subscribe = (callbacks: { onNumOfFieldsChanged?: (fieldInfos: readonly FieldInfo[]) => void}) => { - this.numOfFieldsNotifier.observer.subscribe((fieldInfos) => { + subscribe = (callbacks: { onNumOfFieldsChanged?: (fieldInfos: readonly FieldInfo[]) => void }) => { + this.numOfFieldsNotifier.observer.subscribe((fieldInfos) => { callbacks.onNumOfFieldsChanged?.(fieldInfos); }); }; @@ -63,12 +63,10 @@ export class FieldController { } const deletedFieldIds = deletedFields.map((field) => field.field_id); - const predicate = (element: FieldInfo) => { - !deletedFieldIds.includes(element.field.id); + const predicate = (element: FieldInfo): boolean => { + return !deletedFieldIds.includes(element.field.id); }; - const newFieldInfos = [...this.fieldInfos]; - newFieldInfos.filter(predicate); - this.numOfFieldsNotifier.fieldInfos = newFieldInfos; + this.numOfFieldsNotifier.fieldInfos = [...this.fieldInfos].filter(predicate); }; private _insertFields = (insertedFields: IndexFieldPB[]) => { diff --git a/frontend/scripts/makefile/flutter.toml b/frontend/scripts/makefile/flutter.toml index 88632e43a4..7b7da3eea5 100644 --- a/frontend/scripts/makefile/flutter.toml +++ b/frontend/scripts/makefile/flutter.toml @@ -159,7 +159,7 @@ script = [ [tasks.create-release-archive-macos] script = [ - # TODO + # TODO # "cd ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/appflowy_flutter/product/${VERSION}/${TARGET_OS}/Release/${PRODUCT_NAME}", # "tar -czf ${PRODUCT_NAME}-${TARGET_OS}-x86.tar.gz *" ] @@ -169,7 +169,7 @@ script = [""" cd appflowy_flutter/ flutter clean flutter pub get - flutter build ${TARGET_OS} --${BUILD_FLAG} --build-name=${APP_VERSION} + flutter build ${TARGET_OS} --${BUILD_FLAG} """] script_runner = "@shell"