mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge branch 'feat/tauri-move-fields' into feat/tauri-grid
# Conflicts: # frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/DatePickerPopup.tsx # frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditCellWrapper.tsx # frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditCheckboxCell.tsx # frontend/appflowy_tauri/src/appflowy_app/components/_shared/EditRow/EditRow.tsx # frontend/appflowy_tauri/src/appflowy_app/components/board/BoardCell.tsx # frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_bd_svc.ts # frontend/appflowy_tauri/src/appflowy_app/stores/effects/database/database_controller.ts
This commit is contained in:
commit
ed977868cf
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -0,0 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="16" height="16" rx="8" fill="#00BCF0"/>
|
||||
<rect x="7.5" y="4" width="1" height="8" rx="0.5" fill="#131720"/>
|
||||
<rect x="12" y="7.5" width="1" height="8" rx="0.5" transform="rotate(90 12 7.5)" fill="#131720"/>
|
||||
</svg>
|
After Width: | Height: | Size: 321 B |
@ -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": {
|
||||
|
@ -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": "排列方式"
|
||||
}
|
||||
}
|
||||
}
|
@ -184,7 +184,7 @@ class _BoardContentState extends State<BoardContent> {
|
||||
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<BoardContent> {
|
||||
width: 20,
|
||||
child: svgWidget(
|
||||
"home/add",
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
),
|
||||
),
|
||||
title: FlowyText.medium(
|
||||
|
@ -113,7 +113,7 @@ class _SettingItem extends StatelessWidget {
|
||||
},
|
||||
leftIcon: svgWidget(
|
||||
action.iconName(),
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -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,
|
||||
);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class _DisclosureButtonState extends State<DisclosureButton> {
|
||||
width: 20,
|
||||
icon: svgWidget(
|
||||
"editor/details",
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
),
|
||||
onPressed: () => controller.show(),
|
||||
);
|
||||
|
@ -76,7 +76,7 @@ class _AddFilterButtonState extends State<AddFilterButton> {
|
||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||
leftIcon: svgWidget(
|
||||
"home/add",
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
),
|
||||
onTap: () => popoverController.show(),
|
||||
),
|
||||
|
@ -19,7 +19,7 @@ class GridAddRowButton extends StatelessWidget {
|
||||
onTap: () => context.read<GridBloc>().add(const GridEvent.createRow()),
|
||||
leftIcon: svgWidget(
|
||||
"home/add",
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -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: [
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -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
|
||||
|
@ -67,7 +67,7 @@ class _ActionCell extends StatelessWidget {
|
||||
},
|
||||
leftIcon: svgWidget(
|
||||
action.iconName(),
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -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(
|
||||
|
@ -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: () {
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -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<PrimaryCellAccessory>
|
||||
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<AccessoryHover> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Widget> 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<AccessoryHoverState>(
|
||||
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<GridCellAccessoryBuilder> accessories;
|
||||
const CellAccessoryContainer({required this.accessories, Key? key})
|
||||
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -32,6 +32,7 @@ class _FontSizeSwitcherState extends State<FontSizeSwitcher> {
|
||||
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<FontSizeSwitcher> {
|
||||
_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,
|
||||
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ class _BuiltInPageWidgetState extends State<BuiltInPageWidget> {
|
||||
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<BuiltInPageWidget> {
|
||||
iconPadding: const EdgeInsets.all(3),
|
||||
icon: svgWidget(
|
||||
'common/settings',
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
color: Theme.of(context).iconTheme.color,
|
||||
),
|
||||
onPressed: () => controller.show(),
|
||||
);
|
||||
|
@ -149,7 +149,7 @@ class _LinkToPageMenuState extends State<LinkToPageMenu> {
|
||||
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),
|
||||
|
@ -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,
|
||||
|
@ -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<ChangeCoverPopover> {
|
||||
late Future<List<String>>? 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<String> path) {
|
||||
setState(() {
|
||||
isAddingImage = false;
|
||||
});
|
||||
})
|
||||
: _buildCoverSelection(),
|
||||
return BlocProvider(
|
||||
create: (context) => ChangeCoverPopoverBloc()
|
||||
..add(const ChangeCoverPopoverEvent.fetchPickedImagePaths()),
|
||||
child: BlocBuilder<ChangeCoverPopoverBloc, ChangeCoverPopoverState>(
|
||||
builder: (context, state) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: SingleChildScrollView(
|
||||
child: isAddingImage
|
||||
? CoverImagePicker(
|
||||
onBackPressed: () => setState(() {
|
||||
isAddingImage = false;
|
||||
}),
|
||||
onFileSubmit: (List<String> path) {
|
||||
context.read<ChangeCoverPopoverBloc>().add(
|
||||
const ChangeCoverPopoverEvent
|
||||
.fetchPickedImagePaths());
|
||||
setState(() {
|
||||
isAddingImage = false;
|
||||
});
|
||||
})
|
||||
: _buildCoverSelection(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -104,21 +111,55 @@ class _ChangeCoverPopoverState extends State<ChangeCoverPopover> {
|
||||
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<ChangeCoverPopoverBloc, ChangeCoverPopoverState>(
|
||||
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<ChangeCoverPopoverBloc>()
|
||||
.add(const ChangeCoverPopoverEvent.clearAllImages());
|
||||
},
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildAbstractImagePicker() {
|
||||
return GridView.builder(
|
||||
shrinkWrap: true,
|
||||
@ -173,71 +214,59 @@ class _ChangeCoverPopoverState extends State<ChangeCoverPopover> {
|
||||
}
|
||||
|
||||
Widget _buildFileImagePicker() {
|
||||
return FutureBuilder<List<String>>(
|
||||
future: _getPreviouslyPickedImagePaths(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
List<String> 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<ChangeCoverPopoverBloc, ChangeCoverPopoverState>(
|
||||
builder: (context, state) {
|
||||
if (state is Loaded) {
|
||||
List<String> 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<ColorOption> _generateBackgroundColorOptions(EditorState editorState) {
|
||||
@ -248,19 +277,75 @@ class _ChangeCoverPopoverState extends State<ChangeCoverPopover> {
|
||||
))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<String>> _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<ImageGridItem> createState() => _ImageGridItemState();
|
||||
}
|
||||
|
||||
class _ImageGridItemState extends State<ImageGridItem> {
|
||||
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<ChangeCoverPopoverBloc>().add(
|
||||
ChangeCoverPopoverEvent.deleteImage(widget.imagePath));
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<ChangeCoverPopoverEvent, ChangeCoverPopoverState> {
|
||||
late final SharedPreferences _prefs;
|
||||
final _initCompleter = Completer<void>();
|
||||
ChangeCoverPopoverBloc() : super(const ChangeCoverPopoverState.initial()) {
|
||||
SharedPreferences.getInstance().then((prefs) {
|
||||
_prefs = prefs;
|
||||
_initCompleter.complete();
|
||||
});
|
||||
on<ChangeCoverPopoverEvent>((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<List<String>> _getPreviouslyPickedImagePaths() async {
|
||||
await _initCompleter.future;
|
||||
final imageNames = _prefs.getStringList(kLocalImagesKey) ?? [];
|
||||
if (imageNames.isEmpty) {
|
||||
return imageNames;
|
||||
}
|
||||
imageNames.removeWhere((name) => !File(name).existsSync());
|
||||
return imageNames;
|
||||
}
|
||||
|
||||
Future<void> _updateImagePathsInStorage(List<String> imagePaths) async {
|
||||
await _initCompleter.future;
|
||||
_prefs.setStringList(kLocalImagesKey, imagePaths);
|
||||
return;
|
||||
}
|
||||
|
||||
Future<void> _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<String> imageNames,
|
||||
) = Loaded;
|
||||
}
|
@ -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);
|
||||
|
@ -17,7 +17,7 @@ SelectionMenuItem gridMenuItem = SelectionMenuItem(
|
||||
: editorState.editorStyle.selectionMenuItemIconColor,
|
||||
);
|
||||
},
|
||||
keywords: ['referenced grid'],
|
||||
keywords: ['referenced', 'grid'],
|
||||
handler: (editorState, menuService, context) {
|
||||
showLinkToPageMenu(
|
||||
editorState,
|
||||
|
@ -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()),
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -90,6 +90,7 @@ class _TrashPageState extends State<TrashPage> {
|
||||
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<TrashPage> {
|
||||
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<TrashBloc>().add(
|
||||
const TrashEvent.restoreAll(),
|
||||
@ -110,7 +111,7 @@ class _TrashPageState extends State<TrashPage> {
|
||||
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<TrashBloc>().add(const TrashEvent.deleteAll()),
|
||||
|
@ -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'),
|
||||
|
@ -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<FolderWidget> {
|
||||
|
||||
@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: <Widget>[
|
||||
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<CreateFolderWidget> {
|
||||
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<FilePickerService>().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<SettingsLocationCubit>().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<SettingsLocationCubit>().setLocation(_path);
|
||||
await widget.onPressedCreate();
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
@ -240,12 +221,70 @@ class CreateFolderWidgetState extends State<CreateFolderWidget> {
|
||||
|
||||
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!,
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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<SkipLogInScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: const _SkipLoginMoveWindow(),
|
||||
body: Center(
|
||||
child: _renderBody(context),
|
||||
),
|
||||
@ -54,9 +54,13 @@ class _SkipLogInScreenState extends State<SkipLogInScreen> {
|
||||
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<SkipLogInScreen> {
|
||||
},
|
||||
),
|
||||
),
|
||||
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<SkipLogInScreen> {
|
||||
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<SkipLogInScreen> {
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ class FlowyLogoTitle extends StatelessWidget {
|
||||
FlowyText.semibold(
|
||||
title,
|
||||
fontSize: FontSizes.s24,
|
||||
color: Theme.of(context).colorScheme.tertiary,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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<AppBloc>().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,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -24,6 +24,7 @@ Future<void> showImportPanel(
|
||||
title: FlowyText.semibold(
|
||||
LocaleKeys.moreAction_import.tr(),
|
||||
fontSize: 20,
|
||||
color: Theme.of(context).colorScheme.tertiary,
|
||||
),
|
||||
content: _ImportPanel(importCallback: callback),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
|
@ -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<ViewBloc>().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<Widget> 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);
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
@ -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<MenuUserBloc>().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,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -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),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -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<SettingsDialogBloc>().state.page,
|
||||
),
|
||||
),
|
||||
const VerticalDivider(),
|
||||
VerticalDivider(
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: getSettingsView(
|
||||
|
@ -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) {
|
||||
|
@ -47,7 +47,7 @@ class _LanguageSelectorDropdownState extends State<LanguageSelectorDropdown> {
|
||||
|
||||
void hoverEnterLanguage() {
|
||||
setState(() {
|
||||
currHoverColor = Theme.of(context).colorScheme.primary;
|
||||
currHoverColor = Theme.of(context).colorScheme.secondaryContainer;
|
||||
});
|
||||
}
|
||||
|
||||
@ -67,6 +67,7 @@ class _LanguageSelectorDropdownState extends State<LanguageSelectorDropdown> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
||||
child: DropdownButton<Locale>(
|
||||
value: context.locale,
|
||||
dropdownColor: Theme.of(context).cardColor,
|
||||
onChanged: (locale) {
|
||||
context
|
||||
.read<AppearanceSettingsCubit>()
|
||||
@ -80,7 +81,10 @@ class _LanguageSelectorDropdownState extends State<LanguageSelectorDropdown> {
|
||||
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(),
|
||||
|
@ -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),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -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 '📋';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<ToolbarItem> 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<ToolbarItem> 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<ToolbarItem> 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<ToolbarItem> 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<ToolbarItem> 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<ToolbarItem> 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<ToolbarItem> 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,
|
||||
|
@ -21,6 +21,7 @@ class ToolbarItemWidget extends StatelessWidget {
|
||||
width: 28,
|
||||
height: 28,
|
||||
child: Tooltip(
|
||||
textAlign: TextAlign.center,
|
||||
preferBelow: false,
|
||||
message: item.tooltipsMessage,
|
||||
child: MouseRegion(
|
||||
|
@ -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.
|
||||
|
@ -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<TextNode>();
|
||||
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;
|
||||
|
@ -307,6 +307,11 @@ List<ShortcutEvent> builtInShortcutEvents = [
|
||||
character: '_',
|
||||
handler: underscoreToItalicHandler,
|
||||
),
|
||||
ShortcutEvent(
|
||||
key: 'Asterisk to italic',
|
||||
character: '*',
|
||||
handler: asteriskToItalicHandler,
|
||||
),
|
||||
ShortcutEvent(
|
||||
key: 'Double asterisk to bold',
|
||||
character: '*',
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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":
|
||||
|
@ -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),
|
||||
);
|
||||
|
||||
|
@ -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)),
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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<BaseStyledButton> {
|
||||
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),
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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(),
|
||||
|
@ -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<HTMLDivElement>(null);
|
||||
const [adjustedTop, setAdjustedTop] = useState(-100);
|
||||
// const [value, setValue] = useState();
|
||||
const { t } = useTranslation('');
|
||||
const [selectedDate, setSelectedDate] = useState<Date>(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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -76,7 +76,10 @@ export const EditCellWrapper = ({
|
||||
)}
|
||||
|
||||
{cellIdentifier.fieldType === FieldType.Checkbox && cellController && (
|
||||
<EditCheckboxCell data={data as boolean | undefined} cellController={cellController}></EditCheckboxCell>
|
||||
<EditCheckboxCell
|
||||
data={data as 'Yes' | 'No' | undefined}
|
||||
cellController={cellController}
|
||||
></EditCheckboxCell>
|
||||
)}
|
||||
|
||||
{cellIdentifier.fieldType === FieldType.DateTime && (
|
||||
|
@ -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<any, any>;
|
||||
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 (
|
||||
<div onClick={() => toggleValue()} className={'block px-4 py-2'}>
|
||||
<button className={'h-5 w-5'}>
|
||||
{data ? <EditorCheckSvg></EditorCheckSvg> : <EditorUncheckSvg></EditorUncheckSvg>}
|
||||
{data === 'Yes' ? <EditorCheckSvg></EditorCheckSvg> : <EditorUncheckSvg></EditorUncheckSvg>}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
@ -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 (
|
||||
|
@ -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 ? (
|
||||
<CellOptions
|
||||
data={data as SelectOptionCellDataPB}
|
||||
onEditClick={(top: number, left: number) => {
|
||||
console.log(top, left);
|
||||
}}
|
||||
/>
|
||||
<BoardOptionsCell
|
||||
cellIdentifier={cellIdentifier}
|
||||
cellCache={cellCache}
|
||||
fieldController={fieldController}
|
||||
></BoardOptionsCell>
|
||||
) : cellIdentifier.fieldType === FieldType.DateTime ? (
|
||||
<BoardDateCell
|
||||
cellIdentifier={cellIdentifier}
|
||||
@ -43,6 +39,12 @@ export const BoardCell = ({
|
||||
cellCache={cellCache}
|
||||
fieldController={fieldController}
|
||||
></BoardUrlCell>
|
||||
) : cellIdentifier.fieldType === FieldType.Checkbox ? (
|
||||
<BoardCheckboxCell
|
||||
cellIdentifier={cellIdentifier}
|
||||
cellCache={cellCache}
|
||||
fieldController={fieldController}
|
||||
></BoardCheckboxCell>
|
||||
) : (
|
||||
<BoardTextCell
|
||||
cellIdentifier={cellIdentifier}
|
||||
|
@ -0,0 +1,23 @@
|
||||
import { EditorCheckSvg } from '$app/components/_shared/svg/EditorCheckSvg';
|
||||
import { EditorUncheckSvg } from '$app/components/_shared/svg/EditorUncheckSvg';
|
||||
import { CellIdentifier } from '$app/stores/effects/database/cell/cell_bd_svc';
|
||||
import { CellCache } from '$app/stores/effects/database/cell/cell_cache';
|
||||
import { FieldController } from '$app/stores/effects/database/field/field_controller';
|
||||
import { useCell } from '$app/components/_shared/database-hooks/useCell';
|
||||
|
||||
export const BoardCheckboxCell = ({
|
||||
cellIdentifier,
|
||||
cellCache,
|
||||
fieldController,
|
||||
}: {
|
||||
cellIdentifier: CellIdentifier;
|
||||
cellCache: CellCache;
|
||||
fieldController: FieldController;
|
||||
}) => {
|
||||
const { data } = useCell(cellIdentifier, cellCache, fieldController);
|
||||
return (
|
||||
<i className={'h-5 w-5'}>
|
||||
{data === 'Yes' ? <EditorCheckSvg></EditorCheckSvg> : <EditorUncheckSvg></EditorUncheckSvg>}
|
||||
</i>
|
||||
);
|
||||
};
|
@ -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<Option<CheckboxCellController>> {
|
||||
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,
|
||||
|
@ -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 = () => {
|
||||
<TestEditCell></TestEditCell>
|
||||
<TestEditTextCell></TestEditTextCell>
|
||||
<TestEditURLCell></TestEditURLCell>
|
||||
<TestEditDateCell></TestEditDateCell>
|
||||
<TestEditCheckboxCell></TestEditCheckboxCell>
|
||||
<TestCreateSelectOptionInCell></TestCreateSelectOptionInCell>
|
||||
<TestGetSingleSelectFieldData></TestGetSingleSelectFieldData>
|
||||
<TestEditField></TestEditField>
|
||||
<TestMoveField></TestMoveField>
|
||||
<TestCreateNewField></TestCreateNewField>
|
||||
<TestDeleteField></TestDeleteField>
|
||||
<TestSwitchFromSingleSelectToNumber></TestSwitchFromSingleSelectToNumber>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user