About page

This commit is contained in:
2024-12-08 17:14:31 +08:00
parent 3f0a7a2227
commit 3c621187a7
8 changed files with 181 additions and 39 deletions

View File

@ -29,6 +29,7 @@ import 'package:surface/screens/realm/manage.dart';
import 'package:surface/screens/realm/realm_detail.dart';
import 'package:surface/screens/settings.dart';
import 'package:surface/types/post.dart';
import 'package:surface/widgets/about.dart';
import 'package:surface/widgets/navigation/app_background.dart';
import 'package:surface/widgets/navigation/app_scaffold.dart';
@ -301,6 +302,18 @@ final _appRoutes = [
),
],
),
ShellRoute(
builder: (context, state, child) => AppPageScaffold(body: child),
routes: [
GoRoute(
path: '/about',
name: 'about',
builder: (context, state) => const AppBackground(
child: AboutScreen(),
),
),
],
),
];
final appRouter = GoRouter(

View File

@ -5,6 +5,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
import 'package:image_picker/image_picker.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:path_provider/path_provider.dart';
@ -41,8 +42,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
SharedPreferences.getInstance().then((prefs) {
setState(() {
_prefs = prefs;
_serverUrlController.text =
prefs.getString(kNetworkServerStoreKey) ?? kNetworkServerDefault;
_serverUrlController.text = prefs.getString(kNetworkServerStoreKey) ?? kNetworkServerDefault;
});
});
}
@ -65,11 +65,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('settingsAppearance')
.bold()
.fontSize(17)
.tr()
.padding(horizontal: 20, bottom: 4),
Text('settingsAppearance').bold().fontSize(17).tr().padding(horizontal: 20, bottom: 4),
if (!kIsWeb)
ListTile(
title: Text('settingsBackgroundImage').tr(),
@ -78,20 +74,17 @@ class _SettingsScreenState extends State<SettingsScreen> {
leading: const Icon(Symbols.image),
trailing: const Icon(Symbols.chevron_right),
onTap: () async {
final image = await ImagePicker()
.pickImage(source: ImageSource.gallery);
final image = await ImagePicker().pickImage(source: ImageSource.gallery);
if (image == null) return;
await File(image.path)
.copy('$_docBasepath/app_background_image');
await File(image.path).copy('$_docBasepath/app_background_image');
setState(() {});
},
),
if (!kIsWeb)
FutureBuilder<bool>(
future:
File('$_docBasepath/app_background_image').exists(),
future: File('$_docBasepath/app_background_image').exists(),
builder: (context, snapshot) {
if (!snapshot.hasData || !snapshot.data!) {
return const SizedBox.shrink();
@ -99,16 +92,12 @@ class _SettingsScreenState extends State<SettingsScreen> {
return ListTile(
title: Text('settingsBackgroundImageClear').tr(),
subtitle:
Text('settingsBackgroundImageClearDescription')
.tr(),
contentPadding:
const EdgeInsets.symmetric(horizontal: 24),
subtitle: Text('settingsBackgroundImageClearDescription').tr(),
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
leading: const Icon(Symbols.texture),
trailing: const Icon(Symbols.chevron_right),
onTap: () {
File('$_docBasepath/app_background_image')
.deleteSync();
File('$_docBasepath/app_background_image').deleteSync();
setState(() {});
},
);
@ -136,11 +125,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('settingsNetwork')
.bold()
.fontSize(17)
.tr()
.padding(horizontal: 20, bottom: 4),
Text('settingsNetwork').bold().fontSize(17).tr().padding(horizontal: 20, bottom: 4),
TextField(
controller: _serverUrlController,
decoration: InputDecoration(
@ -161,8 +146,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
},
),
),
onTapOutside: (_) =>
FocusManager.instance.primaryFocus?.unfocus(),
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
).padding(horizontal: 16, top: 8, bottom: 4),
ListTile(
title: Text('settingsNetworkServerPreset').tr(),
@ -174,9 +158,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
isExpanded: true,
items: [
...kNetworkServerDirectory,
if (!kNetworkServerDirectory
.map((ele) => ele.$2)
.contains(_serverUrlController.text))
if (!kNetworkServerDirectory.map((ele) => ele.$2).contains(_serverUrlController.text))
('Custom', _serverUrlController.text),
]
.map(
@ -188,8 +170,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(item.$1).fontSize(14),
Text(item.$2, overflow: TextOverflow.ellipsis)
.fontSize(11)
Text(item.$2, overflow: TextOverflow.ellipsis).fontSize(11)
],
),
),
@ -232,6 +213,22 @@ class _SettingsScreenState extends State<SettingsScreen> {
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('settingsMisc').bold().fontSize(17).tr().padding(horizontal: 20, bottom: 4),
ListTile(
title: Text('settingsMiscAbout').tr(),
subtitle: Text('settingsMiscAboutDescription').tr(),
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
leading: const Icon(Symbols.info),
trailing: const Icon(Symbols.chevron_right),
onTap: () async {
GoRouter.of(context).pushNamed('about');
},
),
],
),
].expand((ele) => [ele, const Gap(16)]).toList(),
).padding(vertical: 20),
),

109
lib/widgets/about.dart Normal file
View File

@ -0,0 +1,109 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:url_launcher/url_launcher_string.dart';
class AboutScreen extends StatelessWidget {
const AboutScreen({super.key});
@override
Widget build(BuildContext context) {
const denseButtonStyle = ButtonStyle(visualDensity: VisualDensity(vertical: -4));
return SizedBox(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(16)),
child: Image.asset('assets/icon/icon-light-radius.png', width: 120, height: 120),
),
const Gap(8),
Text(
'Solian',
style: Theme.of(context).textTheme.titleLarge!.copyWith(fontSize: 36),
),
const Text(
'The Solar Network',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
),
const Gap(8),
FutureBuilder(
future: PackageInfo.fromPlatform(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const SizedBox.shrink();
}
return Text(
'v${snapshot.data!.version} · ${snapshot.data!.buildNumber}',
style: const TextStyle(fontFamily: 'monospace'),
);
},
),
Text('Copyright © ${DateTime.now().year} Solsynth LLC'),
const Gap(16),
Container(
constraints: const BoxConstraints(maxWidth: 280),
child: Wrap(
spacing: 4,
runSpacing: 4,
alignment: WrapAlignment.center,
children: [
TextButton(
style: denseButtonStyle,
child: Text('appDetails').tr(),
onPressed: () async {
final info = await PackageInfo.fromPlatform();
if (!context.mounted) return;
showAboutDialog(
context: context,
applicationName: 'Solian',
applicationVersion: '${info.version}+${info.buildNumber}',
applicationLegalese:
'The Solar Network App is an intuitive and open-source social network and computing platform. Experience the freedom of a user-friendly design that empowers you to create and connect with communities on your own terms. Embrace the future of social networking with a platform that prioritizes your independence and privacy.',
applicationIcon: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(16)),
child: Image.asset(
'assets/icon/icon-light-radius.png',
width: 60,
height: 60,
),
),
);
},
),
TextButton(
style: denseButtonStyle,
child: Text('termRelated').tr(),
onPressed: () {
launchUrlString('https://solsynth.dev/terms');
},
),
TextButton(
style: denseButtonStyle,
child: Text('serviceStatus').tr(),
onPressed: () {
launchUrlString('https://status.solsynth.dev');
},
),
],
),
).center(),
const Gap(16),
const Text(
'Open-sourced under AGPLv3',
style: TextStyle(
fontWeight: FontWeight.w300,
fontSize: 12,
),
),
],
),
);
}
}

View File

@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:provider/provider.dart';
import 'package:responsive_framework/responsive_framework.dart';
import 'package:styled_widget/styled_widget.dart';
@ -48,9 +49,14 @@ class _AppNavigationDrawerState extends State<AppNavigationDrawer> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Solar Network').bold(),
Text('Canary Preview 2.0α')
.fontSize(12)
.textColor(Theme.of(context).colorScheme.onSurface.withOpacity(0.5)),
FutureBuilder<String>(
future: PackageInfo.fromPlatform().then((value) => 'Stable ${value.version}+${value.buildNumber}'),
builder: (context, snapshot) {
return Text(!snapshot.hasData ? 'Stable 2.0' : snapshot.data!)
.fontSize(12)
.textColor(Theme.of(context).colorScheme.onSurface.withOpacity(0.5));
},
),
],
).padding(
horizontal: 32,