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:
|
with:
|
||||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||||
asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_NAME }}
|
asset_path: ${{ env.LINUX_APP_RELEASE_PATH }}/${{ env.LINUX_PACKAGE_NAME }}
|
||||||
|
|
||||||
asset_name: ${{ env.LINUX_PACKAGE_NAME }}
|
asset_name: ${{ env.LINUX_PACKAGE_NAME }}
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
@ -352,3 +353,12 @@ jobs:
|
|||||||
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/appflowy_client:${{ github.ref_name }}
|
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/appflowy_client:${{ github.ref_name }}
|
||||||
cache-from: type=registry,ref=${{ secrets.DOCKER_HUB_USERNAME }}/af_build_cache:buildcache
|
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
|
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
|
# 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
|
## Version 0.1.1 - 03/21/2023
|
||||||
|
|
||||||
### New features
|
### New features
|
||||||
|
@ -23,7 +23,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
|||||||
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
||||||
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
||||||
LIB_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"
|
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite"
|
||||||
PRODUCT_NAME = "AppFlowy"
|
PRODUCT_NAME = "AppFlowy"
|
||||||
# CRATE_TYPE: https://doc.rust-lang.org/reference/linkage.html
|
# 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",
|
"exportDatabase": "Export database",
|
||||||
"selectFiles": "Select the files that need to be export",
|
"selectFiles": "Select the files that need to be export",
|
||||||
"createNewFolder": "Create a new folder",
|
"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",
|
"open": "Open",
|
||||||
"openFolder": "Open an existing folder",
|
"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",
|
"folderHintText": "folder name",
|
||||||
"location": "Creating a new folder",
|
"location": "Creating a new folder",
|
||||||
"locationDesc": "Pick a name for your AppFlowy data folder",
|
"locationDesc": "Pick a name for your AppFlowy data folder",
|
||||||
@ -366,6 +366,7 @@
|
|||||||
"changeCover": "Change Cover",
|
"changeCover": "Change Cover",
|
||||||
"colors": "Colors",
|
"colors": "Colors",
|
||||||
"images": "Images",
|
"images": "Images",
|
||||||
|
"clearAll": "Clear All",
|
||||||
"abstract": "Abstract",
|
"abstract": "Abstract",
|
||||||
"addCover": "Add Cover",
|
"addCover": "Add Cover",
|
||||||
"addLocalImage": "Add local image",
|
"addLocalImage": "Add local image",
|
||||||
@ -383,7 +384,6 @@
|
|||||||
"imageSavingFailed": "Image Saving Failed",
|
"imageSavingFailed": "Image Saving Failed",
|
||||||
"addIcon": "Add Icon"
|
"addIcon": "Add Icon"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"board": {
|
"board": {
|
||||||
|
@ -40,6 +40,13 @@
|
|||||||
"markdown": "Markdown",
|
"markdown": "Markdown",
|
||||||
"copyLink": "複製連結"
|
"copyLink": "複製連結"
|
||||||
},
|
},
|
||||||
|
"moreAction": {
|
||||||
|
"small": "小",
|
||||||
|
"medium": "中",
|
||||||
|
"large": "大",
|
||||||
|
"fontSize": "字體大小",
|
||||||
|
"import": "匯入"
|
||||||
|
},
|
||||||
"disclosureAction": {
|
"disclosureAction": {
|
||||||
"rename": "重新命名",
|
"rename": "重新命名",
|
||||||
"delete": "刪除",
|
"delete": "刪除",
|
||||||
@ -64,6 +71,7 @@
|
|||||||
},
|
},
|
||||||
"dialogCreatePageNameHint": "頁面名稱",
|
"dialogCreatePageNameHint": "頁面名稱",
|
||||||
"questionBubble": {
|
"questionBubble": {
|
||||||
|
"shortcuts": "快捷鍵",
|
||||||
"whatsNew": "新功能",
|
"whatsNew": "新功能",
|
||||||
"help": "幫助 & 支援",
|
"help": "幫助 & 支援",
|
||||||
"debug": {
|
"debug": {
|
||||||
@ -90,11 +98,21 @@
|
|||||||
"inlineCode": "程式碼",
|
"inlineCode": "程式碼",
|
||||||
"quote": "區塊引言",
|
"quote": "區塊引言",
|
||||||
"header": "標題",
|
"header": "標題",
|
||||||
"highlight": "反白"
|
"highlight": "反白",
|
||||||
|
"color": "顏色"
|
||||||
},
|
},
|
||||||
"tooltip": {
|
"tooltip": {
|
||||||
"lightMode": "切換至亮色模式",
|
"lightMode": "切換至亮色模式",
|
||||||
"darkMode": "切換至暗色模式"
|
"darkMode": "切換至暗色模式",
|
||||||
|
"openAsPage": "以頁面開啓",
|
||||||
|
"addNewRow": "新增列表",
|
||||||
|
"openMenu": "點擊開啓選單",
|
||||||
|
"viewDataBase": "查看資料庫",
|
||||||
|
"referencePage": "這個 {name} 已參照"
|
||||||
|
},
|
||||||
|
"sideBar": {
|
||||||
|
"closeSidebar": "關閉側邊欄",
|
||||||
|
"openSidebar": "開啓側邊欄"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"export": {
|
"export": {
|
||||||
@ -114,7 +132,14 @@
|
|||||||
"signIn": "登入",
|
"signIn": "登入",
|
||||||
"signOut": "登出",
|
"signOut": "登出",
|
||||||
"complete": "完成",
|
"complete": "完成",
|
||||||
"save": "儲存"
|
"save": "儲存",
|
||||||
|
"generate": "產生",
|
||||||
|
"esc": "離開",
|
||||||
|
"keep": "保存",
|
||||||
|
"tryAgain": "再試一次",
|
||||||
|
"discard": "放棄變更",
|
||||||
|
"replace": "取代",
|
||||||
|
"insertBelow": "在下面插入"
|
||||||
},
|
},
|
||||||
"label": {
|
"label": {
|
||||||
"welcome": "歡迎!",
|
"welcome": "歡迎!",
|
||||||
@ -142,22 +167,99 @@
|
|||||||
"appearance": "外觀",
|
"appearance": "外觀",
|
||||||
"language": "語言",
|
"language": "語言",
|
||||||
"user": "使用者",
|
"user": "使用者",
|
||||||
|
"files": "檔案",
|
||||||
"open": "開啟設定"
|
"open": "開啟設定"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"themeMode": {
|
"themeMode": {
|
||||||
"label": "Theme Mode",
|
"label": "主題模式",
|
||||||
"light": "亮色模式",
|
"light": "亮色模式",
|
||||||
"dark": "暗色模式",
|
"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": {
|
"grid": {
|
||||||
"settings": {
|
"settings": {
|
||||||
"filter": "篩選",
|
"filter": "篩選",
|
||||||
|
"sort": "排序",
|
||||||
"sortBy": "排序方式",
|
"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": {
|
"field": {
|
||||||
"hide": "隱藏",
|
"hide": "隱藏",
|
||||||
@ -172,6 +274,7 @@
|
|||||||
"singleSelectFieldName": "單選",
|
"singleSelectFieldName": "單選",
|
||||||
"multiSelectFieldName": "多選",
|
"multiSelectFieldName": "多選",
|
||||||
"urlFieldName": "網址",
|
"urlFieldName": "網址",
|
||||||
|
"checklistFieldName": "核取列表",
|
||||||
"numberFormat": "數字格式",
|
"numberFormat": "數字格式",
|
||||||
"dateFormat": "日期格式",
|
"dateFormat": "日期格式",
|
||||||
"includeTime": "包含時間",
|
"includeTime": "包含時間",
|
||||||
@ -186,13 +289,23 @@
|
|||||||
"addSelectOption": "新增選項",
|
"addSelectOption": "新增選項",
|
||||||
"optionTitle": "選項",
|
"optionTitle": "選項",
|
||||||
"addOption": "新增選項",
|
"addOption": "新增選項",
|
||||||
"editProperty": "編輯內容"
|
"editProperty": "編輯內容",
|
||||||
|
"newColumn": "新欄位",
|
||||||
|
"deleteFieldPromptMessage": "你確定嗎?這個內容將被刪除"
|
||||||
|
},
|
||||||
|
"sort": {
|
||||||
|
"ascending": "升冪排序",
|
||||||
|
"descending": "降冪排序",
|
||||||
|
"deleteSort": "刪除排序",
|
||||||
|
"addSort": "新增排序"
|
||||||
},
|
},
|
||||||
"row": {
|
"row": {
|
||||||
"duplicate": "複製",
|
"duplicate": "複製",
|
||||||
"delete": "刪除",
|
"delete": "刪除",
|
||||||
"textPlaceholder": "空",
|
"textPlaceholder": "空",
|
||||||
"copyProperty": "已將內容複製至剪貼簿"
|
"copyProperty": "已將內容複製至剪貼簿",
|
||||||
|
"count": "Count",
|
||||||
|
"newRow": "新列表"
|
||||||
},
|
},
|
||||||
"selectOption": {
|
"selectOption": {
|
||||||
"create": "建立",
|
"create": "建立",
|
||||||
@ -210,6 +323,9 @@
|
|||||||
"panelTitle": "搜尋或建立選項",
|
"panelTitle": "搜尋或建立選項",
|
||||||
"searchOption": "搜尋選項"
|
"searchOption": "搜尋選項"
|
||||||
},
|
},
|
||||||
|
"checklist": {
|
||||||
|
"panelTitle": "新增物件"
|
||||||
|
},
|
||||||
"menuName": "網格"
|
"menuName": "網格"
|
||||||
},
|
},
|
||||||
"document": {
|
"document": {
|
||||||
@ -217,10 +333,78 @@
|
|||||||
"date": {
|
"date": {
|
||||||
"timeHintTextInTwelveHour": "01:00 PM",
|
"timeHintTextInTwelveHour": "01:00 PM",
|
||||||
"timeHintTextInTwentyFourHour": "13:00"
|
"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": {
|
"board": {
|
||||||
"openSidebar": "Open sidebar",
|
"column": {
|
||||||
"closeSidebar": "Close sidebar"
|
"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,
|
width: 20,
|
||||||
child: svgWidget(
|
child: svgWidget(
|
||||||
"home/add",
|
"home/add",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onAddButtonClick: () {
|
onAddButtonClick: () {
|
||||||
@ -207,7 +207,7 @@ class _BoardContentState extends State<BoardContent> {
|
|||||||
width: 20,
|
width: 20,
|
||||||
child: svgWidget(
|
child: svgWidget(
|
||||||
"home/add",
|
"home/add",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
title: FlowyText.medium(
|
title: FlowyText.medium(
|
||||||
|
@ -113,7 +113,7 @@ class _SettingItem extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
action.iconName(),
|
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,
|
iconPadding: EdgeInsets.zero,
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
"home/add",
|
"home/add",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
width: 22,
|
width: 22,
|
||||||
);
|
);
|
||||||
|
@ -43,7 +43,7 @@ class ChoiceChipButton extends StatelessWidget {
|
|||||||
radius: const BorderRadius.all(Radius.circular(14)),
|
radius: const BorderRadius.all(Radius.circular(14)),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
filterInfo.fieldInfo.fieldType.iconName(),
|
filterInfo.fieldInfo.fieldType.iconName(),
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
rightIcon: _ChoicechipFilterDesc(filterDesc: filterDesc),
|
rightIcon: _ChoicechipFilterDesc(filterDesc: filterDesc),
|
||||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
|
@ -162,7 +162,7 @@ class _FilterPropertyCell extends StatelessWidget {
|
|||||||
onTap: () => onTap(fieldInfo),
|
onTap: () => onTap(fieldInfo),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
fieldInfo.fieldType.iconName(),
|
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,
|
width: 20,
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
"editor/details",
|
"editor/details",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
onPressed: () => controller.show(),
|
onPressed: () => controller.show(),
|
||||||
);
|
);
|
||||||
|
@ -76,7 +76,7 @@ class _AddFilterButtonState extends State<AddFilterButton> {
|
|||||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
"home/add",
|
"home/add",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
onTap: () => popoverController.show(),
|
onTap: () => popoverController.show(),
|
||||||
),
|
),
|
||||||
|
@ -19,7 +19,7 @@ class GridAddRowButton extends StatelessWidget {
|
|||||||
onTap: () => context.read<GridBloc>().add(const GridEvent.createRow()),
|
onTap: () => context.read<GridBloc>().add(const GridEvent.createRow()),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
"home/add",
|
"home/add",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ class FieldCellButton extends StatelessWidget {
|
|||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
field.fieldType.iconName(),
|
field.fieldType.iconName(),
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
radius: BorderRadius.zero,
|
radius: BorderRadius.zero,
|
||||||
text: FlowyText.medium(
|
text: FlowyText.medium(
|
||||||
|
@ -61,7 +61,7 @@ class FieldTypeCell extends StatelessWidget {
|
|||||||
onTap: () => onSelectField(fieldType),
|
onTap: () => onSelectField(fieldType),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
fieldType.iconName(),
|
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,
|
margin: GridSize.typeOptionContentInsets,
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
bloc.state.field.fieldType.iconName(),
|
bloc.state.field.fieldType.iconName(),
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
rightIcon: svgWidget(
|
rightIcon: svgWidget(
|
||||||
"grid/more",
|
"grid/more",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ class CreateFieldButton extends StatelessWidget {
|
|||||||
onTap: () {},
|
onTap: () {},
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
"home/add",
|
"home/add",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
popupBuilder: (BuildContext popover) {
|
popupBuilder: (BuildContext popover) {
|
||||||
|
@ -153,7 +153,7 @@ class DateFormatButton extends StatelessWidget {
|
|||||||
onHover: onHover,
|
onHover: onHover,
|
||||||
rightIcon: svgWidget(
|
rightIcon: svgWidget(
|
||||||
"grid/more",
|
"grid/more",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -184,7 +184,7 @@ class TimeFormatButton extends StatelessWidget {
|
|||||||
onHover: onHover,
|
onHover: onHover,
|
||||||
rightIcon: svgWidget(
|
rightIcon: svgWidget(
|
||||||
"grid/more",
|
"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,
|
margin: GridSize.typeOptionContentInsets,
|
||||||
rightIcon: svgWidget(
|
rightIcon: svgWidget(
|
||||||
"grid/more",
|
"grid/more",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
text: Row(
|
text: Row(
|
||||||
children: [
|
children: [
|
||||||
|
@ -194,7 +194,7 @@ class _OptionCellState extends State<_OptionCell> {
|
|||||||
padding: const EdgeInsets.symmetric(horizontal: 6.0),
|
padding: const EdgeInsets.symmetric(horizontal: 6.0),
|
||||||
child: svgWidget(
|
child: svgWidget(
|
||||||
"grid/details",
|
"grid/details",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -251,7 +251,7 @@ class _AddOptionButton extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
"home/add",
|
"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()),
|
text: FlowyText.medium(LocaleKeys.grid_selectOption_deleteTag.tr()),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
"grid/delete",
|
"grid/delete",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context
|
context
|
||||||
|
@ -67,7 +67,7 @@ class _ActionCell extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
action.iconName(),
|
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),
|
onTap: () => onTap(fieldInfo),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
fieldInfo.fieldType.iconName(),
|
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,
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
"home/close",
|
"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(),
|
onTap: () => _popoverController.show(),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
"home/add",
|
"home/add",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -222,7 +222,7 @@ class _DeleteSortButton extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
"editor/delete",
|
"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 text = LocaleKeys.grid_settings_sort.tr();
|
||||||
final leftIcon = svgWidget(
|
final leftIcon = svgWidget(
|
||||||
"grid/setting/sort",
|
"grid/setting/sort",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
);
|
);
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
|
@ -82,7 +82,7 @@ class _GridGroupCell extends StatelessWidget {
|
|||||||
text: FlowyText.medium(fieldInfo.name),
|
text: FlowyText.medium(fieldInfo.name),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
fieldInfo.fieldType.iconName(),
|
fieldInfo.fieldType.iconName(),
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
rightIcon: rightIcon,
|
rightIcon: rightIcon,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
@ -96,7 +96,7 @@ class _GridPropertyCellState extends State<_GridPropertyCell> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final checkmark = svgWidget(
|
final checkmark = svgWidget(
|
||||||
widget.fieldInfo.visibility ? 'home/show' : 'home/hide',
|
widget.fieldInfo.visibility ? 'home/show' : 'home/hide',
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
);
|
);
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
@ -118,7 +118,7 @@ class _GridPropertyCellState extends State<_GridPropertyCell> {
|
|||||||
text: FlowyText.medium(widget.fieldInfo.name),
|
text: FlowyText.medium(widget.fieldInfo.name),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
widget.fieldInfo.fieldType.iconName(),
|
widget.fieldInfo.fieldType.iconName(),
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
rightIcon: FlowyIconButton(
|
rightIcon: FlowyIconButton(
|
||||||
hoverColor: Colors.transparent,
|
hoverColor: Colors.transparent,
|
||||||
|
@ -78,7 +78,7 @@ class _SettingItem extends StatelessWidget {
|
|||||||
onTap: () => onAction(action),
|
onTap: () => onAction(action),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
action.iconName(),
|
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),
|
padding: const EdgeInsets.all(3.0),
|
||||||
child: svgWidget(
|
child: svgWidget(
|
||||||
'grid/details',
|
'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),
|
padding: const EdgeInsets.all(3.0),
|
||||||
child: svgWidget(
|
child: svgWidget(
|
||||||
'editor/edit',
|
'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:flowy_infra_ui/style_widget/hover.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flowy_infra/size.dart';
|
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:textstyle_extensions/textstyle_extensions.dart';
|
|
||||||
|
|
||||||
import '../cell_builder.dart';
|
import '../cell_builder.dart';
|
||||||
|
|
||||||
@ -69,7 +67,6 @@ class _PrimaryCellAccessoryState extends State<PrimaryCellAccessory>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Tooltip(
|
return Tooltip(
|
||||||
message: LocaleKeys.tooltip_openAsPage.tr(),
|
message: LocaleKeys.tooltip_openAsPage.tr(),
|
||||||
textStyle: AFThemeExtension.of(context).caption.textColor(Colors.white),
|
|
||||||
child: svgWidget(
|
child: svgWidget(
|
||||||
"grid/expander",
|
"grid/expander",
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
@ -125,7 +122,6 @@ class _AccessoryHoverState extends State<AccessoryHover> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<Widget> children = [
|
List<Widget> children = [
|
||||||
const _Background(),
|
|
||||||
Padding(padding: widget.contentPadding, child: widget.child),
|
Padding(padding: widget.contentPadding, child: widget.child),
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -173,28 +169,6 @@ class AccessoryHoverState extends ChangeNotifier {
|
|||||||
bool get onHover => _onHover;
|
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 {
|
class CellAccessoryContainer extends StatelessWidget {
|
||||||
final List<GridCellAccessoryBuilder> accessories;
|
final List<GridCellAccessoryBuilder> accessories;
|
||||||
const CellAccessoryContainer({required this.accessories, Key? key})
|
const CellAccessoryContainer({required this.accessories, Key? key})
|
||||||
|
@ -137,7 +137,7 @@ class _ChecklistOptionCellState extends State<_ChecklistOptionCell> {
|
|||||||
iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2),
|
iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2),
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
"editor/details",
|
"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,
|
leftChevronPadding: EdgeInsets.zero,
|
||||||
leftChevronIcon: svgWidget(
|
leftChevronIcon: svgWidget(
|
||||||
"home/arrow_left",
|
"home/arrow_left",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
rightChevronPadding: EdgeInsets.zero,
|
rightChevronPadding: EdgeInsets.zero,
|
||||||
rightChevronMargin: EdgeInsets.zero,
|
rightChevronMargin: EdgeInsets.zero,
|
||||||
rightChevronIcon: svgWidget(
|
rightChevronIcon: svgWidget(
|
||||||
"home/arrow_right",
|
"home/arrow_right",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
headerMargin: const EdgeInsets.only(bottom: 8.0),
|
headerMargin: const EdgeInsets.only(bottom: 8.0),
|
||||||
),
|
),
|
||||||
@ -254,7 +254,7 @@ class _IncludeTimeButton extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
svgWidget(
|
svgWidget(
|
||||||
"grid/clock",
|
"grid/clock",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
const HSpace(4),
|
const HSpace(4),
|
||||||
FlowyText.medium(LocaleKeys.grid_field_includeTime.tr()),
|
FlowyText.medium(LocaleKeys.grid_field_includeTime.tr()),
|
||||||
@ -387,7 +387,7 @@ class _DateTypeOptionButton extends StatelessWidget {
|
|||||||
margin: GridSize.typeOptionContentInsets,
|
margin: GridSize.typeOptionContentInsets,
|
||||||
rightIcon: svgWidget(
|
rightIcon: svgWidget(
|
||||||
"grid/more",
|
"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,
|
hoverColor: Colors.transparent,
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
'home/close',
|
'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),
|
iconPadding: const EdgeInsets.symmetric(horizontal: 6.0),
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
"editor/details",
|
"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),
|
offset: const Offset(0, 8),
|
||||||
child: svgWidget(
|
child: svgWidget(
|
||||||
"editor/edit",
|
"editor/edit",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
popupBuilder: (BuildContext popoverContext) {
|
popupBuilder: (BuildContext popoverContext) {
|
||||||
return URLEditorPopover(
|
return URLEditorPopover(
|
||||||
@ -246,7 +246,7 @@ class _CopyURLAccessoryState extends State<_CopyURLAccessory>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return svgWidget(
|
return svgWidget(
|
||||||
"editor/copy",
|
"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),
|
iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2),
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
"home/close",
|
"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,
|
contentPadding: EdgeInsets.zero,
|
||||||
bgColor: Colors.transparent,
|
bgColor: Colors.transparent,
|
||||||
hoverColor: Theme.of(context).colorScheme.primary,
|
hoverColor: Theme.of(context).colorScheme.primary,
|
||||||
downColor: Theme.of(context).colorScheme.primaryContainer,
|
highlightColor:
|
||||||
|
Theme.of(context).colorScheme.primaryContainer,
|
||||||
outlineColor: Colors.white,
|
outlineColor: Colors.white,
|
||||||
borderRadius: Corners.s8Border,
|
borderRadius: Corners.s8Border,
|
||||||
onPressed: onRestore,
|
onPressed: onRestore,
|
||||||
@ -50,7 +51,7 @@ class DocumentBanner extends StatelessWidget {
|
|||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
bgColor: Colors.transparent,
|
bgColor: Colors.transparent,
|
||||||
hoverColor: Theme.of(context).colorScheme.primaryContainer,
|
hoverColor: Theme.of(context).colorScheme.primaryContainer,
|
||||||
downColor: Theme.of(context).colorScheme.primary,
|
highlightColor: Theme.of(context).colorScheme.primary,
|
||||||
outlineColor: Colors.white,
|
outlineColor: Colors.white,
|
||||||
borderRadius: Corners.s8Border,
|
borderRadius: Corners.s8Border,
|
||||||
onPressed: onDelete,
|
onPressed: onDelete,
|
||||||
|
@ -32,6 +32,7 @@ class _FontSizeSwitcherState extends State<FontSizeSwitcher> {
|
|||||||
FlowyText.semibold(
|
FlowyText.semibold(
|
||||||
LocaleKeys.moreAction_fontSize.tr(),
|
LocaleKeys.moreAction_fontSize.tr(),
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
color: Theme.of(context).colorScheme.tertiary,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 5,
|
height: 5,
|
||||||
@ -43,9 +44,8 @@ class _FontSizeSwitcherState extends State<FontSizeSwitcher> {
|
|||||||
_updateSelectedFontSize(_fontSizes[index].item2);
|
_updateSelectedFontSize(_fontSizes[index].item2);
|
||||||
},
|
},
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(5)),
|
borderRadius: const BorderRadius.all(Radius.circular(5)),
|
||||||
selectedBorderColor: Theme.of(context).colorScheme.primaryContainer,
|
selectedColor: Theme.of(context).colorScheme.tertiary,
|
||||||
selectedColor: Theme.of(context).colorScheme.onSurface,
|
fillColor: Theme.of(context).colorScheme.primary,
|
||||||
fillColor: Theme.of(context).colorScheme.primaryContainer,
|
|
||||||
color: Theme.of(context).hintColor,
|
color: Theme.of(context).hintColor,
|
||||||
constraints: const BoxConstraints(
|
constraints: const BoxConstraints(
|
||||||
minHeight: 40.0,
|
minHeight: 40.0,
|
||||||
|
@ -28,7 +28,7 @@ class DocumentMoreButton extends StatelessWidget {
|
|||||||
child: svgWidget(
|
child: svgWidget(
|
||||||
'editor/details',
|
'editor/details',
|
||||||
size: const Size(18, 18),
|
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),
|
iconPadding: const EdgeInsets.all(3),
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
'common/information',
|
'common/information',
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Name
|
// Name
|
||||||
@ -143,7 +143,7 @@ class _BuiltInPageWidgetState extends State<BuiltInPageWidget> {
|
|||||||
iconPadding: const EdgeInsets.all(3),
|
iconPadding: const EdgeInsets.all(3),
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
'common/settings',
|
'common/settings',
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
onPressed: () => controller.show(),
|
onPressed: () => controller.show(),
|
||||||
);
|
);
|
||||||
|
@ -149,7 +149,7 @@ class _LinkToPageMenuState extends State<LinkToPageMenu> {
|
|||||||
FlowyButton(
|
FlowyButton(
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
_iconName(value),
|
_iconName(value),
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
text: FlowyText.regular(value.name),
|
text: FlowyText.regular(value.name),
|
||||||
onTap: () => widget.onSelected(app.value1, value),
|
onTap: () => widget.onSelected(app.value1, value),
|
||||||
|
@ -18,7 +18,7 @@ SelectionMenuItem boardMenuItem = SelectionMenuItem(
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
// TODO(a-wallen): Translate keywords
|
// TODO(a-wallen): Translate keywords
|
||||||
keywords: ['referenced board', 'referenced kanban'],
|
keywords: ['referenced', 'board', 'kanban'],
|
||||||
handler: (editorState, menuService, context) {
|
handler: (editorState, menuService, context) {
|
||||||
showLinkToPageMenu(
|
showLinkToPageMenu(
|
||||||
editorState,
|
editorState,
|
||||||
|
@ -2,17 +2,20 @@ import 'dart:io';
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
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_image_picker.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/plugins/cover/cover_node_widget.dart';
|
import 'package:appflowy/plugins/document/presentation/plugins/cover/cover_node_widget.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
|
import 'package:appflowy_editor_plugins/appflowy_editor_plugins.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/size.dart';
|
import 'package:flowy_infra/size.dart';
|
||||||
import 'package:flowy_infra/theme_extension.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/icon_button.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
import 'package:flutter/material.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';
|
const String kLocalImagesKey = 'local_images';
|
||||||
|
|
||||||
@ -71,31 +74,35 @@ class CoverColorPicker extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ChangeCoverPopoverState extends State<ChangeCoverPopover> {
|
class _ChangeCoverPopoverState extends State<ChangeCoverPopover> {
|
||||||
late Future<List<String>>? fileImages;
|
|
||||||
bool isAddingImage = false;
|
bool isAddingImage = false;
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
fileImages = _getPreviouslyPickedImagePaths();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return BlocProvider(
|
||||||
padding: const EdgeInsets.all(15),
|
create: (context) => ChangeCoverPopoverBloc()
|
||||||
child: SingleChildScrollView(
|
..add(const ChangeCoverPopoverEvent.fetchPickedImagePaths()),
|
||||||
child: isAddingImage
|
child: BlocBuilder<ChangeCoverPopoverBloc, ChangeCoverPopoverState>(
|
||||||
? CoverImagePicker(
|
builder: (context, state) {
|
||||||
onBackPressed: () => setState(() {
|
return Padding(
|
||||||
isAddingImage = false;
|
padding: const EdgeInsets.all(15),
|
||||||
}),
|
child: SingleChildScrollView(
|
||||||
onFileSubmit: (List<String> path) {
|
child: isAddingImage
|
||||||
setState(() {
|
? CoverImagePicker(
|
||||||
isAddingImage = false;
|
onBackPressed: () => setState(() {
|
||||||
});
|
isAddingImage = false;
|
||||||
})
|
}),
|
||||||
: _buildCoverSelection(),
|
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(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
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),
|
const SizedBox(height: 10),
|
||||||
_buildColorPickerList(),
|
_buildColorPickerList(),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
FlowyText.semibold(LocaleKeys.document_plugins_cover_images.tr()),
|
_buildImageHeader(),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
_buildFileImagePicker(),
|
_buildFileImagePicker(),
|
||||||
const SizedBox(height: 10),
|
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),
|
const SizedBox(height: 10),
|
||||||
_buildAbstractImagePicker(),
|
_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() {
|
Widget _buildAbstractImagePicker() {
|
||||||
return GridView.builder(
|
return GridView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
@ -173,71 +214,59 @@ class _ChangeCoverPopoverState extends State<ChangeCoverPopover> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildFileImagePicker() {
|
Widget _buildFileImagePicker() {
|
||||||
return FutureBuilder<List<String>>(
|
return BlocBuilder<ChangeCoverPopoverBloc, ChangeCoverPopoverState>(
|
||||||
future: _getPreviouslyPickedImagePaths(),
|
builder: (context, state) {
|
||||||
builder: (context, snapshot) {
|
if (state is Loaded) {
|
||||||
if (snapshot.hasData) {
|
List<String> images = state.imageNames;
|
||||||
List<String> images = snapshot.data!;
|
return GridView.builder(
|
||||||
return GridView.builder(
|
shrinkWrap: true,
|
||||||
shrinkWrap: true,
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
crossAxisCount: 3,
|
||||||
crossAxisCount: 3,
|
childAspectRatio: 1 / 0.65,
|
||||||
childAspectRatio: 1 / 0.65,
|
crossAxisSpacing: 7,
|
||||||
crossAxisSpacing: 7,
|
mainAxisSpacing: 7,
|
||||||
mainAxisSpacing: 7,
|
),
|
||||||
),
|
itemCount: images.length + 1,
|
||||||
itemCount: images.length + 1,
|
itemBuilder: (BuildContext ctx, index) {
|
||||||
itemBuilder: (BuildContext ctx, index) {
|
if (index == 0) {
|
||||||
if (index == 0) {
|
return Container(
|
||||||
return Container(
|
decoration: BoxDecoration(
|
||||||
decoration: BoxDecoration(
|
color:
|
||||||
color: Theme.of(context)
|
Theme.of(context).colorScheme.primary.withOpacity(0.15),
|
||||||
.colorScheme
|
border: Border.all(
|
||||||
.primary
|
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,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
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) {
|
List<ColorOption> _generateBackgroundColorOptions(EditorState editorState) {
|
||||||
@ -248,19 +277,75 @@ class _ChangeCoverPopoverState extends State<ChangeCoverPopover> {
|
|||||||
))
|
))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<String>> _getPreviouslyPickedImagePaths() async {
|
class ImageGridItem extends StatefulWidget {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
const ImageGridItem({
|
||||||
final imageNames = prefs.getStringList(kLocalImagesKey) ?? [];
|
Key? key,
|
||||||
final removeNames = [];
|
required this.onImageSelect,
|
||||||
for (final name in imageNames) {
|
required this.imagePath,
|
||||||
if (!File(name).existsSync()) {
|
}) : super(key: key);
|
||||||
removeNames.add(name);
|
|
||||||
}
|
final Function() onImageSelect;
|
||||||
}
|
final String imagePath;
|
||||||
imageNames.removeWhere((element) => removeNames.contains(element));
|
|
||||||
prefs.setStringList(kLocalImagesKey, imageNames);
|
@override
|
||||||
return imageNames;
|
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),
|
leftIconSize: const Size.square(18),
|
||||||
onTap: widget.onTap,
|
onTap: widget.onTap,
|
||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
leftIcon: svgWidget(
|
leftIcon: const FlowySvg(name: 'editor/image'),
|
||||||
'editor/image',
|
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
|
||||||
),
|
|
||||||
text: FlowyText.regular(
|
text: FlowyText.regular(
|
||||||
LocaleKeys.document_plugins_cover_addCover.tr(),
|
LocaleKeys.document_plugins_cover_addCover.tr(),
|
||||||
),
|
),
|
||||||
@ -174,7 +171,7 @@ class _AddCoverButtonState extends State<_AddCoverButton> {
|
|||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
leftIcon: Icon(
|
leftIcon: Icon(
|
||||||
Icons.emoji_emotions_outlined,
|
Icons.emoji_emotions_outlined,
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
size: 18,
|
size: 18,
|
||||||
),
|
),
|
||||||
text: FlowyText.regular(LocaleKeys
|
text: FlowyText.regular(LocaleKeys
|
||||||
@ -197,8 +194,7 @@ class _AddCoverButtonState extends State<_AddCoverButton> {
|
|||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
leftIconSize: const Size.square(18),
|
leftIconSize: const Size.square(18),
|
||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
leftIcon: Icon(Icons.emoji_emotions_outlined,
|
leftIcon: const Icon(Icons.emoji_emotions_outlined,
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
|
||||||
size: 18),
|
size: 18),
|
||||||
text: FlowyText.regular(
|
text: FlowyText.regular(
|
||||||
LocaleKeys.document_plugins_cover_addIcon.tr()),
|
LocaleKeys.document_plugins_cover_addIcon.tr()),
|
||||||
@ -400,7 +396,7 @@ class _CoverImageState extends State<_CoverImage> {
|
|||||||
popoverController.show();
|
popoverController.show();
|
||||||
},
|
},
|
||||||
hoverColor: Theme.of(context).colorScheme.surface,
|
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),
|
fillColor: Theme.of(context).colorScheme.surface.withOpacity(0.8),
|
||||||
width: 120,
|
width: 120,
|
||||||
height: 28,
|
height: 28,
|
||||||
@ -422,7 +418,7 @@ class _CoverImageState extends State<_CoverImage> {
|
|||||||
width: 28,
|
width: 28,
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
'editor/delete',
|
'editor/delete',
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).colorScheme.tertiary,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
widget.onCoverChanged(CoverSelectionType.initial, null);
|
widget.onCoverChanged(CoverSelectionType.initial, null);
|
||||||
|
@ -17,7 +17,7 @@ SelectionMenuItem gridMenuItem = SelectionMenuItem(
|
|||||||
: editorState.editorStyle.selectionMenuItemIconColor,
|
: editorState.editorStyle.selectionMenuItemIconColor,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
keywords: ['referenced grid'],
|
keywords: ['referenced', 'grid'],
|
||||||
handler: (editorState, menuService, context) {
|
handler: (editorState, menuService, context) {
|
||||||
showLinkToPageMenu(
|
showLinkToPageMenu(
|
||||||
editorState,
|
editorState,
|
||||||
|
@ -45,13 +45,9 @@ class MenuTrash extends StatelessWidget {
|
|||||||
Widget _render(BuildContext context) {
|
Widget _render(BuildContext context) {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
const FlowySvg(
|
||||||
width: 16,
|
size: Size(16, 16),
|
||||||
height: 16,
|
name: 'home/trash',
|
||||||
child: svgWidget(
|
|
||||||
"home/trash",
|
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const HSpace(6),
|
const HSpace(6),
|
||||||
FlowyText.medium(LocaleKeys.trash_text.tr()),
|
FlowyText.medium(LocaleKeys.trash_text.tr()),
|
||||||
|
@ -43,7 +43,7 @@ class TrashCell extends StatelessWidget {
|
|||||||
iconPadding: const EdgeInsets.all(5),
|
iconPadding: const EdgeInsets.all(5),
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
"editor/restore",
|
"editor/restore",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const HSpace(20),
|
const HSpace(20),
|
||||||
@ -53,7 +53,7 @@ class TrashCell extends StatelessWidget {
|
|||||||
iconPadding: const EdgeInsets.all(5),
|
iconPadding: const EdgeInsets.all(5),
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
"editor/delete",
|
"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(
|
FlowyText.semibold(
|
||||||
LocaleKeys.trash_text.tr(),
|
LocaleKeys.trash_text.tr(),
|
||||||
fontSize: FontSizes.s16,
|
fontSize: FontSizes.s16,
|
||||||
|
color: Theme.of(context).colorScheme.tertiary,
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
IntrinsicWidth(
|
IntrinsicWidth(
|
||||||
@ -97,7 +98,7 @@ class _TrashPageState extends State<TrashPage> {
|
|||||||
text: FlowyText.medium(LocaleKeys.trash_restoreAll.tr()),
|
text: FlowyText.medium(LocaleKeys.trash_restoreAll.tr()),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
'editor/restore',
|
'editor/restore',
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
onTap: () => context.read<TrashBloc>().add(
|
onTap: () => context.read<TrashBloc>().add(
|
||||||
const TrashEvent.restoreAll(),
|
const TrashEvent.restoreAll(),
|
||||||
@ -110,7 +111,7 @@ class _TrashPageState extends State<TrashPage> {
|
|||||||
text: FlowyText.medium(LocaleKeys.trash_deleteAll.tr()),
|
text: FlowyText.medium(LocaleKeys.trash_deleteAll.tr()),
|
||||||
leftIcon: svgWidget(
|
leftIcon: svgWidget(
|
||||||
'editor/delete',
|
'editor/delete',
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
onTap: () =>
|
onTap: () =>
|
||||||
context.read<TrashBloc>().add(const TrashEvent.deleteAll()),
|
context.read<TrashBloc>().add(const TrashEvent.deleteAll()),
|
||||||
|
@ -46,6 +46,7 @@ class InitAppWidgetTask extends LaunchTask {
|
|||||||
Locale('sv'),
|
Locale('sv'),
|
||||||
Locale('tr', 'TR'),
|
Locale('tr', 'TR'),
|
||||||
Locale('zh', 'CN'),
|
Locale('zh', 'CN'),
|
||||||
|
Locale('zh', 'TW'),
|
||||||
],
|
],
|
||||||
path: 'assets/translations',
|
path: 'assets/translations',
|
||||||
fallbackLocale: const Locale('en'),
|
fallbackLocale: const Locale('en'),
|
||||||
|
@ -2,9 +2,7 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:appflowy/util/file_picker/file_picker_service.dart';
|
import 'package:appflowy/util/file_picker/file_picker_service.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text_field.dart';
|
|
||||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
|
|
||||||
@ -36,10 +34,7 @@ class _FolderWidgetState extends State<FolderWidget> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SizedBox(
|
return _mapIndexToWidget(context);
|
||||||
height: 250,
|
|
||||||
child: _mapIndexToWidget(context),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _mapIndexToWidget(BuildContext context) {
|
Widget _mapIndexToWidget(BuildContext context) {
|
||||||
@ -86,37 +81,24 @@ class FolderOptionsWidget extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListView(
|
return Column(
|
||||||
shrinkWrap: true,
|
children: [
|
||||||
children: <Widget>[
|
_FolderCard(
|
||||||
Card(
|
title: LocaleKeys.settings_files_createNewFolder.tr(),
|
||||||
child: ListTile(
|
subtitle: LocaleKeys.settings_files_createNewFolderDesc.tr(),
|
||||||
title: FlowyText.medium(
|
trailing: _buildTextButton(
|
||||||
LocaleKeys.settings_files_createNewFolder.tr(),
|
context,
|
||||||
),
|
LocaleKeys.settings_files_create.tr(),
|
||||||
subtitle: FlowyText.regular(
|
onPressedCreate,
|
||||||
LocaleKeys.settings_files_createNewFolderDesc.tr(),
|
|
||||||
),
|
|
||||||
trailing: _buildTextButton(
|
|
||||||
context,
|
|
||||||
LocaleKeys.settings_files_create.tr(),
|
|
||||||
onPressedCreate,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Card(
|
_FolderCard(
|
||||||
child: ListTile(
|
title: LocaleKeys.settings_files_openFolder.tr(),
|
||||||
title: FlowyText.medium(
|
subtitle: LocaleKeys.settings_files_openFolderDesc.tr(),
|
||||||
LocaleKeys.settings_files_openFolder.tr(),
|
trailing: _buildTextButton(
|
||||||
),
|
context,
|
||||||
subtitle: FlowyText.regular(
|
LocaleKeys.settings_files_open.tr(),
|
||||||
LocaleKeys.settings_files_openFolderDesc.tr(),
|
onPressedOpen,
|
||||||
),
|
|
||||||
trailing: _buildTextButton(
|
|
||||||
context,
|
|
||||||
LocaleKeys.settings_files_open.tr(),
|
|
||||||
onPressedOpen,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -164,56 +146,55 @@ class CreateFolderWidgetState extends State<CreateFolderWidget> {
|
|||||||
label: const Text('Back'),
|
label: const Text('Back'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Card(
|
_FolderCard(
|
||||||
child: ListTile(
|
title: LocaleKeys.settings_files_location.tr(),
|
||||||
title: FlowyText.medium(
|
subtitle: LocaleKeys.settings_files_locationDesc.tr(),
|
||||||
LocaleKeys.settings_files_location.tr(),
|
trailing: SizedBox(
|
||||||
),
|
width: 120,
|
||||||
subtitle: FlowyText.regular(
|
child: FlowyTextField(
|
||||||
LocaleKeys.settings_files_locationDesc.tr(),
|
hintText: LocaleKeys.settings_files_folderHintText.tr(),
|
||||||
),
|
onChanged: (name) => _folderName = name,
|
||||||
trailing: SizedBox(
|
onSubmitted: (name) => setState(
|
||||||
width: 100,
|
() => _folderName = name,
|
||||||
height: 36,
|
|
||||||
child: FlowyTextField(
|
|
||||||
hintText: LocaleKeys.settings_files_folderHintText.tr(),
|
|
||||||
onChanged: (name) {
|
|
||||||
_folderName = name;
|
|
||||||
},
|
|
||||||
onSubmitted: (name) {
|
|
||||||
setState(() {
|
|
||||||
_folderName = name;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Card(
|
_FolderCard(
|
||||||
child: ListTile(
|
title: LocaleKeys.settings_files_folderPath.tr(),
|
||||||
title: FlowyText.medium(LocaleKeys.settings_files_folderPath.tr()),
|
subtitle: _path,
|
||||||
subtitle: FlowyText.regular(_path),
|
trailing: _buildTextButton(
|
||||||
trailing: _buildTextButton(
|
context,
|
||||||
context, LocaleKeys.settings_files_browser.tr(), () async {
|
LocaleKeys.settings_files_browser.tr(),
|
||||||
|
() async {
|
||||||
final dir = await getIt<FilePickerService>().getDirectoryPath();
|
final dir = await getIt<FilePickerService>().getDirectoryPath();
|
||||||
if (dir != null) {
|
if (dir != null) {
|
||||||
setState(() {
|
setState(() => directory = dir);
|
||||||
directory = dir;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}),
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Card(
|
const VSpace(4.0),
|
||||||
child: _buildTextButton(
|
Padding(
|
||||||
context, LocaleKeys.settings_files_create.tr(), () async {
|
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||||
if (_path.isEmpty) {
|
child: Row(
|
||||||
_showToast(LocaleKeys.settings_files_locationCannotBeEmpty.tr());
|
children: [
|
||||||
} else {
|
_buildTextButton(
|
||||||
await getIt<SettingsLocationCubit>().setLocation(_path);
|
context,
|
||||||
await widget.onPressedCreate();
|
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(
|
Widget _buildTextButton(
|
||||||
BuildContext context, String title, VoidCallback onPressed) {
|
BuildContext context, String title, VoidCallback onPressed) {
|
||||||
return SizedBox(
|
return FlowyTextButton(
|
||||||
width: 70,
|
title,
|
||||||
height: 36,
|
onPressed: onPressed,
|
||||||
child: RoundedTextButton(
|
fillColor: Theme.of(context).colorScheme.primary,
|
||||||
title: title,
|
fontColor: Theme.of(context).colorScheme.onPrimary,
|
||||||
onPressed: onPressed,
|
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:dartz/dartz.dart' as dartz;
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/size.dart';
|
import 'package:flowy_infra/size.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
|
||||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
|
||||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
import 'package:appflowy_backend/log.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||||
@ -39,6 +38,7 @@ class _SkipLogInScreenState extends State<SkipLogInScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
appBar: const _SkipLoginMoveWindow(),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: _renderBody(context),
|
child: _renderBody(context),
|
||||||
),
|
),
|
||||||
@ -54,9 +54,13 @@ class _SkipLogInScreenState extends State<SkipLogInScreen> {
|
|||||||
logoSize: const Size.square(60),
|
logoSize: const Size.square(60),
|
||||||
),
|
),
|
||||||
const VSpace(40),
|
const VSpace(40),
|
||||||
SizedBox(
|
Row(
|
||||||
width: 250,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
child: GoButton(onPressed: () => _autoRegister(context)),
|
children: [
|
||||||
|
GoButton(
|
||||||
|
onPressed: () => _autoRegister(context),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const VSpace(20),
|
const VSpace(20),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
@ -72,18 +76,15 @@ class _SkipLogInScreenState extends State<SkipLogInScreen> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const VSpace(20),
|
const Spacer(),
|
||||||
SizedBox(
|
_buildSubscribeButtons(context),
|
||||||
width: 400,
|
|
||||||
child: _buildSubscribeButtons(context),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Row _buildSubscribeButtons(BuildContext context) {
|
Row _buildSubscribeButtons(BuildContext context) {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
FlowyTextButton(
|
FlowyTextButton(
|
||||||
LocaleKeys.githubStarText.tr(),
|
LocaleKeys.githubStarText.tr(),
|
||||||
@ -95,6 +96,7 @@ class _SkipLogInScreenState extends State<SkipLogInScreen> {
|
|||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
_launchURL('https://github.com/AppFlowy-IO/appflowy'),
|
_launchURL('https://github.com/AppFlowy-IO/appflowy'),
|
||||||
),
|
),
|
||||||
|
const HSpace(20),
|
||||||
FlowyTextButton(
|
FlowyTextButton(
|
||||||
LocaleKeys.subscribeNewsletterText.tr(),
|
LocaleKeys.subscribeNewsletterText.tr(),
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@ -149,19 +151,41 @@ class _SkipLogInScreenState extends State<SkipLogInScreen> {
|
|||||||
|
|
||||||
class GoButton extends StatelessWidget {
|
class GoButton extends StatelessWidget {
|
||||||
final VoidCallback onPressed;
|
final VoidCallback onPressed;
|
||||||
|
|
||||||
const GoButton({
|
const GoButton({
|
||||||
Key? key,
|
super.key,
|
||||||
required this.onPressed,
|
required this.onPressed,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return RoundedTextButton(
|
return FlowyTextButton(
|
||||||
title: LocaleKeys.letsGoButtonText.tr(),
|
LocaleKeys.letsGoButtonText.tr(),
|
||||||
fontSize: FontSizes.s16,
|
fontSize: FontSizes.s16,
|
||||||
height: 50,
|
padding: const EdgeInsets.symmetric(horizontal: 80, vertical: 12.0),
|
||||||
borderRadius: Corners.s10Border,
|
|
||||||
onPressed: onPressed,
|
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(
|
FlowyText.semibold(
|
||||||
title,
|
title,
|
||||||
fontSize: FontSizes.s24,
|
fontSize: FontSizes.s24,
|
||||||
|
color: Theme.of(context).colorScheme.tertiary,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -212,14 +212,20 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
|
|||||||
|
|
||||||
return ThemeData(
|
return ThemeData(
|
||||||
brightness: brightness,
|
brightness: brightness,
|
||||||
textTheme:
|
textTheme: _getTextTheme(fontFamily: fontFamily, fontColor: theme.text),
|
||||||
_getTextTheme(fontFamily: fontFamily, fontColor: theme.shader1),
|
|
||||||
textSelectionTheme: TextSelectionThemeData(
|
textSelectionTheme: TextSelectionThemeData(
|
||||||
cursorColor: theme.main2,
|
cursorColor: theme.main2,
|
||||||
selectionHandleColor: theme.main2,
|
selectionHandleColor: theme.main2,
|
||||||
),
|
),
|
||||||
primaryIconTheme: IconThemeData(color: theme.hover),
|
iconTheme: IconThemeData(color: theme.icon),
|
||||||
iconTheme: IconThemeData(color: theme.shader1),
|
tooltipTheme: TooltipThemeData(
|
||||||
|
textStyle: _getFontStyle(
|
||||||
|
fontFamily: fontFamily,
|
||||||
|
fontSize: FontSizes.s11,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
fontColor: theme.surface,
|
||||||
|
),
|
||||||
|
),
|
||||||
scrollbarTheme: ScrollbarThemeData(
|
scrollbarTheme: ScrollbarThemeData(
|
||||||
thumbColor: MaterialStateProperty.all(theme.shader3),
|
thumbColor: MaterialStateProperty.all(theme.shader3),
|
||||||
thickness: MaterialStateProperty.resolveWith((states) {
|
thickness: MaterialStateProperty.resolveWith((states) {
|
||||||
@ -239,30 +245,38 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
|
|||||||
),
|
),
|
||||||
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
canvasColor: theme.shader6,
|
canvasColor: theme.shader6,
|
||||||
dividerColor: theme.shader6,
|
dividerColor: theme.divider,
|
||||||
hintColor: theme.shader3,
|
hintColor: theme.hint,
|
||||||
|
//action item hover color
|
||||||
|
hoverColor: theme.hoverBG2,
|
||||||
disabledColor: theme.shader4,
|
disabledColor: theme.shader4,
|
||||||
highlightColor: theme.main1,
|
highlightColor: theme.main1,
|
||||||
indicatorColor: theme.main1,
|
indicatorColor: theme.main1,
|
||||||
toggleableActiveColor: theme.main1,
|
toggleableActiveColor: theme.main1,
|
||||||
|
cardColor: theme.input,
|
||||||
colorScheme: ColorScheme(
|
colorScheme: ColorScheme(
|
||||||
brightness: brightness,
|
brightness: brightness,
|
||||||
primary: theme.main1,
|
primary: theme.primary,
|
||||||
onPrimary: _white,
|
onPrimary: theme.onPrimary,
|
||||||
primaryContainer: theme.main2,
|
primaryContainer: theme.main2,
|
||||||
onPrimaryContainer: _white,
|
onPrimaryContainer: _white,
|
||||||
secondary: theme.hover,
|
// page title hover color
|
||||||
|
secondary: theme.hoverBG1,
|
||||||
onSecondary: theme.shader1,
|
onSecondary: theme.shader1,
|
||||||
|
// setting value hover color
|
||||||
secondaryContainer: theme.selector,
|
secondaryContainer: theme.selector,
|
||||||
onSecondaryContainer: theme.shader1,
|
onSecondaryContainer: theme.topbarBg,
|
||||||
|
tertiary: theme.shader7,
|
||||||
|
tertiaryContainer: theme.questionBubbleBG,
|
||||||
background: theme.surface,
|
background: theme.surface,
|
||||||
onBackground: theme.shader1,
|
onBackground: theme.text,
|
||||||
surface: theme.surface,
|
surface: theme.surface,
|
||||||
onSurface: theme.shader1,
|
// text&icon color when it is hovered
|
||||||
|
onSurface: theme.hoverFG,
|
||||||
onError: theme.shader7,
|
onError: theme.shader7,
|
||||||
error: theme.red,
|
error: theme.red,
|
||||||
outline: theme.shader4,
|
outline: theme.shader4,
|
||||||
surfaceVariant: theme.bg1,
|
surfaceVariant: theme.sidebarBg,
|
||||||
shadow: theme.shadow,
|
shadow: theme.shadow,
|
||||||
),
|
),
|
||||||
extensions: [
|
extensions: [
|
||||||
@ -278,7 +292,7 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
|
|||||||
tint7: theme.tint7,
|
tint7: theme.tint7,
|
||||||
tint8: theme.tint8,
|
tint8: theme.tint8,
|
||||||
tint9: theme.tint9,
|
tint9: theme.tint9,
|
||||||
greyHover: theme.bg2,
|
greyHover: theme.hoverBG1,
|
||||||
greySelect: theme.bg3,
|
greySelect: theme.bg3,
|
||||||
lightGreyHover: theme.shader6,
|
lightGreyHover: theme.shader6,
|
||||||
toggleOffFill: theme.shader5,
|
toggleOffFill: theme.shader5,
|
||||||
|
@ -36,7 +36,7 @@ extension ViewExtension on ViewPB {
|
|||||||
Widget renderThumbnail({Color? iconColor}) {
|
Widget renderThumbnail({Color? iconColor}) {
|
||||||
String thumbnail = "file_icon";
|
String thumbnail = "file_icon";
|
||||||
|
|
||||||
final Widget widget = svgWidget(thumbnail, color: iconColor);
|
final Widget widget = FlowySvg(name: thumbnail);
|
||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ class HomeTopBar extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.onSecondaryContainer,
|
||||||
height: HomeSizes.topBarHeight,
|
height: HomeSizes.topBarHeight,
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
@ -18,9 +18,14 @@ class NewAppButton extends StatelessWidget {
|
|||||||
LocaleKeys.newPageText.tr(),
|
LocaleKeys.newPageText.tr(),
|
||||||
fillColor: Colors.transparent,
|
fillColor: Colors.transparent,
|
||||||
hoverColor: Colors.transparent,
|
hoverColor: Colors.transparent,
|
||||||
fontColor: Theme.of(context).colorScheme.onSurfaceVariant,
|
fontColor: Theme.of(context).colorScheme.tertiary,
|
||||||
onPressed: () async => await _showCreateAppDialog(context),
|
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),
|
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_editor/appflowy_editor.dart' show Document;
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.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:flutter/material.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
|
||||||
@ -50,13 +50,19 @@ class AddButton extends StatelessWidget {
|
|||||||
actions: actions,
|
actions: actions,
|
||||||
offset: const Offset(0, 8),
|
offset: const Offset(0, 8),
|
||||||
buildChild: (controller) {
|
buildChild: (controller) {
|
||||||
return FlowyIconButton(
|
return SizedBox(
|
||||||
width: 22,
|
width: 22,
|
||||||
onPressed: () => controller.show(),
|
child: InkWell(
|
||||||
icon: svgWidget(
|
onTap: () => controller.show(),
|
||||||
"home/add",
|
child: FlowyHover(
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
style: HoverStyle(
|
||||||
).padding(horizontal: 3, vertical: 3),
|
hoverColor: AFThemeExtension.of(context).greySelect,
|
||||||
|
),
|
||||||
|
builder: (context, onHover) => const FlowySvg(
|
||||||
|
name: 'home/add',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onSelected: (action, controller) {
|
onSelected: (action, controller) {
|
||||||
@ -83,8 +89,7 @@ class AddButtonActionWrapper extends ActionCell {
|
|||||||
AddButtonActionWrapper({required this.pluginBuilder});
|
AddButtonActionWrapper({required this.pluginBuilder});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? leftIcon(Color iconColor) =>
|
Widget? leftIcon(Color iconColor) => FlowySvg(name: pluginBuilder.menuIcon);
|
||||||
svgWidget(pluginBuilder.menuIcon, color: iconColor);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get name => pluginBuilder.menuName;
|
String get name => pluginBuilder.menuName;
|
||||||
@ -100,9 +105,8 @@ class ImportActionWrapper extends ActionCell {
|
|||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? leftIcon(Color iconColor) => svgWidget(
|
Widget? leftIcon(Color iconColor) => const FlowySvg(
|
||||||
'editor/import',
|
name: 'editor/import',
|
||||||
color: iconColor,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -5,7 +5,6 @@ import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
|||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:expandable/expandable.dart';
|
import 'package:expandable/expandable.dart';
|
||||||
import 'package:flowy_infra/theme_extension.dart';
|
|
||||||
import 'package:flowy_infra/icon_data.dart';
|
import 'package:flowy_infra/icon_data.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder/app.pb.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:styled_widget/styled_widget.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:textstyle_extensions/textstyle_extensions.dart';
|
|
||||||
|
|
||||||
import '../menu_app.dart';
|
import '../menu_app.dart';
|
||||||
import 'add_button.dart';
|
import 'add_button.dart';
|
||||||
@ -58,7 +56,7 @@ class MenuAppHeader extends StatelessWidget {
|
|||||||
theme: ExpandableThemeData(
|
theme: ExpandableThemeData(
|
||||||
expandIcon: FlowyIconData.drop_down_show,
|
expandIcon: FlowyIconData.drop_down_show,
|
||||||
collapseIcon: FlowyIconData.drop_down_hide,
|
collapseIcon: FlowyIconData.drop_down_hide,
|
||||||
iconColor: Theme.of(context).colorScheme.onSurface,
|
iconColor: Theme.of(context).colorScheme.tertiary,
|
||||||
iconSize: MenuAppSizes.iconSize,
|
iconSize: MenuAppSizes.iconSize,
|
||||||
iconPadding: const EdgeInsets.fromLTRB(0, 0, 10, 0),
|
iconPadding: const EdgeInsets.fromLTRB(0, 0, 10, 0),
|
||||||
hasIcon: false,
|
hasIcon: false,
|
||||||
@ -104,7 +102,6 @@ class MenuAppHeader extends StatelessWidget {
|
|||||||
Widget _renderCreateViewButton(BuildContext context) {
|
Widget _renderCreateViewButton(BuildContext context) {
|
||||||
return Tooltip(
|
return Tooltip(
|
||||||
message: LocaleKeys.menuAppHeader_addPageTooltip.tr(),
|
message: LocaleKeys.menuAppHeader_addPageTooltip.tr(),
|
||||||
textStyle: AFThemeExtension.of(context).caption.textColor(Colors.white),
|
|
||||||
child: AddButton(
|
child: AddButton(
|
||||||
onSelected: (pluginBuilder, document) {
|
onSelected: (pluginBuilder, document) {
|
||||||
context.read<AppBloc>().add(
|
context.read<AppBloc>().add(
|
||||||
@ -139,9 +136,9 @@ extension AppDisclosureExtension on AppDisclosureAction {
|
|||||||
Widget icon(Color iconColor) {
|
Widget icon(Color iconColor) {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case AppDisclosureAction.rename:
|
case AppDisclosureAction.rename:
|
||||||
return svgWidget('editor/edit', color: iconColor);
|
return const FlowySvg(name: 'editor/edit');
|
||||||
case AppDisclosureAction.delete:
|
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(
|
builder: (context, app) => FlowyText.medium(
|
||||||
app.name,
|
app.name,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
|
color: Theme.of(context).colorScheme.tertiary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -24,6 +24,7 @@ Future<void> showImportPanel(
|
|||||||
title: FlowyText.semibold(
|
title: FlowyText.semibold(
|
||||||
LocaleKeys.moreAction_import.tr(),
|
LocaleKeys.moreAction_import.tr(),
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
|
color: Theme.of(context).colorScheme.tertiary,
|
||||||
),
|
),
|
||||||
content: _ImportPanel(importCallback: callback),
|
content: _ImportPanel(importCallback: callback),
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
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/home/menu/menu.dart';
|
||||||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||||
import 'package:easy_localization/easy_localization.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/hover.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
@ -51,7 +50,7 @@ class ViewSectionItem extends StatelessWidget {
|
|||||||
onTap: () => onSelected(blocContext.read<ViewBloc>().state.view),
|
onTap: () => onSelected(blocContext.read<ViewBloc>().state.view),
|
||||||
child: FlowyHover(
|
child: FlowyHover(
|
||||||
style: HoverStyle(
|
style: HoverStyle(
|
||||||
hoverColor: AFThemeExtension.of(context).greySelect,
|
hoverColor: Theme.of(context).colorScheme.secondary,
|
||||||
),
|
),
|
||||||
// If current state.isEditing is true, the hover should not
|
// If current state.isEditing is true, the hover should not
|
||||||
// rebuild when onEnter/onExit events happened.
|
// rebuild when onEnter/onExit events happened.
|
||||||
@ -60,7 +59,6 @@ class ViewSectionItem extends StatelessWidget {
|
|||||||
blocContext,
|
blocContext,
|
||||||
onHover,
|
onHover,
|
||||||
state,
|
state,
|
||||||
Theme.of(context).colorScheme.onSurface,
|
|
||||||
),
|
),
|
||||||
isSelected: () => state.isEditing || isSelected,
|
isSelected: () => state.isEditing || isSelected,
|
||||||
),
|
),
|
||||||
@ -75,13 +73,12 @@ class ViewSectionItem extends StatelessWidget {
|
|||||||
BuildContext blocContext,
|
BuildContext blocContext,
|
||||||
bool onHover,
|
bool onHover,
|
||||||
ViewState state,
|
ViewState state,
|
||||||
Color iconColor,
|
|
||||||
) {
|
) {
|
||||||
List<Widget> children = [
|
List<Widget> children = [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
child: state.view.renderThumbnail(iconColor: iconColor),
|
child: state.view.renderThumbnail(),
|
||||||
),
|
),
|
||||||
const HSpace(2),
|
const HSpace(2),
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -154,11 +151,11 @@ extension ViewDisclosureExtension on ViewDisclosureAction {
|
|||||||
Widget icon(Color iconColor) {
|
Widget icon(Color iconColor) {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case ViewDisclosureAction.rename:
|
case ViewDisclosureAction.rename:
|
||||||
return svgWidget('editor/edit', color: iconColor);
|
return const FlowySvg(name: 'editor/edit');
|
||||||
case ViewDisclosureAction.delete:
|
case ViewDisclosureAction.delete:
|
||||||
return svgWidget('editor/delete', color: iconColor);
|
return const FlowySvg(name: 'editor/delete');
|
||||||
case ViewDisclosureAction.duplicate:
|
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,
|
width: 26,
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
"editor/details",
|
"editor/details",
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
color: Theme.of(context).iconTheme.color,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
onEdit(true);
|
onEdit(true);
|
||||||
|
@ -229,7 +229,7 @@ class MenuTopBar extends StatelessWidget {
|
|||||||
iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4),
|
iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4),
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
"home/hide_menu",
|
"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/application/menu/menu_user_bloc.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart';
|
import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_user_view.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/image.dart';
|
||||||
import 'package:flowy_infra/size.dart';
|
import 'package:flowy_infra/size.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.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:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:textstyle_extensions/textstyle_extensions.dart';
|
|
||||||
|
|
||||||
class MenuUser extends StatelessWidget {
|
class MenuUser extends StatelessWidget {
|
||||||
final UserProfilePB user;
|
final UserProfilePB user;
|
||||||
@ -69,6 +67,7 @@ class MenuUser extends StatelessWidget {
|
|||||||
return FlowyText.medium(
|
return FlowyText.medium(
|
||||||
name,
|
name,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
|
color: Theme.of(context).colorScheme.tertiary,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +75,6 @@ class MenuUser extends StatelessWidget {
|
|||||||
final userProfile = context.read<MenuUserBloc>().state.userProfile;
|
final userProfile = context.read<MenuUserBloc>().state.userProfile;
|
||||||
return Tooltip(
|
return Tooltip(
|
||||||
message: LocaleKeys.settings_menu_open.tr(),
|
message: LocaleKeys.settings_menu_open.tr(),
|
||||||
textStyle: AFThemeExtension.of(context).caption.textColor(Colors.white),
|
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
@ -90,7 +88,7 @@ class MenuUser extends StatelessWidget {
|
|||||||
dimension: 20,
|
dimension: 20,
|
||||||
child: svgWidget(
|
child: svgWidget(
|
||||||
"home/settings",
|
"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:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flowy_infra/size.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/icon_button.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:textstyle_extensions/textstyle_extensions.dart';
|
|
||||||
|
|
||||||
typedef NaviAction = void Function();
|
typedef NaviAction = void Function();
|
||||||
|
|
||||||
@ -87,7 +85,7 @@ class FlowyNavigation extends StatelessWidget {
|
|||||||
iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2),
|
iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2),
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
"home/hide_menu",
|
"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: [
|
children: [
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: "$hintText\n",
|
text: "$hintText\n",
|
||||||
style: AFThemeExtension.of(context).callout.textColor(Colors.white),
|
|
||||||
),
|
),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: Platform.isMacOS ? "⌘+\\" : "Ctrl+\\",
|
text: Platform.isMacOS ? "⌘+\\" : "Ctrl+\\",
|
||||||
style: AFThemeExtension.of(context).caption.textColor(Colors.white60),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -32,6 +32,7 @@ class SettingsDialog extends StatelessWidget {
|
|||||||
LocaleKeys.settings_title.tr(),
|
LocaleKeys.settings_title.tr(),
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
|
color: Theme.of(context).colorScheme.tertiary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: ScaffoldMessenger(
|
child: ScaffoldMessenger(
|
||||||
@ -54,7 +55,9 @@ class SettingsDialog extends StatelessWidget {
|
|||||||
context.read<SettingsDialogBloc>().state.page,
|
context.read<SettingsDialogBloc>().state.page,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const VerticalDivider(),
|
VerticalDivider(
|
||||||
|
color: Theme.of(context).dividerColor,
|
||||||
|
),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: getSettingsView(
|
child: getSettingsView(
|
||||||
|
@ -50,8 +50,8 @@ class ThemeSetting extends StatelessWidget {
|
|||||||
direction: PopoverDirection.bottomWithRightAligned,
|
direction: PopoverDirection.bottomWithRightAligned,
|
||||||
child: FlowyTextButton(
|
child: FlowyTextButton(
|
||||||
currentTheme,
|
currentTheme,
|
||||||
|
fontColor: Theme.of(context).colorScheme.onBackground,
|
||||||
fillColor: Colors.transparent,
|
fillColor: Colors.transparent,
|
||||||
hoverColor: Theme.of(context).colorScheme.secondary,
|
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
),
|
),
|
||||||
popupBuilder: (BuildContext context) {
|
popupBuilder: (BuildContext context) {
|
||||||
@ -107,8 +107,8 @@ class ThemeModeSetting extends StatelessWidget {
|
|||||||
direction: PopoverDirection.bottomWithRightAligned,
|
direction: PopoverDirection.bottomWithRightAligned,
|
||||||
child: FlowyTextButton(
|
child: FlowyTextButton(
|
||||||
_themeModeLabelText(currentThemeMode),
|
_themeModeLabelText(currentThemeMode),
|
||||||
|
fontColor: Theme.of(context).colorScheme.onBackground,
|
||||||
fillColor: Colors.transparent,
|
fillColor: Colors.transparent,
|
||||||
hoverColor: Theme.of(context).colorScheme.secondary,
|
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
),
|
),
|
||||||
popupBuilder: (BuildContext context) {
|
popupBuilder: (BuildContext context) {
|
||||||
|
@ -47,7 +47,7 @@ class _LanguageSelectorDropdownState extends State<LanguageSelectorDropdown> {
|
|||||||
|
|
||||||
void hoverEnterLanguage() {
|
void hoverEnterLanguage() {
|
||||||
setState(() {
|
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),
|
padding: const EdgeInsets.symmetric(horizontal: 6),
|
||||||
child: DropdownButton<Locale>(
|
child: DropdownButton<Locale>(
|
||||||
value: context.locale,
|
value: context.locale,
|
||||||
|
dropdownColor: Theme.of(context).cardColor,
|
||||||
onChanged: (locale) {
|
onChanged: (locale) {
|
||||||
context
|
context
|
||||||
.read<AppearanceSettingsCubit>()
|
.read<AppearanceSettingsCubit>()
|
||||||
@ -80,7 +81,10 @@ class _LanguageSelectorDropdownState extends State<LanguageSelectorDropdown> {
|
|||||||
value: locale,
|
value: locale,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(12.0),
|
padding: const EdgeInsets.all(12.0),
|
||||||
child: FlowyText.medium(languageFromLocale(locale)),
|
child: FlowyText.medium(
|
||||||
|
languageFromLocale(locale),
|
||||||
|
color: Theme.of(context).colorScheme.tertiary,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:appflowy/workspace/application/settings/settings_dialog_bloc.dart';
|
import 'package:appflowy/workspace/application/settings/settings_dialog_bloc.dart';
|
||||||
import 'package:flowy_infra/size.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/style_widget/text.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
@ -21,29 +22,32 @@ class SettingsMenuElement extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListTile(
|
return FlowyHover(
|
||||||
leading: Icon(
|
style: HoverStyle(
|
||||||
icon,
|
hoverColor: Theme.of(context).colorScheme.primary,
|
||||||
size: 16,
|
|
||||||
color: page == selectedPage
|
|
||||||
? Theme.of(context).colorScheme.onSurface
|
|
||||||
: Theme.of(context).colorScheme.onSurface,
|
|
||||||
),
|
),
|
||||||
onTap: () {
|
child: ListTile(
|
||||||
changeSelectedPage(page);
|
leading: Icon(icon,
|
||||||
},
|
size: 16,
|
||||||
selected: page == selectedPage,
|
color: page == selectedPage
|
||||||
selectedColor: Theme.of(context).colorScheme.onSurface,
|
? Theme.of(context).colorScheme.onSurface
|
||||||
selectedTileColor: Theme.of(context).colorScheme.primaryContainer,
|
: null),
|
||||||
hoverColor: Theme.of(context).colorScheme.primary,
|
onTap: () {
|
||||||
shape: RoundedRectangleBorder(
|
changeSelectedPage(page);
|
||||||
borderRadius: BorderRadius.circular(5),
|
},
|
||||||
),
|
selected: page == selectedPage,
|
||||||
minLeadingWidth: 0,
|
selectedColor: Theme.of(context).colorScheme.onSurface,
|
||||||
title: FlowyText.semibold(
|
selectedTileColor: Theme.of(context).colorScheme.primary,
|
||||||
label,
|
shape: RoundedRectangleBorder(
|
||||||
fontSize: FontSizes.s14,
|
borderRadius: BorderRadius.circular(5),
|
||||||
overflow: TextOverflow.ellipsis,
|
),
|
||||||
|
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(),
|
tooltip: LocaleKeys.questionBubble_help.tr(),
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
|
fontColor: Theme.of(context).colorScheme.tertiary,
|
||||||
|
fillColor: Theme.of(context).colorScheme.tertiaryContainer,
|
||||||
|
hoverColor: Theme.of(context).colorScheme.tertiaryContainer,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
radius: Corners.s10Border,
|
radius: Corners.s10Border,
|
||||||
onPressed: () => controller.show(),
|
onPressed: () => controller.show(),
|
||||||
@ -200,7 +203,7 @@ extension QuestionBubbleExtension on BubbleAction {
|
|||||||
case BubbleAction.debug:
|
case BubbleAction.debug:
|
||||||
return '🐛';
|
return '🐛';
|
||||||
case BubbleAction.shortcuts:
|
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/text_node_extensions.dart';
|
||||||
import 'package:appflowy_editor/src/extensions/editor_state_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 '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;
|
import 'package:flutter/material.dart' hide Overlay, OverlayEntry;
|
||||||
|
|
||||||
@ -127,7 +128,9 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||||||
ToolbarItem(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.bold',
|
id: 'appflowy.toolbar.bold',
|
||||||
type: 2,
|
type: 2,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.bold,
|
tooltipsMessage: AppFlowyEditorLocalizations.current.bold +
|
||||||
|
"\n" +
|
||||||
|
(Platform.isMacOS ? "⌘ + B" : "CTRL + B"),
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/bold',
|
name: 'toolbar/bold',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
@ -143,7 +146,9 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||||||
ToolbarItem(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.italic',
|
id: 'appflowy.toolbar.italic',
|
||||||
type: 2,
|
type: 2,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.italic,
|
tooltipsMessage: AppFlowyEditorLocalizations.current.italic +
|
||||||
|
"\n" +
|
||||||
|
(Platform.isMacOS ? "⌘ + I" : "CTRL + I"),
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/italic',
|
name: 'toolbar/italic',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
@ -159,7 +164,9 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||||||
ToolbarItem(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.underline',
|
id: 'appflowy.toolbar.underline',
|
||||||
type: 2,
|
type: 2,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.underline,
|
tooltipsMessage: AppFlowyEditorLocalizations.current.underline +
|
||||||
|
"\n" +
|
||||||
|
(Platform.isMacOS ? "⌘ + U" : "CTRL + U"),
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/underline',
|
name: 'toolbar/underline',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
@ -175,7 +182,9 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||||||
ToolbarItem(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.strikethrough',
|
id: 'appflowy.toolbar.strikethrough',
|
||||||
type: 2,
|
type: 2,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.strikethrough,
|
tooltipsMessage: AppFlowyEditorLocalizations.current.strikethrough +
|
||||||
|
"\n" +
|
||||||
|
(Platform.isMacOS ? "⌘ + SHIFT + S" : "CTRL + SHIFT + S"),
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/strikethrough',
|
name: 'toolbar/strikethrough',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
@ -191,7 +200,9 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||||||
ToolbarItem(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.code',
|
id: 'appflowy.toolbar.code',
|
||||||
type: 2,
|
type: 2,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.embedCode,
|
tooltipsMessage: AppFlowyEditorLocalizations.current.embedCode +
|
||||||
|
"\n" +
|
||||||
|
(Platform.isMacOS ? "⌘ + E" : "CTRL + E"),
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/code',
|
name: 'toolbar/code',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
@ -238,10 +249,28 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||||||
),
|
),
|
||||||
handler: (editorState, context) => formatBulletedList(editorState),
|
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(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.link',
|
id: 'appflowy.toolbar.link',
|
||||||
type: 4,
|
type: 4,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.link,
|
tooltipsMessage: AppFlowyEditorLocalizations.current.link +
|
||||||
|
"\n" +
|
||||||
|
(Platform.isMacOS ? "⌘ + K" : "CTRL + K"),
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/link',
|
name: 'toolbar/link',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
@ -257,7 +286,9 @@ List<ToolbarItem> defaultToolbarItems = [
|
|||||||
ToolbarItem(
|
ToolbarItem(
|
||||||
id: 'appflowy.toolbar.highlight',
|
id: 'appflowy.toolbar.highlight',
|
||||||
type: 4,
|
type: 4,
|
||||||
tooltipsMessage: AppFlowyEditorLocalizations.current.highlight,
|
tooltipsMessage: AppFlowyEditorLocalizations.current.highlight +
|
||||||
|
"\n" +
|
||||||
|
(Platform.isMacOS ? "⌘ + SHIFT + H" : "CTRL + SHIFT + H"),
|
||||||
iconBuilder: (isHighlight) => FlowySvg(
|
iconBuilder: (isHighlight) => FlowySvg(
|
||||||
name: 'toolbar/highlight',
|
name: 'toolbar/highlight',
|
||||||
color: isHighlight ? Colors.lightBlue : null,
|
color: isHighlight ? Colors.lightBlue : null,
|
||||||
|
@ -21,6 +21,7 @@ class ToolbarItemWidget extends StatelessWidget {
|
|||||||
width: 28,
|
width: 28,
|
||||||
height: 28,
|
height: 28,
|
||||||
child: Tooltip(
|
child: Tooltip(
|
||||||
|
textAlign: TextAlign.center,
|
||||||
preferBelow: false,
|
preferBelow: false,
|
||||||
message: item.tooltipsMessage,
|
message: item.tooltipsMessage,
|
||||||
child: MouseRegion(
|
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.
|
/// Format the current selection with the given attributes.
|
||||||
///
|
///
|
||||||
/// If the selected nodes are not text nodes, this method will do nothing.
|
/// If the selected nodes are not text nodes, this method will do nothing.
|
||||||
|
@ -310,6 +310,47 @@ ShortcutEventHandler underscoreToItalicHandler = (editorState, event) {
|
|||||||
return KeyEventResult.handled;
|
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) {
|
ShortcutEventHandler doubleAsteriskToBoldHandler = (editorState, event) {
|
||||||
final selectionService = editorState.service.selectionService;
|
final selectionService = editorState.service.selectionService;
|
||||||
final selection = selectionService.currentSelection.value;
|
final selection = selectionService.currentSelection.value;
|
||||||
|
@ -307,6 +307,11 @@ List<ShortcutEvent> builtInShortcutEvents = [
|
|||||||
character: '_',
|
character: '_',
|
||||||
handler: underscoreToItalicHandler,
|
handler: underscoreToItalicHandler,
|
||||||
),
|
),
|
||||||
|
ShortcutEvent(
|
||||||
|
key: 'Asterisk to italic',
|
||||||
|
character: '*',
|
||||||
|
handler: asteriskToItalicHandler,
|
||||||
|
),
|
||||||
ShortcutEvent(
|
ShortcutEvent(
|
||||||
key: 'Double asterisk to bold',
|
key: 'Double asterisk to bold',
|
||||||
character: '*',
|
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', (() {
|
group('toolbar, highlight', (() {
|
||||||
testWidgets('Select Text, Click Toolbar and set style for highlighted text',
|
testWidgets('Select Text, Click Toolbar and set style for highlighted text',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
|
@ -441,4 +441,53 @@ void main() async {
|
|||||||
expect(textNode.toPlainText(), text);
|
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 main1;
|
||||||
final Color main2;
|
final Color main2;
|
||||||
final Color shadow;
|
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({
|
const FlowyColorScheme({
|
||||||
required this.surface,
|
required this.surface,
|
||||||
@ -87,6 +103,19 @@ abstract class FlowyColorScheme {
|
|||||||
required this.main1,
|
required this.main1,
|
||||||
required this.main2,
|
required this.main2,
|
||||||
required this.shadow,
|
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) {
|
factory FlowyColorScheme.builtIn(String themeName, Brightness brightness) {
|
||||||
|
@ -4,6 +4,21 @@ import 'colorscheme.dart';
|
|||||||
|
|
||||||
const _black = Color(0xff000000);
|
const _black = Color(0xff000000);
|
||||||
const _white = Color(0xFFFFFFFF);
|
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 {
|
class DandelionColorScheme extends FlowyColorScheme {
|
||||||
const DandelionColorScheme.light()
|
const DandelionColorScheme.light()
|
||||||
@ -20,8 +35,8 @@ class DandelionColorScheme extends FlowyColorScheme {
|
|||||||
shader4: const Color(0xffbdbdbd),
|
shader4: const Color(0xffbdbdbd),
|
||||||
shader5: const Color(0xffe0e0e0),
|
shader5: const Color(0xffe0e0e0),
|
||||||
shader6: const Color(0xfff2f2f2),
|
shader6: const Color(0xfff2f2f2),
|
||||||
shader7: const Color(0xffffffff),
|
shader7: _black,
|
||||||
bg1: const Color(0xFFFFD13E),
|
bg1: _lightBg1,
|
||||||
bg2: const Color(0xffedeef2),
|
bg2: const Color(0xffedeef2),
|
||||||
bg3: const Color(0xffe2e4eb),
|
bg3: const Color(0xffe2e4eb),
|
||||||
bg4: const Color(0xff2c144b),
|
bg4: const Color(0xff2c144b),
|
||||||
@ -34,9 +49,22 @@ class DandelionColorScheme extends FlowyColorScheme {
|
|||||||
tint7: const Color(0xffddffd6),
|
tint7: const Color(0xffddffd6),
|
||||||
tint8: const Color(0xffdefff1),
|
tint8: const Color(0xffdefff1),
|
||||||
tint9: const Color(0xffe1fbff),
|
tint9: const Color(0xffe1fbff),
|
||||||
main1: const Color(0xffe21f74),
|
main1: _lightMain1,
|
||||||
main2: const Color.fromARGB(255, 224, 25, 111),
|
main2: const Color.fromARGB(255, 224, 25, 111),
|
||||||
shadow: _black,
|
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()
|
const DandelionColorScheme.dark()
|
||||||
@ -48,12 +76,12 @@ class DandelionColorScheme extends FlowyColorScheme {
|
|||||||
yellow: const Color(0xffffd667),
|
yellow: const Color(0xffffd667),
|
||||||
green: const Color(0xff66cf80),
|
green: const Color(0xff66cf80),
|
||||||
shader1: _white,
|
shader1: _white,
|
||||||
shader2: const Color(0xffffffff),
|
shader2: _darkShader2,
|
||||||
shader3: const Color(0xff828282),
|
shader3: const Color(0xff828282),
|
||||||
shader4: const Color(0xffbdbdbd),
|
shader4: const Color(0xffbdbdbd),
|
||||||
shader5: _white,
|
shader5: _darkShader5,
|
||||||
shader6: _black,
|
shader6: _darkShader6,
|
||||||
shader7: _black,
|
shader7: _white,
|
||||||
bg1: const Color(0xFFD5A200),
|
bg1: const Color(0xFFD5A200),
|
||||||
bg2: _black,
|
bg2: _black,
|
||||||
bg3: const Color(0xff4f4f4f),
|
bg3: const Color(0xff4f4f4f),
|
||||||
@ -67,8 +95,21 @@ class DandelionColorScheme extends FlowyColorScheme {
|
|||||||
tint7: const Color(0xffbcffad),
|
tint7: const Color(0xffbcffad),
|
||||||
tint8: const Color(0xffadffe2),
|
tint8: const Color(0xffadffe2),
|
||||||
tint9: const Color(0xffade4ff),
|
tint9: const Color(0xffade4ff),
|
||||||
main1: const Color(0xffe21f74),
|
main1: _darkMain1,
|
||||||
main2: const Color.fromARGB(255, 224, 25, 111),
|
main2: const Color.fromARGB(255, 224, 25, 111),
|
||||||
shadow: _black,
|
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 _black = Color(0xff000000);
|
||||||
const _white = Color(0xFFFFFFFF);
|
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 {
|
class DefaultColorScheme extends FlowyColorScheme {
|
||||||
const DefaultColorScheme.light()
|
const DefaultColorScheme.light()
|
||||||
: super(
|
: super(
|
||||||
surface: Colors.white,
|
surface: _white,
|
||||||
hover: const Color(0xFFe0f8ff),
|
hover: _lightHover,
|
||||||
selector: const Color(0xfff2fcff),
|
selector: _lightSelector,
|
||||||
red: const Color(0xfffb006d),
|
red: const Color(0xfffb006d),
|
||||||
yellow: const Color(0xffffd667),
|
yellow: const Color(0xffffd667),
|
||||||
green: const Color(0xff66cf80),
|
green: const Color(0xff66cf80),
|
||||||
shader1: const Color(0xff333333),
|
shader1: _lightShader1,
|
||||||
shader2: const Color(0xff4f4f4f),
|
shader2: const Color(0xff4f4f4f),
|
||||||
shader3: const Color(0xff828282),
|
shader3: _lightShader3,
|
||||||
shader4: const Color(0xffbdbdbd),
|
shader4: const Color(0xffbdbdbd),
|
||||||
shader5: const Color(0xffe0e0e0),
|
shader5: const Color(0xffe0e0e0),
|
||||||
shader6: const Color(0xfff2f2f2),
|
shader6: _lightShader6,
|
||||||
shader7: const Color(0xffffffff),
|
shader7: _lightShader1,
|
||||||
bg1: const Color(0xfff7f8fc),
|
bg1: _lightBg1,
|
||||||
bg2: const Color(0xffedeef2),
|
bg2: _lightBg2,
|
||||||
bg3: const Color(0xffe2e4eb),
|
bg3: const Color(0xffe2e4eb),
|
||||||
bg4: const Color(0xff2c144b),
|
bg4: const Color(0xff2c144b),
|
||||||
tint1: const Color(0xffe8e0ff),
|
tint1: const Color(0xffe8e0ff),
|
||||||
@ -34,41 +48,67 @@ class DefaultColorScheme extends FlowyColorScheme {
|
|||||||
tint7: const Color(0xffddffd6),
|
tint7: const Color(0xffddffd6),
|
||||||
tint8: const Color(0xffdefff1),
|
tint8: const Color(0xffdefff1),
|
||||||
tint9: const Color(0xffe1fbff),
|
tint9: const Color(0xffe1fbff),
|
||||||
main1: const Color(0xff00bcf0),
|
main1: _lightMain1,
|
||||||
main2: const Color(0xff00b7ea),
|
main2: const Color(0xff00b7ea),
|
||||||
shadow: _black,
|
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()
|
const DefaultColorScheme.dark()
|
||||||
: super(
|
: super(
|
||||||
surface: const Color(0xff292929),
|
surface: _darkShader2,
|
||||||
hover: const Color(0xff1f1f1f),
|
hover: _darkMain1,
|
||||||
selector: const Color(0xff333333),
|
selector: _darkShader2,
|
||||||
red: const Color(0xfffb006d),
|
red: const Color(0xfffb006d),
|
||||||
yellow: const Color(0xffffd667),
|
yellow: const Color(0xffF7CF46),
|
||||||
green: const Color(0xff66cf80),
|
green: const Color(0xff66CF80),
|
||||||
shader1: _white,
|
shader1: _darkShader1,
|
||||||
shader2: const Color(0xffffffff),
|
shader2: _darkShader2,
|
||||||
shader3: const Color(0xff828282),
|
shader3: _darkShader3,
|
||||||
shader4: const Color(0xffbdbdbd),
|
shader4: const Color(0xff7C8CA5),
|
||||||
shader5: _white,
|
shader5: _darkShader5,
|
||||||
shader6: _black,
|
shader6: _darkShader6,
|
||||||
shader7: _black,
|
shader7: _white,
|
||||||
bg1: _black,
|
bg1: const Color(0xffF7F8FC),
|
||||||
bg2: _black,
|
bg2: const Color(0xffEDEEF2),
|
||||||
bg3: const Color(0xff4f4f4f),
|
bg3: _darkMain1,
|
||||||
bg4: const Color(0xff2c144b),
|
bg4: const Color(0xff2C144B),
|
||||||
tint1: const Color(0xffc3adff),
|
tint1: const Color(0xff8738F5),
|
||||||
tint2: const Color(0xffffadf9),
|
tint2: const Color(0xffE6336E),
|
||||||
tint3: const Color(0xffffadad),
|
tint3: const Color(0xffFF2D9E),
|
||||||
tint4: const Color(0xffffcfad),
|
tint4: const Color(0xffE9973E),
|
||||||
tint5: const Color(0xfffffead),
|
tint5: const Color(0xffFBF000),
|
||||||
tint6: const Color(0xffe6ffa3),
|
tint6: const Color(0xffC0F000),
|
||||||
tint7: const Color(0xffbcffad),
|
tint7: const Color(0xff15F74E),
|
||||||
tint8: const Color(0xffadffe2),
|
tint8: const Color(0xff00F0E2),
|
||||||
tint9: const Color(0xffade4ff),
|
tint9: const Color(0xff00BCF0),
|
||||||
main1: const Color(0xff00bcf0),
|
main1: _darkMain1,
|
||||||
main2: const Color(0xff009cc7),
|
main2: const Color(0xff00B7EA),
|
||||||
shadow: _black,
|
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 _black = Color(0xff000000);
|
||||||
const _white = Color(0xFFFFFFFF);
|
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 {
|
class LavenderColorScheme extends FlowyColorScheme {
|
||||||
const LavenderColorScheme.light()
|
const LavenderColorScheme.light()
|
||||||
: super(
|
: super(
|
||||||
@ -20,7 +36,7 @@ class LavenderColorScheme extends FlowyColorScheme {
|
|||||||
shader4: const Color(0xffbdbdbd),
|
shader4: const Color(0xffbdbdbd),
|
||||||
shader5: const Color(0xffe0e0e0),
|
shader5: const Color(0xffe0e0e0),
|
||||||
shader6: const Color(0xfff2f2f2),
|
shader6: const Color(0xfff2f2f2),
|
||||||
shader7: const Color(0xffffffff),
|
shader7: _black,
|
||||||
bg1: const Color(0xffAC59FF),
|
bg1: const Color(0xffAC59FF),
|
||||||
bg2: const Color(0xffedeef2),
|
bg2: const Color(0xffedeef2),
|
||||||
bg3: const Color(0xffe2e4eb),
|
bg3: const Color(0xffe2e4eb),
|
||||||
@ -34,9 +50,22 @@ class LavenderColorScheme extends FlowyColorScheme {
|
|||||||
tint7: const Color(0xffddffd6),
|
tint7: const Color(0xffddffd6),
|
||||||
tint8: const Color(0xffdefff1),
|
tint8: const Color(0xffdefff1),
|
||||||
tint9: const Color(0xffe1fbff),
|
tint9: const Color(0xffe1fbff),
|
||||||
main1: const Color(0xffA652FB),
|
main1: _lightMain1,
|
||||||
main2: const Color(0xff9327FF),
|
main2: const Color(0xff9327FF),
|
||||||
shadow: _black,
|
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()
|
const LavenderColorScheme.dark()
|
||||||
@ -48,12 +77,12 @@ class LavenderColorScheme extends FlowyColorScheme {
|
|||||||
yellow: const Color(0xffffd667),
|
yellow: const Color(0xffffd667),
|
||||||
green: const Color(0xff66cf80),
|
green: const Color(0xff66cf80),
|
||||||
shader1: _white,
|
shader1: _white,
|
||||||
shader2: const Color(0xffffffff),
|
shader2: _darkShader2,
|
||||||
shader3: const Color(0xff828282),
|
shader3: const Color(0xff828282),
|
||||||
shader4: const Color(0xffbdbdbd),
|
shader4: const Color(0xffbdbdbd),
|
||||||
shader5: _white,
|
shader5: _white,
|
||||||
shader6: _black,
|
shader6: _darkShader6,
|
||||||
shader7: _black,
|
shader7: _white,
|
||||||
bg1: const Color(0xff8C23F6),
|
bg1: const Color(0xff8C23F6),
|
||||||
bg2: _black,
|
bg2: _black,
|
||||||
bg3: const Color(0xff4f4f4f),
|
bg3: const Color(0xff4f4f4f),
|
||||||
@ -67,8 +96,21 @@ class LavenderColorScheme extends FlowyColorScheme {
|
|||||||
tint7: const Color(0xffbcffad),
|
tint7: const Color(0xffbcffad),
|
||||||
tint8: const Color(0xffadffe2),
|
tint8: const Color(0xffadffe2),
|
||||||
tint9: const Color(0xffade4ff),
|
tint9: const Color(0xffade4ff),
|
||||||
main1: const Color(0xffA652FB),
|
main1: _darkMain1,
|
||||||
main2: const Color(0xff9327FF),
|
main2: const Color(0xff9327FF),
|
||||||
shadow: _black,
|
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_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}) {
|
Widget svgWidget(String name, {Size? size, Color? color}) {
|
||||||
if (size != null) {
|
if (size != null) {
|
||||||
return SizedBox.fromSize(
|
return SizedBox.fromSize(
|
||||||
|
@ -6,7 +6,14 @@ String languageFromLocale(Locale locale) {
|
|||||||
case "en":
|
case "en":
|
||||||
return "English";
|
return "English";
|
||||||
case "zh":
|
case "zh":
|
||||||
return "简体中文";
|
switch (locale.countryCode) {
|
||||||
|
case "CN":
|
||||||
|
return "简体中文";
|
||||||
|
case "TW":
|
||||||
|
return "繁體中文";
|
||||||
|
default:
|
||||||
|
return locale.languageCode;
|
||||||
|
}
|
||||||
|
|
||||||
// Then in alphabetical order
|
// Then in alphabetical order
|
||||||
case "ca":
|
case "ca":
|
||||||
|
@ -81,7 +81,7 @@ class _PopoverContainer extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final decoration = this.decoration ??
|
final decoration = this.decoration ??
|
||||||
FlowyDecoration.decoration(
|
FlowyDecoration.decoration(
|
||||||
Theme.of(context).colorScheme.surface,
|
Theme.of(context).cardColor,
|
||||||
Theme.of(context).colorScheme.shadow.withOpacity(0.15),
|
Theme.of(context).colorScheme.shadow.withOpacity(0.15),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ class FlowyDialog extends StatelessWidget {
|
|||||||
final size = windowSize * 0.7;
|
final size = windowSize * 0.7;
|
||||||
return SimpleDialog(
|
return SimpleDialog(
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
|
backgroundColor: Theme.of(context).cardColor,
|
||||||
title: title,
|
title: title,
|
||||||
shape: shape ??
|
shape: shape ??
|
||||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
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/size.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.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/ignore_parent_gesture.dart';
|
||||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:textstyle_extensions/textstyle_extensions.dart';
|
|
||||||
|
|
||||||
class FlowyButton extends StatelessWidget {
|
class FlowyButton extends StatelessWidget {
|
||||||
final Widget text;
|
final Widget text;
|
||||||
@ -177,7 +175,8 @@ class FlowyTextButton extends StatelessWidget {
|
|||||||
highlightElevation: 0,
|
highlightElevation: 0,
|
||||||
shape: RoundedRectangleBorder(borderRadius: radius ?? Corners.s6Border),
|
shape: RoundedRectangleBorder(borderRadius: radius ?? Corners.s6Border),
|
||||||
fillColor: fillColor ?? Theme.of(context).colorScheme.secondaryContainer,
|
fillColor: fillColor ?? Theme.of(context).colorScheme.secondaryContainer,
|
||||||
hoverColor: hoverColor ?? Theme.of(context).colorScheme.secondary,
|
hoverColor:
|
||||||
|
hoverColor ?? Theme.of(context).colorScheme.secondaryContainer,
|
||||||
focusColor: Colors.transparent,
|
focusColor: Colors.transparent,
|
||||||
splashColor: Colors.transparent,
|
splashColor: Colors.transparent,
|
||||||
highlightColor: Colors.transparent,
|
highlightColor: Colors.transparent,
|
||||||
@ -195,7 +194,6 @@ class FlowyTextButton extends StatelessWidget {
|
|||||||
if (tooltip != null) {
|
if (tooltip != null) {
|
||||||
child = Tooltip(
|
child = Tooltip(
|
||||||
message: tooltip!,
|
message: tooltip!,
|
||||||
textStyle: AFThemeExtension.of(context).caption.textColor(Colors.white),
|
|
||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -285,7 +283,6 @@ class FlowyRichTextButton extends StatelessWidget {
|
|||||||
if (tooltip != null) {
|
if (tooltip != null) {
|
||||||
child = Tooltip(
|
child = Tooltip(
|
||||||
message: tooltip!,
|
message: tooltip!,
|
||||||
textStyle: AFThemeExtension.of(context).caption.textColor(Colors.white),
|
|
||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -115,11 +115,11 @@ class HoverStyle {
|
|||||||
|
|
||||||
class FlowyHoverContainer extends StatelessWidget {
|
class FlowyHoverContainer extends StatelessWidget {
|
||||||
final HoverStyle style;
|
final HoverStyle style;
|
||||||
final Widget? child;
|
final Widget child;
|
||||||
|
|
||||||
const FlowyHoverContainer({
|
const FlowyHoverContainer({
|
||||||
Key? key,
|
Key? key,
|
||||||
this.child,
|
required this.child,
|
||||||
required this.style,
|
required this.style,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@ -137,7 +137,22 @@ class FlowyHoverContainer extends StatelessWidget {
|
|||||||
color: style.hoverColor ?? Theme.of(context).colorScheme.secondary,
|
color: style.hoverColor ?? Theme.of(context).colorScheme.secondary,
|
||||||
borderRadius: style.borderRadius,
|
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? bgColor;
|
||||||
final Color? focusColor;
|
final Color? focusColor;
|
||||||
final Color? hoverColor;
|
final Color? hoverColor;
|
||||||
final Color? downColor;
|
final Color? highlightColor;
|
||||||
final EdgeInsets? contentPadding;
|
final EdgeInsets? contentPadding;
|
||||||
final double? minWidth;
|
final double? minWidth;
|
||||||
final double? minHeight;
|
final double? minHeight;
|
||||||
@ -34,7 +34,7 @@ class BaseStyledButton extends StatefulWidget {
|
|||||||
this.minHeight,
|
this.minHeight,
|
||||||
this.borderRadius,
|
this.borderRadius,
|
||||||
this.hoverColor,
|
this.hoverColor,
|
||||||
this.downColor,
|
this.highlightColor,
|
||||||
this.shape,
|
this.shape,
|
||||||
this.useBtnText = true,
|
this.useBtnText = true,
|
||||||
this.autoFocus = false,
|
this.autoFocus = false,
|
||||||
@ -116,10 +116,8 @@ class BaseStyledBtnState extends State<BaseStyledButton> {
|
|||||||
highlightElevation: 0,
|
highlightElevation: 0,
|
||||||
focusElevation: 0,
|
focusElevation: 0,
|
||||||
fillColor: Colors.transparent,
|
fillColor: Colors.transparent,
|
||||||
hoverColor:
|
hoverColor: widget.hoverColor ?? Colors.transparent,
|
||||||
widget.hoverColor ?? Theme.of(context).colorScheme.secondary,
|
highlightColor: widget.highlightColor ?? Colors.transparent,
|
||||||
highlightColor:
|
|
||||||
widget.downColor ?? Theme.of(context).colorScheme.primary,
|
|
||||||
focusColor: widget.focusColor ?? Colors.grey.withOpacity(0.35),
|
focusColor: widget.focusColor ?? Colors.grey.withOpacity(0.35),
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
minHeight: widget.minHeight ?? 0, minWidth: widget.minWidth ?? 0),
|
minHeight: widget.minHeight ?? 0, minWidth: widget.minWidth ?? 0),
|
||||||
|
@ -42,7 +42,6 @@ class PrimaryButton extends StatelessWidget {
|
|||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
bgColor: Theme.of(context).colorScheme.primary,
|
bgColor: Theme.of(context).colorScheme.primary,
|
||||||
hoverColor: Theme.of(context).colorScheme.primaryContainer,
|
hoverColor: Theme.of(context).colorScheme.primaryContainer,
|
||||||
downColor: Theme.of(context).colorScheme.primary,
|
|
||||||
borderRadius: bigMode ? Corners.s12Border : Corners.s8Border,
|
borderRadius: bigMode ? Corners.s12Border : Corners.s8Border,
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
child: child,
|
child: child,
|
||||||
|
@ -42,8 +42,6 @@ class SecondaryButton extends StatelessWidget {
|
|||||||
minHeight: bigMode ? 40 : 38,
|
minHeight: bigMode ? 40 : 38,
|
||||||
contentPadding: EdgeInsets.zero,
|
contentPadding: EdgeInsets.zero,
|
||||||
bgColor: Theme.of(context).colorScheme.surface,
|
bgColor: Theme.of(context).colorScheme.surface,
|
||||||
hoverColor: Theme.of(context).colorScheme.secondary,
|
|
||||||
downColor: Theme.of(context).colorScheme.primary,
|
|
||||||
outlineColor: Theme.of(context).colorScheme.primary,
|
outlineColor: Theme.of(context).colorScheme.primary,
|
||||||
borderRadius: bigMode ? Corners.s12Border : Corners.s8Border,
|
borderRadius: bigMode ? Corners.s12Border : Corners.s8Border,
|
||||||
onPressed: onPressed,
|
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.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 0.1.1
|
version: 0.1.2
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.18.0 <3.0.0"
|
sdk: ">=2.18.0 <3.0.0"
|
||||||
@ -89,7 +89,6 @@ dependencies:
|
|||||||
google_fonts: ^3.0.1
|
google_fonts: ^3.0.1
|
||||||
file_picker: <=5.0.0
|
file_picker: <=5.0.0
|
||||||
percent_indicator: ^4.0.1
|
percent_indicator: ^4.0.1
|
||||||
|
|
||||||
appflowy_editor_plugins:
|
appflowy_editor_plugins:
|
||||||
path: packages/appflowy_editor_plugins
|
path: packages/appflowy_editor_plugins
|
||||||
calendar_view: ^1.0.1
|
calendar_view: ^1.0.1
|
||||||
|
@ -10,7 +10,7 @@ pub fn init_flowy_core() -> AppFlowyCore {
|
|||||||
}
|
}
|
||||||
data_path.push("data");
|
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 server_config = get_client_server_configuration().unwrap();
|
||||||
let config = AppFlowyCoreConfig::new(
|
let config = AppFlowyCoreConfig::new(
|
||||||
data_path.to_str().unwrap(),
|
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 { MoreSvg } from '$app/components/_shared/svg/MoreSvg';
|
||||||
import { EditorUncheckSvg } from '$app/components/_shared/svg/EditorUncheckSvg';
|
import { EditorUncheckSvg } from '$app/components/_shared/svg/EditorUncheckSvg';
|
||||||
import { useCell } from '$app/components/_shared/database-hooks/useCell';
|
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 = ({
|
export const DatePickerPopup = ({
|
||||||
left,
|
left,
|
||||||
@ -29,7 +31,6 @@ export const DatePickerPopup = ({
|
|||||||
const { data, cellController } = useCell(cellIdentifier, cellCache, fieldController);
|
const { data, cellController } = useCell(cellIdentifier, cellCache, fieldController);
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
const [adjustedTop, setAdjustedTop] = useState(-100);
|
const [adjustedTop, setAdjustedTop] = useState(-100);
|
||||||
// const [value, setValue] = useState();
|
|
||||||
const { t } = useTranslation('');
|
const { t } = useTranslation('');
|
||||||
const [selectedDate, setSelectedDate] = useState<Date>(new Date());
|
const [selectedDate, setSelectedDate] = useState<Date>(new Date());
|
||||||
|
|
||||||
@ -48,15 +49,18 @@ export const DatePickerPopup = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// console.log((data as DateCellDataPB).date);
|
const date_pb = data as DateCellDataPB | undefined;
|
||||||
// setSelectedDate(new Date((data as DateCellDataPB).date));
|
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]);
|
}, [data]);
|
||||||
|
|
||||||
const onChange = (v: Date | null | (Date | null)[]) => {
|
const onChange = async (v: Date | null | (Date | null)[]) => {
|
||||||
if (v instanceof Date) {
|
if (v instanceof Date) {
|
||||||
console.log(dayjs(v).format('YYYY-MM-DD'));
|
|
||||||
setSelectedDate(v);
|
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 && (
|
{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 && (
|
{cellIdentifier.fieldType === FieldType.DateTime && (
|
||||||
|
@ -1,22 +1,26 @@
|
|||||||
import { EditorCheckSvg } from '$app/components/_shared/svg/EditorCheckSvg';
|
import { EditorCheckSvg } from '$app/components/_shared/svg/EditorCheckSvg';
|
||||||
import { EditorUncheckSvg } from '$app/components/_shared/svg/EditorUncheckSvg';
|
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 = ({
|
export const EditCheckboxCell = ({
|
||||||
data,
|
data,
|
||||||
cellController,
|
cellController,
|
||||||
}: {
|
}: {
|
||||||
data: boolean | undefined;
|
data: 'Yes' | 'No' | undefined;
|
||||||
cellController: CellController<any, any>;
|
cellController: CheckboxCellController;
|
||||||
}) => {
|
}) => {
|
||||||
const toggleValue = async () => {
|
const toggleValue = async () => {
|
||||||
await cellController?.saveCellData(!data);
|
if (data === 'Yes') {
|
||||||
|
await cellController?.saveCellData('No');
|
||||||
|
} else {
|
||||||
|
await cellController?.saveCellData('Yes');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div onClick={() => toggleValue()} className={'block px-4 py-2'}>
|
<div onClick={() => toggleValue()} className={'block px-4 py-2'}>
|
||||||
<button className={'h-5 w-5'}>
|
<button className={'h-5 w-5'}>
|
||||||
{data ? <EditorCheckSvg></EditorCheckSvg> : <EditorUncheckSvg></EditorUncheckSvg>}
|
{data === 'Yes' ? <EditorCheckSvg></EditorCheckSvg> : <EditorUncheckSvg></EditorUncheckSvg>}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -108,7 +108,11 @@ export const EditRow = ({
|
|||||||
|
|
||||||
const onDragEnd: OnDragEndResponder = (result) => {
|
const onDragEnd: OnDragEndResponder = (result) => {
|
||||||
if (!result.destination?.index) return;
|
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 (
|
return (
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import { CellIdentifier } from '../../stores/effects/database/cell/cell_bd_svc';
|
import { CellIdentifier } from '../../stores/effects/database/cell/cell_bd_svc';
|
||||||
import { CellCache } from '../../stores/effects/database/cell/cell_cache';
|
import { CellCache } from '../../stores/effects/database/cell/cell_cache';
|
||||||
import { FieldController } from '../../stores/effects/database/field/field_controller';
|
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 { BoardOptionsCell } from './BoardOptionsCell';
|
||||||
import { BoardDateCell } from './BoardDateCell';
|
import { BoardDateCell } from './BoardDateCell';
|
||||||
import { BoardTextCell } from './BoardTextCell';
|
import { BoardTextCell } from './BoardTextCell';
|
||||||
import { BoardUrlCell } from '$app/components/board/BoardUrlCell';
|
import { BoardUrlCell } from '$app/components/board/BoardUrlCell';
|
||||||
import { useCell } from '../_shared/database-hooks/useCell';
|
import { BoardCheckboxCell } from '$app/components/board/BoardCheckboxCell';
|
||||||
import { CellOptions } from '../_shared/EditRow/CellOptions';
|
|
||||||
|
|
||||||
export const BoardCell = ({
|
export const BoardCell = ({
|
||||||
cellIdentifier,
|
cellIdentifier,
|
||||||
@ -18,19 +17,16 @@ export const BoardCell = ({
|
|||||||
cellCache: CellCache;
|
cellCache: CellCache;
|
||||||
fieldController: FieldController;
|
fieldController: FieldController;
|
||||||
}) => {
|
}) => {
|
||||||
const { data, cellController } = useCell(cellIdentifier, cellCache, fieldController);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{cellIdentifier.fieldType === FieldType.SingleSelect ||
|
{cellIdentifier.fieldType === FieldType.SingleSelect ||
|
||||||
cellIdentifier.fieldType === FieldType.MultiSelect ||
|
cellIdentifier.fieldType === FieldType.MultiSelect ||
|
||||||
cellIdentifier.fieldType === FieldType.Checklist ? (
|
cellIdentifier.fieldType === FieldType.Checklist ? (
|
||||||
<CellOptions
|
<BoardOptionsCell
|
||||||
data={data as SelectOptionCellDataPB}
|
cellIdentifier={cellIdentifier}
|
||||||
onEditClick={(top: number, left: number) => {
|
cellCache={cellCache}
|
||||||
console.log(top, left);
|
fieldController={fieldController}
|
||||||
}}
|
></BoardOptionsCell>
|
||||||
/>
|
|
||||||
) : cellIdentifier.fieldType === FieldType.DateTime ? (
|
) : cellIdentifier.fieldType === FieldType.DateTime ? (
|
||||||
<BoardDateCell
|
<BoardDateCell
|
||||||
cellIdentifier={cellIdentifier}
|
cellIdentifier={cellIdentifier}
|
||||||
@ -43,6 +39,12 @@ export const BoardCell = ({
|
|||||||
cellCache={cellCache}
|
cellCache={cellCache}
|
||||||
fieldController={fieldController}
|
fieldController={fieldController}
|
||||||
></BoardUrlCell>
|
></BoardUrlCell>
|
||||||
|
) : cellIdentifier.fieldType === FieldType.Checkbox ? (
|
||||||
|
<BoardCheckboxCell
|
||||||
|
cellIdentifier={cellIdentifier}
|
||||||
|
cellCache={cellCache}
|
||||||
|
fieldController={fieldController}
|
||||||
|
></BoardCheckboxCell>
|
||||||
) : (
|
) : (
|
||||||
<BoardTextCell
|
<BoardTextCell
|
||||||
cellIdentifier={cellIdentifier}
|
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 { RowController } from '../../stores/effects/database/row/row_controller';
|
||||||
import {
|
import {
|
||||||
CellControllerBuilder,
|
CellControllerBuilder,
|
||||||
|
CheckboxCellController,
|
||||||
DateCellController,
|
DateCellController,
|
||||||
NumberCellController,
|
NumberCellController,
|
||||||
SelectOptionCellController,
|
SelectOptionCellController,
|
||||||
@ -126,6 +127,17 @@ export async function makeDateCellController(
|
|||||||
return Some(builder.build() as DateCellController);
|
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(
|
export async function makeURLCellController(
|
||||||
fieldId: string,
|
fieldId: string,
|
||||||
rowInfo: RowInfo,
|
rowInfo: RowInfo,
|
||||||
|
@ -8,10 +8,13 @@ import {
|
|||||||
TestDeleteField,
|
TestDeleteField,
|
||||||
TestDeleteRow,
|
TestDeleteRow,
|
||||||
TestEditCell,
|
TestEditCell,
|
||||||
|
TestEditCheckboxCell,
|
||||||
|
TestEditDateCell,
|
||||||
TestEditField,
|
TestEditField,
|
||||||
TestEditTextCell,
|
TestEditTextCell,
|
||||||
TestEditURLCell,
|
TestEditURLCell,
|
||||||
TestGetSingleSelectFieldData,
|
TestGetSingleSelectFieldData,
|
||||||
|
TestMoveField,
|
||||||
TestSwitchFromMultiSelectToText,
|
TestSwitchFromMultiSelectToText,
|
||||||
TestSwitchFromSingleSelectToNumber,
|
TestSwitchFromSingleSelectToNumber,
|
||||||
} from './TestGrid';
|
} from './TestGrid';
|
||||||
@ -37,9 +40,12 @@ export const TestAPI = () => {
|
|||||||
<TestEditCell></TestEditCell>
|
<TestEditCell></TestEditCell>
|
||||||
<TestEditTextCell></TestEditTextCell>
|
<TestEditTextCell></TestEditTextCell>
|
||||||
<TestEditURLCell></TestEditURLCell>
|
<TestEditURLCell></TestEditURLCell>
|
||||||
|
<TestEditDateCell></TestEditDateCell>
|
||||||
|
<TestEditCheckboxCell></TestEditCheckboxCell>
|
||||||
<TestCreateSelectOptionInCell></TestCreateSelectOptionInCell>
|
<TestCreateSelectOptionInCell></TestCreateSelectOptionInCell>
|
||||||
<TestGetSingleSelectFieldData></TestGetSingleSelectFieldData>
|
<TestGetSingleSelectFieldData></TestGetSingleSelectFieldData>
|
||||||
<TestEditField></TestEditField>
|
<TestEditField></TestEditField>
|
||||||
|
<TestMoveField></TestMoveField>
|
||||||
<TestCreateNewField></TestCreateNewField>
|
<TestCreateNewField></TestCreateNewField>
|
||||||
<TestDeleteField></TestDeleteField>
|
<TestDeleteField></TestDeleteField>
|
||||||
<TestSwitchFromSingleSelectToNumber></TestSwitchFromSingleSelectToNumber>
|
<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