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
This commit is contained in:
Lucas.Xu 2023-12-05 10:46:17 +08:00 committed by GitHub
parent 0d776a9294
commit 1491fbfb0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 380 additions and 210 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -1,13 +1,14 @@
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/src/render/toolbar/toolbar_widget.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'util/mock/mock_openai_repository.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() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -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
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -150,7 +150,6 @@ class _MobileViewPageState extends State<MobileViewPage> {
onTap: (context) {
showMobileBottomSheet(
context,
showDragHandle: true,
builder: (_) => _buildViewPageBottomSheet(context),
);
},

View File

@ -50,6 +50,8 @@ class _MobileBottomSheetRenameWidgetState
height: 42.0,
child: FlowyTextField(
controller: controller,
textInputAction: TextInputAction.done,
onSubmitted: (text) => widget.onRename(text),
),
),
),

View File

@ -52,7 +52,6 @@ enum MobilePaneActionType {
final favoriteBloc = context.read<FavoriteBloc>();
showMobileBottomSheet(
context,
showDragHandle: true,
builder: (context) {
return MultiBlocProvider(
providers: [

View File

@ -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/row/cells/text_cell/text_cell_bloc.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_bloc/flutter_bloc.dart';
@ -79,13 +79,9 @@ class MobileCardContent<CustomCardData> extends StatelessWidget {
final text = cardDataIsEmpty
? LocaleKeys.grid_row_titlePlaceholder.tr()
: cellData;
final textStyle = Theme.of(context).textTheme.bodyMedium?.copyWith(
color: cardDataIsEmpty
? Theme.of(context).hintColor
: Theme.of(context).colorScheme.onBackground,
fontSize: 20,
);
final color = cardDataIsEmpty
? Theme.of(context).hintColor
: Theme.of(context).colorScheme.onBackground;
return Row(
children: [
@ -94,9 +90,9 @@ class MobileCardContent<CustomCardData> extends StatelessWidget {
const HSpace(4),
],
Expanded(
child: Text(
child: FlowyText.regular(
text,
style: textStyle,
color: color,
overflow: TextOverflow.ellipsis,
),
),

View File

@ -16,7 +16,7 @@ const _supportedFieldTypes = [
FieldType.MultiSelect,
FieldType.DateTime,
FieldType.Checkbox,
FieldType.Checklist,
// FieldType.Checklist,
];
class FieldOptions extends StatelessWidget {

View File

@ -531,7 +531,7 @@ class _TimeOptionState extends State<_TimeOption> {
return FlowyOptionTile.checkbox(
text: format.title(),
isSelected: selectedFormat == format,
showTopBorder: false,
showTopBorder: index == 0,
onTap: () {
widget.onSelected(format);
setState(() {

View File

@ -1,5 +1,6 @@
import 'package:appflowy/generated/flowy_svgs.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/plugins/base/drag_handler.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:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
@ -73,15 +75,17 @@ class _MobileDateCellEditScreenState extends State<MobileDateCellEditScreen> {
initialChildSize: 0.6,
minChildSize: 0.6,
builder: (_, controller) => Material(
child: SingleChildScrollView(
controller: controller,
child: Column(
children: [
const DragHandler(),
_buildHeader(),
const Divider(),
_buildBody(),
],
child: ColoredBox(
color: Theme.of(context).colorScheme.surface,
child: SingleChildScrollView(
controller: controller,
child: Column(
children: [
const DragHandler(),
_buildHeader(),
_buildBody(),
],
),
),
),
),
@ -171,16 +175,16 @@ class _DateCellEditBody extends StatelessWidget {
children: [
FlowyOptionDecorateBox(
showTopBorder: false,
child: _IncludeTimePicker(),
),
_ColoredDivider(),
FlowyOptionDecorateBox(
child: MobileDatePicker(),
),
_ColoredDivider(),
_EndDateSwitch(),
_IncludeTimeSwitch(),
_StartDayTime(),
_EndDayTime(),
_ColoredDivider(),
_DateFormatOption(),
_TimeFormatOption(),
_ClearDateButton(),
_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 {
const _EndDateSwitch();
@ -211,7 +366,6 @@ class _EndDateSwitch extends StatelessWidget {
builder: (context, isRange) {
return FlowyOptionTile.switcher(
text: LocaleKeys.grid_field_isRange.tr(),
leftIcon: const FlowySvg(FlowySvgs.date_s),
isSelected: isRange,
onValueChanged: (value) {
context
@ -235,7 +389,6 @@ class _IncludeTimeSwitch extends StatelessWidget {
return FlowyOptionTile.switcher(
showTopBorder: false,
text: LocaleKeys.grid_field_includeTime.tr(),
leftIcon: const FlowySvg(FlowySvgs.clock_alarm_s),
isSelected: includeTime,
onValueChanged: (value) {
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 {
const _TimeTextField({
required this.timeStr,
@ -378,7 +461,6 @@ class _ClearDateButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FlowyOptionTile.text(
showTopBorder: false,
text: LocaleKeys.grid_field_clearDate.tr(),
onTap: () => context
.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));
// },
// );
},
);
}
}

View File

@ -143,7 +143,9 @@ class _MobileRecentViewState extends State<MobileRecentView> {
builder: ((context, snapshot) {
final node = snapshot.data;
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) {
return placeholder;

View File

@ -141,7 +141,7 @@ class _RemoveIconButton extends StatelessWidget {
child: FlowyButton(
onTap: onTap,
useIntrinsicWidth: true,
text: FlowyText(
text: FlowyText.small(
LocaleKeys.document_plugins_cover_removeIcon.tr(),
),
leftIcon: const FlowySvg(FlowySvgs.delete_s),

View File

@ -80,6 +80,7 @@ class DateCellCalendarBloc
await _updateDateData(isRange: isRange);
},
setTime: (timeStr) async {
emit(state.copyWith(timeStr: timeStr));
await _updateDateData(timeStr: timeStr);
},
selectDateRange: (DateTime? start, DateTime? end) async {
@ -158,6 +159,7 @@ class DateCellCalendarBloc
}
},
setEndTime: (String endTime) async {
emit(state.copyWith(endTimeStr: endTime));
await _updateDateData(endTimeStr: endTime);
},
setDateFormat: (dateFormat) async {

View File

@ -91,11 +91,14 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
final List<ToolbarItem> toolbarItems = [
smartEditItem..isActive = onlyShowInSingleTextTypeSelectionAndExcludeTable,
paragraphItem..isActive = onlyShowInSingleTextTypeSelectionAndExcludeTable,
...(headingItems
...headingItems
..forEach(
(e) => e.isActive = onlyShowInSingleSelectionAndTextType,
)),
...markdownFormatItems,
),
...markdownFormatItems
..forEach(
(e) => e.isActive = showInAnyTextType,
),
quoteItem..isActive = onlyShowInSingleTextTypeSelectionAndExcludeTable,
bulletedListItem
..isActive = onlyShowInSingleTextTypeSelectionAndExcludeTable,
@ -497,3 +500,14 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
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),
);
}

View File

@ -70,7 +70,6 @@ class MobileBlockActionButtons extends StatelessWidget {
showMobileBottomSheet(
context,
showHeader: true,
showDragHandle: true,
showCloseButton: true,
title: LocaleKeys.document_plugins_action.tr(),
builder: (context) {

View File

@ -34,16 +34,24 @@ 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,
),
),
// 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(

View File

@ -230,9 +230,11 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
alignment: Alignment.bottomLeft,
width: double.infinity,
padding: PlatformExtension.isDesktopOrWeb
? EditorStyleCustomizer.documentPadding
? EdgeInsets.symmetric(
horizontal: EditorStyleCustomizer.documentPadding.right,
)
: EdgeInsets.symmetric(
horizontal: EditorStyleCustomizer.documentPadding.left - 6.0,
horizontal: EditorStyleCustomizer.documentPadding.left,
),
child: SizedBox(
height: 28,
@ -276,7 +278,7 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
),
useIntrinsicWidth: true,
leftIcon: const FlowySvg(FlowySvgs.image_s),
text: FlowyText.regular(
text: FlowyText.small(
LocaleKeys.document_plugins_cover_addCover.tr(),
),
),
@ -293,7 +295,7 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
Icons.emoji_emotions_outlined,
size: 18,
),
text: FlowyText.regular(
text: FlowyText.small(
LocaleKeys.document_plugins_cover_removeIcon.tr(),
),
),
@ -306,7 +308,7 @@ class _DocumentHeaderToolbarState extends State<DocumentHeaderToolbar> {
Icons.emoji_emotions_outlined,
size: 18,
),
text: FlowyText.regular(
text: FlowyText.small(
LocaleKeys.document_plugins_cover_addIcon.tr(),
),
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,
title: LocaleKeys.document_plugins_cover_changeCover.tr(),
),
@ -587,7 +592,7 @@ class DeleteCoverButton extends StatelessWidget {
Widget build(BuildContext context) {
final fillColor = PlatformExtension.isDesktopOrWeb
? 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
? Theme.of(context).colorScheme.tertiary
: Theme.of(context).colorScheme.onPrimary;

View File

@ -42,11 +42,13 @@ class MentionBlock extends StatelessWidget {
required this.mention,
required this.node,
required this.index,
required this.textStyle,
});
final Map<String, dynamic> mention;
final Node node;
final int index;
final TextStyle? textStyle;
@override
Widget build(BuildContext context) {
@ -58,6 +60,7 @@ class MentionBlock extends StatelessWidget {
return MentionPageBlock(
key: ValueKey(pageId),
pageId: pageId,
textStyle: textStyle,
);
case MentionType.reminder:
case MentionType.date:

View File

@ -1,5 +1,4 @@
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/startup/startup.dart';
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
@ -22,9 +21,11 @@ class MentionPageBlock extends StatefulWidget {
const MentionPageBlock({
super.key,
required this.pageId,
required this.textStyle,
});
final String pageId;
final TextStyle? textStyle;
@override
State<MentionPageBlock> createState() => _MentionPageBlockState();
@ -59,7 +60,6 @@ class _MentionPageBlockState extends State<MentionPageBlock> {
@override
Widget build(BuildContext context) {
final fontSize = context.read<DocumentAppearanceCubit>().state.fontSize;
return FutureBuilder<ViewPB?>(
initialData: pageMemorizer[widget.pageId],
future: viewPBFuture,
@ -71,6 +71,7 @@ class _MentionPageBlockState extends State<MentionPageBlock> {
return const SizedBox.shrink();
}
updateSelection();
final iconSize = widget.textStyle?.fontSize ?? 16.0;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 2),
child: FlowyHover(
@ -84,13 +85,14 @@ class _MentionPageBlockState extends State<MentionPageBlock> {
const HSpace(4),
FlowySvg(
view.layout.icon,
size: const Size.square(18.0),
size: Size.square(iconSize + 2.0),
),
const HSpace(2),
FlowyText(
view.name,
decoration: TextDecoration.underline,
fontSize: fontSize,
fontSize: widget.textStyle?.fontSize,
fontWeight: widget.textStyle?.fontWeight,
),
const HSpace(2),
],

View File

@ -52,7 +52,6 @@ Future<void> _showBlockActionSheet(
builder: (context) {
return BlockActionBottomSheet(
extendActionWidgets: [
const VSpace(8),
Row(
children: [
Expanded(

View File

@ -140,9 +140,10 @@ class EditorStyleCustomizer {
fontSize + 2,
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,
fontWeight: FontWeight.bold,
);
}
@ -217,11 +218,12 @@ class EditorStyleCustomizer {
Node node,
int index,
TextInsert text,
TextSpan textSpan,
TextSpan before,
TextSpan after,
) {
final attributes = text.attributes;
if (attributes == null) {
return textSpan;
return before;
}
// try to refresh font here.
@ -240,6 +242,7 @@ class EditorStyleCustomizer {
final type = mention[MentionBlockKeys.type];
return WidgetSpan(
alignment: PlaceholderAlignment.middle,
style: after.style,
child: MentionBlock(
key: ValueKey(
switch (type) {
@ -253,6 +256,7 @@ class EditorStyleCustomizer {
node: node,
index: index,
mention: mention,
textStyle: after.style,
),
);
}
@ -275,7 +279,7 @@ class EditorStyleCustomizer {
final href = attributes[AppFlowyRichTextKeys.href] as String?;
if (PlatformExtension.isMobile && href != null) {
return TextSpan(
style: textSpan.style,
style: before.style,
text: text.text,
recognizer: TapGestureRecognizer()
..onTap = () {
@ -305,7 +309,8 @@ class EditorStyleCustomizer {
node,
index,
text,
textSpan,
before,
after,
);
}

View File

@ -60,13 +60,14 @@ void showSnackBarMessage(
? null
: SnackBarAction(
label: LocaleKeys.button_cancel.tr(),
textColor: Theme.of(context).colorScheme.onSurface,
textColor: Colors.white,
onPressed: () {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
content: FlowyText(
message,
color: Colors.white,
),
),
);

View File

@ -152,6 +152,7 @@ class _ViewTitleState extends State<_ViewTitle> {
String name = '';
String icon = '';
String inputtingName = '';
@override
void initState() {
@ -266,6 +267,18 @@ class _ViewTitleState extends State<_ViewTitle> {
}
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),
@ -280,6 +293,7 @@ class _ViewTitleState extends State<_ViewTitle> {
}
void _resetTextEditingController() {
inputtingName = name;
textEditingController
..text = name
..selection = TextSelection(

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart';
class FlowyText extends StatelessWidget {
@ -28,6 +30,21 @@ class FlowyText extends StatelessWidget {
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(
this.text, {
this.fontSize,

View File

@ -54,8 +54,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: "9c7a4e"
resolved-ref: "9c7a4ee671768524b0dd6f3ebb12dd845932ee74"
ref: "4995d21"
resolved-ref: "4995d21ff49907c71286e668f938f830bf94ca0d"
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
source: git
version: "2.0.0"
@ -580,8 +580,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: "140b530"
resolved-ref: "140b53091ce7ad971e97c1d5a53fe0875596326d"
ref: "4a5cac"
resolved-ref: "4a5cac57e31c0ffd49cd6257a9e078f084ae342c"
url: "https://github.com/LucasXu0/emoji_mart.git"
source: git
version: "1.0.2"

View File

@ -46,7 +46,7 @@ dependencies:
appflowy_editor:
git:
url: https://github.com/AppFlowy-IO/appflowy-editor.git
ref: "9c7a4e"
ref: "4995d21"
appflowy_popover:
path: packages/appflowy_popover
@ -115,7 +115,7 @@ dependencies:
flutter_emoji_mart:
git:
url: https://github.com/LucasXu0/emoji_mart.git
ref: "140b530"
ref: "4a5cac"
# Notifications
# TODO: Consider implementing custom package