mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-04-24 22:57:12 -04:00
fix: can't input url in Grid (#2737)
* fix: launch url in url cell * fix: can't input url in Grid * feat: support selecting or deselecting all items in export page * fix: remove the circle shape * fix: light mode toolbar color * chore: update language and adjust the launch page
This commit is contained in:
parent
37547a6485
commit
02b7149514
12 changed files with 149 additions and 108 deletions
|
@ -196,6 +196,8 @@
|
||||||
"restartApp": "Please restart app for the changes to take effect.",
|
"restartApp": "Please restart app for the changes to take effect.",
|
||||||
"exportDatabase": "Export database",
|
"exportDatabase": "Export database",
|
||||||
"selectFiles": "Select the files that need to be export",
|
"selectFiles": "Select the files that need to be export",
|
||||||
|
"selectAll": "Select all",
|
||||||
|
"deselectAll": "Deselect all",
|
||||||
"createNewFolder": "Create a new folder",
|
"createNewFolder": "Create a new folder",
|
||||||
"createNewFolderDesc": "Tell us where you want to store your data",
|
"createNewFolderDesc": "Tell us where you want to store your data",
|
||||||
"defineWhereYourDataIsStored": "Define where your data is stored",
|
"defineWhereYourDataIsStored": "Define where your data is stored",
|
||||||
|
@ -211,12 +213,13 @@
|
||||||
"folderPath": "Path to store your folder",
|
"folderPath": "Path to store your folder",
|
||||||
"locationCannotBeEmpty": "Path cannot be empty",
|
"locationCannotBeEmpty": "Path cannot be empty",
|
||||||
"pathCopiedSnackbar": "File storage path copied to clipboard!",
|
"pathCopiedSnackbar": "File storage path copied to clipboard!",
|
||||||
"changeLocationTooltips": "Change the files read the data directory",
|
"changeLocationTooltips": "Change the data directory",
|
||||||
"change": "Change",
|
"change": "Change",
|
||||||
"openLocationTooltips": "Open the files read the data directory",
|
"openLocationTooltips": "Open another data directory",
|
||||||
"recoverLocationTooltips": "Recover the files read the data directory",
|
"recoverLocationTooltips": "Reset to AppFlowy's default data directory",
|
||||||
"exportFileSuccess": "Export file successfully!",
|
"exportFileSuccess": "Export file successfully!",
|
||||||
"exportFileFail": "Export file failed!"
|
"exportFileFail": "Export file failed!",
|
||||||
|
"export": "Export"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
|
|
|
@ -10,7 +10,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
import '../../../../grid/presentation/layout/sizes.dart';
|
import '../../../../grid/presentation/layout/sizes.dart';
|
||||||
import '../../accessory/cell_accessory.dart';
|
import '../../accessory/cell_accessory.dart';
|
||||||
import '../../cell_builder.dart';
|
import '../../cell_builder.dart';
|
||||||
|
@ -36,13 +36,11 @@ enum GridURLCellAccessoryType {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridURLCell extends GridCellWidget {
|
class GridURLCell extends GridCellWidget {
|
||||||
final CellControllerBuilder cellControllerBuilder;
|
|
||||||
late final GridURLCellStyle? cellStyle;
|
|
||||||
GridURLCell({
|
GridURLCell({
|
||||||
|
super.key,
|
||||||
required this.cellControllerBuilder,
|
required this.cellControllerBuilder,
|
||||||
GridCellStyle? style,
|
GridCellStyle? style,
|
||||||
Key? key,
|
}) {
|
||||||
}) : super(key: key) {
|
|
||||||
if (style != null) {
|
if (style != null) {
|
||||||
cellStyle = (style as GridURLCellStyle);
|
cellStyle = (style as GridURLCellStyle);
|
||||||
} else {
|
} else {
|
||||||
|
@ -50,6 +48,9 @@ class GridURLCell extends GridCellWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final CellControllerBuilder cellControllerBuilder;
|
||||||
|
late final GridURLCellStyle? cellStyle;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
GridCellState<GridURLCell> createState() => _GridURLCellState();
|
GridCellState<GridURLCell> createState() => _GridURLCellState();
|
||||||
|
|
||||||
|
@ -104,28 +105,35 @@ class GridURLCell extends GridCellWidget {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class _GridURLCellState extends GridCellState<GridURLCell> {
|
class _GridURLCellState extends GridFocusNodeCellState<GridURLCell> {
|
||||||
final _popoverController = PopoverController();
|
final _popoverController = PopoverController();
|
||||||
late URLCellBloc _cellBloc;
|
late final URLCellBloc _cellBloc;
|
||||||
late TextEditingController _controller;
|
late final TextEditingController _controller;
|
||||||
late FocusNode _focusNode;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
final cellController =
|
final cellController =
|
||||||
widget.cellControllerBuilder.build() as URLCellController;
|
widget.cellControllerBuilder.build() as URLCellController;
|
||||||
_cellBloc = URLCellBloc(cellController: cellController);
|
_cellBloc = URLCellBloc(cellController: cellController)
|
||||||
_cellBloc.add(const URLCellEvent.initial());
|
..add(const URLCellEvent.initial());
|
||||||
_controller = TextEditingController(text: _cellBloc.state.content);
|
_controller = TextEditingController(text: _cellBloc.state.content);
|
||||||
_focusNode = FocusNode();
|
}
|
||||||
super.initState();
|
|
||||||
|
@override
|
||||||
|
Future<void> dispose() async {
|
||||||
|
_cellBloc.close();
|
||||||
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider.value(
|
return BlocProvider.value(
|
||||||
value: _cellBloc,
|
value: _cellBloc,
|
||||||
child: BlocBuilder<URLCellBloc, URLCellState>(
|
child: BlocConsumer<URLCellBloc, URLCellState>(
|
||||||
|
listenWhen: (previous, current) => previous.content != current.content,
|
||||||
|
listener: (context, state) => _controller.text = state.content,
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final urlEditor = Padding(
|
final urlEditor = Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
|
@ -134,7 +142,7 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
|
||||||
),
|
),
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
focusNode: _focusNode,
|
focusNode: focusNode,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
style: (widget.cellStyle?.textStyle ??
|
style: (widget.cellStyle?.textStyle ??
|
||||||
Theme.of(context).textTheme.bodyMedium)
|
Theme.of(context).textTheme.bodyMedium)
|
||||||
|
@ -143,8 +151,6 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
|
||||||
decoration: TextDecoration.underline,
|
decoration: TextDecoration.underline,
|
||||||
),
|
),
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
onEditingComplete: focusChanged,
|
|
||||||
onSubmitted: (value) => focusChanged(isUrlSubmitted: true),
|
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
contentPadding: EdgeInsets.only(
|
contentPadding: EdgeInsets.only(
|
||||||
top: GridSize.cellContentInsets.top,
|
top: GridSize.cellContentInsets.top,
|
||||||
|
@ -162,24 +168,10 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void focusChanged({
|
|
||||||
bool isUrlSubmitted = false,
|
|
||||||
}) {
|
|
||||||
if (mounted) {
|
|
||||||
if (_cellBloc.isClosed == false &&
|
|
||||||
_controller.text != _cellBloc.state.content) {
|
|
||||||
_cellBloc.add(URLCellEvent.updateURL(_controller.text));
|
|
||||||
}
|
|
||||||
if (isUrlSubmitted) {
|
|
||||||
_focusNode.unfocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> dispose() async {
|
Future<void> focusChanged() async {
|
||||||
_cellBloc.close();
|
_cellBloc.add(URLCellEvent.updateURL(_controller.text));
|
||||||
super.dispose();
|
return super.focusChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -192,19 +184,17 @@ class _GridURLCellState extends GridCellState<GridURLCell> {
|
||||||
String? onCopy() => _cellBloc.state.content;
|
String? onCopy() => _cellBloc.state.content;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInsert(String value) {
|
void onInsert(String value) => _cellBloc.add(URLCellEvent.updateURL(value));
|
||||||
_cellBloc.add(URLCellEvent.updateURL(value));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _EditURLAccessory extends StatefulWidget {
|
class _EditURLAccessory extends StatefulWidget {
|
||||||
final CellControllerBuilder cellControllerBuilder;
|
|
||||||
final BuildContext anchorContext;
|
|
||||||
const _EditURLAccessory({
|
const _EditURLAccessory({
|
||||||
required this.cellControllerBuilder,
|
required this.cellControllerBuilder,
|
||||||
required this.anchorContext,
|
required this.anchorContext,
|
||||||
Key? key,
|
});
|
||||||
}) : super(key: key);
|
|
||||||
|
final CellControllerBuilder cellControllerBuilder;
|
||||||
|
final BuildContext anchorContext;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _EditURLAccessoryState();
|
State<StatefulWidget> createState() => _EditURLAccessoryState();
|
||||||
|
@ -212,20 +202,14 @@ class _EditURLAccessory extends StatefulWidget {
|
||||||
|
|
||||||
class _EditURLAccessoryState extends State<_EditURLAccessory>
|
class _EditURLAccessoryState extends State<_EditURLAccessory>
|
||||||
with GridCellAccessoryState {
|
with GridCellAccessoryState {
|
||||||
late PopoverController _popoverController;
|
final popoverController = PopoverController();
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
_popoverController = PopoverController();
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppFlowyPopover(
|
return AppFlowyPopover(
|
||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
constraints: BoxConstraints.loose(const Size(300, 160)),
|
constraints: BoxConstraints.loose(const Size(300, 160)),
|
||||||
controller: _popoverController,
|
controller: popoverController,
|
||||||
direction: PopoverDirection.bottomWithLeftAligned,
|
direction: PopoverDirection.bottomWithLeftAligned,
|
||||||
offset: const Offset(0, 8),
|
offset: const Offset(0, 8),
|
||||||
child: svgWidget(
|
child: svgWidget(
|
||||||
|
@ -236,7 +220,7 @@ class _EditURLAccessoryState extends State<_EditURLAccessory>
|
||||||
return URLEditorPopover(
|
return URLEditorPopover(
|
||||||
cellController:
|
cellController:
|
||||||
widget.cellControllerBuilder.build() as URLCellController,
|
widget.cellControllerBuilder.build() as URLCellController,
|
||||||
onExit: () => _popoverController.close(),
|
onExit: () => popoverController.close(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -244,14 +228,17 @@ class _EditURLAccessoryState extends State<_EditURLAccessory>
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onTap() {
|
void onTap() {
|
||||||
_popoverController.show();
|
popoverController.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CopyURLAccessory extends StatefulWidget {
|
class _CopyURLAccessory extends StatefulWidget {
|
||||||
|
const _CopyURLAccessory({
|
||||||
|
super.key,
|
||||||
|
required this.cellContext,
|
||||||
|
});
|
||||||
|
|
||||||
final URLCellController cellContext;
|
final URLCellController cellContext;
|
||||||
const _CopyURLAccessory({required this.cellContext, Key? key})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _CopyURLAccessoryState();
|
State<StatefulWidget> createState() => _CopyURLAccessoryState();
|
||||||
|
@ -270,16 +257,22 @@ class _CopyURLAccessoryState extends State<_CopyURLAccessory>
|
||||||
@override
|
@override
|
||||||
void onTap() {
|
void onTap() {
|
||||||
final content =
|
final content =
|
||||||
widget.cellContext.getCellData(loadIfNotExist: false)?.content ?? "";
|
widget.cellContext.getCellData(loadIfNotExist: false)?.content;
|
||||||
|
if (content == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Clipboard.setData(ClipboardData(text: content));
|
Clipboard.setData(ClipboardData(text: content));
|
||||||
showMessageToast(LocaleKeys.grid_row_copyProperty.tr());
|
showMessageToast(LocaleKeys.grid_row_copyProperty.tr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _VisitURLAccessory extends StatefulWidget {
|
class _VisitURLAccessory extends StatefulWidget {
|
||||||
|
const _VisitURLAccessory({
|
||||||
|
super.key,
|
||||||
|
required this.cellContext,
|
||||||
|
});
|
||||||
|
|
||||||
final URLCellController cellContext;
|
final URLCellController cellContext;
|
||||||
const _VisitURLAccessory({required this.cellContext, Key? key})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _VisitURLAccessoryState();
|
State<StatefulWidget> createState() => _VisitURLAccessoryState();
|
||||||
|
@ -297,14 +290,14 @@ class _VisitURLAccessoryState extends State<_VisitURLAccessory>
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onTap() {
|
void onTap() {
|
||||||
var content =
|
final content =
|
||||||
widget.cellContext.getCellData(loadIfNotExist: false)?.content ?? "";
|
widget.cellContext.getCellData(loadIfNotExist: false)?.content;
|
||||||
if (!content.startsWith('http://') && !content.startsWith('https://')) {
|
if (content == null) {
|
||||||
content = 'http://$content';
|
return;
|
||||||
}
|
|
||||||
final uri = Uri.parse(content);
|
|
||||||
if (content.isNotEmpty) {
|
|
||||||
canLaunchUrl(uri).then((value) => launchUrl(uri));
|
|
||||||
}
|
}
|
||||||
|
final shouldAddScheme =
|
||||||
|
!['http', 'https'].any((pattern) => content.startsWith(pattern));
|
||||||
|
final url = shouldAddScheme ? 'http://$content' : content;
|
||||||
|
canLaunchUrlString(url).then((value) => launchUrlString(url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
||||||
|
|
||||||
late final Map<String, BlockComponentBuilder> blockComponentBuilders =
|
late final Map<String, BlockComponentBuilder> blockComponentBuilders =
|
||||||
_customAppFlowyBlockComponentBuilders();
|
_customAppFlowyBlockComponentBuilders();
|
||||||
late final List<CharacterShortcutEvent> characterShortcutEvents = [
|
List<CharacterShortcutEvent> get characterShortcutEvents => [
|
||||||
// code block
|
// code block
|
||||||
...codeBlockCharacterEvents,
|
...codeBlockCharacterEvents,
|
||||||
|
|
||||||
|
@ -82,7 +82,9 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
|
||||||
style: styleCustomizer.selectionMenuStyleBuilder(),
|
style: styleCustomizer.selectionMenuStyleBuilder(),
|
||||||
).handler;
|
).handler;
|
||||||
|
|
||||||
late final styleCustomizer = EditorStyleCustomizer(context: context);
|
EditorStyleCustomizer get styleCustomizer => EditorStyleCustomizer(
|
||||||
|
context: context,
|
||||||
|
);
|
||||||
DocumentBloc get documentBloc => context.read<DocumentBloc>();
|
DocumentBloc get documentBloc => context.read<DocumentBloc>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -140,7 +140,7 @@ class EditorStyleCustomizer {
|
||||||
FloatingToolbarStyle floatingToolbarStyleBuilder() {
|
FloatingToolbarStyle floatingToolbarStyleBuilder() {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
return FloatingToolbarStyle(
|
return FloatingToolbarStyle(
|
||||||
backgroundColor: theme.cardColor,
|
backgroundColor: theme.colorScheme.onTertiary,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,10 +218,13 @@ Widget _buildTextButton(
|
||||||
String title,
|
String title,
|
||||||
VoidCallback onPressed,
|
VoidCallback onPressed,
|
||||||
) {
|
) {
|
||||||
return SecondaryTextButton(
|
return SizedBox(
|
||||||
|
width: 60,
|
||||||
|
child: SecondaryTextButton(
|
||||||
title,
|
title,
|
||||||
mode: SecondaryTextButtonMode.small,
|
mode: SecondaryTextButtonMode.small,
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ class _SkipLogInScreenState extends State<SkipLogInScreen> {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
|
const Spacer(),
|
||||||
FlowyLogoTitle(
|
FlowyLogoTitle(
|
||||||
title: LocaleKeys.welcomeText.tr(),
|
title: LocaleKeys.welcomeText.tr(),
|
||||||
logoSize: const Size.square(40),
|
logoSize: const Size.square(40),
|
||||||
|
@ -68,8 +69,6 @@ class _SkipLogInScreenState extends State<SkipLogInScreen> {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const VSpace(32),
|
const VSpace(32),
|
||||||
_buildSubscribeButtons(context),
|
|
||||||
const VSpace(32),
|
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: MediaQuery.of(context).size.width * 0.5,
|
width: MediaQuery.of(context).size.width * 0.5,
|
||||||
child: FolderWidget(
|
child: FolderWidget(
|
||||||
|
@ -78,7 +77,10 @@ class _SkipLogInScreenState extends State<SkipLogInScreen> {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const VSpace(64),
|
const Spacer(),
|
||||||
|
const VSpace(48),
|
||||||
|
_buildSubscribeButtons(context),
|
||||||
|
const VSpace(24),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -182,6 +184,7 @@ class GoButton extends StatelessWidget {
|
||||||
maxWidth: 340,
|
maxWidth: 340,
|
||||||
maxHeight: 48,
|
maxHeight: 48,
|
||||||
),
|
),
|
||||||
|
radius: BorderRadius.circular(12),
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
fontSize: FontSizes.s14,
|
fontSize: FontSizes.s14,
|
||||||
fontFamily: GoogleFonts.poppins(fontWeight: FontWeight.w500).fontFamily,
|
fontFamily: GoogleFonts.poppins(fontWeight: FontWeight.w500).fontFamily,
|
||||||
|
|
|
@ -55,6 +55,18 @@ class SettingsFileExporterCubit extends Cubit<SettingsFileExportState> {
|
||||||
required List<ViewPB> views,
|
required List<ViewPB> views,
|
||||||
}) : super(SettingsFileExportState(views: views));
|
}) : super(SettingsFileExportState(views: views));
|
||||||
|
|
||||||
|
void selectOrDeselectAllItems() {
|
||||||
|
final List<List<bool>> selectedItems = state.selectedItems;
|
||||||
|
final isSelectAll =
|
||||||
|
selectedItems.expand((element) => element).every((element) => element);
|
||||||
|
for (var i = 0; i < selectedItems.length; i++) {
|
||||||
|
for (var j = 0; j < selectedItems[i].length; j++) {
|
||||||
|
selectedItems[i][j] = !isSelectAll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit(state.copyWith(selectedItems: selectedItems));
|
||||||
|
}
|
||||||
|
|
||||||
void selectOrDeselectItem(int outerIndex, int innerIndex) {
|
void selectOrDeselectItem(int outerIndex, int innerIndex) {
|
||||||
final selectedItems = state.selectedItems;
|
final selectedItems = state.selectedItems;
|
||||||
selectedItems[outerIndex][innerIndex] =
|
selectedItems[outerIndex][innerIndex] =
|
||||||
|
@ -69,7 +81,7 @@ class SettingsFileExporterCubit extends Cubit<SettingsFileExportState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, List<String>> fetchSelectedPages() {
|
Map<String, List<String>> fetchSelectedPages() {
|
||||||
final apps = state.views;
|
final views = state.views;
|
||||||
final selectedItems = state.selectedItems;
|
final selectedItems = state.selectedItems;
|
||||||
final Map<String, List<String>> result = {};
|
final Map<String, List<String>> result = {};
|
||||||
for (var i = 0; i < selectedItems.length; i++) {
|
for (var i = 0; i < selectedItems.length; i++) {
|
||||||
|
@ -77,11 +89,11 @@ class SettingsFileExporterCubit extends Cubit<SettingsFileExportState> {
|
||||||
final ids = <String>[];
|
final ids = <String>[];
|
||||||
for (var j = 0; j < selectedItem.length; j++) {
|
for (var j = 0; j < selectedItem.length; j++) {
|
||||||
if (selectedItem[j]) {
|
if (selectedItem[j]) {
|
||||||
ids.add(apps[i].childViews[j].id);
|
ids.add(views[i].childViews[j].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ids.isNotEmpty) {
|
if (ids.isNotEmpty) {
|
||||||
result[apps[i].id] = ids;
|
result[views[i].id] = ids;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:flowy_infra/image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.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:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
import '../../../../generated/locale_keys.g.dart';
|
import '../../../../generated/locale_keys.g.dart';
|
||||||
|
|
||||||
|
@ -25,8 +26,9 @@ class SettingsExportFileWidgetState extends State<SettingsExportFileWidget> {
|
||||||
children: [
|
children: [
|
||||||
FlowyText.medium(
|
FlowyText.medium(
|
||||||
LocaleKeys.settings_files_exportData.tr(),
|
LocaleKeys.settings_files_exportData.tr(),
|
||||||
|
fontSize: 13,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
).padding(horizontal: 5.0),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
_OpenExportedDirectoryButton(
|
_OpenExportedDirectoryButton(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
|
@ -62,7 +64,7 @@ class _OpenExportedDirectoryButton extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FlowyIconButton(
|
return FlowyIconButton(
|
||||||
hoverColor: Theme.of(context).colorScheme.secondaryContainer,
|
hoverColor: Theme.of(context).colorScheme.secondaryContainer,
|
||||||
tooltipText: LocaleKeys.settings_files_open.tr(),
|
tooltipText: LocaleKeys.settings_files_export.tr(),
|
||||||
icon: svgWidget(
|
icon: svgWidget(
|
||||||
'common/open_folder',
|
'common/open_folder',
|
||||||
color: Theme.of(context).iconTheme.color,
|
color: Theme.of(context).iconTheme.color,
|
||||||
|
|
|
@ -129,12 +129,14 @@ class _CopyableText extends StatelessWidget {
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (onHover)
|
if (onHover) ...[
|
||||||
|
const HSpace(5),
|
||||||
FlowyText.regular(
|
FlowyText.regular(
|
||||||
LocaleKeys.settings_files_copy.tr(),
|
LocaleKeys.settings_files_copy.tr(),
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
)
|
),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -48,11 +48,31 @@ class _FileExporterWidgetState extends State<FileExporterWidget> {
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
FlowyText.medium(
|
FlowyText.medium(
|
||||||
LocaleKeys.settings_files_selectFiles.tr(),
|
LocaleKeys.settings_files_selectFiles.tr(),
|
||||||
fontSize: 16.0,
|
fontSize: 16.0,
|
||||||
),
|
),
|
||||||
|
BlocBuilder<SettingsFileExporterCubit,
|
||||||
|
SettingsFileExportState>(
|
||||||
|
builder: (context, state) => FlowyTextButton(
|
||||||
|
state.selectedItems
|
||||||
|
.expand((element) => element)
|
||||||
|
.every((element) => element)
|
||||||
|
? LocaleKeys.settings_files_deselectAll.tr()
|
||||||
|
: LocaleKeys.settings_files_selectAll.tr(),
|
||||||
|
onPressed: () {
|
||||||
|
context
|
||||||
|
.read<SettingsFileExporterCubit>()
|
||||||
|
.selectOrDeselectAllItems();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
const VSpace(8),
|
const VSpace(8),
|
||||||
const Expanded(child: _ExpandedList()),
|
const Expanded(child: _ExpandedList()),
|
||||||
const VSpace(8),
|
const VSpace(8),
|
||||||
|
|
|
@ -63,8 +63,9 @@ class FlowyColorPicker extends StatelessWidget {
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: option.color,
|
color: option.color,
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
border: border,
|
// border: border,
|
||||||
)),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
|
|
|
@ -11,7 +11,7 @@ use serde::Serialize;
|
||||||
use crate::kv::schema::{kv_table, kv_table::dsl, KV_SQL};
|
use crate::kv::schema::{kv_table, kv_table::dsl, KV_SQL};
|
||||||
use crate::sqlite::{DBConnection, Database, PoolConfig};
|
use crate::sqlite::{DBConnection, Database, PoolConfig};
|
||||||
|
|
||||||
const DB_NAME: &str = "kv.db";
|
const DB_NAME: &str = "cache.db";
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref KV_HOLDER: RwLock<KV> = RwLock::new(KV::new());
|
static ref KV_HOLDER: RwLock<KV> = RwLock::new(KV::new());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue