fix: tooltips and overlay related issues (#4206)
* fix: align button tooltip * chore: upgrade Flutter to latest beta version * chore: bump version 0.4.0 * chore: minor ui update * chore: update dependencies * chore: upgrade flutter api * chore: use beta channel * chore: disable search bar and optimize toolbar ui * chore: rename extra info keys * feat: highlight text again after changing color * chore: update iOS icon * fix: lose children issues when converting block type * chore: update editor version * chore: update iOS icon and android navigation bar color * fix: docker build issue * fix: android keyboard issues * chore: update icon
4
.github/workflows/build_android_apk.yaml
vendored
@ -3,7 +3,7 @@ name: Build AppFlowy Release APK
|
||||
on: workflow_dispatch
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.16.2"
|
||||
FLUTTER_VERSION: "3.18.0-0.2.pre"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
|
||||
jobs:
|
||||
@ -43,7 +43,7 @@ jobs:
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
|
12
.github/workflows/flutter_ci.yaml
vendored
@ -23,7 +23,7 @@ on:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
FLUTTER_VERSION: "3.16.2"
|
||||
FLUTTER_VERSION: "3.18.0-0.2.pre"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
CARGO_MAKE_VERSION: "0.36.6"
|
||||
|
||||
@ -76,7 +76,7 @@ jobs:
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
@ -157,7 +157,7 @@ jobs:
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
@ -262,7 +262,7 @@ jobs:
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
@ -335,7 +335,7 @@ jobs:
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
@ -426,7 +426,7 @@ jobs:
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- uses: taiki-e/install-action@v2
|
||||
|
4
.github/workflows/mobile_ci.yaml
vendored
@ -18,7 +18,7 @@ on:
|
||||
- "!frontend/appflowy_tauri/**"
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.16.2"
|
||||
FLUTTER_VERSION: "3.18.0-0.2.pre"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
|
||||
concurrency:
|
||||
@ -63,7 +63,7 @@ jobs:
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
|
10
.github/workflows/release.yml
vendored
@ -6,7 +6,7 @@ on:
|
||||
- "*"
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.16.2"
|
||||
FLUTTER_VERSION: "3.18.0-0.2.pre"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
|
||||
jobs:
|
||||
@ -57,7 +57,7 @@ jobs:
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- name: Install Rust toolchain
|
||||
@ -143,7 +143,7 @@ jobs:
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- name: Install Rust toolchain
|
||||
@ -243,7 +243,7 @@ jobs:
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- name: Install Rust toolchain
|
||||
@ -346,7 +346,7 @@ jobs:
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- name: Install Rust toolchain
|
||||
|
4
.github/workflows/rust_coverage.yml
vendored
@ -11,7 +11,7 @@ on:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
FLUTTER_VERSION: "3.16.2"
|
||||
FLUTTER_VERSION: "3.18.0-0.2.pre"
|
||||
RUST_TOOLCHAIN: "1.70"
|
||||
|
||||
jobs:
|
||||
@ -34,7 +34,7 @@ jobs:
|
||||
id: flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
channel: "beta"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
|
@ -25,7 +25,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
||||
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
||||
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
||||
LIB_NAME = "dart_ffi"
|
||||
CURRENT_APP_VERSION = "0.3.9.1"
|
||||
CURRENT_APP_VERSION = "0.4.0"
|
||||
FLUTTER_DESKTOP_FEATURES = "dart,rev-sqlite"
|
||||
PRODUCT_NAME = "AppFlowy"
|
||||
MACOSX_DEPLOYMENT_TARGET = "11.0"
|
||||
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 5.1 KiB |
@ -1,80 +1 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "40.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "60.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "29.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "1x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "58.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "87.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "80.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "120.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "57.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "1x",
|
||||
"size" : "57x57"
|
||||
},
|
||||
{
|
||||
"filename" : "114.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "57x57"
|
||||
},
|
||||
{
|
||||
"filename" : "120.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"filename" : "180.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"filename" : "1024.png",
|
||||
"idiom" : "ios-marketing",
|
||||
"scale" : "1x",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"}]}
|
@ -4,5 +4,6 @@ import 'startup/startup.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
await runAppFlowy();
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ class MobileBottomNavigationBar extends StatelessWidget {
|
||||
final style = Theme.of(context);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.red,
|
||||
body: navigationShell,
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
showSelectedLabels: false,
|
||||
@ -43,14 +44,15 @@ class MobileBottomNavigationBar extends StatelessWidget {
|
||||
blendMode: null,
|
||||
),
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
label: 'search',
|
||||
icon: const FlowySvg(FlowySvgs.m_search_lg),
|
||||
activeIcon: FlowySvg(
|
||||
FlowySvgs.m_search_lg,
|
||||
color: style.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
// Enable this when search is ready.
|
||||
// BottomNavigationBarItem(
|
||||
// label: 'search',
|
||||
// icon: const FlowySvg(FlowySvgs.m_search_lg),
|
||||
// activeIcon: FlowySvg(
|
||||
// FlowySvgs.m_search_lg,
|
||||
// color: style.colorScheme.primary,
|
||||
// ),
|
||||
// ),
|
||||
BottomNavigationBarItem(
|
||||
label: 'notification',
|
||||
icon: const FlowySvg(FlowySvgs.m_notification_unselected_lg),
|
||||
|
@ -6,7 +6,6 @@ import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:calendar_view/calendar_view.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra/time/duration.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
@ -115,11 +114,11 @@ class CalendarDayCard extends StatelessWidget {
|
||||
],
|
||||
);
|
||||
},
|
||||
onAccept: (CalendarDayEvent event) {
|
||||
onAcceptWithDetails: (details) {
|
||||
final event = details.data;
|
||||
if (event.date == date) {
|
||||
return;
|
||||
}
|
||||
|
||||
context
|
||||
.read<CalendarBloc>()
|
||||
.add(CalendarEvent.moveEvent(event, date));
|
||||
|
@ -1,7 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:appflowy/plugins/document/application/doc_service.dart';
|
||||
import 'package:appflowy/plugins/document/application/document_data_pb_extension.dart';
|
||||
import 'package:appflowy/plugins/document/application/editor_transaction_adapter.dart';
|
||||
@ -22,6 +20,7 @@ import 'package:appflowy_editor/appflowy_editor.dart'
|
||||
Position,
|
||||
paragraphNode;
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
@ -60,6 +59,7 @@ class DocumentBloc extends Bloc<DocumentEvent, DocumentState> {
|
||||
await _viewListener.stop();
|
||||
await _subscription?.cancel();
|
||||
await _documentService.closeDocument(view: view);
|
||||
state.editorState?.selection = null;
|
||||
state.editorState?.dispose();
|
||||
return super.close();
|
||||
}
|
||||
|
@ -10,12 +10,6 @@ import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
List<AppFlowyMobileToolbarItem> getMobileToolbarItems() {
|
||||
return [
|
||||
aaToolbarItem,
|
||||
];
|
||||
}
|
||||
|
||||
Map<String, BlockComponentBuilder> getEditorBuilderMap({
|
||||
required BuildContext context,
|
||||
required EditorState editorState,
|
||||
|
@ -296,11 +296,11 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
||||
return AdaptiveTextSelectionToolbar.editable(
|
||||
clipboardStatus: ClipboardStatus.pasteable,
|
||||
onCopy: () {
|
||||
copyCommand.execute(editorState);
|
||||
customCopyCommand.execute(editorState);
|
||||
closeToolbar();
|
||||
},
|
||||
onCut: () => cutCommand.execute(editorState),
|
||||
onPaste: () => pasteCommand.execute(editorState),
|
||||
onCut: () => customCutCommand.execute(editorState),
|
||||
onPaste: () => customPasteCommand.execute(editorState),
|
||||
onSelectAll: () => selectAllCommand.execute(editorState),
|
||||
onLiveTextInput: null,
|
||||
onLookUp: null,
|
||||
|
@ -34,41 +34,33 @@ final alignToolbarItem = ToolbarItem(
|
||||
data = FlowySvgs.toolbar_align_right_s;
|
||||
}
|
||||
|
||||
// final child = MouseRegion(
|
||||
// cursor: SystemMouseCursors.click,
|
||||
// child: FlowyTooltip(
|
||||
// message: LocaleKeys.document_plugins_optionAction_align.tr(),
|
||||
// child: FlowySvg(
|
||||
// data,
|
||||
// size: const Size.square(16),
|
||||
// color: isHighlight ? highlightColor : Colors.white,
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
|
||||
// the above code will cause an error in Flutter 3.13:
|
||||
// Cannot hit test a render box that has never been laid out.
|
||||
final child = FlowySvg(
|
||||
data,
|
||||
size: const Size.square(16),
|
||||
color: isHighlight ? highlightColor : Colors.white,
|
||||
);
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
child: _AlignmentButtons(
|
||||
child: child,
|
||||
onAlignChanged: (align) async {
|
||||
await editorState.updateNode(
|
||||
selection,
|
||||
(node) => node.copyWith(
|
||||
attributes: {
|
||||
...node.attributes,
|
||||
blockComponentAlign: align,
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: FlowyTooltip(
|
||||
message: LocaleKeys.document_plugins_optionAction_align.tr(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
child: _AlignmentButtons(
|
||||
child: child,
|
||||
onAlignChanged: (align) async {
|
||||
await editorState.updateNode(
|
||||
selection,
|
||||
(node) => node.copyWith(
|
||||
attributes: {
|
||||
...node.attributes,
|
||||
blockComponentAlign: align,
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -177,7 +177,7 @@ class _TextDecorationMenuState extends State<_TextDecorationMenu> {
|
||||
editorState.updateSelectionWithReason(
|
||||
widget.selection,
|
||||
extraInfo: {
|
||||
disableMobileToolbarKey: true,
|
||||
selectionExtraInfoDisableMobileToolbarKey: true,
|
||||
},
|
||||
);
|
||||
editorState.service.keyboardService?.closeKeyboard();
|
||||
|
@ -177,7 +177,7 @@ class _TextDecorationMenuState extends State<_TextDecorationMenu> {
|
||||
editorState.updateSelectionWithReason(
|
||||
widget.selection,
|
||||
extraInfo: {
|
||||
disableMobileToolbarKey: true,
|
||||
selectionExtraInfoDisableMobileToolbarKey: true,
|
||||
},
|
||||
);
|
||||
editorState.service.keyboardService?.closeKeyboard();
|
||||
|
@ -26,7 +26,13 @@ class AlignItems extends StatelessWidget {
|
||||
return PopupMenu(
|
||||
itemLength: alignMenuItems.length,
|
||||
onSelected: (index) {
|
||||
editorState.alignBlock(alignMenuItems[index].$1);
|
||||
editorState.alignBlock(
|
||||
alignMenuItems[index].$1,
|
||||
selectionExtraInfo: {
|
||||
selectionExtraInfoDoNotAttachTextService: true,
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
},
|
||||
);
|
||||
},
|
||||
menuBuilder: (context, keys, currentIndex) {
|
||||
final children = alignMenuItems
|
||||
@ -54,7 +60,13 @@ class AlignItems extends StatelessWidget {
|
||||
key: key,
|
||||
size: const Size(82, 52),
|
||||
onTap: () async {
|
||||
await editorState.alignBlock(currentAlignItem.$1);
|
||||
await editorState.alignBlock(
|
||||
currentAlignItem.$1,
|
||||
selectionExtraInfo: {
|
||||
selectionExtraInfoDoNotAttachTextService: true,
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
},
|
||||
);
|
||||
},
|
||||
icon: currentAlignItem.$2,
|
||||
isSelected: false,
|
||||
@ -78,23 +90,28 @@ class AlignItems extends StatelessWidget {
|
||||
}
|
||||
|
||||
List<(String, FlowySvgData)> _getAlignMenuItems() {
|
||||
final align = _getCurrentBlockAlign();
|
||||
|
||||
if (align == _center) {
|
||||
return [
|
||||
(_left, FlowySvgs.m_aa_align_left_s),
|
||||
(_right, FlowySvgs.m_aa_align_right_s),
|
||||
];
|
||||
} else if (align == _right) {
|
||||
return [
|
||||
(_left, FlowySvgs.m_aa_align_left_s),
|
||||
(_center, FlowySvgs.m_aa_align_center_s),
|
||||
];
|
||||
}
|
||||
return [
|
||||
(_left, FlowySvgs.m_aa_align_left_s),
|
||||
(_center, FlowySvgs.m_aa_align_center_s),
|
||||
(_right, FlowySvgs.m_aa_align_right_s),
|
||||
];
|
||||
// final align = _getCurrentBlockAlign();
|
||||
|
||||
// if (align == _center) {
|
||||
// return [
|
||||
// (_left, FlowySvgs.m_aa_align_left_s),
|
||||
// (_right, FlowySvgs.m_aa_align_right_s),
|
||||
// ];
|
||||
// } else if (align == _right) {
|
||||
// return [
|
||||
// (_left, FlowySvgs.m_aa_align_left_s),
|
||||
// (_center, FlowySvgs.m_aa_align_center_s),
|
||||
// ];
|
||||
// }
|
||||
// return [
|
||||
// (_center, FlowySvgs.m_aa_align_center_s),
|
||||
// (_right, FlowySvgs.m_aa_align_right_s),
|
||||
// ];
|
||||
}
|
||||
|
||||
String _getCurrentBlockAlign() {
|
||||
|
@ -56,7 +56,13 @@ class BIUSItems extends StatelessWidget {
|
||||
enableBottomRightRadius: index == _bius.length - 1,
|
||||
backgroundColor: const Color(0xFFF2F2F7),
|
||||
onTap: () async {
|
||||
await editorState.toggleAttribute(richTextKey);
|
||||
await editorState.toggleAttribute(
|
||||
richTextKey,
|
||||
selectionExtraInfo: {
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
selectionExtraInfoDoNotAttachTextService: true,
|
||||
},
|
||||
);
|
||||
// refresh the status
|
||||
setState(() {});
|
||||
},
|
||||
|
@ -165,7 +165,8 @@ class BlockItems extends StatelessWidget {
|
||||
editorState.updateSelectionWithReason(
|
||||
selection,
|
||||
extraInfo: {
|
||||
disableMobileToolbarKey: true,
|
||||
selectionExtraInfoDisableMobileToolbarKey: true,
|
||||
selectionExtraInfoDoNotAttachTextService: true,
|
||||
},
|
||||
);
|
||||
editorState.service.keyboardService?.closeKeyboard();
|
||||
|
@ -0,0 +1,33 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CloseKeyboardOrMenuButton extends StatelessWidget {
|
||||
const CloseKeyboardOrMenuButton({
|
||||
super.key,
|
||||
required this.showingMenu,
|
||||
required this.onPressed,
|
||||
});
|
||||
|
||||
final bool showingMenu;
|
||||
final VoidCallback onPressed;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: 62,
|
||||
height: 46,
|
||||
child: FlowyButton(
|
||||
margin: showingMenu ? const EdgeInsets.only(right: 0.5) : null,
|
||||
text: showingMenu
|
||||
? const FlowySvg(
|
||||
FlowySvgs.m_toolbar_show_keyboard_s,
|
||||
)
|
||||
: const FlowySvg(
|
||||
FlowySvgs.m_toolbar_hide_keyboard_s,
|
||||
),
|
||||
onTap: onPressed,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/util.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_color_list.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@ -7,23 +8,38 @@ class ColorItem extends StatelessWidget {
|
||||
const ColorItem({
|
||||
super.key,
|
||||
required this.editorState,
|
||||
required this.service,
|
||||
});
|
||||
|
||||
final EditorState editorState;
|
||||
final AppFlowyMobileToolbarWidgetService service;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MobileToolbarItemWrapper(
|
||||
size: const Size(82, 52),
|
||||
onTap: () {
|
||||
onTap: () async {
|
||||
service.closeKeyboard();
|
||||
editorState.updateSelectionWithReason(
|
||||
editorState.selection,
|
||||
extraInfo: {
|
||||
selectionExtraInfoDisableMobileToolbarKey: true,
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
selectionExtraInfoDoNotAttachTextService: true,
|
||||
},
|
||||
);
|
||||
keepEditorFocusNotifier.increase();
|
||||
|
||||
// showTextColorAndBackgroundColorPicker(context);
|
||||
await showTextColorAndBackgroundColorPicker(
|
||||
context,
|
||||
editorState: editorState,
|
||||
selection: editorState.selection!,
|
||||
);
|
||||
},
|
||||
icon: FlowySvgs.m_aa_color_s,
|
||||
backgroundColor: const Color(0xFFF2F2F7),
|
||||
isSelected: false,
|
||||
showRightArrow: true,
|
||||
enable: editorState.selection?.isCollapsed == false,
|
||||
iconPadding: const EdgeInsets.only(
|
||||
top: 14.0,
|
||||
bottom: 14.0,
|
||||
|
@ -31,10 +31,15 @@ Future<void> showTextColorAndBackgroundColorPicker(
|
||||
);
|
||||
},
|
||||
);
|
||||
await editorState.updateSelectionWithReason(
|
||||
null,
|
||||
extraInfo: null,
|
||||
);
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
// highlight the selected text again.
|
||||
editorState.updateSelectionWithReason(
|
||||
selection,
|
||||
extraInfo: {
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
class _TextColorAndBackgroundColor extends StatefulWidget {
|
||||
@ -88,8 +93,9 @@ class _TextColorAndBackgroundColorState
|
||||
AppFlowyRichTextKeys.textColor: hex,
|
||||
},
|
||||
selectionExtraInfo: {
|
||||
disableFloatingToolbar: true,
|
||||
disableMobileToolbarKey: true,
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
selectionExtraInfoDisableMobileToolbarKey: true,
|
||||
selectionExtraInfoDoNotAttachTextService: true,
|
||||
},
|
||||
);
|
||||
setState(() {});
|
||||
@ -116,8 +122,9 @@ class _TextColorAndBackgroundColorState
|
||||
AppFlowyRichTextKeys.highlightColor: hex,
|
||||
},
|
||||
selectionExtraInfo: {
|
||||
disableFloatingToolbar: true,
|
||||
disableMobileToolbarKey: true,
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
selectionExtraInfoDisableMobileToolbarKey: true,
|
||||
selectionExtraInfoDoNotAttachTextService: true,
|
||||
},
|
||||
);
|
||||
setState(() {});
|
||||
|
@ -34,6 +34,12 @@ class FontFamilyItem extends StatelessWidget {
|
||||
AppFlowyRichTextKeys.fontFamily:
|
||||
GoogleFonts.getFont(newFont).fontFamily,
|
||||
});
|
||||
await editorState.updateSelectionWithReason(
|
||||
selection,
|
||||
extraInfo: {
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
text: fontFamily ?? systemFonFamily,
|
||||
|
@ -88,6 +88,9 @@ class _HeadingOrTextItem extends StatelessWidget {
|
||||
HeadingBlockKeys.level: level!,
|
||||
}
|
||||
: null,
|
||||
selectionExtraInfo: {
|
||||
selectionExtraInfoDoNotAttachTextService: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
final aaToolbarItem = AppFlowyMobileToolbarItem(
|
||||
pilotAtExpandedSelection: true,
|
||||
itemBuilder: (context, editorState, service, onMenu, _) {
|
||||
return AppFlowyMobileToolbarIconItem(
|
||||
isSelected: () => service.showMenuNotifier.value,
|
||||
@ -52,58 +53,64 @@ class _TextDecorationMenuState extends State<_TextDecorationMenu> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 24,
|
||||
bottom: 20,
|
||||
left: 12,
|
||||
right: 12,
|
||||
) *
|
||||
context.scale,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
HeadingsAndTextItems(
|
||||
editorState: editorState,
|
||||
),
|
||||
const ScaledVSpace(),
|
||||
Row(
|
||||
return SingleChildScrollView(
|
||||
child: ColoredBox(
|
||||
color: Colors.white,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 16,
|
||||
bottom: 20,
|
||||
left: 12,
|
||||
right: 12,
|
||||
) *
|
||||
context.scale,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
BIUSItems(
|
||||
HeadingsAndTextItems(
|
||||
editorState: editorState,
|
||||
),
|
||||
const Spacer(),
|
||||
ColorItem(
|
||||
editorState: editorState,
|
||||
const ScaledVSpace(),
|
||||
Row(
|
||||
children: [
|
||||
BIUSItems(
|
||||
editorState: editorState,
|
||||
),
|
||||
const Spacer(),
|
||||
ColorItem(
|
||||
editorState: editorState,
|
||||
service: widget.service,
|
||||
),
|
||||
],
|
||||
),
|
||||
const ScaledVSpace(),
|
||||
Row(
|
||||
children: [
|
||||
BlockItems(
|
||||
service: widget.service,
|
||||
editorState: editorState,
|
||||
),
|
||||
const Spacer(),
|
||||
AlignItems(
|
||||
editorState: editorState,
|
||||
),
|
||||
],
|
||||
),
|
||||
const ScaledVSpace(),
|
||||
Row(
|
||||
children: [
|
||||
FontFamilyItem(
|
||||
editorState: editorState,
|
||||
),
|
||||
const Spacer(),
|
||||
IndentAndOutdentItems(
|
||||
editorState: editorState,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const ScaledVSpace(),
|
||||
Row(
|
||||
children: [
|
||||
BlockItems(
|
||||
service: widget.service,
|
||||
editorState: editorState,
|
||||
),
|
||||
const Spacer(),
|
||||
AlignItems(
|
||||
editorState: editorState,
|
||||
),
|
||||
],
|
||||
),
|
||||
const ScaledVSpace(),
|
||||
Row(
|
||||
children: [
|
||||
FontFamilyItem(
|
||||
editorState: editorState,
|
||||
),
|
||||
const Spacer(),
|
||||
IndentAndOutdentItems(
|
||||
editorState: editorState,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/_close_keyboard_or_menu_button.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/appflowy_mobile_toolbar_item.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/keyboard_height_observer.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
@ -94,7 +96,8 @@ class _AppFlowyMobileToolbarState extends State<AppFlowyMobileToolbar> {
|
||||
builder: (_, Selection? selection, __) {
|
||||
// if the selection is null, hide the toolbar
|
||||
if (selection == null ||
|
||||
widget.editorState.selectionExtraInfo?[disableMobileToolbarKey] ==
|
||||
widget.editorState.selectionExtraInfo?[
|
||||
selectionExtraInfoDisableMobileToolbarKey] ==
|
||||
true) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
@ -173,12 +176,19 @@ class _MobileToolbarState extends State<_MobileToolbar>
|
||||
|
||||
bool closeKeyboardInitiative = false;
|
||||
|
||||
final ScrollOffsetListener offsetListener = ScrollOffsetListener.create();
|
||||
late final StreamSubscription offsetSubscription;
|
||||
ValueNotifier<double> toolbarOffset = ValueNotifier(0.0);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
currentSelection = widget.editorState.selection;
|
||||
KeyboardHeightObserver.instance.addListener(_onKeyboardHeightChanged);
|
||||
offsetSubscription = offsetListener.changes.listen((event) {
|
||||
toolbarOffset.value += event;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
@ -196,6 +206,8 @@ class _MobileToolbarState extends State<_MobileToolbar>
|
||||
showMenuNotifier.dispose();
|
||||
cachedKeyboardHeight.dispose();
|
||||
KeyboardHeightObserver.instance.removeListener(_onKeyboardHeightChanged);
|
||||
offsetSubscription.cancel();
|
||||
toolbarOffset.dispose();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
@ -245,10 +257,6 @@ class _MobileToolbarState extends State<_MobileToolbar>
|
||||
}
|
||||
|
||||
void _onKeyboardHeightChanged(double height) {
|
||||
if (canUpdateCachedKeyboardHeight) {
|
||||
cachedKeyboardHeight.value = height;
|
||||
}
|
||||
|
||||
// if the keyboard is not closed initiative, we need to close the menu at same time
|
||||
if (!closeKeyboardInitiative &&
|
||||
cachedKeyboardHeight.value != 0 &&
|
||||
@ -256,6 +264,10 @@ class _MobileToolbarState extends State<_MobileToolbar>
|
||||
widget.editorState.selection = null;
|
||||
}
|
||||
|
||||
if (canUpdateCachedKeyboardHeight) {
|
||||
cachedKeyboardHeight.value = height;
|
||||
}
|
||||
|
||||
if (height == 0) {
|
||||
closeKeyboardInitiative = false;
|
||||
}
|
||||
@ -264,15 +276,26 @@ class _MobileToolbarState extends State<_MobileToolbar>
|
||||
// toolbar list view and close keyboard/menu button
|
||||
Widget _buildToolbar(BuildContext context) {
|
||||
return Container(
|
||||
color: const Color(0xFFF3F3F8),
|
||||
height: widget.toolbarHeight,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xFFF3F3F8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0F181818),
|
||||
blurRadius: 40,
|
||||
offset: Offset(0, -4),
|
||||
spreadRadius: 0,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// toolbar list view
|
||||
Expanded(
|
||||
child: _ToolbarItemListView(
|
||||
offsetListener: offsetListener,
|
||||
toolbarItems: widget.toolbarItems,
|
||||
editorState: widget.editorState,
|
||||
toolbarWidgetService: this,
|
||||
@ -308,36 +331,52 @@ class _MobileToolbarState extends State<_MobileToolbar>
|
||||
},
|
||||
),
|
||||
),
|
||||
// divider
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
),
|
||||
child: VerticalDivider(
|
||||
width: 1,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
// close menu or close keyboard button
|
||||
ValueListenableBuilder(
|
||||
valueListenable: showMenuNotifier,
|
||||
builder: (_, showingMenu, __) {
|
||||
return _CloseKeyboardOrMenuButton(
|
||||
showingMenu: showingMenu,
|
||||
onPressed: () {
|
||||
if (showingMenu) {
|
||||
// close the menu and show the keyboard
|
||||
closeItemMenu();
|
||||
_showKeyboard();
|
||||
} else {
|
||||
closeKeyboardInitiative = true;
|
||||
// close the keyboard and clear the selection
|
||||
// if the selection is null, the keyboard and the toolbar will be hidden automatically
|
||||
widget.editorState.selection = null;
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
ClipRect(
|
||||
clipper: const _MyClipper(
|
||||
offset: -20,
|
||||
),
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: showMenuNotifier,
|
||||
builder: (_, showingMenu, __) {
|
||||
return ValueListenableBuilder(
|
||||
valueListenable: toolbarOffset,
|
||||
builder: (_, offset, __) {
|
||||
final showShadow = offset > 0;
|
||||
return DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF3F3F8),
|
||||
boxShadow: showShadow
|
||||
? [
|
||||
const BoxShadow(
|
||||
color: Color(0x51000000),
|
||||
blurRadius: 20,
|
||||
offset: Offset(-2, 0),
|
||||
spreadRadius: -10,
|
||||
),
|
||||
]
|
||||
: null,
|
||||
),
|
||||
child: CloseKeyboardOrMenuButton(
|
||||
showingMenu: showingMenu,
|
||||
onPressed: () {
|
||||
if (showingMenu) {
|
||||
// close the menu and show the keyboard
|
||||
closeItemMenu();
|
||||
_showKeyboard();
|
||||
} else {
|
||||
closeKeyboardInitiative = true;
|
||||
// close the keyboard and clear the selection
|
||||
// if the selection is null, the keyboard and the toolbar will be hidden automatically
|
||||
widget.editorState.selection = null;
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 4.0,
|
||||
@ -391,6 +430,7 @@ class _MobileToolbarState extends State<_MobileToolbar>
|
||||
|
||||
class _ToolbarItemListView extends StatefulWidget {
|
||||
const _ToolbarItemListView({
|
||||
required this.offsetListener,
|
||||
required this.toolbarItems,
|
||||
required this.editorState,
|
||||
required this.toolbarWidgetService,
|
||||
@ -403,6 +443,7 @@ class _ToolbarItemListView extends StatefulWidget {
|
||||
final List<AppFlowyMobileToolbarItem> toolbarItems;
|
||||
final EditorState editorState;
|
||||
final AppFlowyMobileToolbarWidgetService toolbarWidgetService;
|
||||
final ScrollOffsetListener offsetListener;
|
||||
|
||||
@override
|
||||
State<_ToolbarItemListView> createState() => _ToolbarItemListViewState();
|
||||
@ -432,7 +473,7 @@ class _ToolbarItemListViewState extends State<_ToolbarItemListView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final children = [
|
||||
const HSpace(8),
|
||||
const HSpace(16),
|
||||
...widget.toolbarItems
|
||||
.mapIndexed(
|
||||
(index, element) => element.itemBuilder.call(
|
||||
@ -453,12 +494,14 @@ class _ToolbarItemListViewState extends State<_ToolbarItemListView> {
|
||||
)
|
||||
.map((e) => [e, const HSpace(10)])
|
||||
.flattened,
|
||||
const HSpace(4),
|
||||
];
|
||||
|
||||
return PageStorage(
|
||||
bucket: PageStorageBucket(),
|
||||
child: ScrollablePositionedList.builder(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
scrollOffsetListener: widget.offsetListener,
|
||||
itemScrollController: scrollController,
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (context, index) => children[index],
|
||||
@ -507,33 +550,16 @@ class _ToolbarItemListViewState extends State<_ToolbarItemListView> {
|
||||
}
|
||||
}
|
||||
|
||||
class _CloseKeyboardOrMenuButton extends StatelessWidget {
|
||||
const _CloseKeyboardOrMenuButton({
|
||||
required this.showingMenu,
|
||||
required this.onPressed,
|
||||
class _MyClipper extends CustomClipper<Rect> {
|
||||
const _MyClipper({
|
||||
this.offset = 0,
|
||||
});
|
||||
|
||||
final bool showingMenu;
|
||||
final VoidCallback onPressed;
|
||||
final double offset;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: 64,
|
||||
height: 46,
|
||||
child: FlowyButton(
|
||||
text: showingMenu
|
||||
? const Padding(
|
||||
padding: EdgeInsets.only(right: 0.5),
|
||||
child: FlowySvg(
|
||||
FlowySvgs.m_toolbar_show_keyboard_s,
|
||||
),
|
||||
)
|
||||
: const FlowySvg(
|
||||
FlowySvgs.m_toolbar_hide_keyboard_s,
|
||||
),
|
||||
onTap: onPressed,
|
||||
),
|
||||
);
|
||||
}
|
||||
Rect getClip(Size size) => Rect.fromLTWH(offset, 0, 64.0, 46.0);
|
||||
|
||||
@override
|
||||
bool shouldReclip(CustomClipper<Rect> oldClipper) => false;
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.da
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
|
||||
final boldToolbarItem = AppFlowyMobileToolbarItem(
|
||||
pilotAtExpandedSelection: true,
|
||||
itemBuilder: (context, editorState, _, __, onAction) {
|
||||
return AppFlowyMobileToolbarIconItem(
|
||||
isSelected: () => editorState.isTextDecorationSelected(
|
||||
@ -13,6 +12,9 @@ final boldToolbarItem = AppFlowyMobileToolbarItem(
|
||||
icon: FlowySvgs.m_toolbar_bold_s,
|
||||
onTap: () async => await editorState.toggleAttribute(
|
||||
AppFlowyRichTextKeys.bold,
|
||||
selectionExtraInfo: {
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -28,6 +30,9 @@ final italicToolbarItem = AppFlowyMobileToolbarItem(
|
||||
icon: FlowySvgs.m_toolbar_italic_s,
|
||||
onTap: () async => await editorState.toggleAttribute(
|
||||
AppFlowyRichTextKeys.italic,
|
||||
selectionExtraInfo: {
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -42,6 +47,9 @@ final underlineToolbarItem = AppFlowyMobileToolbarItem(
|
||||
icon: FlowySvgs.m_toolbar_underline_s,
|
||||
onTap: () async => await editorState.toggleAttribute(
|
||||
AppFlowyRichTextKeys.underline,
|
||||
selectionExtraInfo: {
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -56,7 +64,9 @@ final colorToolbarItem = AppFlowyMobileToolbarItem(
|
||||
editorState.updateSelectionWithReason(
|
||||
editorState.selection,
|
||||
extraInfo: {
|
||||
disableMobileToolbarKey: true,
|
||||
selectionExtraInfoDisableMobileToolbarKey: true,
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
selectionExtraInfoDoNotAttachTextService: true,
|
||||
},
|
||||
);
|
||||
keepEditorFocusNotifier.increase();
|
||||
|
@ -144,6 +144,13 @@ extension MobileToolbarBuildContext on BuildContext {
|
||||
double get scale => MediaQuery.of(this).size.width / 375.0;
|
||||
}
|
||||
|
||||
final _blocksCanContainChildren = [
|
||||
ParagraphBlockKeys.type,
|
||||
BulletedListBlockKeys.type,
|
||||
NumberedListBlockKeys.type,
|
||||
TodoListBlockKeys.type,
|
||||
];
|
||||
|
||||
extension MobileToolbarEditorState on EditorState {
|
||||
bool isBlockTypeSelected(
|
||||
String blockType, {
|
||||
@ -208,6 +215,7 @@ extension MobileToolbarEditorState on EditorState {
|
||||
Selection? selection,
|
||||
Attributes? extraAttributes,
|
||||
bool? isSelected,
|
||||
Map? selectionExtraInfo,
|
||||
}) async {
|
||||
selection = selection ?? this.selection;
|
||||
if (selection == null) {
|
||||
@ -220,6 +228,20 @@ extension MobileToolbarEditorState on EditorState {
|
||||
return;
|
||||
}
|
||||
final selected = isSelected ?? type == newBlockType;
|
||||
|
||||
// if the new block type can't contain children, we need to move all the children to the parent
|
||||
bool needToDeleteChildren = false;
|
||||
if (!selected &&
|
||||
node.children.isNotEmpty &&
|
||||
!_blocksCanContainChildren.contains(newBlockType)) {
|
||||
final transaction = this.transaction;
|
||||
needToDeleteChildren = true;
|
||||
transaction.insertNodes(
|
||||
selection.end.path.next,
|
||||
node.children.map((e) => e.copyWith()),
|
||||
);
|
||||
await apply(transaction);
|
||||
}
|
||||
await formatNode(
|
||||
selection,
|
||||
(node) {
|
||||
@ -231,14 +253,17 @@ extension MobileToolbarEditorState on EditorState {
|
||||
return node.copyWith(
|
||||
type: selected ? ParagraphBlockKeys.type : newBlockType,
|
||||
attributes: attributes,
|
||||
children: needToDeleteChildren ? [] : null,
|
||||
);
|
||||
},
|
||||
selectionExtraInfo: selectionExtraInfo,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> alignBlock(
|
||||
String alignment, {
|
||||
Selection? selection,
|
||||
Map? selectionExtraInfo,
|
||||
}) async {
|
||||
await updateNode(
|
||||
selection,
|
||||
@ -248,6 +273,7 @@ extension MobileToolbarEditorState on EditorState {
|
||||
blockComponentAlign: alignment,
|
||||
},
|
||||
),
|
||||
selectionExtraInfo: selectionExtraInfo,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -297,7 +297,7 @@ class EditorStyleCustomizer {
|
||||
editorState.updateSelectionWithReason(
|
||||
editorState.selection,
|
||||
extraInfo: {
|
||||
disableMobileToolbarKey: true,
|
||||
selectionExtraInfoDisableMobileToolbarKey: true,
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -2,7 +2,6 @@ import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/startup/tasks/memory_leak_detector.dart';
|
||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||
import 'package:appflowy_backend/appflowy_backend.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
@ -14,7 +13,6 @@ import 'deps_resolver.dart';
|
||||
import 'entry_point.dart';
|
||||
import 'launch_configuration.dart';
|
||||
import 'plugin/plugin.dart';
|
||||
import 'tasks/appflowy_cloud_task.dart';
|
||||
import 'tasks/prelude.dart';
|
||||
|
||||
final getIt = GetIt.instance;
|
||||
@ -105,6 +103,7 @@ class FlowyRunner {
|
||||
// this task should be second task, for handling memory leak.
|
||||
// there's a flag named _enable in memory_leak_detector.dart. If it's false, the task will be ignored.
|
||||
MemoryLeakDetectorTask(),
|
||||
const DebugTask(),
|
||||
// localization
|
||||
const InitLocalizationTask(),
|
||||
// init the app window
|
||||
|
20
frontend/appflowy_flutter/lib/startup/tasks/debug_task.dart
Normal file
@ -0,0 +1,20 @@
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import '../startup.dart';
|
||||
|
||||
class DebugTask extends LaunchTask {
|
||||
const DebugTask();
|
||||
|
||||
@override
|
||||
Future<void> initialize(LaunchContext context) async {
|
||||
// the hotkey manager is not supported on mobile
|
||||
if (PlatformExtension.isMobile && kDebugMode) {
|
||||
SystemChannels.textInput.invokeMethod('TextInput.hide');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import 'package:appflowy/mobile/presentation/database/board/mobile_board_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/card/card.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/date_picker/mobile_date_picker_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/field/mobile_create_field_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/field/mobile_edit_field_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/date_picker/mobile_date_picker_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/mobile_calendar_events_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/mobile_calendar_screen.dart';
|
||||
import 'package:appflowy/mobile/presentation/database/mobile_grid_screen.dart';
|
||||
@ -152,27 +152,28 @@ StatefulShellRoute _mobileHomeScreenWithNavigationBarRoute() {
|
||||
),
|
||||
],
|
||||
),
|
||||
StatefulShellBranch(
|
||||
routes: <RouteBase>[
|
||||
GoRoute(
|
||||
path: '/d',
|
||||
builder: (BuildContext context, GoRouterState state) =>
|
||||
const RootPlaceholderScreen(
|
||||
label: 'Search',
|
||||
detailsPath: '/d/details',
|
||||
),
|
||||
routes: <RouteBase>[
|
||||
GoRoute(
|
||||
path: 'details',
|
||||
builder: (BuildContext context, GoRouterState state) =>
|
||||
const DetailsPlaceholderScreen(
|
||||
label: 'Search Page details',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
// Enable search feature after we have a search page.
|
||||
// StatefulShellBranch(
|
||||
// routes: <RouteBase>[
|
||||
// GoRoute(
|
||||
// path: '/d',
|
||||
// builder: (BuildContext context, GoRouterState state) =>
|
||||
// const RootPlaceholderScreen(
|
||||
// label: 'Search',
|
||||
// detailsPath: '/d/details',
|
||||
// ),
|
||||
// routes: <RouteBase>[
|
||||
// GoRoute(
|
||||
// path: 'details',
|
||||
// builder: (BuildContext context, GoRouterState state) =>
|
||||
// const DetailsPlaceholderScreen(
|
||||
// label: 'Search Page details',
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
StatefulShellBranch(
|
||||
routes: <RouteBase>[
|
||||
GoRoute(
|
||||
|
@ -1,10 +1,13 @@
|
||||
export 'app_widget.dart';
|
||||
export 'rust_sdk.dart';
|
||||
export 'platform_service.dart';
|
||||
export 'load_plugin.dart';
|
||||
export 'hot_key.dart';
|
||||
export 'platform_error_catcher.dart';
|
||||
export 'windows.dart';
|
||||
export 'localization.dart';
|
||||
export 'supabase_task.dart';
|
||||
export 'appflowy_cloud_task.dart';
|
||||
export 'debug_task.dart';
|
||||
export 'generate_router.dart';
|
||||
export 'hot_key.dart';
|
||||
export 'load_plugin.dart';
|
||||
export 'localization.dart';
|
||||
export 'memory_leak_detector.dart';
|
||||
export 'platform_error_catcher.dart';
|
||||
export 'platform_service.dart';
|
||||
export 'rust_sdk.dart';
|
||||
export 'supabase_task.dart';
|
||||
export 'windows.dart';
|
||||
|
@ -85,6 +85,7 @@ class MobileAppearance extends BaseAppearance {
|
||||
return ThemeData(
|
||||
// color
|
||||
useMaterial3: false,
|
||||
|
||||
primaryColor: colorTheme.primary, //primary 100
|
||||
primaryColorLight: const Color(0xFF57B5F8), //primary 80
|
||||
dividerColor: colorTheme.outline, //caption
|
||||
|
@ -57,7 +57,7 @@ class _DraggableViewItemState extends State<DraggableViewItem> {
|
||||
return DraggableItem<ViewPB>(
|
||||
data: widget.view,
|
||||
onDragging: widget.onDragging,
|
||||
onWillAccept: (data) => true,
|
||||
onWillAcceptWithDetails: (data) => true,
|
||||
onMove: (data) {
|
||||
final renderBox = context.findRenderObject() as RenderBox;
|
||||
final offset = renderBox.globalToLocal(data.offset);
|
||||
@ -70,7 +70,8 @@ class _DraggableViewItemState extends State<DraggableViewItem> {
|
||||
onLeave: (_) => _updatePosition(
|
||||
DraggableHoverPosition.none,
|
||||
),
|
||||
onAccept: (data) {
|
||||
onAcceptWithDetails: (details) {
|
||||
final data = details.data;
|
||||
_move(
|
||||
data,
|
||||
widget.view,
|
||||
|
@ -8,8 +8,8 @@ class DraggableItem<T extends Object> extends StatefulWidget {
|
||||
required this.data,
|
||||
this.feedback,
|
||||
this.childWhenDragging,
|
||||
this.onAccept,
|
||||
this.onWillAccept,
|
||||
this.onAcceptWithDetails,
|
||||
this.onWillAcceptWithDetails,
|
||||
this.onMove,
|
||||
this.onLeave,
|
||||
this.enableAutoScroll = true,
|
||||
@ -23,8 +23,8 @@ class DraggableItem<T extends Object> extends StatefulWidget {
|
||||
final Widget? feedback;
|
||||
final Widget? childWhenDragging;
|
||||
|
||||
final DragTargetAccept<T>? onAccept;
|
||||
final DragTargetWillAccept<T>? onWillAccept;
|
||||
final DragTargetAcceptWithDetails<T>? onAcceptWithDetails;
|
||||
final DragTargetWillAcceptWithDetails<T>? onWillAcceptWithDetails;
|
||||
final DragTargetMove<T>? onMove;
|
||||
final DragTargetLeave<T>? onLeave;
|
||||
|
||||
@ -57,8 +57,8 @@ class _DraggableItemState<T extends Object> extends State<DraggableItem<T>> {
|
||||
initAutoScrollerIfNeeded(context);
|
||||
|
||||
return DragTarget(
|
||||
onAccept: widget.onAccept,
|
||||
onWillAccept: widget.onWillAccept,
|
||||
onAcceptWithDetails: widget.onAcceptWithDetails,
|
||||
onWillAcceptWithDetails: widget.onWillAcceptWithDetails,
|
||||
onMove: widget.onMove,
|
||||
onLeave: widget.onLeave,
|
||||
builder: (_, __, ___) => _Draggable<T>(
|
||||
|
@ -1,6 +1,7 @@
|
||||
// ignore_for_file: unused_element
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flowy_infra_ui/src/flowy_overlay/layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -315,11 +316,11 @@ class FlowyOverlayState extends State<FlowyOverlay> {
|
||||
),
|
||||
child: Focus(
|
||||
focusNode: focusNode,
|
||||
onKey: (node, event) {
|
||||
onKeyEvent: (node, event) {
|
||||
KeyEventResult result = KeyEventResult.ignored;
|
||||
for (final ShortcutActivator activator
|
||||
in _keyboardShortcutBindings.keys) {
|
||||
if (activator.accepts(event, RawKeyboard.instance)) {
|
||||
if (activator.accepts(event, HardwareKeyboard.instance)) {
|
||||
_keyboardShortcutBindings[activator]!.call(identifier);
|
||||
result = KeyEventResult.handled;
|
||||
}
|
||||
|
@ -5,18 +5,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051
|
||||
sha256: "36a321c3d2cbe01cbcb3540a87b8843846e0206df3e691fa7b23e19e78de6d49"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "64.0.0"
|
||||
version: "65.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893"
|
||||
sha256: dfe03b90ec022450e22513b5e5ca1f01c0c01de9c3fba2f7fd233cb57a6b9a07
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.0"
|
||||
version: "6.3.0"
|
||||
animations:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -53,8 +53,8 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: "92e4260"
|
||||
resolved-ref: "92e4260c062189cf4d5626272af62d0024d69455"
|
||||
ref: "20a714a"
|
||||
resolved-ref: "20a714ae0848fd69b2c947d445a2c6b1c2391472"
|
||||
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
||||
source: git
|
||||
version: "2.1.0"
|
||||
@ -303,10 +303,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
sha256: "595a29b55ce82d53398e1bcc2cba525d7bd7c59faeb2d2540e9d42c390cfeeeb"
|
||||
sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.6.4"
|
||||
version: "1.7.2"
|
||||
cross_file:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -460,13 +460,13 @@ packages:
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
file:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: file
|
||||
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
|
||||
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.4"
|
||||
version: "7.0.0"
|
||||
file_picker:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1018,6 +1018,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.0.16"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: b06739349ec2477e943055aea30172c5c7000225f79dad4702e2ec0eda79a6ff
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
linked_scroll_controller:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1102,18 +1110,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
|
||||
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
version: "0.8.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
|
||||
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
version: "1.11.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1310,10 +1318,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102
|
||||
sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
version: "3.1.3"
|
||||
plugin_platform_interface:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@ -1350,10 +1358,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
|
||||
sha256: "266ca5be5820feefc777793d0a583acfc8c40834893c87c00c6c09e2cf58ea42"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.4"
|
||||
version: "5.0.1"
|
||||
protobuf:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -2069,10 +2077,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583
|
||||
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "11.10.0"
|
||||
version: "13.0.0"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -2085,10 +2093,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
|
||||
sha256: edc8a9573dd8c5a83a183dae1af2b6fd4131377404706ca4e5420474784906fa
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
version: "0.4.0"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -2101,10 +2109,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webdriver
|
||||
sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49"
|
||||
sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
version: "3.0.3"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -2203,4 +2211,4 @@ packages:
|
||||
version: "1.1.1"
|
||||
sdks:
|
||||
dart: ">=3.2.0 <4.0.0"
|
||||
flutter: ">=3.16.0"
|
||||
flutter: ">=3.18.0-0.2.pre"
|
||||
|
@ -15,10 +15,10 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 0.3.9+1
|
||||
version: 0.4.0
|
||||
|
||||
environment:
|
||||
flutter: ">=3.16.0"
|
||||
flutter: ">=3.18.0-0.2.pre"
|
||||
sdk: ">=3.1.5 <4.0.0"
|
||||
|
||||
# Dependencies specify other packages that your package needs in order to work.
|
||||
@ -131,6 +131,7 @@ dependencies:
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^3.0.1
|
||||
analyzer: ^6.3.0
|
||||
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
@ -163,7 +164,9 @@ dependency_overrides:
|
||||
appflowy_editor:
|
||||
git:
|
||||
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
||||
ref: "92e4260"
|
||||
ref: "20a714a"
|
||||
|
||||
file: ^7.0.0
|
||||
|
||||
logger: ^2.0.0
|
||||
|
||||
|
@ -39,7 +39,7 @@ RUN source ~/.cargo/env && \
|
||||
RUN sudo pacman -S --noconfirm git tar gtk3
|
||||
RUN curl -sSfL \
|
||||
--output flutter.tar.xz \
|
||||
https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.16.2-stable.tar.xz && \
|
||||
https://storage.googleapis.com/flutter_infra_release/releases/beta/linux/flutter_linux_3.18.0-0.2.pre-beta.tar.xz && \
|
||||
tar -xf flutter.tar.xz && \
|
||||
rm flutter.tar.xz
|
||||
RUN flutter config --enable-linux-desktop
|
||||
|
@ -44,9 +44,9 @@ printMessage "Setting up Flutter"
|
||||
|
||||
# Get the current Flutter version
|
||||
FLUTTER_VERSION=$(flutter --version | grep -oE 'Flutter [^ ]+' | grep -oE '[^ ]+$')
|
||||
# Check if the current version is 3.16.2
|
||||
if [ "$FLUTTER_VERSION" = "3.16.2" ]; then
|
||||
echo "Flutter version is already 3.16.2"
|
||||
# Check if the current version is 3.18.0-0.2.pre2
|
||||
if [ "$FLUTTER_VERSION" = "3.18.0-0.2.pre2" ]; then
|
||||
echo "Flutter version is already 3.18.0-0.2.pre2"
|
||||
else
|
||||
# Get the path to the Flutter SDK
|
||||
FLUTTER_PATH=$(which flutter)
|
||||
@ -55,12 +55,12 @@ else
|
||||
current_dir=$(pwd)
|
||||
|
||||
cd $FLUTTER_PATH
|
||||
# Use git to checkout version 3.16.2 of Flutter
|
||||
git checkout 3.16.2
|
||||
# Use git to checkout version 3.18.0-0.2.pre2 of Flutter
|
||||
git checkout 3.18.0-0.2.pre2
|
||||
# Get back to current working directory
|
||||
cd "$current_dir"
|
||||
|
||||
echo "Switched to Flutter version 3.16.2"
|
||||
echo "Switched to Flutter version 3.18.0-0.2.pre2"
|
||||
fi
|
||||
|
||||
# Enable linux desktop
|
||||
|
@ -38,9 +38,9 @@ fi
|
||||
printMessage "Setting up Flutter"
|
||||
# Get the current Flutter version
|
||||
FLUTTER_VERSION=$(flutter --version | grep -oP 'Flutter \K\S+')
|
||||
# Check if the current version is 3.16.2
|
||||
if [ "$FLUTTER_VERSION" = "3.16.2" ]; then
|
||||
echo "Flutter version is already 3.16.2"
|
||||
# Check if the current version is 3.18.0-0.2.pre2
|
||||
if [ "$FLUTTER_VERSION" = "3.18.0-0.2.pre2" ]; then
|
||||
echo "Flutter version is already 3.18.0-0.2.pre2"
|
||||
else
|
||||
# Get the path to the Flutter SDK
|
||||
FLUTTER_PATH=$(which flutter)
|
||||
@ -49,12 +49,12 @@ else
|
||||
current_dir=$(pwd)
|
||||
|
||||
cd $FLUTTER_PATH
|
||||
# Use git to checkout version 3.16.2 of Flutter
|
||||
git checkout 3.16.2
|
||||
# Use git to checkout version 3.18.0-0.2.pre2 of Flutter
|
||||
git checkout 3.18.0-0.2.pre2
|
||||
# Get back to current working directory
|
||||
cd "$current_dir"
|
||||
|
||||
echo "Switched to Flutter version 3.16.2"
|
||||
echo "Switched to Flutter version 3.18.0-0.2.pre2"
|
||||
fi
|
||||
|
||||
# Enable linux desktop
|
||||
|
@ -41,9 +41,9 @@ printMessage "Setting up Flutter"
|
||||
|
||||
# Get the current Flutter version
|
||||
FLUTTER_VERSION=$(flutter --version | grep -oE 'Flutter [^ ]+' | grep -oE '[^ ]+$')
|
||||
# Check if the current version is 3.16.2
|
||||
if [ "$FLUTTER_VERSION" = "3.16.2" ]; then
|
||||
echo "Flutter version is already 3.16.2"
|
||||
# Check if the current version is 3.18.0-0.2.pre2
|
||||
if [ "$FLUTTER_VERSION" = "3.18.0-0.2.pre2" ]; then
|
||||
echo "Flutter version is already 3.18.0-0.2.pre2"
|
||||
else
|
||||
# Get the path to the Flutter SDK
|
||||
FLUTTER_PATH=$(which flutter)
|
||||
@ -52,12 +52,12 @@ else
|
||||
current_dir=$(pwd)
|
||||
|
||||
cd $FLUTTER_PATH
|
||||
# Use git to checkout version 3.16.2 of Flutter
|
||||
git checkout 3.16.2
|
||||
# Use git to checkout version 3.18.0-0.2.pre2 of Flutter
|
||||
git checkout 3.18.0-0.2.pre2
|
||||
# Get back to current working directory
|
||||
cd "$current_dir"
|
||||
|
||||
echo "Switched to Flutter version 3.16.2"
|
||||
echo "Switched to Flutter version 3.18.0-0.2.pre2"
|
||||
fi
|
||||
|
||||
# Enable linux desktop
|
||||
|
@ -48,9 +48,9 @@ fi
|
||||
printMessage "Setting up Flutter"
|
||||
# Get the current Flutter version
|
||||
FLUTTER_VERSION=$(flutter --version | grep -oP 'Flutter \K\S+')
|
||||
# Check if the current version is 3.16.2
|
||||
if [ "$FLUTTER_VERSION" = "3.16.2" ]; then
|
||||
echo "Flutter version is already 3.16.2"
|
||||
# Check if the current version is 3.18.0-0.2.pre2
|
||||
if [ "$FLUTTER_VERSION" = "3.18.0-0.2.pre2" ]; then
|
||||
echo "Flutter version is already 3.18.0-0.2.pre2"
|
||||
else
|
||||
# Get the path to the Flutter SDK
|
||||
FLUTTER_PATH=$(which flutter)
|
||||
@ -59,12 +59,12 @@ else
|
||||
current_dir=$(pwd)
|
||||
|
||||
cd $FLUTTER_PATH
|
||||
# Use git to checkout version 3.16.2 of Flutter
|
||||
git checkout 3.16.2
|
||||
# Use git to checkout version 3.18.0-0.2.pre2 of Flutter
|
||||
git checkout 3.18.0-0.2.pre2
|
||||
# Get back to current working directory
|
||||
cd "$current_dir"
|
||||
|
||||
echo "Switched to Flutter version 3.16.2"
|
||||
echo "Switched to Flutter version 3.18.0-0.2.pre2"
|
||||
fi
|
||||
|
||||
# Add pub cache and cargo to PATH
|
||||
|