mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-10-30 09:24:02 +00:00
feat: support settings on sign in page (#6342)
* feat: support settings on sign in page * feat: add settings entry in sign in page * feat: support exporting log files on desktop * chore: remove openfile dependency
This commit is contained in:
parent
d189c1ca4e
commit
c5afbb97a0
@ -56,6 +56,8 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
- keyboard_height_plugin (0.0.1):
|
- keyboard_height_plugin (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- open_file_ios (0.0.1):
|
||||||
|
- Flutter
|
||||||
- open_filex (0.0.2):
|
- open_filex (0.0.2):
|
||||||
- Flutter
|
- Flutter
|
||||||
- package_info_plus (0.4.5):
|
- package_info_plus (0.4.5):
|
||||||
@ -102,6 +104,7 @@ DEPENDENCIES:
|
|||||||
- integration_test (from `.symlinks/plugins/integration_test/ios`)
|
- integration_test (from `.symlinks/plugins/integration_test/ios`)
|
||||||
- irondash_engine_context (from `.symlinks/plugins/irondash_engine_context/ios`)
|
- irondash_engine_context (from `.symlinks/plugins/irondash_engine_context/ios`)
|
||||||
- keyboard_height_plugin (from `.symlinks/plugins/keyboard_height_plugin/ios`)
|
- keyboard_height_plugin (from `.symlinks/plugins/keyboard_height_plugin/ios`)
|
||||||
|
- open_file_ios (from `.symlinks/plugins/open_file_ios/ios`)
|
||||||
- open_filex (from `.symlinks/plugins/open_filex/ios`)
|
- open_filex (from `.symlinks/plugins/open_filex/ios`)
|
||||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
@ -148,6 +151,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/irondash_engine_context/ios"
|
:path: ".symlinks/plugins/irondash_engine_context/ios"
|
||||||
keyboard_height_plugin:
|
keyboard_height_plugin:
|
||||||
:path: ".symlinks/plugins/keyboard_height_plugin/ios"
|
:path: ".symlinks/plugins/keyboard_height_plugin/ios"
|
||||||
|
open_file_ios:
|
||||||
|
:path: ".symlinks/plugins/open_file_ios/ios"
|
||||||
open_filex:
|
open_filex:
|
||||||
:path: ".symlinks/plugins/open_filex/ios"
|
:path: ".symlinks/plugins/open_filex/ios"
|
||||||
package_info_plus:
|
package_info_plus:
|
||||||
@ -184,6 +189,7 @@ SPEC CHECKSUMS:
|
|||||||
integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4
|
integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4
|
||||||
irondash_engine_context: 3458bf979b90d616ffb8ae03a150bafe2e860cc9
|
irondash_engine_context: 3458bf979b90d616ffb8ae03a150bafe2e860cc9
|
||||||
keyboard_height_plugin: 43fa8bba20fd5c4fdeed5076466b8b9d43cc6b86
|
keyboard_height_plugin: 43fa8bba20fd5c4fdeed5076466b8b9d43cc6b86
|
||||||
|
open_file_ios: 461db5853723763573e140de3193656f91990d9e
|
||||||
open_filex: 6e26e659846ec990262224a12ef1c528bb4edbe4
|
open_filex: 6e26e659846ec990262224a12ef1c528bb4edbe4
|
||||||
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
|
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
|
||||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||||
|
|||||||
@ -0,0 +1,67 @@
|
|||||||
|
import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart';
|
||||||
|
import 'package:appflowy/startup/startup.dart';
|
||||||
|
import 'package:appflowy/workspace/application/settings/settings_dialog_bloc.dart';
|
||||||
|
import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/home/af_focus_manager.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart';
|
||||||
|
import 'package:appflowy_backend/log.dart';
|
||||||
|
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
|
||||||
|
show UserProfilePB;
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
|
final GlobalKey _settingsDialogKey = GlobalKey();
|
||||||
|
|
||||||
|
// show settings dialog with user profile for fully customized settings dialog
|
||||||
|
void showSettingsDialog(
|
||||||
|
BuildContext context,
|
||||||
|
UserProfilePB userProfile, [
|
||||||
|
UserWorkspaceBloc? bloc,
|
||||||
|
SettingsPage? initPage,
|
||||||
|
]) {
|
||||||
|
AFFocusManager.of(context).notifyLoseFocus();
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (dialogContext) => MultiBlocProvider(
|
||||||
|
key: _settingsDialogKey,
|
||||||
|
providers: [
|
||||||
|
BlocProvider<DocumentAppearanceCubit>.value(
|
||||||
|
value: BlocProvider.of<DocumentAppearanceCubit>(dialogContext),
|
||||||
|
),
|
||||||
|
BlocProvider.value(value: bloc ?? context.read<UserWorkspaceBloc>()),
|
||||||
|
],
|
||||||
|
child: SettingsDialog(
|
||||||
|
userProfile,
|
||||||
|
initPage: initPage,
|
||||||
|
didLogout: () async {
|
||||||
|
// Pop the dialog using the dialog context
|
||||||
|
Navigator.of(dialogContext).pop();
|
||||||
|
await runAppFlowy();
|
||||||
|
},
|
||||||
|
dismissDialog: () {
|
||||||
|
if (Navigator.of(dialogContext).canPop()) {
|
||||||
|
return Navigator.of(dialogContext).pop();
|
||||||
|
}
|
||||||
|
Log.warn("Can't pop dialog context");
|
||||||
|
},
|
||||||
|
restartApp: () async {
|
||||||
|
// Pop the dialog using the dialog context
|
||||||
|
Navigator.of(dialogContext).pop();
|
||||||
|
await runAppFlowy();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// show settings dialog without user profile for simple settings dialog
|
||||||
|
// only support
|
||||||
|
// - language
|
||||||
|
// - self-host
|
||||||
|
// - support
|
||||||
|
void showSimpleSettingsDialog(BuildContext context) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (dialogContext) => const SimpleSettingsDialog(),
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import 'package:appflowy/core/frameless_window.dart';
|
import 'package:appflowy/core/frameless_window.dart';
|
||||||
import 'package:appflowy/env/cloud_env.dart';
|
import 'package:appflowy/env/cloud_env.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
|
import 'package:appflowy/shared/settings/show_settings.dart';
|
||||||
import 'package:appflowy/shared/window_title_bar.dart';
|
import 'package:appflowy/shared/window_title_bar.dart';
|
||||||
import 'package:appflowy/user/application/sign_in_bloc.dart';
|
import 'package:appflowy/user/application/sign_in_bloc.dart';
|
||||||
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
|
import 'package:appflowy/user/presentation/screens/sign_in_screen/widgets/widgets.dart';
|
||||||
@ -63,8 +64,15 @@ class DesktopSignInScreen extends StatelessWidget {
|
|||||||
|
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
|
|
||||||
// anonymous sign in
|
// anonymous sign in and settings
|
||||||
const SignInAnonymousButtonV2(),
|
const Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
_SettingsButton(),
|
||||||
|
HSpace(42),
|
||||||
|
SignInAnonymousButtonV2(),
|
||||||
|
],
|
||||||
|
),
|
||||||
const VSpace(16),
|
const VSpace(16),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -84,6 +92,28 @@ class DesktopSignInScreen extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _SettingsButton extends StatelessWidget {
|
||||||
|
const _SettingsButton();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return FlowyButton(
|
||||||
|
useIntrinsicWidth: true,
|
||||||
|
text: FlowyText(
|
||||||
|
LocaleKeys.signIn_settings.tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
fontSize: 12.0,
|
||||||
|
// fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey,
|
||||||
|
decoration: TextDecoration.underline,
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
showSimpleSettingsDialog(context);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _OrDivider extends StatelessWidget {
|
class _OrDivider extends StatelessWidget {
|
||||||
const _OrDivider();
|
const _OrDivider();
|
||||||
|
|
||||||
|
|||||||
@ -118,16 +118,7 @@ class MobileSignInScreen extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
const HSpace(24),
|
const HSpace(24),
|
||||||
SignInAnonymousButtonV2(
|
const SignInAnonymousButtonV2(),
|
||||||
child: FlowyText(
|
|
||||||
LocaleKeys.signIn_anonymous.tr(),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
fontSize: 12.0,
|
|
||||||
// fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.grey,
|
|
||||||
decoration: TextDecoration.underline,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,11 +89,8 @@ class SignInAnonymousButton extends StatelessWidget {
|
|||||||
class SignInAnonymousButtonV2 extends StatelessWidget {
|
class SignInAnonymousButtonV2 extends StatelessWidget {
|
||||||
const SignInAnonymousButtonV2({
|
const SignInAnonymousButtonV2({
|
||||||
super.key,
|
super.key,
|
||||||
this.child,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final Widget? child;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<SignInBloc, SignInState>(
|
return BlocBuilder<SignInBloc, SignInState>(
|
||||||
@ -111,9 +108,7 @@ class SignInAnonymousButtonV2 extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
child: BlocBuilder<AnonUserBloc, AnonUserState>(
|
child: BlocBuilder<AnonUserBloc, AnonUserState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final text = state.anonUsers.isEmpty
|
final text = LocaleKeys.signIn_anonymous.tr();
|
||||||
? LocaleKeys.signIn_loginStartWithAnonymous.tr()
|
|
||||||
: LocaleKeys.signIn_continueAnonymousUser.tr();
|
|
||||||
final onTap = state.anonUsers.isEmpty
|
final onTap = state.anonUsers.isEmpty
|
||||||
? () {
|
? () {
|
||||||
context
|
context
|
||||||
@ -125,16 +120,14 @@ class SignInAnonymousButtonV2 extends StatelessWidget {
|
|||||||
final user = bloc.state.anonUsers.first;
|
final user = bloc.state.anonUsers.first;
|
||||||
bloc.add(AnonUserEvent.openAnonUser(user));
|
bloc.add(AnonUserEvent.openAnonUser(user));
|
||||||
};
|
};
|
||||||
return MouseRegion(
|
return FlowyButton(
|
||||||
cursor: SystemMouseCursors.click,
|
useIntrinsicWidth: true,
|
||||||
child: GestureDetector(
|
onTap: onTap,
|
||||||
onTap: onTap,
|
text: FlowyText(
|
||||||
child: child ??
|
text,
|
||||||
FlowyText(
|
color: Colors.grey,
|
||||||
text,
|
decoration: TextDecoration.underline,
|
||||||
color: Colors.blue,
|
fontSize: 12,
|
||||||
fontSize: 12,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -99,17 +99,20 @@ class _DesktopThirdPartySignInState extends State<_DesktopThirdPartySignIn> {
|
|||||||
List<Widget> _buildCollapsedButtons() {
|
List<Widget> _buildCollapsedButtons() {
|
||||||
return [
|
return [
|
||||||
const VSpace(padding),
|
const VSpace(padding),
|
||||||
GestureDetector(
|
MouseRegion(
|
||||||
onTap: () {
|
cursor: SystemMouseCursors.click,
|
||||||
setState(() {
|
child: GestureDetector(
|
||||||
isExpanded = !isExpanded;
|
onTap: () {
|
||||||
});
|
setState(() {
|
||||||
},
|
isExpanded = !isExpanded;
|
||||||
child: FlowyText(
|
});
|
||||||
LocaleKeys.signIn_continueAnotherWay.tr(),
|
},
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
child: FlowyText(
|
||||||
decoration: TextDecoration.underline,
|
LocaleKeys.signIn_continueAnotherWay.tr(),
|
||||||
fontSize: 14,
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
decoration: TextDecoration.underline,
|
||||||
|
fontSize: 14,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
|||||||
import 'package:archive/archive_io.dart';
|
import 'package:archive/archive_io.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:open_filex/open_filex.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
@ -59,12 +60,16 @@ Future<void> shareLogFiles(BuildContext? context) async {
|
|||||||
|
|
||||||
if (Platform.isIOS) {
|
if (Platform.isIOS) {
|
||||||
await Share.shareUri(zipFile.uri);
|
await Share.shareUri(zipFile.uri);
|
||||||
} else {
|
// delete the zipped appflowy logs file
|
||||||
|
await zipFile.delete();
|
||||||
|
} else if (Platform.isAndroid) {
|
||||||
await Share.shareXFiles([XFile(zipFile.path)]);
|
await Share.shareXFiles([XFile(zipFile.path)]);
|
||||||
|
// delete the zipped appflowy logs file
|
||||||
|
await zipFile.delete();
|
||||||
|
} else {
|
||||||
|
// open the directory
|
||||||
|
await OpenFilex.open(zipFile.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the zipped appflowy logs file
|
|
||||||
await zipFile.delete();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (context != null && context.mounted) {
|
if (context != null && context.mounted) {
|
||||||
showToastNotification(
|
showToastNotification(
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import 'package:appflowy/generated/locale_keys.g.dart';
|
|||||||
import 'package:appflowy/shared/appflowy_cache_manager.dart';
|
import 'package:appflowy/shared/appflowy_cache_manager.dart';
|
||||||
import 'package:appflowy/startup/startup.dart';
|
import 'package:appflowy/startup/startup.dart';
|
||||||
import 'package:appflowy/startup/tasks/rust_sdk.dart';
|
import 'package:appflowy/startup/tasks/rust_sdk.dart';
|
||||||
|
import 'package:appflowy/util/share_log_files.dart';
|
||||||
import 'package:appflowy/util/theme_extension.dart';
|
import 'package:appflowy/util/theme_extension.dart';
|
||||||
import 'package:appflowy/workspace/application/settings/setting_file_importer_bloc.dart';
|
import 'package:appflowy/workspace/application/settings/setting_file_importer_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/settings/settings_location_cubit.dart';
|
import 'package:appflowy/workspace/application/settings/settings_location_cubit.dart';
|
||||||
@ -112,6 +113,20 @@ class SettingsManageDataView extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
SettingsCategory(
|
||||||
|
title: LocaleKeys.workspace_errorActions_exportLogFiles.tr(),
|
||||||
|
children: [
|
||||||
|
SingleSettingAction(
|
||||||
|
labelMaxLines: 4,
|
||||||
|
label:
|
||||||
|
LocaleKeys.workspace_errorActions_exportLogFiles.tr(),
|
||||||
|
buttonLabel: LocaleKeys.settings_files_export.tr(),
|
||||||
|
onPressed: () {
|
||||||
|
shareLogFiles(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
SettingsCategory(
|
SettingsCategory(
|
||||||
title: LocaleKeys.settings_manageDataPage_cache_title.tr(),
|
title: LocaleKeys.settings_manageDataPage_cache_title.tr(),
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:appflowy/env/cloud_env.dart';
|
||||||
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
|
import 'package:appflowy/shared/appflowy_cache_manager.dart';
|
||||||
|
import 'package:appflowy/startup/startup.dart';
|
||||||
|
import 'package:appflowy/util/share_log_files.dart';
|
||||||
|
import 'package:appflowy/workspace/application/settings/appflowy_cloud_urls_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/settings/settings_dialog_bloc.dart';
|
import 'package:appflowy/workspace/application/settings/settings_dialog_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
|
import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/pages/setting_ai_view/settings_ai_view.dart';
|
import 'package:appflowy/workspace/presentation/settings/pages/setting_ai_view/settings_ai_view.dart';
|
||||||
@ -9,12 +13,18 @@ import 'package:appflowy/workspace/presentation/settings/pages/settings_manage_d
|
|||||||
import 'package:appflowy/workspace/presentation/settings/pages/settings_plan_view.dart';
|
import 'package:appflowy/workspace/presentation/settings/pages/settings_plan_view.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/pages/settings_shortcuts_view.dart';
|
import 'package:appflowy/workspace/presentation/settings/pages/settings_shortcuts_view.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/pages/settings_workspace_view.dart';
|
import 'package:appflowy/workspace/presentation/settings/pages/settings_workspace_view.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/settings/shared/settings_category.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/settings/shared/settings_category_spacer.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/feature_flags/feature_flag_page.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/feature_flags/feature_flag_page.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/members/workspace_member_page.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/members/workspace_member_page.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_menu.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_menu.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_notifications_view.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_notifications_view.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
|
||||||
|
import 'package:appflowy_backend/log.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.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:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
import 'widgets/setting_cloud.dart';
|
import 'widgets/setting_cloud.dart';
|
||||||
@ -28,11 +38,11 @@ class SettingsDialog extends StatelessWidget {
|
|||||||
this.initPage,
|
this.initPage,
|
||||||
}) : super(key: ValueKey(user.id));
|
}) : super(key: ValueKey(user.id));
|
||||||
|
|
||||||
|
final UserProfilePB user;
|
||||||
|
final SettingsPage? initPage;
|
||||||
final VoidCallback dismissDialog;
|
final VoidCallback dismissDialog;
|
||||||
final VoidCallback didLogout;
|
final VoidCallback didLogout;
|
||||||
final VoidCallback restartApp;
|
final VoidCallback restartApp;
|
||||||
final UserProfilePB user;
|
|
||||||
final SettingsPage? initPage;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -144,3 +154,164 @@ class SettingsDialog extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SimpleSettingsDialog extends StatefulWidget {
|
||||||
|
const SimpleSettingsDialog({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SimpleSettingsDialog> createState() => _SimpleSettingsDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SimpleSettingsDialogState extends State<SimpleSettingsDialog> {
|
||||||
|
SettingsPage page = SettingsPage.cloud;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return FlowyDialog(
|
||||||
|
width: MediaQuery.of(context).size.width * 0.7,
|
||||||
|
constraints: const BoxConstraints(maxWidth: 784, minWidth: 564),
|
||||||
|
child: const Padding(
|
||||||
|
padding: EdgeInsets.all(24.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
// language
|
||||||
|
_LanguageSettings(),
|
||||||
|
SettingsCategorySpacer(),
|
||||||
|
// self-host cloud
|
||||||
|
_SelfHostSettings(),
|
||||||
|
SettingsCategorySpacer(),
|
||||||
|
// support
|
||||||
|
_SupportSettings(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LanguageSettings extends StatelessWidget {
|
||||||
|
const _LanguageSettings();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SettingsCategory(
|
||||||
|
title: LocaleKeys.settings_workspacePage_language_title.tr(),
|
||||||
|
children: const [LanguageDropdown()],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SelfHostSettings extends StatefulWidget {
|
||||||
|
const _SelfHostSettings();
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_SelfHostSettings> createState() => _SelfHostSettingsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SelfHostSettingsState extends State<_SelfHostSettings> {
|
||||||
|
final textController = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
getAppFlowyCloudUrl().then((url) {
|
||||||
|
textController.text = url;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
textController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SettingsCategory(
|
||||||
|
title: LocaleKeys.settings_menu_cloudAppFlowySelfHost.tr(),
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 48,
|
||||||
|
child: FlowyTextField(
|
||||||
|
controller: textController,
|
||||||
|
autoFocus: false,
|
||||||
|
textStyle: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
onEditingComplete: _saveSelfHostUrl,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _saveSelfHostUrl() {
|
||||||
|
final url = textController.text;
|
||||||
|
if (url.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
validateUrl(url).fold(
|
||||||
|
(url) async {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
await useSelfHostedAppFlowyCloudWithURL(url);
|
||||||
|
await runAppFlowy();
|
||||||
|
},
|
||||||
|
(err) => Log.error(err),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SupportSettings extends StatelessWidget {
|
||||||
|
const _SupportSettings();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SettingsCategory(
|
||||||
|
title: LocaleKeys.settings_mobile_support.tr(),
|
||||||
|
children: [
|
||||||
|
// export logs
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
FlowyText(
|
||||||
|
LocaleKeys.workspace_errorActions_exportLogFiles.tr(),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
OutlinedRoundedButton(
|
||||||
|
text: LocaleKeys.settings_files_export.tr(),
|
||||||
|
onTap: () {
|
||||||
|
shareLogFiles(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
// clear cache
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
FlowyText(
|
||||||
|
LocaleKeys.settings_files_clearCache.tr(),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
OutlinedRoundedButton(
|
||||||
|
text: LocaleKeys.button_clear.tr(),
|
||||||
|
onTap: () async {
|
||||||
|
await getIt<FlowyCacheManager>().clearAllCache();
|
||||||
|
if (context.mounted) {
|
||||||
|
showToastNotification(
|
||||||
|
context,
|
||||||
|
message: LocaleKeys
|
||||||
|
.settings_manageDataPage_cache_dialog_successHint
|
||||||
|
.tr(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -23,7 +23,10 @@ import 'package:universal_platform/universal_platform.dart';
|
|||||||
import 'setting_appflowy_cloud.dart';
|
import 'setting_appflowy_cloud.dart';
|
||||||
|
|
||||||
class SettingCloud extends StatelessWidget {
|
class SettingCloud extends StatelessWidget {
|
||||||
const SettingCloud({required this.restartAppFlowy, super.key});
|
const SettingCloud({
|
||||||
|
super.key,
|
||||||
|
required this.restartAppFlowy,
|
||||||
|
});
|
||||||
|
|
||||||
final VoidCallback restartAppFlowy;
|
final VoidCallback restartAppFlowy;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,3 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/shared/feature_flags.dart';
|
import 'package:appflowy/shared/feature_flags.dart';
|
||||||
@ -9,6 +6,8 @@ import 'package:appflowy/workspace/presentation/settings/widgets/settings_menu_e
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.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:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class SettingsMenu extends StatelessWidget {
|
class SettingsMenu extends StatelessWidget {
|
||||||
const SettingsMenu({
|
const SettingsMenu({
|
||||||
@ -147,3 +146,56 @@ class SettingsMenu extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SimpleSettingsMenu extends StatelessWidget {
|
||||||
|
const SimpleSettingsMenu({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8) +
|
||||||
|
const EdgeInsets.only(left: 8, right: 4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(8),
|
||||||
|
bottomLeft: Radius.circular(8),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
// Right padding is added to make the scrollbar centered
|
||||||
|
// in the space between the menu and the content
|
||||||
|
padding: const EdgeInsets.only(right: 4) +
|
||||||
|
const EdgeInsets.symmetric(vertical: 16),
|
||||||
|
physics: const ClampingScrollPhysics(),
|
||||||
|
child: SeparatedColumn(
|
||||||
|
separatorBuilder: () => const VSpace(16),
|
||||||
|
children: [
|
||||||
|
SettingsMenuElement(
|
||||||
|
page: SettingsPage.cloud,
|
||||||
|
selectedPage: SettingsPage.cloud,
|
||||||
|
label: LocaleKeys.settings_menu_cloudSettings.tr(),
|
||||||
|
icon: const Icon(Icons.sync),
|
||||||
|
changeSelectedPage: () {},
|
||||||
|
),
|
||||||
|
if (kDebugMode)
|
||||||
|
SettingsMenuElement(
|
||||||
|
// no need to translate this page
|
||||||
|
page: SettingsPage.featureFlags,
|
||||||
|
selectedPage: SettingsPage.cloud,
|
||||||
|
label: 'Feature Flags',
|
||||||
|
icon: const Icon(Icons.flag),
|
||||||
|
changeSelectedPage: () {},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -25,6 +25,8 @@ PODS:
|
|||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- local_notifier (0.1.0):
|
- local_notifier (0.1.0):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- open_file_mac (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
- package_info_plus (0.0.1):
|
- package_info_plus (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
@ -66,6 +68,7 @@ DEPENDENCIES:
|
|||||||
- hotkey_manager (from `Flutter/ephemeral/.symlinks/plugins/hotkey_manager/macos`)
|
- hotkey_manager (from `Flutter/ephemeral/.symlinks/plugins/hotkey_manager/macos`)
|
||||||
- irondash_engine_context (from `Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos`)
|
- irondash_engine_context (from `Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos`)
|
||||||
- local_notifier (from `Flutter/ephemeral/.symlinks/plugins/local_notifier/macos`)
|
- local_notifier (from `Flutter/ephemeral/.symlinks/plugins/local_notifier/macos`)
|
||||||
|
- open_file_mac (from `Flutter/ephemeral/.symlinks/plugins/open_file_mac/macos`)
|
||||||
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
|
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
|
||||||
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
- screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`)
|
- screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`)
|
||||||
@ -108,6 +111,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos
|
||||||
local_notifier:
|
local_notifier:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/local_notifier/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/local_notifier/macos
|
||||||
|
open_file_mac:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/open_file_mac/macos
|
||||||
package_info_plus:
|
package_info_plus:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
@ -143,6 +148,7 @@ SPEC CHECKSUMS:
|
|||||||
hotkey_manager: c32bf0bfe8f934b7bc17ab4ad5c4c142960b023c
|
hotkey_manager: c32bf0bfe8f934b7bc17ab4ad5c4c142960b023c
|
||||||
irondash_engine_context: da62996ee25616d2f01bbeb85dc115d813359478
|
irondash_engine_context: da62996ee25616d2f01bbeb85dc115d813359478
|
||||||
local_notifier: e9506bc66fc70311e8bc7291fb70f743c081e4ff
|
local_notifier: e9506bc66fc70311e8bc7291fb70f743c081e4ff
|
||||||
|
open_file_mac: 0e554648e2a87ce59e9438e3e5ca3e552e90d89a
|
||||||
package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
|
package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
|
||||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||||
ReachabilitySwift: 7f151ff156cea1481a8411701195ac6a984f4979
|
ReachabilitySwift: 7f151ff156cea1481a8411701195ac6a984f4979
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user