mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: show indicator when importing appflowy data (#4357)
* feat: show indicator when importing appflowy data * Update frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_file_import_appflowy_data_view.dart Co-authored-by: Mathias Mogensen <42929161+Xazin@users.noreply.github.com> * chore: fix analyzer * chore: fix test --------- Co-authored-by: Mathias Mogensen <42929161+Xazin@users.noreply.github.com>
This commit is contained in:
parent
b1cc4e485b
commit
6e41359fc5
@ -34,6 +34,7 @@ typedef OnError = void Function(FlowyError);
|
|||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class LoadingState with _$LoadingState {
|
class LoadingState with _$LoadingState {
|
||||||
|
const factory LoadingState.idle() = _Idle;
|
||||||
const factory LoadingState.loading() = _Loading;
|
const factory LoadingState.loading() = _Loading;
|
||||||
const factory LoadingState.finish(
|
const factory LoadingState.finish(
|
||||||
Either<Unit, FlowyError> successOrFail,
|
Either<Unit, FlowyError> successOrFail,
|
||||||
|
@ -103,6 +103,7 @@ class BoardPage extends StatelessWidget {
|
|||||||
howToFix: LocaleKeys.errorDialog_howToFixFallback.tr(),
|
howToFix: LocaleKeys.errorDialog_howToFixFallback.tr(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
idle: (_) => const SizedBox.shrink(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -131,6 +131,7 @@ class _GridPageState extends State<GridPage> {
|
|||||||
howToFix: LocaleKeys.errorDialog_howToFixFallback.tr(),
|
howToFix: LocaleKeys.errorDialog_howToFixFallback.tr(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
idle: (_) => const SizedBox.shrink(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -97,6 +97,7 @@ class _MobileGridPageState extends State<MobileGridPage> {
|
|||||||
howToFix: LocaleKeys.errorDialog_howToFixFallback.tr(),
|
howToFix: LocaleKeys.errorDialog_howToFixFallback.tr(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
idle: (_) => const SizedBox.shrink(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -14,17 +14,20 @@ class DeviceOrApplicationInfoTask extends LaunchTask {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> initialize(LaunchContext context) async {
|
Future<void> initialize(LaunchContext context) async {
|
||||||
final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
|
// Can't get the device info from test environment
|
||||||
final PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
if (!context.env.isTest) {
|
||||||
|
final DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
|
||||||
|
final PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||||
|
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
final androidInfo = await deviceInfoPlugin.androidInfo;
|
final androidInfo = await deviceInfoPlugin.androidInfo;
|
||||||
androidSDKVersion = androidInfo.version.sdkInt;
|
androidSDKVersion = androidInfo.version.sdkInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Platform.isAndroid || Platform.isIOS) {
|
if (Platform.isAndroid || Platform.isIOS) {
|
||||||
applicationVersion = packageInfo.version;
|
applicationVersion = packageInfo.version;
|
||||||
buildNumber = packageInfo.buildNumber;
|
buildNumber = packageInfo.buildNumber;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,11 @@ class EncryptSecretBloc extends Bloc<EncryptSecretEvent, EncryptSecretState> {
|
|||||||
bool isLoading() {
|
bool isLoading() {
|
||||||
final loadingState = state.loadingState;
|
final loadingState = state.loadingState;
|
||||||
if (loadingState != null) {
|
if (loadingState != null) {
|
||||||
return loadingState.when(loading: () => true, finish: (_) => false);
|
return loadingState.when(
|
||||||
|
loading: () => true,
|
||||||
|
finish: (_) => false,
|
||||||
|
idle: () => false,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,7 @@ class _EncryptSecretScreenState extends State<EncryptSecretScreen> {
|
|||||||
child: CircularProgressIndicator.adaptive(),
|
child: CircularProgressIndicator.adaptive(),
|
||||||
),
|
),
|
||||||
finish: (result) => const SizedBox.shrink(),
|
finish: (result) => const SizedBox.shrink(),
|
||||||
|
idle: () => const SizedBox.shrink(),
|
||||||
) ??
|
) ??
|
||||||
const SizedBox.shrink();
|
const SizedBox.shrink();
|
||||||
return Center(
|
return Center(
|
||||||
|
@ -70,6 +70,7 @@ class WorkspaceErrorScreen extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
idle: () {},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:appflowy/plugins/database/application/defines.dart';
|
||||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
import 'package:appflowy_backend/log.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||||
@ -9,39 +10,51 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
|||||||
|
|
||||||
part 'setting_file_importer_bloc.freezed.dart';
|
part 'setting_file_importer_bloc.freezed.dart';
|
||||||
|
|
||||||
class SettingFileImporterBloc
|
class SettingFileImportBloc
|
||||||
extends Bloc<SettingFileImportEvent, SettingFileImportState> {
|
extends Bloc<SettingFileImportEvent, SettingFileImportState> {
|
||||||
SettingFileImporterBloc() : super(SettingFileImportState.initial()) {
|
SettingFileImportBloc() : super(SettingFileImportState.initial()) {
|
||||||
on<SettingFileImportEvent>((event, emit) async {
|
on<SettingFileImportEvent>(
|
||||||
await event.when(
|
(event, emit) async {
|
||||||
importAppFlowyDataFolder: (String path) async {
|
await event.when(
|
||||||
final formattedDate =
|
importAppFlowyDataFolder: (String path) async {
|
||||||
DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now());
|
final formattedDate =
|
||||||
final payload = ImportAppFlowyDataPB.create()
|
DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now());
|
||||||
..path = path
|
final payload = ImportAppFlowyDataPB.create()
|
||||||
..importContainerName = "appflowy_import_$formattedDate";
|
..path = path
|
||||||
final result =
|
..importContainerName = "appflowy_import_$formattedDate";
|
||||||
await FolderEventImportAppFlowyDataFolder(payload).send();
|
emit(
|
||||||
result.fold(
|
state.copyWith(loadingState: const LoadingState.loading()),
|
||||||
(l) {
|
);
|
||||||
emit(
|
FolderEventImportAppFlowyDataFolder(payload).send().then((result) {
|
||||||
state.copyWith(
|
if (!isClosed) {
|
||||||
successOrFail: some(left(unit)),
|
add(SettingFileImportEvent.finishImport(result));
|
||||||
),
|
}
|
||||||
);
|
});
|
||||||
},
|
},
|
||||||
(err) {
|
finishImport: (result) {
|
||||||
Log.error(err);
|
result.fold(
|
||||||
emit(
|
(l) {
|
||||||
state.copyWith(
|
emit(
|
||||||
successOrFail: some(right(err)),
|
state.copyWith(
|
||||||
),
|
successOrFail: some(left(unit)),
|
||||||
);
|
loadingState: LoadingState.finish(left(unit)),
|
||||||
},
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
(err) {
|
||||||
});
|
Log.error(err);
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
successOrFail: some(right(err)),
|
||||||
|
loadingState: LoadingState.finish(right(err)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,15 +62,20 @@ class SettingFileImporterBloc
|
|||||||
class SettingFileImportEvent with _$SettingFileImportEvent {
|
class SettingFileImportEvent with _$SettingFileImportEvent {
|
||||||
const factory SettingFileImportEvent.importAppFlowyDataFolder(String path) =
|
const factory SettingFileImportEvent.importAppFlowyDataFolder(String path) =
|
||||||
_ImportAppFlowyDataFolder;
|
_ImportAppFlowyDataFolder;
|
||||||
|
const factory SettingFileImportEvent.finishImport(
|
||||||
|
Either<Unit, FlowyError> result,
|
||||||
|
) = _ImportResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class SettingFileImportState with _$SettingFileImportState {
|
class SettingFileImportState with _$SettingFileImportState {
|
||||||
const factory SettingFileImportState({
|
const factory SettingFileImportState({
|
||||||
|
required LoadingState loadingState,
|
||||||
required Option<Either<Unit, FlowyError>> successOrFail,
|
required Option<Either<Unit, FlowyError>> successOrFail,
|
||||||
}) = _SettingFileImportState;
|
}) = _SettingFileImportState;
|
||||||
|
|
||||||
factory SettingFileImportState.initial() => SettingFileImportState(
|
factory SettingFileImportState.initial() => SettingFileImportState(
|
||||||
|
loadingState: const LoadingState.idle(),
|
||||||
successOrFail: none(),
|
successOrFail: none(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,8 @@ class _ImportAppFlowyDataState extends State<ImportAppFlowyData> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => SettingFileImporterBloc(),
|
create: (context) => SettingFileImportBloc(),
|
||||||
child: BlocListener<SettingFileImporterBloc, SettingFileImportState>(
|
child: BlocListener<SettingFileImportBloc, SettingFileImportState>(
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
state.successOrFail.fold(
|
state.successOrFail.fold(
|
||||||
() {},
|
() {},
|
||||||
@ -47,7 +47,7 @@ class _ImportAppFlowyDataState extends State<ImportAppFlowyData> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: BlocBuilder<SettingFileImporterBloc, SettingFileImportState>(
|
child: BlocBuilder<SettingFileImportBloc, SettingFileImportState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return const Column(
|
return const Column(
|
||||||
children: [
|
children: [
|
||||||
@ -120,24 +120,33 @@ class ImportAppFlowyDataButton extends StatefulWidget {
|
|||||||
class _ImportAppFlowyDataButtonState extends State<ImportAppFlowyDataButton> {
|
class _ImportAppFlowyDataButtonState extends State<ImportAppFlowyDataButton> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SizedBox(
|
return BlocBuilder<SettingFileImportBloc, SettingFileImportState>(
|
||||||
height: 40,
|
builder: (context, state) {
|
||||||
child: FlowyButton(
|
return Column(
|
||||||
text: FlowyText(LocaleKeys.settings_menu_importAppFlowyData.tr()),
|
children: [
|
||||||
onTap: () async {
|
SizedBox(
|
||||||
final path = await getIt<FilePickerService>().getDirectoryPath();
|
height: 40,
|
||||||
if (path == null) {
|
child: FlowyButton(
|
||||||
return;
|
text:
|
||||||
}
|
FlowyText(LocaleKeys.settings_menu_importAppFlowyData.tr()),
|
||||||
if (!mounted) {
|
onTap: () async {
|
||||||
return;
|
final path =
|
||||||
}
|
await getIt<FilePickerService>().getDirectoryPath();
|
||||||
|
if (path == null || !mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
context
|
context.read<SettingFileImportBloc>().add(
|
||||||
.read<SettingFileImporterBloc>()
|
SettingFileImportEvent.importAppFlowyDataFolder(path),
|
||||||
.add(SettingFileImportEvent.importAppFlowyDataFolder(path));
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
if (state.loadingState.isLoading())
|
||||||
|
const LinearProgressIndicator(minHeight: 1),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,6 +154,7 @@ class EnableEncrypt extends StatelessWidget {
|
|||||||
final indicator = state.loadingState.when(
|
final indicator = state.loadingState.when(
|
||||||
loading: () => const CircularProgressIndicator.adaptive(),
|
loading: () => const CircularProgressIndicator.adaptive(),
|
||||||
finish: (successOrFail) => const SizedBox.shrink(),
|
finish: (successOrFail) => const SizedBox.shrink(),
|
||||||
|
idle: () => const SizedBox.shrink(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user