fix: notes disappears (#4122)

This commit is contained in:
Mathias Mogensen 2023-12-10 13:44:37 +02:00 committed by GitHub
parent 649545cdf3
commit 177cca60c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 191 additions and 261 deletions

View File

@ -14,11 +14,13 @@ class EmojiText extends StatelessWidget {
required this.emoji, required this.emoji,
required this.fontSize, required this.fontSize,
this.textAlign, this.textAlign,
this.lineHeight,
}); });
final String emoji; final String emoji;
final double fontSize; final double fontSize;
final TextAlign? textAlign; final TextAlign? textAlign;
final double? lineHeight;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -28,6 +30,7 @@ class EmojiText extends StatelessWidget {
fontSize: fontSize, fontSize: fontSize,
textAlign: textAlign, textAlign: textAlign,
fallbackFontFamily: _cachedFallbackFontFamily, fallbackFontFamily: _cachedFallbackFontFamily,
lineHeight: lineHeight,
); );
} }

View File

@ -61,7 +61,7 @@ extension NumberFormatExtension on NumberFormatPB {
case NumberFormatPB.ColombianPeso: case NumberFormatPB.ColombianPeso:
return "Colombian peso"; return "Colombian peso";
case NumberFormatPB.DanishKrone: case NumberFormatPB.DanishKrone:
return "Danish krone"; return "Danish crown";
case NumberFormatPB.Dirham: case NumberFormatPB.Dirham:
return "Dirham"; return "Dirham";
case NumberFormatPB.EUR: case NumberFormatPB.EUR:

View File

@ -208,20 +208,27 @@ class _DesktopBoardContentState extends State<DesktopBoardContent> {
} }
Widget _buildFooter(BuildContext context, AppFlowyGroupData columnData) { Widget _buildFooter(BuildContext context, AppFlowyGroupData columnData) {
return AppFlowyGroupFooter( return Padding(
height: 36, padding: config.groupFooterPadding,
margin: config.groupFooterPadding, child: FlowyTooltip(
icon: FlowySvg( message: LocaleKeys.board_column_addToColumnBottomTooltip.tr(),
FlowySvgs.add_s, child: FlowyHover(
color: Theme.of(context).hintColor, child: AppFlowyGroupFooter(
height: 36,
icon: FlowySvg(
FlowySvgs.add_s,
color: Theme.of(context).hintColor,
),
title: FlowyText.medium(
LocaleKeys.board_column_createNewCard.tr(),
color: Theme.of(context).hintColor,
),
onAddButtonClick: () => context
.read<BoardBloc>()
.add(BoardEvent.createBottomRow(columnData.id)),
),
),
), ),
title: FlowyText.medium(
LocaleKeys.board_column_createNewCard.tr(),
color: Theme.of(context).hintColor,
),
onAddButtonClick: () => context
.read<BoardBloc>()
.add(BoardEvent.createBottomRow(columnData.id)),
); );
} }
@ -233,11 +240,14 @@ class _DesktopBoardContentState extends State<DesktopBoardContent> {
final boardBloc = context.read<BoardBloc>(); final boardBloc = context.read<BoardBloc>();
final groupItem = afGroupItem as GroupItem; final groupItem = afGroupItem as GroupItem;
final groupData = afGroupData.customData as GroupData; final groupData = afGroupData.customData as GroupData;
final rowMeta = groupItem.row;
final rowCache = boardBloc.getRowCache(); final rowCache = boardBloc.getRowCache();
final rowInfo = rowCache?.getRow(groupItem.row.id);
/// Return placeholder widget if the rowCache or rowInfo is null.
if (rowCache == null) {
return SizedBox.shrink(key: ObjectKey(groupItem));
}
/// Return placeholder widget if the rowCache is null.
if (rowCache == null) return SizedBox.shrink(key: ObjectKey(groupItem));
final cellCache = rowCache.cellCache; final cellCache = rowCache.cellCache;
final fieldController = boardBloc.fieldController; final fieldController = boardBloc.fieldController;
final viewId = boardBloc.viewId; final viewId = boardBloc.viewId;
@ -247,6 +257,7 @@ class _DesktopBoardContentState extends State<DesktopBoardContent> {
boardBloc.state.editingRow?.row.id == groupItem.row.id; boardBloc.state.editingRow?.row.id == groupItem.row.id;
final groupItemId = "${groupData.group.groupId}${groupItem.row.id}"; final groupItemId = "${groupData.group.groupId}${groupItem.row.id}";
final rowMeta = rowInfo?.rowMeta ?? groupItem.row;
return AppFlowyGroupCard( return AppFlowyGroupCard(
key: ValueKey(groupItemId), key: ValueKey(groupItemId),
@ -278,10 +289,9 @@ class _DesktopBoardContentState extends State<DesktopBoardContent> {
foregroundColorOnHover: Theme.of(context).colorScheme.onBackground, foregroundColorOnHover: Theme.of(context).colorScheme.onBackground,
), ),
), ),
onStartEditing: () => boardBloc onStartEditing: () =>
.add(BoardEvent.startEditingRow(groupData.group, groupItem.row)), boardBloc.add(BoardEvent.startEditingRow(groupData.group, rowMeta)),
onEndEditing: () => onEndEditing: () => boardBloc.add(BoardEvent.endEditingRow(rowMeta.id)),
boardBloc.add(BoardEvent.endEditingRow(groupItem.row.id)),
), ),
); );
} }

View File

@ -258,7 +258,6 @@ class _GridRows extends StatelessWidget {
}).toList() }).toList()
..add(const GridRowBottomBar(key: Key('gridFooter'))); ..add(const GridRowBottomBar(key: Key('gridFooter')));
return ReorderableListView.builder( return ReorderableListView.builder(
/// TODO(Xazin): Resolve inconsistent scrollbar behavior
/// This is a workaround related to /// This is a workaround related to
/// https://github.com/flutter/flutter/issues/25652 /// https://github.com/flutter/flutter/issues/25652
cacheExtent: 5000, cacheExtent: 5000,

View File

@ -141,13 +141,11 @@ class _RowCardState<T> extends State<RowCard<T>> {
triggerActions: PopoverTriggerFlags.none, triggerActions: PopoverTriggerFlags.none,
constraints: BoxConstraints.loose(const Size(140, 200)), constraints: BoxConstraints.loose(const Size(140, 200)),
direction: PopoverDirection.rightWithCenterAligned, direction: PopoverDirection.rightWithCenterAligned,
popupBuilder: (popoverContext) { popupBuilder: (_) => RowActions(
return RowActions( viewId: _cardBloc.viewId,
viewId: _cardBloc.viewId, rowId: _cardBloc.rowMeta.id,
rowId: _cardBloc.rowMeta.id, groupId: widget.groupId,
groupId: widget.groupId, ),
);
},
child: RowCardContainer( child: RowCardContainer(
buildAccessoryWhen: () => state.isEditing == false, buildAccessoryWhen: () => state.isEditing == false,
accessories: [ accessories: [
@ -203,12 +201,12 @@ class _CardContent<CustomCardData> extends StatefulWidget {
this.renderHook, this.renderHook,
}); });
final CardCellBuilder<CustomCardData> cellBuilder;
final EditableRowNotifier rowNotifier; final EditableRowNotifier rowNotifier;
final CardCellBuilder<CustomCardData> cellBuilder;
final List<DatabaseCellContext> cells; final List<DatabaseCellContext> cells;
final RowCardRenderHook<CustomCardData>? renderHook;
final CustomCardData? cardData; final CustomCardData? cardData;
final RowCardStyleConfiguration styleConfiguration; final RowCardStyleConfiguration styleConfiguration;
final RowCardRenderHook<CustomCardData>? renderHook;
@override @override
State<_CardContent<CustomCardData>> createState() => State<_CardContent<CustomCardData>> createState() =>

View File

@ -4,6 +4,7 @@ import 'package:appflowy/plugins/database_view/application/cell/cell_controller_
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/style_widget/text.dart'; import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
@ -142,9 +143,12 @@ class _TextCellState extends State<TextCardCell> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (widget.showNotes) ...[ if (widget.showNotes) ...[
FlowySvg( FlowyTooltip(
FlowySvgs.notes_s, message: LocaleKeys.board_notesTooltip.tr(),
color: Theme.of(context).hintColor, child: FlowySvg(
FlowySvgs.notes_s,
color: Theme.of(context).hintColor,
),
), ),
const HSpace(4), const HSpace(4),
], ],

View File

@ -4,20 +4,21 @@ import 'package:provider/provider.dart';
import 'accessory.dart'; import 'accessory.dart';
class RowCardContainer extends StatelessWidget { class RowCardContainer extends StatelessWidget {
final Widget child;
final List<CardAccessory> accessories;
final bool Function()? buildAccessoryWhen;
final void Function(BuildContext) openCard;
final void Function(AccessoryType) openAccessory;
const RowCardContainer({ const RowCardContainer({
super.key,
required this.child, required this.child,
required this.openCard, required this.openCard,
required this.openAccessory, required this.openAccessory,
required this.accessories, required this.accessories,
this.buildAccessoryWhen, this.buildAccessoryWhen,
super.key,
}); });
final Widget child;
final void Function(BuildContext) openCard;
final void Function(AccessoryType) openAccessory;
final List<CardAccessory> accessories;
final bool Function()? buildAccessoryWhen;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ChangeNotifierProvider( return ChangeNotifierProvider(
@ -53,15 +54,16 @@ class RowCardContainer extends StatelessWidget {
} }
class _CardEnterRegion extends StatelessWidget { class _CardEnterRegion extends StatelessWidget {
final Widget child;
final List<CardAccessory> accessories;
final void Function(AccessoryType) onTapAccessory;
const _CardEnterRegion({ const _CardEnterRegion({
required this.child, required this.child,
required this.accessories, required this.accessories,
required this.onTapAccessory, required this.onTapAccessory,
}); });
final Widget child;
final List<CardAccessory> accessories;
final void Function(AccessoryType) onTapAccessory;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Selector<_CardContainerNotifier, bool>( return Selector<_CardContainerNotifier, bool>(

View File

@ -13,6 +13,7 @@ import 'package:appflowy/workspace/presentation/widgets/tab_bar_item.dart';
import 'package:appflowy/workspace/presentation/widgets/view_title_bar.dart'; import 'package:appflowy/workspace/presentation/widgets/view_title_bar.dart';
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
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:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
@ -117,7 +118,7 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder
key: ValueKey(view.id), key: ValueKey(view.id),
view: view, view: view,
), ),
const SizedBox(width: 10), const HSpace(4),
const DocumentMoreButton(), const DocumentMoreButton(),
], ],
); );

View File

@ -398,7 +398,6 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
} }
Future<void> _initializeShortcuts() async { Future<void> _initializeShortcuts() async {
// TODO(Xazin): Refactor lazy initialization
defaultCommandShortcutEvents; defaultCommandShortcutEvents;
final settingsShortcutService = SettingsShortcutService(); final settingsShortcutService = SettingsShortcutService();
final customizeShortcuts = final customizeShortcuts =

View File

@ -29,7 +29,7 @@ enum UploadImageType {
case UploadImageType.url: case UploadImageType.url:
return LocaleKeys.document_imageBlock_embedLink_label.tr(); return LocaleKeys.document_imageBlock_embedLink_label.tr();
case UploadImageType.unsplash: case UploadImageType.unsplash:
return 'Unsplash'; return LocaleKeys.document_imageBlock_unsplash_label.tr();
case UploadImageType.openAI: case UploadImageType.openAI:
return LocaleKeys.document_imageBlock_ai_label.tr(); return LocaleKeys.document_imageBlock_ai_label.tr();
case UploadImageType.stabilityAI: case UploadImageType.stabilityAI:

View File

@ -1,4 +1,5 @@
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/base/emoji/emoji_text.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';
@ -33,8 +34,8 @@ class MentionPageBlock extends StatefulWidget {
class _MentionPageBlockState extends State<MentionPageBlock> { class _MentionPageBlockState extends State<MentionPageBlock> {
late final EditorState editorState; late final EditorState editorState;
late final ViewListener viewListener = ViewListener(viewId: widget.pageId);
late Future<ViewPB?> viewPBFuture; late Future<ViewPB?> viewPBFuture;
ViewListener? viewListener;
@override @override
void initState() { void initState() {
@ -42,19 +43,18 @@ class _MentionPageBlockState extends State<MentionPageBlock> {
editorState = context.read<EditorState>(); editorState = context.read<EditorState>();
viewPBFuture = fetchView(widget.pageId); viewPBFuture = fetchView(widget.pageId);
viewListener = ViewListener(viewId: widget.pageId) viewListener.start(
..start( onViewUpdated: (p0) {
onViewUpdated: (p0) { pageMemorizer[p0.id] = p0;
pageMemorizer[p0.id] = p0; viewPBFuture = fetchView(widget.pageId);
viewPBFuture = fetchView(widget.pageId); editorState.reload();
editorState.reload(); },
}, );
);
} }
@override @override
void dispose() { void dispose() {
viewListener?.stop(); viewListener.stop();
super.dispose(); super.dispose();
} }
@ -83,10 +83,17 @@ class _MentionPageBlockState extends State<MentionPageBlock> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
const HSpace(4), const HSpace(4),
FlowySvg( view.icon.value.isNotEmpty
view.layout.icon, ? EmojiText(
size: Size.square(iconSize + 2.0), emoji: view.icon.value,
), fontSize: 12,
textAlign: TextAlign.center,
lineHeight: 1.3,
)
: FlowySvg(
view.layout.icon,
size: Size.square(iconSize + 2.0),
),
const HSpace(2), const HSpace(2),
FlowyText( FlowyText(
view.name, view.name,

View File

@ -8,9 +8,6 @@ import 'package:http/http.dart' as http;
import 'error.dart'; import 'error.dart';
import 'text_completion.dart'; import 'text_completion.dart';
// Please fill in your own API key
const apiKey = '';
enum OpenAIRequestType { enum OpenAIRequestType {
textCompletion, textCompletion,
textEdit, textEdit,

View File

@ -4,6 +4,7 @@ import 'package:appflowy/plugins/document/presentation/more/cubit/document_appea
import 'package:appflowy/plugins/document/presentation/more/font_size_switcher.dart'; import 'package:appflowy/plugins/document/presentation/more/font_size_switcher.dart';
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:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.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';
@ -20,10 +21,15 @@ class DocumentMoreButton extends StatelessWidget {
offset: const Offset(0, 30), offset: const Offset(0, 30),
child: FlowyTooltip( child: FlowyTooltip(
message: LocaleKeys.moreAction_moreOptions.tr(), message: LocaleKeys.moreAction_moreOptions.tr(),
child: FlowySvg( child: FlowyHover(
FlowySvgs.details_s, child: Padding(
size: const Size(18, 18), padding: const EdgeInsets.all(6),
color: Theme.of(context).iconTheme.color, child: FlowySvg(
FlowySvgs.details_s,
size: const Size(18, 18),
color: Theme.of(context).iconTheme.color,
),
),
), ),
), ),
popupBuilder: (context) { popupBuilder: (context) {

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/base/emoji/emoji_text.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_block.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_block.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart';
import 'package:appflowy/plugins/inline_actions/inline_actions_result.dart'; import 'package:appflowy/plugins/inline_actions/inline_actions_result.dart';
@ -8,6 +9,7 @@ import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy/workspace/application/view/view_service.dart'; import 'package:appflowy/workspace/application/view/view_service.dart';
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
class InlinePageReferenceService { class InlinePageReferenceService {
InlinePageReferenceService({ InlinePageReferenceService({
@ -83,7 +85,14 @@ class InlinePageReferenceService {
final pageSelectionMenuItem = InlineActionsMenuItem( final pageSelectionMenuItem = InlineActionsMenuItem(
keywords: [view.name.toLowerCase()], keywords: [view.name.toLowerCase()],
label: view.name, label: view.name,
icon: (onSelected) => view.defaultIcon(), icon: (onSelected) => view.icon.value.isNotEmpty
? EmojiText(
emoji: view.icon.value,
fontSize: 12,
textAlign: TextAlign.center,
lineHeight: 1.3,
)
: view.defaultIcon(),
onSelected: (context, editorState, menuService, replace) async { onSelected: (context, editorState, menuService, replace) async {
final selection = editorState.selection; final selection = editorState.selection;
if (selection == null || !selection.isCollapsed) { if (selection == null || !selection.isCollapsed) {

View File

@ -1,6 +0,0 @@
import 'package:dartz/dartz.dart';
extension EitherX<L, R> on Either<L, R> {
R asRight() => (this as Right).value;
L asLeft() => (this as Left).value;
}

View File

@ -3,16 +3,10 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
extension LabelTextPhrasing on ThemeMode { extension LabelTextPhrasing on ThemeMode {
String get labelText { String get labelText => switch (this) {
switch (this) { ThemeMode.light => LocaleKeys.settings_appearance_themeMode_light.tr(),
case (ThemeMode.light): ThemeMode.dark => LocaleKeys.settings_appearance_themeMode_dark.tr(),
return LocaleKeys.settings_appearance_themeMode_light.tr(); ThemeMode.system =>
case (ThemeMode.dark): LocaleKeys.settings_appearance_themeMode_system.tr(),
return LocaleKeys.settings_appearance_themeMode_dark.tr(); };
case (ThemeMode.system):
return LocaleKeys.settings_appearance_themeMode_system.tr();
default:
return "";
}
}
} }

View File

@ -7,7 +7,9 @@ import 'package:appflowy/plugins/database_view/tab_bar/tab_bar_view.dart';
import 'package:appflowy/plugins/document/document.dart'; import 'package:appflowy/plugins/document/document.dart';
import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/startup/plugin/plugin.dart';
import 'package:appflowy/workspace/application/view/view_service.dart'; import 'package:appflowy/workspace/application/view/view_service.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
import 'package:dartz/dartz.dart' hide id;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
enum FlowyPlugin { enum FlowyPlugin {
@ -15,73 +17,31 @@ enum FlowyPlugin {
kanban, kanban,
} }
extension FlowyPluginExtension on FlowyPlugin {
String displayName() {
switch (this) {
case FlowyPlugin.editor:
return "Doc";
case FlowyPlugin.kanban:
return "Kanban";
default:
return "";
}
}
bool enable() {
switch (this) {
case FlowyPlugin.editor:
return true;
case FlowyPlugin.kanban:
return false;
default:
return false;
}
}
}
extension ViewExtension on ViewPB { extension ViewExtension on ViewPB {
Widget renderThumbnail({Color? iconColor}) { Widget defaultIcon() => FlowySvg(
return const FlowySvg( switch (layout) {
FlowySvgs.document_s, ViewLayoutPB.Board => FlowySvgs.board_s,
); ViewLayoutPB.Calendar => FlowySvgs.date_s,
} ViewLayoutPB.Grid => FlowySvgs.grid_s,
ViewLayoutPB.Document => FlowySvgs.document_s,
_ => FlowySvgs.document_s,
},
);
Widget defaultIcon() { PluginType get pluginType => switch (layout) {
return FlowySvg( ViewLayoutPB.Board => PluginType.board,
switch (layout) { ViewLayoutPB.Calendar => PluginType.calendar,
ViewLayoutPB.Board => FlowySvgs.board_s, ViewLayoutPB.Document => PluginType.editor,
ViewLayoutPB.Calendar => FlowySvgs.date_s, ViewLayoutPB.Grid => PluginType.grid,
ViewLayoutPB.Grid => FlowySvgs.grid_s, _ => throw UnimplementedError(),
ViewLayoutPB.Document => FlowySvgs.document_s, };
_ => FlowySvgs.document_s,
},
);
}
PluginType get pluginType {
switch (layout) {
case ViewLayoutPB.Board:
return PluginType.board;
case ViewLayoutPB.Calendar:
return PluginType.calendar;
case ViewLayoutPB.Document:
return PluginType.editor;
case ViewLayoutPB.Grid:
return PluginType.grid;
}
throw UnimplementedError;
}
Plugin plugin({bool listenOnViewChanged = false}) { Plugin plugin({bool listenOnViewChanged = false}) {
switch (layout) { switch (layout) {
case ViewLayoutPB.Board: case ViewLayoutPB.Board:
case ViewLayoutPB.Calendar: case ViewLayoutPB.Calendar:
case ViewLayoutPB.Grid: case ViewLayoutPB.Grid:
return DatabaseTabBarViewPlugin( return DatabaseTabBarViewPlugin(view: this, pluginType: pluginType);
view: this,
pluginType: pluginType,
);
case ViewLayoutPB.Document: case ViewLayoutPB.Document:
return DocumentPlugin( return DocumentPlugin(
view: this, view: this,
@ -92,31 +52,19 @@ extension ViewExtension on ViewPB {
throw UnimplementedError; throw UnimplementedError;
} }
DatabaseTabBarItemBuilder tabBarItem() { DatabaseTabBarItemBuilder tabBarItem() => switch (layout) {
switch (layout) { ViewLayoutPB.Board => BoardPageTabBarBuilderImpl(),
case ViewLayoutPB.Board: ViewLayoutPB.Calendar => CalendarPageTabBarBuilderImpl(),
return BoardPageTabBarBuilderImpl(); ViewLayoutPB.Grid => DesktopGridTabBarBuilderImpl(),
case ViewLayoutPB.Calendar: _ => throw UnimplementedError,
return CalendarPageTabBarBuilderImpl(); };
case ViewLayoutPB.Grid:
return DesktopGridTabBarBuilderImpl();
default:
throw UnimplementedError;
}
}
DatabaseTabBarItemBuilder mobileTabBarItem() { DatabaseTabBarItemBuilder mobileTabBarItem() => switch (layout) {
switch (layout) { ViewLayoutPB.Board => BoardPageTabBarBuilderImpl(),
case ViewLayoutPB.Board: ViewLayoutPB.Calendar => CalendarPageTabBarBuilderImpl(),
return BoardPageTabBarBuilderImpl(); ViewLayoutPB.Grid => MobileGridTabBarBuilderImpl(),
case ViewLayoutPB.Calendar: _ => throw UnimplementedError,
return CalendarPageTabBarBuilderImpl(); };
case ViewLayoutPB.Grid:
return MobileGridTabBarBuilderImpl();
default:
throw UnimplementedError;
}
}
FlowySvgData get iconData => layout.icon; FlowySvgData get iconData => layout.icon;
@ -129,7 +77,8 @@ extension ViewExtension on ViewPB {
final self = await ViewBackendService.getView(id); final self = await ViewBackendService.getView(id);
ancestors.add(self.getLeftOrNull<ViewPB>() ?? this); ancestors.add(self.getLeftOrNull<ViewPB>() ?? this);
} }
var parent = await ViewBackendService.getView(parentViewId); Either<ViewPB, FlowyError> parent =
await ViewBackendService.getView(parentViewId);
while (parent.isLeft()) { while (parent.isLeft()) {
// parent is not null // parent is not null
final view = parent.getLeftOrNull<ViewPB>(); final view = parent.getLeftOrNull<ViewPB>();
@ -144,33 +93,22 @@ extension ViewExtension on ViewPB {
} }
extension ViewLayoutExtension on ViewLayoutPB { extension ViewLayoutExtension on ViewLayoutPB {
FlowySvgData get icon { FlowySvgData get icon => switch (this) {
switch (this) { ViewLayoutPB.Grid => FlowySvgs.grid_s,
case ViewLayoutPB.Grid: ViewLayoutPB.Board => FlowySvgs.board_s,
return FlowySvgs.grid_s; ViewLayoutPB.Calendar => FlowySvgs.date_s,
case ViewLayoutPB.Board: ViewLayoutPB.Document => FlowySvgs.document_s,
return FlowySvgs.board_s; _ => throw Exception('Unknown layout type'),
case ViewLayoutPB.Calendar: };
return FlowySvgs.date_s;
case ViewLayoutPB.Document:
return FlowySvgs.document_s;
default:
throw Exception('Unknown layout type');
}
}
bool get isDatabaseView { bool get isDatabaseView => switch (this) {
switch (this) { ViewLayoutPB.Grid ||
case ViewLayoutPB.Grid: ViewLayoutPB.Board ||
case ViewLayoutPB.Board: ViewLayoutPB.Calendar =>
case ViewLayoutPB.Calendar: true,
return true; ViewLayoutPB.Document => false,
case ViewLayoutPB.Document: _ => throw Exception('Unknown layout type'),
return false; };
default:
throw Exception('Unknown layout type');
}
}
} }
extension ViewFinder on List<ViewPB> { extension ViewFinder on List<ViewPB> {

View File

@ -10,7 +10,6 @@ import 'package:appflowy/workspace/presentation/home/toast.dart';
import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart';
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/extension.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -264,7 +263,12 @@ class HomeTopBar extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
color: Theme.of(context).colorScheme.onSecondaryContainer, decoration: BoxDecoration(
color: Theme.of(context).colorScheme.onSecondaryContainer,
border: Border(
bottom: BorderSide(color: Theme.of(context).dividerColor),
),
),
height: HomeSizes.topBarHeight, height: HomeSizes.topBarHeight,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
@ -286,7 +290,7 @@ class HomeTopBar extends StatelessWidget {
), ),
], ],
), ),
).bottomBorder(color: Theme.of(context).dividerColor), ),
); );
} }
} }

View File

@ -370,9 +370,7 @@ class _SingleInnerViewItemState extends State<SingleInnerViewItem> {
controller: controller, controller: controller,
direction: PopoverDirection.rightWithCenterAligned, direction: PopoverDirection.rightWithCenterAligned,
constraints: BoxConstraints.loose(const Size(360, 380)), constraints: BoxConstraints.loose(const Size(360, 380)),
onClose: () => setState(() { onClose: () => setState(() => isIconPickerOpened = false),
isIconPickerOpened = false;
}),
child: GestureDetector( child: GestureDetector(
// prevent the tap event from being passed to the parent widget // prevent the tap event from being passed to the parent widget
onTap: () {}, onTap: () {},

View File

@ -74,8 +74,6 @@ class _NotificationDialogState extends State<NotificationDialog>
children: [ children: [
const NotificationHubTitle(), const NotificationHubTitle(),
NotificationTabBar(tabController: _controller), NotificationTabBar(tabController: _controller),
// TODO(Xazin): Resolve issue with taking up
// max amount of vertical space
Expanded( Expanded(
child: TabBarView( child: TabBarView(
controller: _controller, controller: _controller,

View File

@ -1,30 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
export 'package:styled_widget/styled_widget.dart'; export 'package:styled_widget/styled_widget.dart';
extension FlowyStyledWidget on Widget {
Widget bottomBorder({double width = 1.0, Color color = Colors.grey}) {
return DecoratedBox(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(width: width, color: color),
),
),
child: this,
);
}
Widget topBorder({double width = 1.0, Color color = Colors.grey}) {
return DecoratedBox(
decoration: BoxDecoration(
border: Border(
top: BorderSide(width: width, color: color),
),
),
child: this,
);
}
}
class TopBorder extends StatelessWidget { class TopBorder extends StatelessWidget {
const TopBorder({ const TopBorder({
super.key, super.key,

View File

@ -14,9 +14,11 @@ class FlowyText extends StatelessWidget {
final bool selectable; final bool selectable;
final String? fontFamily; final String? fontFamily;
final List<String>? fallbackFontFamily; final List<String>? fallbackFontFamily;
final double? lineHeight;
const FlowyText( const FlowyText(
this.text, { this.text, {
super.key,
this.overflow = TextOverflow.clip, this.overflow = TextOverflow.clip,
this.fontSize, this.fontSize,
this.fontWeight, this.fontWeight,
@ -27,11 +29,12 @@ class FlowyText extends StatelessWidget {
this.selectable = false, this.selectable = false,
this.fontFamily, this.fontFamily,
this.fallbackFontFamily, this.fallbackFontFamily,
Key? key, this.lineHeight,
}) : super(key: key); });
FlowyText.small( FlowyText.small(
this.text, { this.text, {
super.key,
this.overflow, this.overflow,
this.color, this.color,
this.textAlign, this.textAlign,
@ -40,13 +43,13 @@ class FlowyText extends StatelessWidget {
this.selectable = false, this.selectable = false,
this.fontFamily, this.fontFamily,
this.fallbackFontFamily, this.fallbackFontFamily,
Key? key, this.lineHeight,
}) : fontWeight = FontWeight.w400, }) : fontWeight = FontWeight.w400,
fontSize = (Platform.isIOS || Platform.isAndroid) ? 14 : 12, fontSize = (Platform.isIOS || Platform.isAndroid) ? 14 : 12;
super(key: key);
const FlowyText.regular( const FlowyText.regular(
this.text, { this.text, {
super.key,
this.fontSize, this.fontSize,
this.overflow, this.overflow,
this.color, this.color,
@ -56,12 +59,12 @@ class FlowyText extends StatelessWidget {
this.selectable = false, this.selectable = false,
this.fontFamily, this.fontFamily,
this.fallbackFontFamily, this.fallbackFontFamily,
Key? key, this.lineHeight,
}) : fontWeight = FontWeight.w400, }) : fontWeight = FontWeight.w400;
super(key: key);
const FlowyText.medium( const FlowyText.medium(
this.text, { this.text, {
super.key,
this.fontSize, this.fontSize,
this.overflow, this.overflow,
this.color, this.color,
@ -71,12 +74,12 @@ class FlowyText extends StatelessWidget {
this.selectable = false, this.selectable = false,
this.fontFamily, this.fontFamily,
this.fallbackFontFamily, this.fallbackFontFamily,
Key? key, this.lineHeight,
}) : fontWeight = FontWeight.w500, }) : fontWeight = FontWeight.w500;
super(key: key);
const FlowyText.semibold( const FlowyText.semibold(
this.text, { this.text, {
super.key,
this.fontSize, this.fontSize,
this.overflow, this.overflow,
this.color, this.color,
@ -86,13 +89,13 @@ class FlowyText extends StatelessWidget {
this.selectable = false, this.selectable = false,
this.fontFamily, this.fontFamily,
this.fallbackFontFamily, this.fallbackFontFamily,
Key? key, this.lineHeight,
}) : fontWeight = FontWeight.w600, }) : fontWeight = FontWeight.w600;
super(key: key);
// Some emojis are not supported on Linux and Android, fallback to noto color emoji // Some emojis are not supported on Linux and Android, fallback to noto color emoji
const FlowyText.emoji( const FlowyText.emoji(
this.text, { this.text, {
super.key,
this.fontSize, this.fontSize,
this.overflow, this.overflow,
this.color, this.color,
@ -100,11 +103,10 @@ class FlowyText extends StatelessWidget {
this.maxLines = 1, this.maxLines = 1,
this.decoration, this.decoration,
this.selectable = false, this.selectable = false,
Key? key, this.lineHeight,
}) : fontWeight = FontWeight.w400, }) : fontWeight = FontWeight.w400,
fontFamily = 'noto color emoji', fontFamily = 'noto color emoji',
fallbackFontFamily = null, fallbackFontFamily = null;
super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -120,6 +122,7 @@ class FlowyText extends StatelessWidget {
decoration: decoration, decoration: decoration,
fontFamily: fontFamily, fontFamily: fontFamily,
fontFamilyFallback: fallbackFontFamily, fontFamilyFallback: fallbackFontFamily,
height: lineHeight,
), ),
); );
} else { } else {
@ -135,6 +138,7 @@ class FlowyText extends StatelessWidget {
decoration: decoration, decoration: decoration,
fontFamily: fontFamily, fontFamily: fontFamily,
fontFamilyFallback: fallbackFontFamily, fontFamilyFallback: fallbackFontFamily,
height: lineHeight,
), ),
); );
} }

View File

@ -1,15 +0,0 @@
import 'package:flutter/material.dart';
extension ClickableExtensions on Widget {
Widget clickable(void Function() action, {bool opaque = true}) {
return GestureDetector(
behavior: opaque ? HitTestBehavior.opaque : HitTestBehavior.deferToChild,
onTap: action,
child: MouseRegion(
cursor: SystemMouseCursors.click,
opaque: opaque,
child: this,
),
);
}
}

View File

@ -779,6 +779,9 @@
"label": "Embed link", "label": "Embed link",
"placeholder": "Paste or type an image link" "placeholder": "Paste or type an image link"
}, },
"unsplash": {
"label": "Unsplash"
},
"searchForAnImage": "Search for an image", "searchForAnImage": "Search for an image",
"pleaseInputYourOpenAIKey": "please input your OpenAI key in Settings page", "pleaseInputYourOpenAIKey": "please input your OpenAI key in Settings page",
"pleaseInputYourStabilityAIKey": "please input your Stability AI key in Settings page", "pleaseInputYourStabilityAIKey": "please input your Stability AI key in Settings page",
@ -828,6 +831,7 @@
"renameGroupTooltip": "Press to rename group", "renameGroupTooltip": "Press to rename group",
"createNewColumn": "Add a new group", "createNewColumn": "Add a new group",
"addToColumnTopTooltip": "Add a new card at the top", "addToColumnTopTooltip": "Add a new card at the top",
"addToColumnBottomTooltip": "Add a new card at the bottom",
"renameColumn": "Rename", "renameColumn": "Rename",
"hideColumn": "Hide", "hideColumn": "Hide",
"groupActions": "Group Actions", "groupActions": "Group Actions",
@ -854,6 +858,7 @@
"ungroupedItemsTitle": "Click to add to the board", "ungroupedItemsTitle": "Click to add to the board",
"groupBy": "Group by", "groupBy": "Group by",
"referencedBoardPrefix": "View of", "referencedBoardPrefix": "View of",
"notesTooltip": "Notes inside",
"mobile": { "mobile": {
"editURL": "Edit URL", "editURL": "Edit URL",
"unhideGroup": "Unhide group", "unhideGroup": "Unhide group",