feat: customize self host url on launch page (#4465)

This commit is contained in:
Lucas.Xu
2024-01-23 16:38:15 +08:00
committed by GitHub
parent 2554ba81b5
commit e239ba46aa
11 changed files with 293 additions and 93 deletions

View File

@ -0,0 +1,37 @@
import 'package:appflowy/env/env.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/presentation.dart';
import 'package:appflowy/mobile/presentation/setting/self_host_setting_group.dart';
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class MobileLaunchSettingsPage extends StatelessWidget {
const MobileLaunchSettingsPage({
super.key,
});
static const routeName = '/launch_settings';
@override
Widget build(BuildContext context) {
context.watch<AppearanceSettingsCubit>();
return Scaffold(
appBar: AppBar(
title: Text(LocaleKeys.settings_title.tr()),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
const LanguageSettingGroup(),
if (Env.enableCustomCloud) const SelfHostSettingGroup(),
],
),
),
),
);
}
}

View File

@ -1,38 +0,0 @@
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/auth/auth_service.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
class LogoutSettingGroup extends StatelessWidget {
const LogoutSettingGroup({
super.key,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
const Divider(),
Padding(
padding: const EdgeInsets.only(bottom: 4),
child: FlowyButton(
margin: const EdgeInsets.symmetric(
vertical: 16.0,
),
text: FlowyText.medium(
LocaleKeys.settings_menu_logout.tr(),
textAlign: TextAlign.center,
fontSize: 14.0,
),
onTap: () async {
await getIt<AuthService>().signOut();
runAppFlowy();
},
),
),
],
);
}
}

View File

@ -0,0 +1,110 @@
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/workspace/application/settings/appflowy_cloud_urls_bloc.dart';
import 'package:appflowy_backend/log.dart';
import 'package:dartz/dartz.dart' show Some;
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class SelfHostUrlBottomSheet extends StatefulWidget {
const SelfHostUrlBottomSheet({
super.key,
required this.url,
});
final String url;
@override
State<SelfHostUrlBottomSheet> createState() => _SelfHostUrlBottomSheetState();
}
class _SelfHostUrlBottomSheetState extends State<SelfHostUrlBottomSheet> {
final TextEditingController _textFieldController = TextEditingController();
final _formKey = GlobalKey<FormState>();
@override
void initState() {
super.initState();
_textFieldController.text = widget.url;
}
@override
void dispose() {
_textFieldController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
LocaleKeys.editor_urlHint.tr(),
style: theme.textTheme.labelSmall,
),
IconButton(
icon: Icon(
Icons.close,
color: theme.hintColor,
),
onPressed: () {
context.pop();
},
),
],
),
const SizedBox(
height: 16,
),
Form(
key: _formKey,
child: TextFormField(
controller: _textFieldController,
keyboardType: TextInputType.text,
validator: (value) {
if (value == null || value.isEmpty) {
return LocaleKeys.settings_mobile_usernameEmptyError.tr();
}
return null;
},
onEditingComplete: _saveSelfHostUrl,
),
),
const SizedBox(
height: 16,
),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: _saveSelfHostUrl,
child: Text(LocaleKeys.settings_menu_restartApp.tr()),
),
),
],
);
}
void _saveSelfHostUrl() {
if (_formKey.currentState!.validate()) {
final value = _textFieldController.text;
if (value.isNotEmpty) {
validateUrl(value).fold(
(url) async {
await setAppFlowyCloudUrl(Some(url));
runAppFlowy();
},
(err) => Log.error(err),
);
}
}
}
}

View File

@ -0,0 +1,52 @@
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
import 'package:appflowy/mobile/presentation/setting/self_host/self_host_bottom_sheet.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'setting.dart';
class SelfHostSettingGroup extends StatefulWidget {
const SelfHostSettingGroup({
super.key,
});
@override
State<SelfHostSettingGroup> createState() => _SelfHostSettingGroupState();
}
class _SelfHostSettingGroupState extends State<SelfHostSettingGroup> {
final future = getAppFlowyCloudUrl();
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: future,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const SizedBox.shrink();
}
final url = snapshot.data ?? '';
return MobileSettingGroup(
groupTitle: LocaleKeys.settings_menu_cloudAppFlowySelfHost.tr(),
settingItemList: [
MobileSettingItem(
name: url,
onTap: () {
showMobileBottomSheet(
context,
builder: (_) {
return SelfHostUrlBottomSheet(
url: url,
);
},
);
},
),
],
);
},
);
}
}