mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: billing+cleanup (#5634)
* fix: billing fixes * chore: best practice and cleaning * chore: dispose of unused resources * chore: upgrade editor version
This commit is contained in:
parent
7859fc7922
commit
bbb3f95a13
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/plugins/ai_chat/chat_page.dart';
|
||||
import 'package:appflowy/plugins/util.dart';
|
||||
@ -7,7 +9,6 @@ import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/tab_bar_item.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/view_title_bar.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class AIChatPluginBuilder extends PluginBuilder {
|
||||
@ -65,6 +66,13 @@ class AIChatPagePlugin extends Plugin {
|
||||
_viewInfoBloc = ViewInfoBloc(view: notifier.view)
|
||||
..add(const ViewInfoEvent.started());
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_viewInfoBloc.close();
|
||||
notifier.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class AIChatPagePluginWidgetBuilder extends PluginWidgetBuilder
|
||||
|
@ -1,9 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/plugins/base/emoji/emoji_picker_header.dart';
|
||||
import 'package:appflowy/plugins/base/emoji/emoji_search_bar.dart';
|
||||
import 'package:appflowy/plugins/base/emoji/emoji_skin_tone.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_emoji_mart/flutter_emoji_mart.dart';
|
||||
|
||||
// use a global value to store the selected emoji to prevent reloading every time.
|
||||
@ -37,9 +38,7 @@ class _FlowyEmojiPickerState extends State<FlowyEmojiPicker> {
|
||||
EmojiData.builtIn().then(
|
||||
(value) {
|
||||
kCachedEmojiData = value;
|
||||
setState(() {
|
||||
emojiData = value;
|
||||
});
|
||||
setState(() => emojiData = value);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/plugins/database/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database/application/view/view_cache.dart';
|
||||
import 'package:appflowy/plugins/database/domain/database_view_service.dart';
|
||||
@ -12,7 +14,6 @@ import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'defines.dart';
|
||||
import 'row/row_cache.dart';
|
||||
@ -223,6 +224,7 @@ class DatabaseController {
|
||||
_databaseCallbacks.clear();
|
||||
_groupCallbacks.clear();
|
||||
_layoutCallbacks.clear();
|
||||
_isLoading.dispose();
|
||||
}
|
||||
|
||||
Future<void> _loadGroups() async {
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
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';
|
||||
@ -19,12 +21,12 @@ import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../../application/row/row_controller.dart';
|
||||
import '../../widgets/row/row_detail.dart';
|
||||
|
||||
import 'calendar_day.dart';
|
||||
import 'layout/sizes.dart';
|
||||
import 'toolbar/calendar_setting_bar.dart';
|
||||
@ -90,12 +92,11 @@ class _CalendarPageState extends State<CalendarPage> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_calendarState = GlobalKey<MonthViewState>();
|
||||
_calendarBloc = CalendarBloc(
|
||||
databaseController: widget.databaseController,
|
||||
)..add(const CalendarEvent.initial());
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -378,13 +379,7 @@ class UnscheduledEventsButton extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _UnscheduledEventsButtonState extends State<UnscheduledEventsButton> {
|
||||
late final PopoverController _popoverController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_popoverController = PopoverController();
|
||||
}
|
||||
final PopoverController _popoverController = PopoverController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -30,6 +30,12 @@ class CalendarLayoutSetting extends StatefulWidget {
|
||||
class _CalendarLayoutSettingState extends State<CalendarLayoutSetting> {
|
||||
final PopoverMutex popoverMutex = PopoverMutex();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
popoverMutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
|
@ -1,18 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database/grid/application/filter/checkbox_filter_editor_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/checkbox_filter.pbenum.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/checkbox_filter.pbenum.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../condition_button.dart';
|
||||
import '../disclosure_button.dart';
|
||||
import '../filter_info.dart';
|
||||
|
||||
import 'choicechip.dart';
|
||||
|
||||
class CheckboxFilterChoicechip extends StatefulWidget {
|
||||
@ -30,9 +31,9 @@ class _CheckboxFilterChoicechipState extends State<CheckboxFilterChoicechip> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
bloc = CheckboxFilterEditorBloc(filterInfo: widget.filterInfo)
|
||||
..add(const CheckboxFilterEditorEvent.initial());
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -82,6 +83,12 @@ class CheckboxFilterEditor extends StatefulWidget {
|
||||
class _CheckboxFilterEditorState extends State<CheckboxFilterEditor> {
|
||||
final popoverMutex = PopoverMutex();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
popoverMutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider.value(
|
||||
|
@ -1,12 +1,14 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database/grid/application/filter/checklist_filter_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/checklist_filter.pbenum.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/checklist_filter.pbenum.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../condition_button.dart';
|
||||
import '../../disclosure_button.dart';
|
||||
import '../../filter_info.dart';
|
||||
@ -23,20 +25,20 @@ class ChecklistFilterChoicechip extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ChecklistFilterChoicechipState extends State<ChecklistFilterChoicechip> {
|
||||
late ChecklistFilterEditorBloc bloc;
|
||||
late PopoverMutex popoverMutex;
|
||||
late final ChecklistFilterEditorBloc bloc;
|
||||
final PopoverMutex popoverMutex = PopoverMutex();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
popoverMutex = PopoverMutex();
|
||||
super.initState();
|
||||
bloc = ChecklistFilterEditorBloc(filterInfo: widget.filterInfo);
|
||||
bloc.add(const ChecklistFilterEditorEvent.initial());
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
bloc.close();
|
||||
popoverMutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database/grid/application/filter/number_filter_editor_bloc.dart';
|
||||
@ -6,12 +8,12 @@ import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.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_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../condition_button.dart';
|
||||
import '../disclosure_button.dart';
|
||||
import '../filter_info.dart';
|
||||
|
||||
import 'choicechip.dart';
|
||||
|
||||
class NumberFilterChoiceChip extends StatefulWidget {
|
||||
@ -64,6 +66,12 @@ class NumberFilterEditor extends StatefulWidget {
|
||||
class _NumberFilterEditorState extends State<NumberFilterEditor> {
|
||||
final popoverMutex = PopoverMutex();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
popoverMutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<NumberFilterEditorBloc, NumberFilterEditorState>(
|
||||
|
@ -1,14 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/plugins/database/grid/application/filter/select_option_filter_bloc.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/select_option_filter.pb.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../disclosure_button.dart';
|
||||
import '../../filter_info.dart';
|
||||
import '../choicechip.dart';
|
||||
|
||||
import 'condition_list.dart';
|
||||
import 'option_list.dart';
|
||||
import 'select_option_loader.dart';
|
||||
@ -29,6 +31,7 @@ class _SelectOptionFilterChoicechipState
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.filterInfo.fieldInfo.fieldType == FieldType.SingleSelect) {
|
||||
bloc = SelectOptionFilterEditorBloc(
|
||||
filterInfo: widget.filterInfo,
|
||||
@ -43,7 +46,6 @@ class _SelectOptionFilterChoicechipState
|
||||
);
|
||||
}
|
||||
bloc.add(const SelectOptionFilterEditorEvent.initial());
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -90,6 +92,12 @@ class SelectOptionFilterEditor extends StatefulWidget {
|
||||
class _SelectOptionFilterEditorState extends State<SelectOptionFilterEditor> {
|
||||
final popoverMutex = PopoverMutex();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
popoverMutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider.value(
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database/grid/application/filter/text_filter_editor_bloc.dart';
|
||||
@ -6,12 +8,12 @@ import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.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_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../condition_button.dart';
|
||||
import '../disclosure_button.dart';
|
||||
import '../filter_info.dart';
|
||||
|
||||
import 'choicechip.dart';
|
||||
|
||||
class TextFilterChoicechip extends StatelessWidget {
|
||||
@ -72,6 +74,12 @@ class TextFilterEditor extends StatefulWidget {
|
||||
class _TextFilterEditorState extends State<TextFilterEditor> {
|
||||
final popoverMutex = PopoverMutex();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
popoverMutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<TextFilterEditorBloc, TextFilterEditorState>(
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database/grid/application/filter/time_filter_editor_bloc.dart';
|
||||
@ -6,12 +8,12 @@ import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.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_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../condition_button.dart';
|
||||
import '../disclosure_button.dart';
|
||||
import '../filter_info.dart';
|
||||
|
||||
import 'choicechip.dart';
|
||||
|
||||
class TimeFilterChoiceChip extends StatefulWidget {
|
||||
@ -64,6 +66,12 @@ class TimeFilterEditor extends StatefulWidget {
|
||||
class _TimeFilterEditorState extends State<TimeFilterEditor> {
|
||||
final popoverMutex = PopoverMutex();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
popoverMutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<TimeFilterEditorBloc, TimeFilterEditorState>(
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/field_info.dart';
|
||||
@ -10,7 +12,6 @@ import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text_field.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../../../application/field/field_controller.dart';
|
||||
@ -35,15 +36,15 @@ class GridCreateFilterList extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _GridCreateFilterListState extends State<GridCreateFilterList> {
|
||||
late GridCreateFilterBloc editBloc;
|
||||
late final GridCreateFilterBloc editBloc;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
editBloc = GridCreateFilterBloc(
|
||||
viewId: widget.viewId,
|
||||
fieldController: widget.fieldController,
|
||||
)..add(const GridCreateFilterEvent.initial());
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/field_controller.dart';
|
||||
@ -5,9 +7,7 @@ import 'package:appflowy/plugins/database/grid/application/filter/filter_menu_bl
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'create_filter_list.dart';
|
||||
@ -77,13 +77,7 @@ class AddFilterButton extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _AddFilterButtonState extends State<AddFilterButton> {
|
||||
late PopoverController popoverController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
popoverController = PopoverController();
|
||||
super.initState();
|
||||
}
|
||||
final PopoverController popoverController = PopoverController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/field_cell_bloc.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/field_controller.dart';
|
||||
@ -9,7 +11,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../layout/sizes.dart';
|
||||
@ -41,13 +42,12 @@ class GridFieldCell extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _GridFieldCellState extends State<GridFieldCell> {
|
||||
final PopoverController popoverController = PopoverController();
|
||||
late final FieldCellBloc _bloc;
|
||||
late PopoverController popoverController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
popoverController = PopoverController();
|
||||
_bloc = FieldCellBloc(viewId: widget.viewId, fieldInfo: widget.fieldInfo);
|
||||
if (widget.isEditing) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
|
@ -1,5 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database/grid/application/sort/sort_editor_bloc.dart';
|
||||
@ -7,10 +9,8 @@ import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-database2/sort_entities.pbenum.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'create_sort_list.dart';
|
||||
@ -28,6 +28,12 @@ class SortEditor extends StatefulWidget {
|
||||
class _SortEditorState extends State<SortEditor> {
|
||||
final popoverMutex = PopoverMutex();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
popoverMutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<SortEditorBloc, SortEditorState>(
|
||||
|
@ -1,6 +1,10 @@
|
||||
import 'dart:collection';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database/application/cell/bloc/select_option_cell_editor_bloc.dart';
|
||||
@ -10,14 +14,12 @@ import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../grid/presentation/layout/sizes.dart';
|
||||
import '../../grid/presentation/widgets/common/type_option_separator.dart';
|
||||
import '../field/type_option_editor/select/select_option_editor.dart';
|
||||
|
||||
import 'extension.dart';
|
||||
import 'select_option_text_field.dart';
|
||||
|
||||
@ -314,13 +316,7 @@ class _SelectOptionCell extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _SelectOptionCellState extends State<_SelectOptionCell> {
|
||||
late PopoverController _popoverController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_popoverController = PopoverController();
|
||||
super.initState();
|
||||
}
|
||||
final _popoverController = PopoverController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -370,13 +370,7 @@ class FieldDetailsEditor extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _FieldDetailsEditorState extends State<FieldDetailsEditor> {
|
||||
late PopoverMutex popoverMutex;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
popoverMutex = PopoverMutex();
|
||||
super.initState();
|
||||
}
|
||||
final PopoverMutex popoverMutex = PopoverMutex();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
@ -575,10 +569,7 @@ class _FieldNameTextFieldState extends State<FieldNameTextField> {
|
||||
}
|
||||
|
||||
class SwitchFieldButton extends StatefulWidget {
|
||||
const SwitchFieldButton({
|
||||
super.key,
|
||||
required this.popoverMutex,
|
||||
});
|
||||
const SwitchFieldButton({super.key, required this.popoverMutex});
|
||||
|
||||
final PopoverMutex popoverMutex;
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/database/application/cell/cell_controller.dart';
|
||||
@ -18,13 +21,12 @@ import 'package:collection/collection.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'accessory/cell_accessory.dart';
|
||||
import '../cell/editable_cell_builder.dart';
|
||||
|
||||
import 'accessory/cell_accessory.dart';
|
||||
|
||||
/// Display the row properties in a list. Only used in [RowDetailPage].
|
||||
class RowPropertyList extends StatelessWidget {
|
||||
const RowPropertyList({
|
||||
@ -363,15 +365,9 @@ class CreateRowFieldButton extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _CreateRowFieldButtonState extends State<CreateRowFieldButton> {
|
||||
late PopoverController popoverController;
|
||||
final PopoverController popoverController = PopoverController();
|
||||
FieldPB? createdField;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
popoverController = PopoverController();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppFlowyPopover(
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'package:appflowy/plugins/database/application/database_controller.dart';
|
||||
import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart';
|
||||
import 'package:appflowy/plugins/database/widgets/setting/database_setting_action.dart';
|
||||
@ -6,7 +8,6 @@ import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class DatabaseSettingsList extends StatefulWidget {
|
||||
const DatabaseSettingsList({
|
||||
@ -21,7 +22,13 @@ class DatabaseSettingsList extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _DatabaseSettingsListState extends State<DatabaseSettingsList> {
|
||||
late final PopoverMutex popoverMutex = PopoverMutex();
|
||||
final PopoverMutex popoverMutex = PopoverMutex();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
popoverMutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -1,5 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/field_controller.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/field_info.dart';
|
||||
@ -13,7 +15,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class DatabasePropertyList extends StatefulWidget {
|
||||
@ -43,6 +44,12 @@ class _DatabasePropertyListState extends State<DatabasePropertyList> {
|
||||
)..add(const DatabasePropertyEvent.initial());
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_popoverMutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider<DatabasePropertyBloc>.value(
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/bottom_sheet/show_mobile_bottom_sheet.dart';
|
||||
@ -25,7 +27,6 @@ import 'package:collection/collection.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:nanoid/non_secure.dart';
|
||||
|
||||
@ -64,6 +65,12 @@ class _MentionDateBlockState extends State<MentionDateBlock> {
|
||||
late bool _includeTime = widget.includeTime;
|
||||
late DateTime? parsedDate = DateTime.tryParse(widget.date);
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
mutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (parsedDate == null) {
|
||||
|
@ -67,8 +67,9 @@ class SettingsAIBloc extends Bloc<SettingsAIEvent, SettingsAIState> {
|
||||
bool? disableSearchIndexing,
|
||||
AIModelPB? model,
|
||||
}) {
|
||||
final payload =
|
||||
UpdateUserWorkspaceSettingPB(workspaceId: userProfile.workspaceId);
|
||||
final payload = UpdateUserWorkspaceSettingPB(
|
||||
workspaceId: userProfile.workspaceId,
|
||||
);
|
||||
if (disableSearchIndexing != null) {
|
||||
payload.disableSearchIndexing = disableSearchIndexing;
|
||||
}
|
||||
@ -82,17 +83,16 @@ class SettingsAIBloc extends Bloc<SettingsAIEvent, SettingsAIState> {
|
||||
FlowyResult<UserProfilePB, FlowyError> userProfileOrFailed,
|
||||
) =>
|
||||
userProfileOrFailed.fold(
|
||||
(newUserProfile) =>
|
||||
add(SettingsAIEvent.didReceiveUserProfile(newUserProfile)),
|
||||
(profile) => add(SettingsAIEvent.didReceiveUserProfile(profile)),
|
||||
(err) => Log.error(err),
|
||||
);
|
||||
|
||||
void _loadUserWorkspaceSetting() {
|
||||
final payload = UserWorkspaceIdPB(workspaceId: userProfile.workspaceId);
|
||||
UserEventGetWorkspaceSetting(payload).send().then((result) {
|
||||
result.fold((settins) {
|
||||
result.fold((settings) {
|
||||
if (!isClosed) {
|
||||
add(SettingsAIEvent.didLoadAISetting(settins));
|
||||
add(SettingsAIEvent.didLoadAISetting(settings));
|
||||
}
|
||||
}, (err) {
|
||||
Log.error(err);
|
||||
|
@ -117,6 +117,10 @@ class SettingsPlanBloc extends Bloc<SettingsPlanEvent, SettingsPlanState> {
|
||||
);
|
||||
},
|
||||
cancelSubscription: () async {
|
||||
final newState = state
|
||||
.mapOrNull(ready: (state) => state)
|
||||
?.copyWith(downgradeProcessing: true);
|
||||
emit(newState ?? state);
|
||||
await _userService.cancelSubscription(workspaceId);
|
||||
add(const SettingsPlanEvent.started());
|
||||
},
|
||||
@ -174,5 +178,6 @@ class SettingsPlanState with _$SettingsPlanState {
|
||||
required WorkspaceSubscriptionPB subscription,
|
||||
required BillingPortalPB? billingPortal,
|
||||
@Default(false) bool showSuccessDialog,
|
||||
@Default(false) bool downgradeProcessing,
|
||||
}) = _Ready;
|
||||
}
|
||||
|
@ -1,8 +1,20 @@
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/workspace.pb.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
final _storageNumberFormat = NumberFormat()
|
||||
..maximumFractionDigits = 2
|
||||
..minimumFractionDigits = 0;
|
||||
|
||||
extension PresentableUsage on WorkspaceUsagePB {
|
||||
String get totalBlobInGb =>
|
||||
(totalBlobBytesLimit.toInt() / 1024 / 1024 / 1024).round().toString();
|
||||
|
||||
/// We use [NumberFormat] to format the current blob in GB.
|
||||
///
|
||||
/// Where the [totalBlobBytes] is the total blob bytes in bytes.
|
||||
/// And [NumberFormat.maximumFractionDigits] is set to 2.
|
||||
/// And [NumberFormat.minimumFractionDigits] is set to 0.
|
||||
///
|
||||
String get currentBlobInGb =>
|
||||
(totalBlobBytes.toInt() / 1024 / 1024 / 1024).round().toString();
|
||||
_storageNumberFormat.format(totalBlobBytes.toInt() / 1024 / 1024 / 1024);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/startup/tasks/app_window_size_manager.dart';
|
||||
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
|
||||
@ -9,7 +11,6 @@ import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hotkey_manager/hotkey_manager.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:scaled_app/scaled_app.dart';
|
||||
@ -186,14 +187,12 @@ class _HomeHotKeysState extends State<HomeHotKeys> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_registerHotKeys(context);
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
|
||||
_registerHotKeys(context);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/tabs/flowy_tab.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class TabsManager extends StatefulWidget {
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/user/application/notification_filter/notification_filter_bloc.dart';
|
||||
import 'package:appflowy/user/application/reminder/reminder_bloc.dart';
|
||||
@ -9,7 +11,6 @@ import 'package:appflowy/workspace/presentation/notifications/widgets/notificati
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/reminder.pb.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class NotificationDialog extends StatefulWidget {
|
||||
@ -44,7 +45,7 @@ class _NotificationDialogState extends State<NotificationDialog>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_mutex.close();
|
||||
_mutex.dispose();
|
||||
_controller.removeListener(_updateState);
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
@ -10,18 +12,27 @@ import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class NotificationButton extends StatelessWidget {
|
||||
const NotificationButton({
|
||||
super.key,
|
||||
});
|
||||
class NotificationButton extends StatefulWidget {
|
||||
const NotificationButton({super.key});
|
||||
|
||||
@override
|
||||
State<NotificationButton> createState() => _NotificationButtonState();
|
||||
}
|
||||
|
||||
class _NotificationButtonState extends State<NotificationButton> {
|
||||
final mutex = PopoverMutex();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
mutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final views = context.watch<SidebarSectionsBloc>().state.section.views;
|
||||
final mutex = PopoverMutex();
|
||||
|
||||
return BlocProvider<ReminderBloc>.value(
|
||||
value: getIt<ReminderBloc>(),
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_configuration.dart';
|
||||
@ -12,7 +14,6 @@ import 'package:fixnum/fixnum.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class NotificationItem extends StatefulWidget {
|
||||
@ -71,6 +72,12 @@ class _NotificationItemState extends State<NotificationItem> {
|
||||
infoString = _buildInfoString();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
mutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
String _buildInfoString() {
|
||||
String scheduledString =
|
||||
_scheduledString(widget.scheduled, widget.includeTime);
|
||||
|
@ -1,13 +1,13 @@
|
||||
import 'package:appflowy/workspace/presentation/settings/shared/af_dropdown_menu_entry.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/shared/settings_dropdown.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/workspace/application/settings/ai/settings_ai_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/shared/af_dropdown_menu_entry.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/shared/settings_body.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/shared/settings_dropdown.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/toggle/toggle.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
@ -153,11 +153,9 @@ class _AISearchToggle extends StatelessWidget {
|
||||
} else {
|
||||
return Toggle(
|
||||
value: state.enableSearchIndexing,
|
||||
onChanged: (_) {
|
||||
context.read<SettingsAIBloc>().add(
|
||||
const SettingsAIEvent.toggleAISearch(),
|
||||
);
|
||||
},
|
||||
onChanged: (_) => context
|
||||
.read<SettingsAIBloc>()
|
||||
.add(const SettingsAIEvent.toggleAISearch()),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
@ -47,7 +47,7 @@ class _SettingsPlanComparisonDialogState
|
||||
Widget build(BuildContext context) {
|
||||
final isLM = Theme.of(context).isLightMode;
|
||||
|
||||
return BlocListener<SettingsPlanBloc, SettingsPlanState>(
|
||||
return BlocConsumer<SettingsPlanBloc, SettingsPlanState>(
|
||||
listener: (context, state) {
|
||||
final readyState = state.mapOrNull(ready: (state) => state);
|
||||
|
||||
@ -82,7 +82,7 @@ class _SettingsPlanComparisonDialogState
|
||||
currentSubscription = readyState.subscription;
|
||||
});
|
||||
},
|
||||
child: FlowyDialog(
|
||||
builder: (context, state) => FlowyDialog(
|
||||
constraints: const BoxConstraints(maxWidth: 784, minWidth: 674),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -185,7 +185,16 @@ class _SettingsPlanComparisonDialogState
|
||||
canDowngrade:
|
||||
currentSubscription.subscriptionPlan !=
|
||||
SubscriptionPlanPB.None,
|
||||
currentCanceled: currentSubscription.hasCanceled,
|
||||
currentCanceled: currentSubscription.hasCanceled ||
|
||||
(context
|
||||
.watch<SettingsPlanBloc>()
|
||||
.state
|
||||
.mapOrNull(
|
||||
loading: (_) => true,
|
||||
ready: (state) =>
|
||||
state.downgradeProcessing,
|
||||
) ??
|
||||
false),
|
||||
onSelected: () async {
|
||||
if (currentSubscription.subscriptionPlan ==
|
||||
SubscriptionPlanPB.None ||
|
||||
@ -484,8 +493,9 @@ class _ActionButton extends StatelessWidget {
|
||||
cursor: onPressed != null
|
||||
? SystemMouseCursors.click
|
||||
: MouseCursor.defer,
|
||||
child: _drawGradientBorder(
|
||||
child: _drawBorder(
|
||||
isLM: isLM,
|
||||
isUpgrade: isUpgrade,
|
||||
child: Container(
|
||||
height: 36,
|
||||
width: 148,
|
||||
@ -496,9 +506,7 @@ class _ActionButton extends StatelessWidget {
|
||||
border: Border.all(color: Colors.transparent),
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
),
|
||||
child: Center(
|
||||
child: _drawText(label, isLM),
|
||||
),
|
||||
child: Center(child: _drawText(label, isLM, isUpgrade)),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -509,13 +517,13 @@ class _ActionButton extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _drawText(String text, bool isLM) {
|
||||
Widget _drawText(String text, bool isLM, bool isUpgrade) {
|
||||
final child = FlowyText(
|
||||
text,
|
||||
fontSize: 14,
|
||||
lineHeight: 1.2,
|
||||
fontWeight: useGradientBorder ? FontWeight.w600 : FontWeight.w500,
|
||||
color: const Color(0xFFC49BEC),
|
||||
color: isUpgrade ? const Color(0xFFC49BEC) : null,
|
||||
);
|
||||
|
||||
if (!useGradientBorder || !isLM) {
|
||||
@ -536,18 +544,25 @@ class _ActionButton extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _drawGradientBorder({required bool isLM, required Widget child}) {
|
||||
Widget _drawBorder({
|
||||
required bool isLM,
|
||||
required bool isUpgrade,
|
||||
required Widget child,
|
||||
}) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(2),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
gradient: isUpgrade
|
||||
? LinearGradient(
|
||||
transform: const GradientRotation(-1.2),
|
||||
stops: const [0.4, 1],
|
||||
colors: [
|
||||
isLM ? const Color(0xFF251D37) : const Color(0xFF7459AD),
|
||||
isLM ? const Color(0xFF7547C0) : const Color(0xFFDDC8FF),
|
||||
],
|
||||
),
|
||||
)
|
||||
: null,
|
||||
border: isUpgrade ? null : Border.all(),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: child,
|
||||
|
@ -80,11 +80,30 @@ class SettingsPlanView extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _CurrentPlanBox extends StatelessWidget {
|
||||
class _CurrentPlanBox extends StatefulWidget {
|
||||
const _CurrentPlanBox({required this.subscription});
|
||||
|
||||
final WorkspaceSubscriptionPB subscription;
|
||||
|
||||
@override
|
||||
State<_CurrentPlanBox> createState() => _CurrentPlanBoxState();
|
||||
}
|
||||
|
||||
class _CurrentPlanBoxState extends State<_CurrentPlanBox> {
|
||||
late SettingsPlanBloc planBloc;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
planBloc = context.read<SettingsPlanBloc>();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
planBloc = context.read<SettingsPlanBloc>();
|
||||
super.didChangeDependencies();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
@ -105,13 +124,13 @@ class _CurrentPlanBox extends StatelessWidget {
|
||||
children: [
|
||||
const VSpace(4),
|
||||
FlowyText.semibold(
|
||||
subscription.label,
|
||||
widget.subscription.label,
|
||||
fontSize: 24,
|
||||
color: AFThemeExtension.of(context).strongText,
|
||||
),
|
||||
const VSpace(8),
|
||||
FlowyText.regular(
|
||||
subscription.info,
|
||||
widget.subscription.info,
|
||||
fontSize: 16,
|
||||
color: AFThemeExtension.of(context).strongText,
|
||||
maxLines: 3,
|
||||
@ -124,10 +143,10 @@ class _CurrentPlanBox extends StatelessWidget {
|
||||
onPressed: () => _openPricingDialog(
|
||||
context,
|
||||
context.read<SettingsPlanBloc>().workspaceId,
|
||||
subscription,
|
||||
widget.subscription,
|
||||
),
|
||||
),
|
||||
if (subscription.hasCanceled) ...[
|
||||
if (widget.subscription.hasCanceled) ...[
|
||||
const VSpace(12),
|
||||
FlowyText(
|
||||
LocaleKeys
|
||||
@ -149,10 +168,10 @@ class _CurrentPlanBox extends StatelessWidget {
|
||||
separatorBuilder: () => const VSpace(4),
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
..._getPros(subscription.subscriptionPlan).map(
|
||||
..._getPros(widget.subscription.subscriptionPlan).map(
|
||||
(s) => _ProConItem(label: s),
|
||||
),
|
||||
..._getCons(subscription.subscriptionPlan).map(
|
||||
..._getCons(widget.subscription.subscriptionPlan).map(
|
||||
(s) => _ProConItem(label: s, isPro: false),
|
||||
),
|
||||
],
|
||||
@ -185,7 +204,7 @@ class _CurrentPlanBox extends StatelessWidget {
|
||||
String _canceledDate(BuildContext context) {
|
||||
final appearance = context.read<AppearanceSettingsCubit>().state;
|
||||
return appearance.dateFormat.formatDate(
|
||||
subscription.canceledAt.toDateTime(),
|
||||
widget.subscription.canceledAt.toDateTime(),
|
||||
true,
|
||||
appearance.timeFormat,
|
||||
);
|
||||
@ -199,7 +218,7 @@ class _CurrentPlanBox extends StatelessWidget {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => BlocProvider<SettingsPlanBloc>.value(
|
||||
value: context.read<SettingsPlanBloc>(),
|
||||
value: planBloc,
|
||||
child: SettingsPlanComparisonDialog(
|
||||
workspaceId: workspaceId,
|
||||
subscription: subscription,
|
||||
@ -224,6 +243,7 @@ class _CurrentPlanBox extends StatelessWidget {
|
||||
LocaleKeys.settings_planPage_planUsage_currentPlan_freeProFour.tr(),
|
||||
LocaleKeys.settings_planPage_planUsage_currentPlan_freeProFive.tr(),
|
||||
];
|
||||
|
||||
List<String> _freeCons() => [
|
||||
LocaleKeys.settings_planPage_planUsage_currentPlan_freeConOne.tr(),
|
||||
LocaleKeys.settings_planPage_planUsage_currentPlan_freeConTwo.tr(),
|
||||
@ -242,6 +262,7 @@ class _CurrentPlanBox extends StatelessWidget {
|
||||
LocaleKeys.settings_planPage_planUsage_currentPlan_professionalProFive
|
||||
.tr(),
|
||||
];
|
||||
|
||||
List<String> _proCons() => [
|
||||
LocaleKeys.settings_planPage_planUsage_currentPlan_professionalConOne
|
||||
.tr(),
|
||||
@ -314,6 +335,11 @@ class _PlanUsageSummary extends StatelessWidget {
|
||||
Expanded(
|
||||
child: _UsageBox(
|
||||
title: LocaleKeys.settings_planPage_planUsage_storageLabel.tr(),
|
||||
replacementText: subscription.subscriptionPlan ==
|
||||
SubscriptionPlanPB.Pro
|
||||
? LocaleKeys.settings_planPage_planUsage_storageUnlimited
|
||||
.tr()
|
||||
: null,
|
||||
label: LocaleKeys.settings_planPage_planUsage_storageUsage.tr(
|
||||
args: [
|
||||
usage.currentBlobInGb,
|
||||
@ -372,12 +398,16 @@ class _UsageBox extends StatelessWidget {
|
||||
required this.title,
|
||||
required this.label,
|
||||
required this.value,
|
||||
this.replacementText,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final String label;
|
||||
final double value;
|
||||
|
||||
/// Replaces the progress indicator if not null
|
||||
final String? replacementText;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
@ -388,8 +418,22 @@ class _UsageBox extends StatelessWidget {
|
||||
fontSize: 11,
|
||||
color: AFThemeExtension.of(context).secondaryTextColor,
|
||||
),
|
||||
if (replacementText != null) ...[
|
||||
Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: FlowyText.medium(
|
||||
replacementText!,
|
||||
fontSize: 11,
|
||||
color: AFThemeExtension.of(context).secondaryTextColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
] else ...[
|
||||
_PlanProgressIndicator(label: label, progress: value),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/base/emoji/emoji_picker.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/base/selectable_svg_widget.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/decoration.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
SelectionMenuItem emojiMenuItem = SelectionMenuItem(
|
||||
getName: LocaleKeys.document_plugins_emoji.tr,
|
||||
@ -85,8 +86,8 @@ class EmojiSelectionMenu extends StatefulWidget {
|
||||
class _EmojiSelectionMenuState extends State<EmojiSelectionMenu> {
|
||||
@override
|
||||
void initState() {
|
||||
HardwareKeyboard.instance.addHandler(_handleGlobalKeyEvent);
|
||||
super.initState();
|
||||
HardwareKeyboard.instance.addHandler(_handleGlobalKeyEvent);
|
||||
}
|
||||
|
||||
bool _handleGlobalKeyEvent(KeyEvent event) {
|
||||
@ -95,9 +96,8 @@ class _EmojiSelectionMenuState extends State<EmojiSelectionMenu> {
|
||||
//triggers on esc
|
||||
widget.onExit();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -106,17 +106,10 @@ class _EmojiSelectionMenuState extends State<EmojiSelectionMenu> {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FlowyEmojiPicker(
|
||||
onEmojiSelected: (_, emoji) {
|
||||
widget.onSubmitted(emoji);
|
||||
},
|
||||
onEmojiSelected: (_, emoji) => widget.onSubmitted(emoji),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'emoji_picker.dart';
|
||||
import 'emoji_picker_builder.dart';
|
||||
import 'models/emoji_category_models.dart';
|
||||
@ -29,8 +31,10 @@ class DefaultEmojiPickerViewState extends State<DefaultEmojiPickerView>
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
var initCategory = widget.state.emojiCategoryGroupList.indexWhere(
|
||||
(element) => element.category == widget.config.initCategory,
|
||||
super.initState();
|
||||
|
||||
int initCategory = widget.state.emojiCategoryGroupList.indexWhere(
|
||||
(el) => el.category == widget.config.initCategory,
|
||||
);
|
||||
if (initCategory == -1) {
|
||||
initCategory = 0;
|
||||
@ -42,27 +46,23 @@ class DefaultEmojiPickerViewState extends State<DefaultEmojiPickerView>
|
||||
);
|
||||
_pageController = PageController(initialPage: initCategory);
|
||||
_emojiFocusNode.requestFocus();
|
||||
|
||||
_emojiController.addListener(() {
|
||||
final String query = _emojiController.text.toLowerCase();
|
||||
if (query.isEmpty) {
|
||||
searchEmojiList.emoji.clear();
|
||||
_pageController!.jumpToPage(
|
||||
_tabController!.index,
|
||||
);
|
||||
_pageController!.jumpToPage(_tabController!.index);
|
||||
} else {
|
||||
searchEmojiList.emoji.clear();
|
||||
for (final element in widget.state.emojiCategoryGroupList) {
|
||||
searchEmojiList.emoji.addAll(
|
||||
element.emoji.where((item) {
|
||||
return item.name.toLowerCase().contains(query);
|
||||
}).toList(),
|
||||
element.emoji
|
||||
.where((item) => item.name.toLowerCase().contains(query))
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
setState(() {});
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -81,26 +81,18 @@ class DefaultEmojiPickerViewState extends State<DefaultEmojiPickerView>
|
||||
type: MaterialType.transparency,
|
||||
child: IconButton(
|
||||
padding: const EdgeInsets.only(bottom: 2),
|
||||
icon: Icon(
|
||||
Icons.backspace,
|
||||
color: widget.config.backspaceColor,
|
||||
),
|
||||
onPressed: () {
|
||||
widget.state.onBackspacePressed!();
|
||||
},
|
||||
icon: Icon(Icons.backspace, color: widget.config.backspaceColor),
|
||||
onPressed: () => widget.state.onBackspacePressed!(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
bool isEmojiSearching() {
|
||||
final bool result =
|
||||
bool isEmojiSearching() =>
|
||||
searchEmojiList.emoji.isNotEmpty || _emojiController.text.isNotEmpty;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
@ -213,15 +205,9 @@ class DefaultEmojiPickerViewState extends State<DefaultEmojiPickerView>
|
||||
required Widget child,
|
||||
}) {
|
||||
if (widget.config.buttonMode == ButtonMode.MATERIAL) {
|
||||
return InkWell(
|
||||
onTap: onPressed,
|
||||
child: child,
|
||||
);
|
||||
return InkWell(onTap: onPressed, child: child);
|
||||
}
|
||||
return GestureDetector(
|
||||
onTap: onPressed,
|
||||
child: child,
|
||||
);
|
||||
return GestureDetector(onTap: onPressed, child: child);
|
||||
}
|
||||
|
||||
Widget _buildPage(double emojiSize, EmojiCategoryGroup emojiCategoryGroup) {
|
||||
@ -275,9 +261,7 @@ class DefaultEmojiPickerViewState extends State<DefaultEmojiPickerView>
|
||||
child: FittedBox(
|
||||
child: Text(
|
||||
emoji.emoji,
|
||||
style: TextStyle(
|
||||
fontSize: emojiSize,
|
||||
),
|
||||
style: TextStyle(fontSize: emojiSize),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -1,3 +1,7 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:appflowy/core/helpers/url_launcher.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/workspace/application/settings/supabase_cloud_setting_bloc.dart';
|
||||
@ -15,9 +19,6 @@ import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class SettingSupabaseCloudView extends StatelessWidget {
|
||||
@ -265,13 +266,7 @@ class SupabaseInput extends StatefulWidget {
|
||||
}
|
||||
|
||||
class SupabaseInputState extends State<SupabaseInput> {
|
||||
late TextEditingController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = TextEditingController(text: widget.url);
|
||||
}
|
||||
late final _controller = TextEditingController(text: widget.url);
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
|
@ -29,6 +29,12 @@ class _DateTimeSettingState extends State<DateTimeSetting> {
|
||||
final timeSettingPopoverMutex = PopoverMutex();
|
||||
String? overlayIdentifier;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
timeSettingPopoverMutex.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final List<Widget> children = [
|
||||
|
@ -129,11 +129,6 @@ class NavigatorAlertDialog extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _CreateFlowyAlertDialog extends State<NavigatorAlertDialog> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StyledDialog(
|
||||
|
@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
class PopoverActionList<T extends PopoverAction> extends StatefulWidget {
|
||||
@ -42,12 +43,12 @@ class PopoverActionList<T extends PopoverAction> extends StatefulWidget {
|
||||
|
||||
class _PopoverActionListState<T extends PopoverAction>
|
||||
extends State<PopoverActionList<T>> {
|
||||
late PopoverController popoverController;
|
||||
final PopoverController popoverController = PopoverController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
popoverController = PopoverController();
|
||||
super.initState();
|
||||
void dispose() {
|
||||
popoverController.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/workspace/application/view/view_listener.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ViewTabBarItem extends StatefulWidget {
|
||||
const ViewTabBarItem({super.key, required this.view});
|
||||
@ -37,7 +38,5 @@ class _ViewTabBarItemState extends State<ViewTabBarItem> {
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FlowyText.medium(view.name);
|
||||
}
|
||||
Widget build(BuildContext context) => FlowyText.medium(view.name);
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:appflowy_backend/appflowy_backend.dart';
|
||||
|
||||
void main() {
|
||||
@ -36,21 +37,15 @@ class _MyAppState extends State<MyApp> {
|
||||
// message was in flight, we want to discard the reply rather than calling
|
||||
// setState to update our non-existent appearance.
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_platformVersion = platformVersion;
|
||||
});
|
||||
setState(() => _platformVersion = platformVersion);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Plugin example app'),
|
||||
),
|
||||
body: Center(
|
||||
child: Text('Running on: $_platformVersion\n'),
|
||||
),
|
||||
appBar: AppBar(title: const Text('Plugin example app')),
|
||||
body: Center(child: Text('Running on: $_platformVersion\n')),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import 'package:appflowy_popover/src/layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:appflowy_popover/src/layout.dart';
|
||||
|
||||
import 'mask.dart';
|
||||
import 'mutex.dart';
|
||||
|
||||
@ -177,9 +178,7 @@ class PopoverState extends State<Popover> {
|
||||
_rootEntry.addEntry(context, this, newEntry, widget.asBarrier);
|
||||
}
|
||||
|
||||
void close({
|
||||
bool notify = true,
|
||||
}) {
|
||||
void close({bool notify = true}) {
|
||||
if (_rootEntry.contains(this)) {
|
||||
_rootEntry.removeEntry(this);
|
||||
if (notify) {
|
||||
@ -286,9 +285,7 @@ class PopoverContainer extends StatefulWidget {
|
||||
if (context is StatefulElement && context.state is PopoverContainerState) {
|
||||
return context.state as PopoverContainerState;
|
||||
}
|
||||
final PopoverContainerState? result =
|
||||
context.findAncestorStateOfType<PopoverContainerState>();
|
||||
return result!;
|
||||
return context.findAncestorStateOfType<PopoverContainerState>()!;
|
||||
}
|
||||
|
||||
static PopoverContainerState? maybeOf(BuildContext context) {
|
||||
|
@ -2,10 +2,11 @@
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flowy_infra_ui/src/flowy_overlay/layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:flowy_infra_ui/src/flowy_overlay/layout.dart';
|
||||
|
||||
/// Specifies how overlay are anchored to the SourceWidget
|
||||
enum AnchorDirection {
|
||||
// Corner aligned with a corner of the SourceWidget
|
||||
@ -341,18 +342,17 @@ class FlowyOverlayState extends State<FlowyOverlay> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_keyboardShortcutBindings.addAll({
|
||||
LogicalKeySet(LogicalKeyboardKey.escape): (identifier) {
|
||||
remove(identifier);
|
||||
},
|
||||
});
|
||||
super.initState();
|
||||
_keyboardShortcutBindings.addAll({
|
||||
LogicalKeySet(LogicalKeyboardKey.escape): (identifier) =>
|
||||
remove(identifier),
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final overlays = _overlayList.map((item) {
|
||||
var widget = item.widget;
|
||||
Widget widget = item.widget;
|
||||
|
||||
// requestFocus will cause the children weird focus behaviors.
|
||||
// item.focusNode.requestFocus();
|
||||
@ -390,15 +390,11 @@ class FlowyOverlayState extends State<FlowyOverlay> {
|
||||
return MaterialApp(
|
||||
theme: Theme.of(context),
|
||||
debugShowCheckedModeBanner: false,
|
||||
home: Stack(
|
||||
children: children..addAll(overlays),
|
||||
),
|
||||
home: Stack(children: children..addAll(overlays)),
|
||||
);
|
||||
}
|
||||
|
||||
void _handleTapOnBackground() {
|
||||
removeAll();
|
||||
}
|
||||
void _handleTapOnBackground() => removeAll();
|
||||
|
||||
Widget? _renderBackground(List<Widget> overlays) {
|
||||
Widget? child;
|
||||
|
@ -36,13 +36,7 @@ class StyledListView extends StatefulWidget {
|
||||
|
||||
/// State is public so this can easily be controlled externally
|
||||
class StyledListViewState extends State<StyledListView> {
|
||||
late ScrollController scrollController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
scrollController = ScrollController();
|
||||
super.initState();
|
||||
}
|
||||
final scrollController = ScrollController();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
@ -50,15 +44,6 @@ class StyledListViewState extends State<StyledListView> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(StyledListView oldWidget) {
|
||||
if (oldWidget.itemCount != widget.itemCount ||
|
||||
oldWidget.itemExtent != widget.itemExtent) {
|
||||
setState(() {});
|
||||
}
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final contentSize = (widget.itemCount ?? 0.0) * (widget.itemExtent ?? 00.0);
|
||||
@ -75,7 +60,7 @@ class StyledListViewState extends State<StyledListView> {
|
||||
controller: scrollController,
|
||||
itemExtent: widget.itemExtent,
|
||||
itemCount: widget.itemCount,
|
||||
itemBuilder: (c, i) => widget.itemBuilder(c, i),
|
||||
itemBuilder: widget.itemBuilder,
|
||||
),
|
||||
);
|
||||
return listContent;
|
||||
|
@ -137,7 +137,6 @@ class FlowyTextFieldState extends State<FlowyTextField> {
|
||||
void _onSubmitted(String text) {
|
||||
widget.onSubmitted?.call(text);
|
||||
if (widget.autoClearWhenDone) {
|
||||
// using `controller.clear()` instead of `controller.text = ''` which will crash on Windows.
|
||||
controller.clear();
|
||||
}
|
||||
}
|
||||
@ -154,7 +153,7 @@ class FlowyTextFieldState extends State<FlowyTextField> {
|
||||
_onChanged(text);
|
||||
}
|
||||
},
|
||||
onSubmitted: (text) => _onSubmitted(text),
|
||||
onSubmitted: _onSubmitted,
|
||||
onEditingComplete: widget.onEditingComplete,
|
||||
minLines: 1,
|
||||
maxLines: widget.maxLines,
|
||||
|
@ -1,10 +1,11 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:flowy_infra/size.dart';
|
||||
|
||||
class FlowyFormTextInput extends StatelessWidget {
|
||||
static EdgeInsets kDefaultTextInputPadding =
|
||||
EdgeInsets.only(bottom: Insets.sm, top: 4);
|
||||
@ -162,10 +163,12 @@ class StyledSearchTextInputState extends State<StyledSearchTextInput> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller =
|
||||
widget.controller ?? TextEditingController(text: widget.initialValue);
|
||||
_focusNode = FocusNode(
|
||||
debugLabel: widget.label ?? '',
|
||||
debugLabel: widget.label,
|
||||
canRequestFocus: true,
|
||||
onKeyEvent: (node, event) {
|
||||
if (event.logicalKey == LogicalKeyboardKey.escape) {
|
||||
widget.onEditingCancel?.call();
|
||||
@ -173,7 +176,6 @@ class StyledSearchTextInputState extends State<StyledSearchTextInput> {
|
||||
}
|
||||
return KeyEventResult.ignored;
|
||||
},
|
||||
canRequestFocus: true,
|
||||
);
|
||||
// Listen for focus out events
|
||||
_focusNode
|
||||
@ -182,7 +184,6 @@ class StyledSearchTextInputState extends State<StyledSearchTextInput> {
|
||||
if (widget.autoFocus ?? false) {
|
||||
scheduleMicrotask(() => _focusNode.requestFocus());
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -292,8 +293,10 @@ class ThinUnderlineBorder extends InputBorder {
|
||||
bool get isOutline => false;
|
||||
|
||||
@override
|
||||
UnderlineInputBorder copyWith(
|
||||
{BorderSide? borderSide, BorderRadius? borderRadius}) {
|
||||
UnderlineInputBorder copyWith({
|
||||
BorderSide? borderSide,
|
||||
BorderRadius? borderRadius,
|
||||
}) {
|
||||
return UnderlineInputBorder(
|
||||
borderSide: borderSide ?? this.borderSide,
|
||||
borderRadius: borderRadius ?? this.borderRadius,
|
||||
@ -301,14 +304,12 @@ class ThinUnderlineBorder extends InputBorder {
|
||||
}
|
||||
|
||||
@override
|
||||
EdgeInsetsGeometry get dimensions {
|
||||
return EdgeInsets.only(bottom: borderSide.width);
|
||||
}
|
||||
EdgeInsetsGeometry get dimensions =>
|
||||
EdgeInsets.only(bottom: borderSide.width);
|
||||
|
||||
@override
|
||||
UnderlineInputBorder scale(double t) {
|
||||
return UnderlineInputBorder(borderSide: borderSide.scale(t));
|
||||
}
|
||||
UnderlineInputBorder scale(double t) =>
|
||||
UnderlineInputBorder(borderSide: borderSide.scale(t));
|
||||
|
||||
@override
|
||||
Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
|
||||
|
@ -1,9 +1,10 @@
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flowy_infra/time/duration.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/time/duration.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||
|
||||
class RoundedInputField extends StatefulWidget {
|
||||
final String? hintText;
|
||||
final bool obscureText;
|
||||
@ -60,33 +61,26 @@ class RoundedInputField extends StatefulWidget {
|
||||
|
||||
class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||
String inputText = "";
|
||||
bool obscuteText = false;
|
||||
bool obscureText = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
obscuteText = widget.obscureText;
|
||||
if (widget.controller != null) {
|
||||
inputText = widget.controller!.text;
|
||||
} else {
|
||||
inputText = widget.initialValue ?? "";
|
||||
}
|
||||
|
||||
super.initState();
|
||||
obscureText = widget.obscureText;
|
||||
inputText = widget.controller != null
|
||||
? widget.controller!.text
|
||||
: widget.initialValue ?? "";
|
||||
}
|
||||
|
||||
String? _suffixText() {
|
||||
if (widget.maxLength != null) {
|
||||
return ' ${widget.controller!.text.length}/${widget.maxLength}';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
String? _suffixText() => widget.maxLength != null
|
||||
? ' ${widget.controller!.text.length}/${widget.maxLength}'
|
||||
: null;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var borderColor =
|
||||
Color borderColor =
|
||||
widget.normalBorderColor ?? Theme.of(context).colorScheme.outline;
|
||||
var focusBorderColor =
|
||||
Color focusBorderColor =
|
||||
widget.focusBorderColor ?? Theme.of(context).colorScheme.primary;
|
||||
|
||||
if (widget.errorText.isNotEmpty) {
|
||||
@ -122,7 +116,7 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||
},
|
||||
cursorColor:
|
||||
widget.cursorColor ?? Theme.of(context).colorScheme.primary,
|
||||
obscureText: obscuteText,
|
||||
obscureText: obscureText,
|
||||
style: widget.style ?? Theme.of(context).textTheme.bodyMedium,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: widget.contentPadding,
|
||||
@ -134,17 +128,11 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||
suffixText: _suffixText(),
|
||||
counterText: "",
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: borderColor,
|
||||
width: 1.0,
|
||||
),
|
||||
borderSide: BorderSide(color: borderColor, width: 1.0),
|
||||
borderRadius: Corners.s10Border,
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: focusBorderColor,
|
||||
width: 1.0,
|
||||
),
|
||||
borderSide: BorderSide(color: focusBorderColor, width: 1.0),
|
||||
borderRadius: Corners.s10Border,
|
||||
),
|
||||
suffixIcon: obscureIcon(),
|
||||
@ -186,19 +174,11 @@ class _RoundedInputFieldState extends State<RoundedInputField> {
|
||||
}
|
||||
|
||||
assert(widget.obscureIcon != null && widget.obscureHideIcon != null);
|
||||
Widget? icon;
|
||||
if (obscuteText) {
|
||||
icon = widget.obscureIcon!;
|
||||
} else {
|
||||
icon = widget.obscureHideIcon!;
|
||||
}
|
||||
final icon = obscureText ? widget.obscureIcon! : widget.obscureHideIcon!;
|
||||
|
||||
return RoundedImageButton(
|
||||
size: iconWidth,
|
||||
press: () {
|
||||
obscuteText = !obscuteText;
|
||||
setState(() {});
|
||||
},
|
||||
press: () => setState(() => obscureText = !obscureText),
|
||||
child: icon,
|
||||
);
|
||||
}
|
||||
|
@ -53,11 +53,11 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: "64c0be8"
|
||||
resolved-ref: "64c0be88a113c2eece5512701527e7d11b8c9239"
|
||||
ref: e8ee051
|
||||
resolved-ref: e8ee051719eded6621ccdc2722f696411c020209
|
||||
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
||||
source: git
|
||||
version: "2.5.1"
|
||||
version: "3.0.0"
|
||||
appflowy_editor_plugins:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -185,7 +185,7 @@ dependency_overrides:
|
||||
appflowy_editor:
|
||||
git:
|
||||
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
||||
ref: "64c0be8"
|
||||
ref: "e8ee051"
|
||||
|
||||
appflowy_editor_plugins:
|
||||
git:
|
||||
|
@ -633,6 +633,7 @@
|
||||
"proBadge": "Pro",
|
||||
"memberProToggle": "Unlimited members",
|
||||
"guestCollabToggle": "10 guest collaborators",
|
||||
"storageUnlimited": "Unlimited storage with your Pro Plan",
|
||||
"aiCredit": {
|
||||
"title": "Add AppFlowy AI Credit",
|
||||
"price": "5$",
|
||||
|
Loading…
Reference in New Issue
Block a user