fix: 0.3.9 launch review (#4076)
* fix: cursor away doesn’t save the change. This behavior is inconsistent with the rest * fix: emoji doesn’t show fully * chore: set the default header text style to bold * fix: add missing divider in time option * fix: update placeholder cover color * fix: background color of the change cover button * fix: remove redundant padding * fix: use done action instead of return * fix: incorrect font size used in board and editor * feat: update appflowy-editor * fix: document freeze and the toolbar was invisible when hovering the align icon that in the toolbar * fix: snackbar text is invisiable * feat: padding of add icon button should be aligned the block * chore: update icon * fix: ci issues * feat: add time picker
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 17 KiB |
@ -1,13 +1,14 @@
|
|||||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/service/openai_client.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/service/openai_client.dart';
|
||||||
|
import 'package:appflowy/startup/startup.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
import 'package:appflowy_editor/src/render/toolbar/toolbar_widget.dart';
|
||||||
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
|
||||||
import 'util/mock/mock_openai_repository.dart';
|
import 'util/mock/mock_openai_repository.dart';
|
||||||
import 'util/util.dart';
|
import 'util/util.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
|
||||||
import 'package:appflowy_editor/src/render/toolbar/toolbar_widget.dart';
|
|
||||||
import 'package:appflowy/startup/startup.dart';
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.6 KiB |
@ -1 +1,80 @@
|
|||||||
{"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"}]}
|
{
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
@ -150,7 +150,6 @@ class _MobileViewPageState extends State<MobileViewPage> {
|
|||||||
onTap: (context) {
|
onTap: (context) {
|
||||||
showMobileBottomSheet(
|
showMobileBottomSheet(
|
||||||
context,
|
context,
|
||||||
showDragHandle: true,
|
|
||||||
builder: (_) => _buildViewPageBottomSheet(context),
|
builder: (_) => _buildViewPageBottomSheet(context),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -50,6 +50,8 @@ class _MobileBottomSheetRenameWidgetState
|
|||||||
height: 42.0,
|
height: 42.0,
|
||||||
child: FlowyTextField(
|
child: FlowyTextField(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
|
textInputAction: TextInputAction.done,
|
||||||
|
onSubmitted: (text) => widget.onRename(text),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -52,7 +52,6 @@ enum MobilePaneActionType {
|
|||||||
final favoriteBloc = context.read<FavoriteBloc>();
|
final favoriteBloc = context.read<FavoriteBloc>();
|
||||||
showMobileBottomSheet(
|
showMobileBottomSheet(
|
||||||
context,
|
context,
|
||||||
showDragHandle: true,
|
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
|
@ -6,7 +6,7 @@ import 'package:appflowy/plugins/database_view/widgets/card/card_cell_builder.da
|
|||||||
import 'package:appflowy/plugins/database_view/widgets/card/cells/card_cell.dart';
|
import 'package:appflowy/plugins/database_view/widgets/card/cells/card_cell.dart';
|
||||||
import 'package:appflowy/plugins/database_view/widgets/row/cells/text_cell/text_cell_bloc.dart';
|
import 'package:appflowy/plugins/database_view/widgets/row/cells/text_cell/text_cell_bloc.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.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';
|
||||||
|
|
||||||
@ -79,13 +79,9 @@ class MobileCardContent<CustomCardData> extends StatelessWidget {
|
|||||||
final text = cardDataIsEmpty
|
final text = cardDataIsEmpty
|
||||||
? LocaleKeys.grid_row_titlePlaceholder.tr()
|
? LocaleKeys.grid_row_titlePlaceholder.tr()
|
||||||
: cellData;
|
: cellData;
|
||||||
|
final color = cardDataIsEmpty
|
||||||
final textStyle = Theme.of(context).textTheme.bodyMedium?.copyWith(
|
? Theme.of(context).hintColor
|
||||||
color: cardDataIsEmpty
|
: Theme.of(context).colorScheme.onBackground;
|
||||||
? Theme.of(context).hintColor
|
|
||||||
: Theme.of(context).colorScheme.onBackground,
|
|
||||||
fontSize: 20,
|
|
||||||
);
|
|
||||||
|
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
@ -94,9 +90,9 @@ class MobileCardContent<CustomCardData> extends StatelessWidget {
|
|||||||
const HSpace(4),
|
const HSpace(4),
|
||||||
],
|
],
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: FlowyText.regular(
|
||||||
text,
|
text,
|
||||||
style: textStyle,
|
color: color,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -16,7 +16,7 @@ const _supportedFieldTypes = [
|
|||||||
FieldType.MultiSelect,
|
FieldType.MultiSelect,
|
||||||
FieldType.DateTime,
|
FieldType.DateTime,
|
||||||
FieldType.Checkbox,
|
FieldType.Checkbox,
|
||||||
FieldType.Checklist,
|
// FieldType.Checklist,
|
||||||
];
|
];
|
||||||
|
|
||||||
class FieldOptions extends StatelessWidget {
|
class FieldOptions extends StatelessWidget {
|
||||||
|
@ -531,7 +531,7 @@ class _TimeOptionState extends State<_TimeOption> {
|
|||||||
return FlowyOptionTile.checkbox(
|
return FlowyOptionTile.checkbox(
|
||||||
text: format.title(),
|
text: format.title(),
|
||||||
isSelected: selectedFormat == format,
|
isSelected: selectedFormat == format,
|
||||||
showTopBorder: false,
|
showTopBorder: index == 0,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
widget.onSelected(format);
|
widget.onSelected(format);
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
|
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||||
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
|
import 'package:appflowy/mobile/presentation/widgets/widgets.dart';
|
||||||
import 'package:appflowy/plugins/base/drag_handler.dart';
|
import 'package:appflowy/plugins/base/drag_handler.dart';
|
||||||
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
|
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
|
||||||
@ -12,6 +13,7 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
|||||||
import 'package:dartz/dartz.dart' hide State;
|
import 'package:dartz/dartz.dart' hide State;
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
import 'package:flutter/cupertino.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:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@ -73,15 +75,17 @@ class _MobileDateCellEditScreenState extends State<MobileDateCellEditScreen> {
|
|||||||
initialChildSize: 0.6,
|
initialChildSize: 0.6,
|
||||||
minChildSize: 0.6,
|
minChildSize: 0.6,
|
||||||
builder: (_, controller) => Material(
|
builder: (_, controller) => Material(
|
||||||
child: SingleChildScrollView(
|
child: ColoredBox(
|
||||||
controller: controller,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
child: Column(
|
child: SingleChildScrollView(
|
||||||
children: [
|
controller: controller,
|
||||||
const DragHandler(),
|
child: Column(
|
||||||
_buildHeader(),
|
children: [
|
||||||
const Divider(),
|
const DragHandler(),
|
||||||
_buildBody(),
|
_buildHeader(),
|
||||||
],
|
_buildBody(),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -171,16 +175,16 @@ class _DateCellEditBody extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
FlowyOptionDecorateBox(
|
FlowyOptionDecorateBox(
|
||||||
showTopBorder: false,
|
showTopBorder: false,
|
||||||
|
child: _IncludeTimePicker(),
|
||||||
|
),
|
||||||
|
_ColoredDivider(),
|
||||||
|
FlowyOptionDecorateBox(
|
||||||
child: MobileDatePicker(),
|
child: MobileDatePicker(),
|
||||||
),
|
),
|
||||||
_ColoredDivider(),
|
_ColoredDivider(),
|
||||||
_EndDateSwitch(),
|
_EndDateSwitch(),
|
||||||
_IncludeTimeSwitch(),
|
_IncludeTimeSwitch(),
|
||||||
_StartDayTime(),
|
|
||||||
_EndDayTime(),
|
|
||||||
_ColoredDivider(),
|
_ColoredDivider(),
|
||||||
_DateFormatOption(),
|
|
||||||
_TimeFormatOption(),
|
|
||||||
_ClearDateButton(),
|
_ClearDateButton(),
|
||||||
_ColoredDivider(),
|
_ColoredDivider(),
|
||||||
],
|
],
|
||||||
@ -201,6 +205,157 @@ class _ColoredDivider extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _IncludeTimePicker extends StatefulWidget {
|
||||||
|
const _IncludeTimePicker();
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_IncludeTimePicker> createState() => _IncludeTimePickerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _IncludeTimePickerState extends State<_IncludeTimePicker> {
|
||||||
|
String? _selectedTime;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<DateCellCalendarBloc, DateCellCalendarState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
final startDay = state.dateStr;
|
||||||
|
final endDay = state.endDateStr;
|
||||||
|
final includeTime = state.includeTime;
|
||||||
|
final use24hFormat =
|
||||||
|
state.dateTypeOptionPB.timeFormat == TimeFormatPB.TwentyFourHour;
|
||||||
|
if (startDay == null || startDay.isEmpty) {
|
||||||
|
return const Divider(
|
||||||
|
height: 1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Container(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_buildTime(
|
||||||
|
context,
|
||||||
|
includeTime,
|
||||||
|
use24hFormat,
|
||||||
|
true,
|
||||||
|
startDay,
|
||||||
|
state.timeStr,
|
||||||
|
),
|
||||||
|
VSpace(
|
||||||
|
8.0,
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
),
|
||||||
|
_buildTime(
|
||||||
|
context,
|
||||||
|
includeTime,
|
||||||
|
use24hFormat,
|
||||||
|
false,
|
||||||
|
endDay,
|
||||||
|
state.endTimeStr,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildTime(
|
||||||
|
BuildContext context,
|
||||||
|
bool isIncludeTime,
|
||||||
|
bool use24hFormat,
|
||||||
|
bool isStartDay,
|
||||||
|
String? dateStr,
|
||||||
|
String? timeStr,
|
||||||
|
) {
|
||||||
|
if (dateStr == null) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Widget> children = [];
|
||||||
|
|
||||||
|
if (!isIncludeTime) {
|
||||||
|
children.addAll([
|
||||||
|
const HSpace(12.0),
|
||||||
|
FlowyText(
|
||||||
|
dateStr,
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
children.addAll([
|
||||||
|
Expanded(
|
||||||
|
child: FlowyText(
|
||||||
|
dateStr,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 1,
|
||||||
|
height: 16,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: FlowyText(
|
||||||
|
timeStr ?? '',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
final bloc = context.read<DateCellCalendarBloc>();
|
||||||
|
await showMobileBottomSheet(
|
||||||
|
context,
|
||||||
|
builder: (context) {
|
||||||
|
return ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
maxHeight: 300,
|
||||||
|
),
|
||||||
|
child: CupertinoDatePicker(
|
||||||
|
showDayOfWeek: false,
|
||||||
|
mode: CupertinoDatePickerMode.time,
|
||||||
|
use24hFormat: use24hFormat,
|
||||||
|
onDateTimeChanged: (dateTime) {
|
||||||
|
_selectedTime = use24hFormat
|
||||||
|
? DateFormat('HH:mm').format(dateTime)
|
||||||
|
: DateFormat('hh:mm a').format(dateTime);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (_selectedTime != null) {
|
||||||
|
bloc.add(
|
||||||
|
isStartDay
|
||||||
|
? DateCellCalendarEvent.setTime(_selectedTime!)
|
||||||
|
: DateCellCalendarEvent.setEndTime(_selectedTime!),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
minHeight: 36,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(6),
|
||||||
|
color: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
|
border: Border.all(
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: children,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _EndDateSwitch extends StatelessWidget {
|
class _EndDateSwitch extends StatelessWidget {
|
||||||
const _EndDateSwitch();
|
const _EndDateSwitch();
|
||||||
|
|
||||||
@ -211,7 +366,6 @@ class _EndDateSwitch extends StatelessWidget {
|
|||||||
builder: (context, isRange) {
|
builder: (context, isRange) {
|
||||||
return FlowyOptionTile.switcher(
|
return FlowyOptionTile.switcher(
|
||||||
text: LocaleKeys.grid_field_isRange.tr(),
|
text: LocaleKeys.grid_field_isRange.tr(),
|
||||||
leftIcon: const FlowySvg(FlowySvgs.date_s),
|
|
||||||
isSelected: isRange,
|
isSelected: isRange,
|
||||||
onValueChanged: (value) {
|
onValueChanged: (value) {
|
||||||
context
|
context
|
||||||
@ -235,7 +389,6 @@ class _IncludeTimeSwitch extends StatelessWidget {
|
|||||||
return FlowyOptionTile.switcher(
|
return FlowyOptionTile.switcher(
|
||||||
showTopBorder: false,
|
showTopBorder: false,
|
||||||
text: LocaleKeys.grid_field_includeTime.tr(),
|
text: LocaleKeys.grid_field_includeTime.tr(),
|
||||||
leftIcon: const FlowySvg(FlowySvgs.clock_alarm_s),
|
|
||||||
isSelected: includeTime,
|
isSelected: includeTime,
|
||||||
onValueChanged: (value) {
|
onValueChanged: (value) {
|
||||||
context
|
context
|
||||||
@ -248,76 +401,6 @@ class _IncludeTimeSwitch extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _StartDayTime extends StatelessWidget {
|
|
||||||
const _StartDayTime();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return BlocBuilder<DateCellCalendarBloc, DateCellCalendarState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
return AnimatedSwitcher(
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
child: state.includeTime
|
|
||||||
? Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
state.isRange
|
|
||||||
? LocaleKeys.grid_field_startDateTime.tr()
|
|
||||||
: LocaleKeys.grid_field_dateTime.tr(),
|
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
|
||||||
),
|
|
||||||
const Spacer(),
|
|
||||||
// TODO(yijing): improve width
|
|
||||||
SizedBox(
|
|
||||||
width: 180,
|
|
||||||
child: _TimeTextField(
|
|
||||||
timeStr: state.timeStr,
|
|
||||||
isEndTime: false,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: const SizedBox.shrink(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _EndDayTime extends StatelessWidget {
|
|
||||||
const _EndDayTime();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return BlocBuilder<DateCellCalendarBloc, DateCellCalendarState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
return AnimatedSwitcher(
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
child: state.includeTime && state.endTimeStr != null
|
|
||||||
? Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
LocaleKeys.grid_field_endDateTime.tr(),
|
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
|
||||||
),
|
|
||||||
const Spacer(),
|
|
||||||
// TODO(yijing): improve width
|
|
||||||
SizedBox(
|
|
||||||
width: 180,
|
|
||||||
child: _TimeTextField(
|
|
||||||
timeStr: state.timeStr,
|
|
||||||
isEndTime: true,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: const SizedBox.shrink(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _TimeTextField extends StatefulWidget {
|
class _TimeTextField extends StatefulWidget {
|
||||||
const _TimeTextField({
|
const _TimeTextField({
|
||||||
required this.timeStr,
|
required this.timeStr,
|
||||||
@ -378,7 +461,6 @@ class _ClearDateButton extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FlowyOptionTile.text(
|
return FlowyOptionTile.text(
|
||||||
showTopBorder: false,
|
|
||||||
text: LocaleKeys.grid_field_clearDate.tr(),
|
text: LocaleKeys.grid_field_clearDate.tr(),
|
||||||
onTap: () => context
|
onTap: () => context
|
||||||
.read<DateCellCalendarBloc>()
|
.read<DateCellCalendarBloc>()
|
||||||
@ -386,68 +468,3 @@ class _ClearDateButton extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TimeFormatOption extends StatelessWidget {
|
|
||||||
const _TimeFormatOption();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return BlocSelector<DateCellCalendarBloc, DateCellCalendarState,
|
|
||||||
TimeFormatPB>(
|
|
||||||
selector: (state) => state.dateTypeOptionPB.timeFormat,
|
|
||||||
builder: (context, state) {
|
|
||||||
return FlowyOptionTile.text(
|
|
||||||
showTopBorder: false,
|
|
||||||
text: LocaleKeys.settings_appearance_timeFormat_label.tr(),
|
|
||||||
leftIcon: const FlowySvg(FlowySvgs.time_s),
|
|
||||||
);
|
|
||||||
// TimeFormatListTile(
|
|
||||||
// currentFormatStr: state.title(),
|
|
||||||
// groupValue: context
|
|
||||||
// .watch<DateCellCalendarBloc>()
|
|
||||||
// .state
|
|
||||||
// .dateTypeOptionPB
|
|
||||||
// .timeFormat,
|
|
||||||
// onChanged: (newFormat) {
|
|
||||||
// if (newFormat == null) return;
|
|
||||||
// context
|
|
||||||
// .read<DateCellCalendarBloc>()
|
|
||||||
// .add(DateCellCalendarEvent.setTimeFormat(newFormat));
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DateFormatOption extends StatelessWidget {
|
|
||||||
const _DateFormatOption();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return BlocSelector<DateCellCalendarBloc, DateCellCalendarState,
|
|
||||||
DateFormatPB>(
|
|
||||||
selector: (state) => state.dateTypeOptionPB.dateFormat,
|
|
||||||
builder: (context, state) {
|
|
||||||
return FlowyOptionTile.text(
|
|
||||||
text: LocaleKeys.settings_appearance_dateFormat_label.tr(),
|
|
||||||
leftIcon: const FlowySvg(FlowySvgs.clock_alarm_s),
|
|
||||||
);
|
|
||||||
// DateFormatListTile(
|
|
||||||
// currentFormatStr: state.title(),
|
|
||||||
// groupValue: context
|
|
||||||
// .watch<DateCellCalendarBloc>()
|
|
||||||
// .state
|
|
||||||
// .dateTypeOptionPB
|
|
||||||
// .dateFormat,
|
|
||||||
// onChanged: (newFormat) {
|
|
||||||
// if (newFormat == null) return;
|
|
||||||
// context
|
|
||||||
// .read<DateCellCalendarBloc>()
|
|
||||||
// .add(DateCellCalendarEvent.setDateFormat(newFormat));
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -143,7 +143,9 @@ class _MobileRecentViewState extends State<MobileRecentView> {
|
|||||||
builder: ((context, snapshot) {
|
builder: ((context, snapshot) {
|
||||||
final node = snapshot.data;
|
final node = snapshot.data;
|
||||||
final placeholder = Container(
|
final placeholder = Container(
|
||||||
color: Theme.of(context).colorScheme.onSecondaryContainer,
|
// random color, update it once we have a better placeholder
|
||||||
|
color:
|
||||||
|
Theme.of(context).colorScheme.onSurfaceVariant.withOpacity(0.2),
|
||||||
);
|
);
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
return placeholder;
|
return placeholder;
|
||||||
|
@ -141,7 +141,7 @@ class _RemoveIconButton extends StatelessWidget {
|
|||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
text: FlowyText(
|
text: FlowyText.small(
|
||||||
LocaleKeys.document_plugins_cover_removeIcon.tr(),
|
LocaleKeys.document_plugins_cover_removeIcon.tr(),
|
||||||
),
|
),
|
||||||
leftIcon: const FlowySvg(FlowySvgs.delete_s),
|
leftIcon: const FlowySvg(FlowySvgs.delete_s),
|
||||||
|
@ -80,6 +80,7 @@ class DateCellCalendarBloc
|
|||||||
await _updateDateData(isRange: isRange);
|
await _updateDateData(isRange: isRange);
|
||||||
},
|
},
|
||||||
setTime: (timeStr) async {
|
setTime: (timeStr) async {
|
||||||
|
emit(state.copyWith(timeStr: timeStr));
|
||||||
await _updateDateData(timeStr: timeStr);
|
await _updateDateData(timeStr: timeStr);
|
||||||
},
|
},
|
||||||
selectDateRange: (DateTime? start, DateTime? end) async {
|
selectDateRange: (DateTime? start, DateTime? end) async {
|
||||||
@ -158,6 +159,7 @@ class DateCellCalendarBloc
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setEndTime: (String endTime) async {
|
setEndTime: (String endTime) async {
|
||||||
|
emit(state.copyWith(endTimeStr: endTime));
|
||||||
await _updateDateData(endTimeStr: endTime);
|
await _updateDateData(endTimeStr: endTime);
|
||||||
},
|
},
|
||||||
setDateFormat: (dateFormat) async {
|
setDateFormat: (dateFormat) async {
|
||||||
|
@ -91,11 +91,14 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
|||||||
final List<ToolbarItem> toolbarItems = [
|
final List<ToolbarItem> toolbarItems = [
|
||||||
smartEditItem..isActive = onlyShowInSingleTextTypeSelectionAndExcludeTable,
|
smartEditItem..isActive = onlyShowInSingleTextTypeSelectionAndExcludeTable,
|
||||||
paragraphItem..isActive = onlyShowInSingleTextTypeSelectionAndExcludeTable,
|
paragraphItem..isActive = onlyShowInSingleTextTypeSelectionAndExcludeTable,
|
||||||
...(headingItems
|
...headingItems
|
||||||
..forEach(
|
..forEach(
|
||||||
(e) => e.isActive = onlyShowInSingleSelectionAndTextType,
|
(e) => e.isActive = onlyShowInSingleSelectionAndTextType,
|
||||||
)),
|
),
|
||||||
...markdownFormatItems,
|
...markdownFormatItems
|
||||||
|
..forEach(
|
||||||
|
(e) => e.isActive = showInAnyTextType,
|
||||||
|
),
|
||||||
quoteItem..isActive = onlyShowInSingleTextTypeSelectionAndExcludeTable,
|
quoteItem..isActive = onlyShowInSingleTextTypeSelectionAndExcludeTable,
|
||||||
bulletedListItem
|
bulletedListItem
|
||||||
..isActive = onlyShowInSingleTextTypeSelectionAndExcludeTable,
|
..isActive = onlyShowInSingleTextTypeSelectionAndExcludeTable,
|
||||||
@ -497,3 +500,14 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
|||||||
await editorState.apply(transaction);
|
await editorState.apply(transaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool showInAnyTextType(EditorState editorState) {
|
||||||
|
final selection = editorState.selection;
|
||||||
|
if (selection == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final nodes = editorState.getNodesInSelection(selection);
|
||||||
|
return nodes.any(
|
||||||
|
(node) => toolbarItemWhiteList.contains(node.type),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -70,7 +70,6 @@ class MobileBlockActionButtons extends StatelessWidget {
|
|||||||
showMobileBottomSheet(
|
showMobileBottomSheet(
|
||||||
context,
|
context,
|
||||||
showHeader: true,
|
showHeader: true,
|
||||||
showDragHandle: true,
|
|
||||||
showCloseButton: true,
|
showCloseButton: true,
|
||||||
title: LocaleKeys.document_plugins_action.tr(),
|
title: LocaleKeys.document_plugins_action.tr(),
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
|
@ -34,16 +34,24 @@ final alignToolbarItem = ToolbarItem(
|
|||||||
data = FlowySvgs.toolbar_align_right_s;
|
data = FlowySvgs.toolbar_align_right_s;
|
||||||
}
|
}
|
||||||
|
|
||||||
final child = MouseRegion(
|
// final child = MouseRegion(
|
||||||
cursor: SystemMouseCursors.click,
|
// cursor: SystemMouseCursors.click,
|
||||||
child: FlowyTooltip(
|
// child: FlowyTooltip(
|
||||||
message: LocaleKeys.document_plugins_optionAction_align.tr(),
|
// message: LocaleKeys.document_plugins_optionAction_align.tr(),
|
||||||
child: FlowySvg(
|
// child: FlowySvg(
|
||||||
data,
|
// data,
|
||||||
size: const Size.square(16),
|
// size: const Size.square(16),
|
||||||
color: isHighlight ? highlightColor : Colors.white,
|
// 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(
|
return Padding(
|
||||||
|
@ -230,9 +230,11 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
|
|||||||
alignment: Alignment.bottomLeft,
|
alignment: Alignment.bottomLeft,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
padding: PlatformExtension.isDesktopOrWeb
|
padding: PlatformExtension.isDesktopOrWeb
|
||||||
? EditorStyleCustomizer.documentPadding
|
? EdgeInsets.symmetric(
|
||||||
|
horizontal: EditorStyleCustomizer.documentPadding.right,
|
||||||
|
)
|
||||||
: EdgeInsets.symmetric(
|
: EdgeInsets.symmetric(
|
||||||
horizontal: EditorStyleCustomizer.documentPadding.left - 6.0,
|
horizontal: EditorStyleCustomizer.documentPadding.left,
|
||||||
),
|
),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 28,
|
height: 28,
|
||||||
@ -276,7 +278,7 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
|
|||||||
),
|
),
|
||||||
useIntrinsicWidth: true,
|
useIntrinsicWidth: true,
|
||||||
leftIcon: const FlowySvg(FlowySvgs.image_s),
|
leftIcon: const FlowySvg(FlowySvgs.image_s),
|
||||||
text: FlowyText.regular(
|
text: FlowyText.small(
|
||||||
LocaleKeys.document_plugins_cover_addCover.tr(),
|
LocaleKeys.document_plugins_cover_addCover.tr(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -293,7 +295,7 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
|
|||||||
Icons.emoji_emotions_outlined,
|
Icons.emoji_emotions_outlined,
|
||||||
size: 18,
|
size: 18,
|
||||||
),
|
),
|
||||||
text: FlowyText.regular(
|
text: FlowyText.small(
|
||||||
LocaleKeys.document_plugins_cover_removeIcon.tr(),
|
LocaleKeys.document_plugins_cover_removeIcon.tr(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -306,7 +308,7 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
|
|||||||
Icons.emoji_emotions_outlined,
|
Icons.emoji_emotions_outlined,
|
||||||
size: 18,
|
size: 18,
|
||||||
),
|
),
|
||||||
text: FlowyText.regular(
|
text: FlowyText.small(
|
||||||
LocaleKeys.document_plugins_cover_addIcon.tr(),
|
LocaleKeys.document_plugins_cover_addIcon.tr(),
|
||||||
),
|
),
|
||||||
onTap: PlatformExtension.isDesktop
|
onTap: PlatformExtension.isDesktop
|
||||||
@ -468,7 +470,10 @@ class DocumentCoverState extends State<DocumentCover> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
fillColor: Theme.of(context).colorScheme.onSurfaceVariant,
|
fillColor: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.onSurfaceVariant
|
||||||
|
.withOpacity(0.5),
|
||||||
height: 32,
|
height: 32,
|
||||||
title: LocaleKeys.document_plugins_cover_changeCover.tr(),
|
title: LocaleKeys.document_plugins_cover_changeCover.tr(),
|
||||||
),
|
),
|
||||||
@ -587,7 +592,7 @@ class DeleteCoverButton extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final fillColor = PlatformExtension.isDesktopOrWeb
|
final fillColor = PlatformExtension.isDesktopOrWeb
|
||||||
? Theme.of(context).colorScheme.surface.withOpacity(0.5)
|
? Theme.of(context).colorScheme.surface.withOpacity(0.5)
|
||||||
: Theme.of(context).colorScheme.onSurfaceVariant;
|
: Theme.of(context).colorScheme.onSurfaceVariant.withOpacity(0.5);
|
||||||
final svgColor = PlatformExtension.isDesktopOrWeb
|
final svgColor = PlatformExtension.isDesktopOrWeb
|
||||||
? Theme.of(context).colorScheme.tertiary
|
? Theme.of(context).colorScheme.tertiary
|
||||||
: Theme.of(context).colorScheme.onPrimary;
|
: Theme.of(context).colorScheme.onPrimary;
|
||||||
|
@ -42,11 +42,13 @@ class MentionBlock extends StatelessWidget {
|
|||||||
required this.mention,
|
required this.mention,
|
||||||
required this.node,
|
required this.node,
|
||||||
required this.index,
|
required this.index,
|
||||||
|
required this.textStyle,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Map<String, dynamic> mention;
|
final Map<String, dynamic> mention;
|
||||||
final Node node;
|
final Node node;
|
||||||
final int index;
|
final int index;
|
||||||
|
final TextStyle? textStyle;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -58,6 +60,7 @@ class MentionBlock extends StatelessWidget {
|
|||||||
return MentionPageBlock(
|
return MentionPageBlock(
|
||||||
key: ValueKey(pageId),
|
key: ValueKey(pageId),
|
||||||
pageId: pageId,
|
pageId: pageId,
|
||||||
|
textStyle: textStyle,
|
||||||
);
|
);
|
||||||
case MentionType.reminder:
|
case MentionType.reminder:
|
||||||
case MentionType.date:
|
case MentionType.date:
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/more/cubit/document_appearance_cubit.dart';
|
|
||||||
import 'package:appflowy/plugins/trash/application/trash_service.dart';
|
import 'package:appflowy/plugins/trash/application/trash_service.dart';
|
||||||
import 'package:appflowy/startup/startup.dart';
|
import 'package:appflowy/startup/startup.dart';
|
||||||
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
|
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
|
||||||
@ -22,9 +21,11 @@ class MentionPageBlock extends StatefulWidget {
|
|||||||
const MentionPageBlock({
|
const MentionPageBlock({
|
||||||
super.key,
|
super.key,
|
||||||
required this.pageId,
|
required this.pageId,
|
||||||
|
required this.textStyle,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String pageId;
|
final String pageId;
|
||||||
|
final TextStyle? textStyle;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<MentionPageBlock> createState() => _MentionPageBlockState();
|
State<MentionPageBlock> createState() => _MentionPageBlockState();
|
||||||
@ -59,7 +60,6 @@ class _MentionPageBlockState extends State<MentionPageBlock> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final fontSize = context.read<DocumentAppearanceCubit>().state.fontSize;
|
|
||||||
return FutureBuilder<ViewPB?>(
|
return FutureBuilder<ViewPB?>(
|
||||||
initialData: pageMemorizer[widget.pageId],
|
initialData: pageMemorizer[widget.pageId],
|
||||||
future: viewPBFuture,
|
future: viewPBFuture,
|
||||||
@ -71,6 +71,7 @@ class _MentionPageBlockState extends State<MentionPageBlock> {
|
|||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
updateSelection();
|
updateSelection();
|
||||||
|
final iconSize = widget.textStyle?.fontSize ?? 16.0;
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 2),
|
padding: const EdgeInsets.symmetric(horizontal: 2),
|
||||||
child: FlowyHover(
|
child: FlowyHover(
|
||||||
@ -84,13 +85,14 @@ class _MentionPageBlockState extends State<MentionPageBlock> {
|
|||||||
const HSpace(4),
|
const HSpace(4),
|
||||||
FlowySvg(
|
FlowySvg(
|
||||||
view.layout.icon,
|
view.layout.icon,
|
||||||
size: const Size.square(18.0),
|
size: Size.square(iconSize + 2.0),
|
||||||
),
|
),
|
||||||
const HSpace(2),
|
const HSpace(2),
|
||||||
FlowyText(
|
FlowyText(
|
||||||
view.name,
|
view.name,
|
||||||
decoration: TextDecoration.underline,
|
decoration: TextDecoration.underline,
|
||||||
fontSize: fontSize,
|
fontSize: widget.textStyle?.fontSize,
|
||||||
|
fontWeight: widget.textStyle?.fontWeight,
|
||||||
),
|
),
|
||||||
const HSpace(2),
|
const HSpace(2),
|
||||||
],
|
],
|
||||||
|
@ -52,7 +52,6 @@ Future<void> _showBlockActionSheet(
|
|||||||
builder: (context) {
|
builder: (context) {
|
||||||
return BlockActionBottomSheet(
|
return BlockActionBottomSheet(
|
||||||
extendActionWidgets: [
|
extendActionWidgets: [
|
||||||
const VSpace(8),
|
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
|
@ -140,9 +140,10 @@ class EditorStyleCustomizer {
|
|||||||
fontSize + 2,
|
fontSize + 2,
|
||||||
fontSize,
|
fontSize,
|
||||||
];
|
];
|
||||||
return TextStyle(
|
final fontFamily = context.read<DocumentAppearanceCubit>().state.fontFamily;
|
||||||
|
return baseTextStyle(fontFamily, fontWeight: FontWeight.bold).copyWith(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
fontSize: fontSizes.elementAtOrNull(level - 1) ?? fontSize,
|
fontSize: fontSizes.elementAtOrNull(level - 1) ?? fontSize,
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,11 +218,12 @@ class EditorStyleCustomizer {
|
|||||||
Node node,
|
Node node,
|
||||||
int index,
|
int index,
|
||||||
TextInsert text,
|
TextInsert text,
|
||||||
TextSpan textSpan,
|
TextSpan before,
|
||||||
|
TextSpan after,
|
||||||
) {
|
) {
|
||||||
final attributes = text.attributes;
|
final attributes = text.attributes;
|
||||||
if (attributes == null) {
|
if (attributes == null) {
|
||||||
return textSpan;
|
return before;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to refresh font here.
|
// try to refresh font here.
|
||||||
@ -240,6 +242,7 @@ class EditorStyleCustomizer {
|
|||||||
final type = mention[MentionBlockKeys.type];
|
final type = mention[MentionBlockKeys.type];
|
||||||
return WidgetSpan(
|
return WidgetSpan(
|
||||||
alignment: PlaceholderAlignment.middle,
|
alignment: PlaceholderAlignment.middle,
|
||||||
|
style: after.style,
|
||||||
child: MentionBlock(
|
child: MentionBlock(
|
||||||
key: ValueKey(
|
key: ValueKey(
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -253,6 +256,7 @@ class EditorStyleCustomizer {
|
|||||||
node: node,
|
node: node,
|
||||||
index: index,
|
index: index,
|
||||||
mention: mention,
|
mention: mention,
|
||||||
|
textStyle: after.style,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -275,7 +279,7 @@ class EditorStyleCustomizer {
|
|||||||
final href = attributes[AppFlowyRichTextKeys.href] as String?;
|
final href = attributes[AppFlowyRichTextKeys.href] as String?;
|
||||||
if (PlatformExtension.isMobile && href != null) {
|
if (PlatformExtension.isMobile && href != null) {
|
||||||
return TextSpan(
|
return TextSpan(
|
||||||
style: textSpan.style,
|
style: before.style,
|
||||||
text: text.text,
|
text: text.text,
|
||||||
recognizer: TapGestureRecognizer()
|
recognizer: TapGestureRecognizer()
|
||||||
..onTap = () {
|
..onTap = () {
|
||||||
@ -305,7 +309,8 @@ class EditorStyleCustomizer {
|
|||||||
node,
|
node,
|
||||||
index,
|
index,
|
||||||
text,
|
text,
|
||||||
textSpan,
|
before,
|
||||||
|
after,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,13 +60,14 @@ void showSnackBarMessage(
|
|||||||
? null
|
? null
|
||||||
: SnackBarAction(
|
: SnackBarAction(
|
||||||
label: LocaleKeys.button_cancel.tr(),
|
label: LocaleKeys.button_cancel.tr(),
|
||||||
textColor: Theme.of(context).colorScheme.onSurface,
|
textColor: Colors.white,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
content: FlowyText(
|
content: FlowyText(
|
||||||
message,
|
message,
|
||||||
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -152,6 +152,7 @@ class _ViewTitleState extends State<_ViewTitle> {
|
|||||||
|
|
||||||
String name = '';
|
String name = '';
|
||||||
String icon = '';
|
String icon = '';
|
||||||
|
String inputtingName = '';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -266,6 +267,18 @@ class _ViewTitleState extends State<_ViewTitle> {
|
|||||||
}
|
}
|
||||||
popoverController.close();
|
popoverController.close();
|
||||||
},
|
},
|
||||||
|
onChanged: (text) async {
|
||||||
|
inputtingName = text;
|
||||||
|
},
|
||||||
|
onCanceled: () async {
|
||||||
|
if (inputtingName.isNotEmpty && inputtingName != name) {
|
||||||
|
await ViewBackendService.updateView(
|
||||||
|
viewId: widget.view.id,
|
||||||
|
name: inputtingName,
|
||||||
|
);
|
||||||
|
popoverController.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const HSpace(4.0),
|
const HSpace(4.0),
|
||||||
@ -280,6 +293,7 @@ class _ViewTitleState extends State<_ViewTitle> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _resetTextEditingController() {
|
void _resetTextEditingController() {
|
||||||
|
inputtingName = name;
|
||||||
textEditingController
|
textEditingController
|
||||||
..text = name
|
..text = name
|
||||||
..selection = TextSelection(
|
..selection = TextSelection(
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class FlowyText extends StatelessWidget {
|
class FlowyText extends StatelessWidget {
|
||||||
@ -28,6 +30,21 @@ class FlowyText extends StatelessWidget {
|
|||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
FlowyText.small(
|
||||||
|
this.text, {
|
||||||
|
this.overflow,
|
||||||
|
this.color,
|
||||||
|
this.textAlign,
|
||||||
|
this.maxLines = 1,
|
||||||
|
this.decoration,
|
||||||
|
this.selectable = false,
|
||||||
|
this.fontFamily,
|
||||||
|
this.fallbackFontFamily,
|
||||||
|
Key? key,
|
||||||
|
}) : fontWeight = FontWeight.w400,
|
||||||
|
fontSize = (Platform.isIOS || Platform.isAndroid) ? 14 : 12,
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
const FlowyText.regular(
|
const FlowyText.regular(
|
||||||
this.text, {
|
this.text, {
|
||||||
this.fontSize,
|
this.fontSize,
|
||||||
|
@ -54,8 +54,8 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: "9c7a4e"
|
ref: "4995d21"
|
||||||
resolved-ref: "9c7a4ee671768524b0dd6f3ebb12dd845932ee74"
|
resolved-ref: "4995d21ff49907c71286e668f938f830bf94ca0d"
|
||||||
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
||||||
source: git
|
source: git
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
@ -580,8 +580,8 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: "140b530"
|
ref: "4a5cac"
|
||||||
resolved-ref: "140b53091ce7ad971e97c1d5a53fe0875596326d"
|
resolved-ref: "4a5cac57e31c0ffd49cd6257a9e078f084ae342c"
|
||||||
url: "https://github.com/LucasXu0/emoji_mart.git"
|
url: "https://github.com/LucasXu0/emoji_mart.git"
|
||||||
source: git
|
source: git
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
|
@ -46,7 +46,7 @@ dependencies:
|
|||||||
appflowy_editor:
|
appflowy_editor:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
||||||
ref: "9c7a4e"
|
ref: "4995d21"
|
||||||
|
|
||||||
appflowy_popover:
|
appflowy_popover:
|
||||||
path: packages/appflowy_popover
|
path: packages/appflowy_popover
|
||||||
@ -115,7 +115,7 @@ dependencies:
|
|||||||
flutter_emoji_mart:
|
flutter_emoji_mart:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/LucasXu0/emoji_mart.git
|
url: https://github.com/LucasXu0/emoji_mart.git
|
||||||
ref: "140b530"
|
ref: "4a5cac"
|
||||||
|
|
||||||
# Notifications
|
# Notifications
|
||||||
# TODO: Consider implementing custom package
|
# TODO: Consider implementing custom package
|
||||||
|