mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-12-27 23:24:38 +00:00
feat: support editing path name on mobile (#6798)
* feat: support editing path name on mobile * chore: format code * chore: update publish toast * feat: optimize the toast for mobile more actions menu * feat: optimize update path name logic * test: add update path name test * fix: integration test
This commit is contained in:
parent
8a39ff0580
commit
7e528cf260
@ -1,6 +1,8 @@
|
||||
import 'package:appflowy/env/cloud_env.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/home/workspaces/create_workspace_menu.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
@ -11,7 +13,11 @@ void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('publish:', () {
|
||||
testWidgets('publish document', (tester) async {
|
||||
testWidgets('''
|
||||
1. publish document
|
||||
2. update path name
|
||||
3. unpublish document
|
||||
''', (tester) async {
|
||||
await tester.initializeAppFlowy(
|
||||
cloudType: AuthenticatorType.appflowyCloudSelfHost,
|
||||
);
|
||||
@ -45,6 +51,51 @@ void main() {
|
||||
findsOneWidget,
|
||||
);
|
||||
|
||||
// update the path name
|
||||
await tester.editor.clickMoreActionItemOnMobile(
|
||||
LocaleKeys.shareAction_updatePathName.tr(),
|
||||
);
|
||||
|
||||
const pathName1 = '???????????????';
|
||||
const pathName2 = 'AppFlowy';
|
||||
|
||||
final textField = find.descendant(
|
||||
of: find.byType(EditWorkspaceNameBottomSheet),
|
||||
matching: find.byType(TextFormField),
|
||||
);
|
||||
await tester.enterText(textField, pathName1);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// wait 50ms to ensure the error message is shown
|
||||
await tester.wait(50);
|
||||
|
||||
// click the confirm button
|
||||
final confirmButton = find.text(LocaleKeys.button_confirm.tr());
|
||||
await tester.tapButton(confirmButton);
|
||||
|
||||
// expect to see the update path name failed toast
|
||||
final updatePathFailedText = find.text(
|
||||
LocaleKeys.settings_sites_error_publishNameContainsInvalidCharacters
|
||||
.tr(),
|
||||
);
|
||||
expect(updatePathFailedText, findsOneWidget);
|
||||
|
||||
// input the valid path name
|
||||
await tester.enterText(textField, pathName2);
|
||||
await tester.pumpAndSettle();
|
||||
// click the confirm button
|
||||
await tester.tapButton(confirmButton);
|
||||
|
||||
// wait 50ms to ensure the error message is shown
|
||||
await tester.wait(50);
|
||||
|
||||
// expect to see the update path name success toast
|
||||
final updatePathSuccessText = find.findTextInFlowyText(
|
||||
LocaleKeys.settings_sites_success_updatePathNameSuccess.tr(),
|
||||
);
|
||||
expect(updatePathSuccessText, findsOneWidget);
|
||||
await tester.pumpUntilNotFound(updatePathSuccessText);
|
||||
|
||||
// unpublish the document
|
||||
await tester.editor.clickMoreActionItemOnMobile(
|
||||
LocaleKeys.shareAction_unPublish.tr(),
|
||||
|
||||
@ -3,18 +3,24 @@ import 'dart:async';
|
||||
import 'package:appflowy/core/helpers/url_launcher.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||
import 'package:appflowy/mobile/presentation/home/workspaces/create_workspace_menu.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_notification.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/copy_and_paste/clipboard_service.dart';
|
||||
import 'package:appflowy/plugins/shared/share/constants.dart';
|
||||
import 'package:appflowy/plugins/shared/share/publish_name_generator.dart';
|
||||
import 'package:appflowy/plugins/shared/share/share_bloc.dart';
|
||||
import 'package:appflowy/shared/error_code/error_code_map.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/util/string_extension.dart';
|
||||
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/view/prelude.dart';
|
||||
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
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:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
@ -24,78 +30,89 @@ class MobileViewPageMoreBottomSheet extends StatelessWidget {
|
||||
const MobileViewPageMoreBottomSheet({super.key, required this.view});
|
||||
|
||||
final ViewPB view;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocListener<ViewBloc, ViewState>(
|
||||
listener: (context, state) {
|
||||
if (state.successOrFailure.isSuccess && state.isDeleted) {
|
||||
context.go('/home');
|
||||
}
|
||||
},
|
||||
child: ViewPageBottomSheet(
|
||||
view: view,
|
||||
onAction: (action) async {
|
||||
switch (action) {
|
||||
case MobileViewBottomSheetBodyAction.duplicate:
|
||||
context.read<ViewBloc>().add(const ViewEvent.duplicate());
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.delete:
|
||||
context.read<ViewBloc>().add(const ViewEvent.delete());
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.addToFavorites:
|
||||
case MobileViewBottomSheetBodyAction.removeFromFavorites:
|
||||
context.read<FavoriteBloc>().add(FavoriteEvent.toggle(view));
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.undo:
|
||||
EditorNotification.undo().post();
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.redo:
|
||||
EditorNotification.redo().post();
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.helpCenter:
|
||||
// unimplemented
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.publish:
|
||||
await _publish(context);
|
||||
if (context.mounted) {
|
||||
context.pop();
|
||||
}
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.unpublish:
|
||||
_unpublish(context);
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.copyPublishLink:
|
||||
_copyPublishLink(context);
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.visitSite:
|
||||
_visitPublishedSite(context);
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.copyShareLink:
|
||||
_copyShareLink(context);
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.rename:
|
||||
// no need to implement, rename is handled by the onRename callback.
|
||||
throw UnimplementedError();
|
||||
return BlocListener<ShareBloc, ShareState>(
|
||||
listener: (context, state) => _showToast(context, state),
|
||||
child: BlocListener<ViewBloc, ViewState>(
|
||||
listener: (context, state) {
|
||||
if (state.successOrFailure.isSuccess && state.isDeleted) {
|
||||
context.go('/home');
|
||||
}
|
||||
},
|
||||
onRename: (name) {
|
||||
_onRename(context, name);
|
||||
context.pop();
|
||||
},
|
||||
child: ViewPageBottomSheet(
|
||||
view: view,
|
||||
onAction: (action) async => _onAction(context, action),
|
||||
onRename: (name) {
|
||||
_onRename(context, name);
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onAction(
|
||||
BuildContext context,
|
||||
MobileViewBottomSheetBodyAction action,
|
||||
) async {
|
||||
switch (action) {
|
||||
case MobileViewBottomSheetBodyAction.duplicate:
|
||||
_duplicate(context);
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.delete:
|
||||
context.read<ViewBloc>().add(const ViewEvent.delete());
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.addToFavorites:
|
||||
_addFavorite(context);
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.removeFromFavorites:
|
||||
_removeFavorite(context);
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.undo:
|
||||
EditorNotification.undo().post();
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.redo:
|
||||
EditorNotification.redo().post();
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.helpCenter:
|
||||
// unimplemented
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.publish:
|
||||
await _publish(context);
|
||||
if (context.mounted) {
|
||||
context.pop();
|
||||
}
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.unpublish:
|
||||
_unpublish(context);
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.copyPublishLink:
|
||||
_copyPublishLink(context);
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.visitSite:
|
||||
_visitPublishedSite(context);
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.copyShareLink:
|
||||
_copyShareLink(context);
|
||||
context.pop();
|
||||
break;
|
||||
case MobileViewBottomSheetBodyAction.updatePathName:
|
||||
_updatePathName(context);
|
||||
case MobileViewBottomSheetBodyAction.rename:
|
||||
// no need to implement, rename is handled by the onRename callback.
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _publish(BuildContext context) async {
|
||||
final id = context.read<ShareBloc>().view.id;
|
||||
final lastPublishName = context.read<ShareBloc>().state.pathName;
|
||||
@ -113,19 +130,44 @@ class MobileViewPageMoreBottomSheet extends StatelessWidget {
|
||||
[view.id],
|
||||
),
|
||||
);
|
||||
showToastNotification(
|
||||
context,
|
||||
message: LocaleKeys.publish_publishSuccessfully.tr(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _duplicate(BuildContext context) {
|
||||
context.read<ViewBloc>().add(const ViewEvent.duplicate());
|
||||
context.pop();
|
||||
|
||||
showToastNotification(
|
||||
context,
|
||||
message: LocaleKeys.button_duplicateSuccessfully.tr(),
|
||||
);
|
||||
}
|
||||
|
||||
void _addFavorite(BuildContext context) {
|
||||
_toggleFavorite(context);
|
||||
|
||||
showToastNotification(
|
||||
context,
|
||||
message: LocaleKeys.button_favoriteSuccessfully.tr(),
|
||||
);
|
||||
}
|
||||
|
||||
void _removeFavorite(BuildContext context) {
|
||||
_toggleFavorite(context);
|
||||
|
||||
showToastNotification(
|
||||
context,
|
||||
message: LocaleKeys.button_unfavoriteSuccessfully.tr(),
|
||||
);
|
||||
}
|
||||
|
||||
void _toggleFavorite(BuildContext context) {
|
||||
context.read<FavoriteBloc>().add(FavoriteEvent.toggle(view));
|
||||
context.pop();
|
||||
}
|
||||
|
||||
void _unpublish(BuildContext context) {
|
||||
context.read<ShareBloc>().add(const ShareEvent.unPublish());
|
||||
showToastNotification(
|
||||
context,
|
||||
message: LocaleKeys.publish_unpublishSuccessfully.tr(),
|
||||
);
|
||||
}
|
||||
|
||||
void _copyPublishLink(BuildContext context) {
|
||||
@ -186,4 +228,112 @@ class MobileViewPageMoreBottomSheet extends StatelessWidget {
|
||||
context.read<ViewBloc>().add(ViewEvent.rename(name));
|
||||
}
|
||||
}
|
||||
|
||||
void _updatePathName(BuildContext context) async {
|
||||
final shareBloc = context.read<ShareBloc>();
|
||||
final pathName = shareBloc.state.pathName;
|
||||
await showMobileBottomSheet(
|
||||
context,
|
||||
showHeader: true,
|
||||
title: LocaleKeys.shareAction_updatePathName.tr(),
|
||||
showCloseButton: true,
|
||||
showDragHandle: true,
|
||||
showDivider: false,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
builder: (bottomSheetContext) {
|
||||
FlowyResult<void, FlowyError>? previousUpdatePathNameResult;
|
||||
return EditWorkspaceNameBottomSheet(
|
||||
type: EditWorkspaceNameType.edit,
|
||||
workspaceName: pathName,
|
||||
hintText: '',
|
||||
validator: (value) => null,
|
||||
validatorBuilder: (context) {
|
||||
return BlocProvider.value(
|
||||
value: shareBloc,
|
||||
child: BlocBuilder<ShareBloc, ShareState>(
|
||||
builder: (context, state) {
|
||||
final updatePathNameResult = state.updatePathNameResult;
|
||||
|
||||
if (updatePathNameResult == null &&
|
||||
previousUpdatePathNameResult == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
if (updatePathNameResult != null) {
|
||||
previousUpdatePathNameResult = updatePathNameResult;
|
||||
}
|
||||
|
||||
final widget = previousUpdatePathNameResult?.fold(
|
||||
(value) => const SizedBox.shrink(),
|
||||
(error) => FlowyText(
|
||||
error.code.publishErrorMessage.orDefault(
|
||||
LocaleKeys.settings_sites_error_updatePathNameFailed
|
||||
.tr(),
|
||||
),
|
||||
maxLines: 3,
|
||||
fontSize: 12,
|
||||
textAlign: TextAlign.left,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
) ??
|
||||
const SizedBox.shrink();
|
||||
|
||||
return widget;
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onSubmitted: (name) {
|
||||
// rename the path name
|
||||
Log.info('rename the path name, from: $pathName, to: $name');
|
||||
|
||||
shareBloc.add(ShareEvent.updatePathName(name));
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
shareBloc.add(const ShareEvent.clearPathNameResult());
|
||||
}
|
||||
|
||||
void _showToast(BuildContext context, ShareState state) {
|
||||
if (state.publishResult != null) {
|
||||
state.publishResult!.fold(
|
||||
(value) => showToastNotification(
|
||||
context,
|
||||
message: LocaleKeys.publish_publishSuccessfully.tr(),
|
||||
),
|
||||
(error) => showToastNotification(
|
||||
context,
|
||||
message: '${LocaleKeys.publish_publishFailed.tr()}: ${error.code}',
|
||||
type: ToastificationType.error,
|
||||
),
|
||||
);
|
||||
} else if (state.unpublishResult != null) {
|
||||
state.unpublishResult!.fold(
|
||||
(value) => showToastNotification(
|
||||
context,
|
||||
message: LocaleKeys.publish_unpublishSuccessfully.tr(),
|
||||
),
|
||||
(error) => showToastNotification(
|
||||
context,
|
||||
message: LocaleKeys.publish_unpublishFailed.tr(),
|
||||
description: error.msg,
|
||||
type: ToastificationType.error,
|
||||
),
|
||||
);
|
||||
} else if (state.updatePathNameResult != null) {
|
||||
state.updatePathNameResult!.onSuccess(
|
||||
(value) {
|
||||
showToastNotification(
|
||||
context,
|
||||
message:
|
||||
LocaleKeys.settings_sites_success_updatePathNameSuccess.tr(),
|
||||
);
|
||||
|
||||
context.pop();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ enum MobileViewBottomSheetBodyAction {
|
||||
copyPublishLink,
|
||||
visitSite,
|
||||
copyShareLink,
|
||||
updatePathName,
|
||||
}
|
||||
|
||||
typedef MobileViewBottomSheetBodyActionCallback = void Function(
|
||||
@ -164,6 +165,15 @@ class MobileViewBottomSheetBody extends StatelessWidget {
|
||||
final isPublished = context.watch<ShareBloc>().state.isPublished;
|
||||
if (isPublished) {
|
||||
return [
|
||||
MobileQuickActionButton(
|
||||
text: LocaleKeys.shareAction_updatePathName.tr(),
|
||||
icon: FlowySvgs.view_item_rename_s,
|
||||
iconSize: const Size.square(18),
|
||||
onTap: () => onAction(
|
||||
MobileViewBottomSheetBodyAction.updatePathName,
|
||||
),
|
||||
),
|
||||
_divider(),
|
||||
MobileQuickActionButton(
|
||||
text: LocaleKeys.shareAction_visitSite.tr(),
|
||||
icon: FlowySvgs.m_visit_site_s,
|
||||
|
||||
@ -363,6 +363,7 @@ class _SpaceMenuItemTrailingState extends State<SpaceMenuItemTrailing> {
|
||||
type: EditWorkspaceNameType.edit,
|
||||
workspaceName: widget.space.name,
|
||||
hintText: LocaleKeys.space_spaceNamePlaceholder.tr(),
|
||||
validator: (value) => null,
|
||||
onSubmitted: (name) {
|
||||
// rename the workspace
|
||||
Log.info('rename the space, from: ${widget.space.name}, to: $name');
|
||||
|
||||
@ -33,6 +33,8 @@ class EditWorkspaceNameBottomSheet extends StatefulWidget {
|
||||
required this.onSubmitted,
|
||||
required this.workspaceName,
|
||||
this.hintText,
|
||||
this.validator,
|
||||
this.validatorBuilder,
|
||||
});
|
||||
|
||||
final EditWorkspaceNameType type;
|
||||
@ -43,6 +45,10 @@ class EditWorkspaceNameBottomSheet extends StatefulWidget {
|
||||
|
||||
final String? hintText;
|
||||
|
||||
final String? Function(String?)? validator;
|
||||
|
||||
final WidgetBuilder? validatorBuilder;
|
||||
|
||||
@override
|
||||
State<EditWorkspaceNameBottomSheet> createState() =>
|
||||
_EditWorkspaceNameBottomSheetState();
|
||||
@ -71,6 +77,7 @@ class _EditWorkspaceNameBottomSheetState
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Form(
|
||||
@ -83,15 +90,21 @@ class _EditWorkspaceNameBottomSheetState
|
||||
hintText:
|
||||
widget.hintText ?? LocaleKeys.workspace_defaultName.tr(),
|
||||
),
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return LocaleKeys.workspace_workspaceNameCannotBeEmpty.tr();
|
||||
}
|
||||
return null;
|
||||
},
|
||||
validator: widget.validator ??
|
||||
(value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return LocaleKeys.workspace_workspaceNameCannotBeEmpty.tr();
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onEditingComplete: _onSubmit,
|
||||
),
|
||||
),
|
||||
if (widget.validatorBuilder != null) ...[
|
||||
const VSpace(4),
|
||||
widget.validatorBuilder!(context),
|
||||
const VSpace(4),
|
||||
],
|
||||
const VSpace(16),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
|
||||
@ -74,6 +74,13 @@ class ShareBloc extends Bloc<ShareEvent, ShareState> {
|
||||
pathName,
|
||||
emit,
|
||||
),
|
||||
clearPathNameResult: () async {
|
||||
emit(
|
||||
state.copyWith(
|
||||
updatePathNameResult: null,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
@ -381,6 +388,7 @@ class ShareEvent with _$ShareEvent {
|
||||
const factory ShareEvent.setPublishStatus(bool isPublished) =
|
||||
_SetPublishStatus;
|
||||
const factory ShareEvent.updatePathName(String pathName) = _UpdatePathName;
|
||||
const factory ShareEvent.clearPathNameResult() = _ClearPathNameResult;
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
||||
@ -379,6 +379,7 @@ void showToastNotification(
|
||||
message: message,
|
||||
type: type,
|
||||
bottomPadding: bottomPadding,
|
||||
description: description,
|
||||
),
|
||||
);
|
||||
return;
|
||||
@ -416,11 +417,13 @@ class _MToast extends StatelessWidget {
|
||||
required this.message,
|
||||
this.type = ToastificationType.success,
|
||||
this.bottomPadding = 100,
|
||||
this.description,
|
||||
});
|
||||
|
||||
final String message;
|
||||
final ToastificationType type;
|
||||
final double bottomPadding;
|
||||
final String? description;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -431,30 +434,65 @@ class _MToast extends StatelessWidget {
|
||||
color: Colors.white,
|
||||
maxLines: 10,
|
||||
);
|
||||
final descriptionText = description != null
|
||||
? FlowyText.regular(
|
||||
description!,
|
||||
fontSize: 12,
|
||||
color: Colors.white,
|
||||
maxLines: 10,
|
||||
)
|
||||
: null;
|
||||
return Container(
|
||||
alignment: Alignment.bottomCenter,
|
||||
padding: EdgeInsets.only(bottom: bottomPadding, left: 16, right: 16),
|
||||
padding: EdgeInsets.only(
|
||||
bottom: bottomPadding,
|
||||
left: 16,
|
||||
right: 16,
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 13.0),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12.0,
|
||||
vertical: 13.0,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
color: const Color(0xE5171717),
|
||||
),
|
||||
child: type == ToastificationType.success
|
||||
? Row(
|
||||
? Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (type == ToastificationType.success) ...[
|
||||
const FlowySvg(
|
||||
FlowySvgs.success_s,
|
||||
blendMode: null,
|
||||
),
|
||||
const HSpace(8.0),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (type == ToastificationType.success) ...[
|
||||
const FlowySvg(
|
||||
FlowySvgs.success_s,
|
||||
blendMode: null,
|
||||
),
|
||||
const HSpace(8.0),
|
||||
],
|
||||
Expanded(child: hintText),
|
||||
],
|
||||
),
|
||||
if (descriptionText != null) ...[
|
||||
const VSpace(4.0),
|
||||
descriptionText,
|
||||
],
|
||||
Expanded(child: hintText),
|
||||
],
|
||||
)
|
||||
: hintText,
|
||||
: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
hintText,
|
||||
if (descriptionText != null) ...[
|
||||
const VSpace(4.0),
|
||||
descriptionText,
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -131,7 +131,8 @@
|
||||
"copyLinkFailed": "Failed to copy link to clipboard",
|
||||
"copyLinkToBlockSuccess": "Copied block link to clipboard",
|
||||
"copyLinkToBlockFailed": "Failed to copy block link to clipboard",
|
||||
"manageAllSites": "Manage all sites"
|
||||
"manageAllSites": "Manage all sites",
|
||||
"updatePathName": "Update path name"
|
||||
},
|
||||
"moreAction": {
|
||||
"small": "small",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user