Compare commits
1 commit
main
...
krille/pro
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e66bf0a10c |
7 changed files with 198 additions and 20 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:fluffychat/pages/settings_profile/settings_profile_presenter.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
@ -218,6 +219,15 @@ abstract class AppRoutes {
|
||||||
: const Settings(),
|
: const Settings(),
|
||||||
),
|
),
|
||||||
routes: [
|
routes: [
|
||||||
|
GoRoute(
|
||||||
|
path: 'profile_settings',
|
||||||
|
pageBuilder: (context, state) => defaultPageBuilder(
|
||||||
|
context,
|
||||||
|
state,
|
||||||
|
const SettingsProfilePresenter(),
|
||||||
|
),
|
||||||
|
redirect: loggedOutRedirect,
|
||||||
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: 'notifications',
|
path: 'notifications',
|
||||||
pageBuilder: (context, state) => defaultPageBuilder(
|
pageBuilder: (context, state) => defaultPageBuilder(
|
||||||
|
|
|
||||||
|
|
@ -2782,5 +2782,9 @@
|
||||||
"description": "This should be a very short string because there is not much space in the button!"
|
"description": "This should be a very short string because there is not much space in the button!"
|
||||||
},
|
},
|
||||||
"createNewChat": "Create new chat",
|
"createNewChat": "Create new chat",
|
||||||
"reset": "Reset"
|
"reset": "Reset",
|
||||||
|
"profileSettings": "Profile settings",
|
||||||
|
"timezone": "Timezone",
|
||||||
|
"pronouns": "Pronouns",
|
||||||
|
"save": "Save"
|
||||||
}
|
}
|
||||||
|
|
@ -118,24 +118,6 @@ class SettingsView extends StatelessWidget {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
FutureBuilder(
|
|
||||||
future: Matrix.of(context).client.getAuthMetadata(),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
final accountManageUrl = snapshot.data?.issuer;
|
|
||||||
if (accountManageUrl == null) {
|
|
||||||
return const SizedBox.shrink();
|
|
||||||
}
|
|
||||||
return ListTile(
|
|
||||||
leading: const Icon(Icons.account_circle_outlined),
|
|
||||||
title: Text(L10n.of(context).manageAccount),
|
|
||||||
trailing: const Icon(Icons.open_in_new_outlined),
|
|
||||||
onTap: () => launchUrl(
|
|
||||||
accountManageUrl,
|
|
||||||
mode: LaunchMode.inAppBrowserView,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Divider(color: theme.dividerColor),
|
Divider(color: theme.dividerColor),
|
||||||
SwitchListTile.adaptive(
|
SwitchListTile.adaptive(
|
||||||
controlAffinity: ListTileControlAffinity.trailing,
|
controlAffinity: ListTileControlAffinity.trailing,
|
||||||
|
|
@ -145,6 +127,34 @@ class SettingsView extends StatelessWidget {
|
||||||
onChanged: controller.firstRunBootstrapAction,
|
onChanged: controller.firstRunBootstrapAction,
|
||||||
),
|
),
|
||||||
Divider(color: theme.dividerColor),
|
Divider(color: theme.dividerColor),
|
||||||
|
|
||||||
|
FutureBuilder(
|
||||||
|
future: Matrix.of(context).client.getAuthMetadata(),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
final accountManageUrl = snapshot.data?.issuer;
|
||||||
|
if (accountManageUrl == null) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(Icons.admin_panel_settings_outlined),
|
||||||
|
title: Text(L10n.of(context).manageAccount),
|
||||||
|
trailing: const Icon(Icons.open_in_new_outlined),
|
||||||
|
onTap: () => launchUrl(
|
||||||
|
accountManageUrl,
|
||||||
|
mode: LaunchMode.inAppBrowserView,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.account_circle_outlined),
|
||||||
|
title: Text(L10n.of(context).profileSettings),
|
||||||
|
tileColor:
|
||||||
|
activeRoute.startsWith('/rooms/settings/profile_settings')
|
||||||
|
? theme.colorScheme.surfaceContainerHigh
|
||||||
|
: null,
|
||||||
|
onTap: () => context.go('/rooms/settings/profile_settings'),
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.format_paint_outlined),
|
leading: const Icon(Icons.format_paint_outlined),
|
||||||
title: Text(L10n.of(context).changeTheme),
|
title: Text(L10n.of(context).changeTheme),
|
||||||
|
|
|
||||||
62
lib/pages/settings_profile/settings_profile_page.dart
Normal file
62
lib/pages/settings_profile/settings_profile_page.dart
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
import 'package:fluffychat/config/app_config.dart';
|
||||||
|
import 'package:fluffychat/config/themes.dart';
|
||||||
|
import 'package:fluffychat/l10n/l10n.dart';
|
||||||
|
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SettingsProfilePage extends StatelessWidget {
|
||||||
|
final TextEditingController? pronounsController;
|
||||||
|
final String? timezone;
|
||||||
|
final VoidCallback save;
|
||||||
|
final bool isLoading;
|
||||||
|
|
||||||
|
const SettingsProfilePage({
|
||||||
|
super.key,
|
||||||
|
required this.pronounsController,
|
||||||
|
required this.save,
|
||||||
|
required this.timezone,
|
||||||
|
required this.isLoading,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
automaticallyImplyLeading: !FluffyThemes.isColumnMode(context),
|
||||||
|
title: Text(L10n.of(context).profileSettings),
|
||||||
|
),
|
||||||
|
body: MaxWidthBody(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(32.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: .stretch,
|
||||||
|
spacing: 32,
|
||||||
|
children: [
|
||||||
|
TextField(
|
||||||
|
controller: pronounsController,
|
||||||
|
readOnly: pronounsController == null,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: L10n.of(context).pronouns,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
bottomNavigationBar: Material(
|
||||||
|
elevation: 8,
|
||||||
|
shadowColor: theme.appBarTheme.shadowColor,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: pronounsController == null || isLoading ? null : save,
|
||||||
|
child: isLoading
|
||||||
|
? LinearProgressIndicator()
|
||||||
|
: Text(L10n.of(context).saveChanges),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
91
lib/pages/settings_profile/settings_profile_presenter.dart
Normal file
91
lib/pages/settings_profile/settings_profile_presenter.dart
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
import 'package:fluffychat/pages/settings_profile/settings_profile_page.dart';
|
||||||
|
import 'package:fluffychat/utils/localized_exception_extension.dart';
|
||||||
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
|
class SettingsProfilePresenter extends StatefulWidget {
|
||||||
|
const SettingsProfilePresenter({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SettingsProfilePresenter> createState() =>
|
||||||
|
_SettingsProfilePresenterState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SettingsProfilePresenterState extends State<SettingsProfilePresenter> {
|
||||||
|
static const String pronounsKey = 'io.fsky.nyx.pronouns';
|
||||||
|
static const String timezoneFallbackKey = 'us.cloke.msc4175.tz';
|
||||||
|
|
||||||
|
TextEditingController? _pronounsController;
|
||||||
|
String? _timezone;
|
||||||
|
bool _isLoading = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_loadProfile();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadProfile() async {
|
||||||
|
final client = Matrix.of(context).client;
|
||||||
|
final cachedProfile = await client.getUserProfile(
|
||||||
|
client.userID!,
|
||||||
|
maxCacheAge: Duration.zero,
|
||||||
|
);
|
||||||
|
print(cachedProfile.additionalProperties);
|
||||||
|
setState(() {
|
||||||
|
_timezone =
|
||||||
|
cachedProfile.mTz ??
|
||||||
|
cachedProfile.additionalProperties.tryGet<String>(
|
||||||
|
timezoneFallbackKey,
|
||||||
|
);
|
||||||
|
_pronounsController = TextEditingController(
|
||||||
|
text: cachedProfile.additionalProperties.tryGet<String>(pronounsKey),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _save() async {
|
||||||
|
final client = Matrix.of(context).client;
|
||||||
|
final cachedProfile = await client.getUserProfile(client.userID!);
|
||||||
|
setState(() {
|
||||||
|
_isLoading = true;
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
final newPronouns = _pronounsController!.text.trim();
|
||||||
|
if (newPronouns !=
|
||||||
|
cachedProfile.additionalProperties.tryGet<String>(pronounsKey)) {
|
||||||
|
await client.setProfileField(client.userID!, pronounsKey, {
|
||||||
|
pronounsKey: newPronouns,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cachedProfile.mTz != _timezone) {
|
||||||
|
await client.setProfileField(client.userID!, 'm.tz', {
|
||||||
|
'm.tz': _timezone,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e, s) {
|
||||||
|
Logs().e('Unable to update profile', e, s);
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(
|
||||||
|
context,
|
||||||
|
).showSnackBar(SnackBar(content: Text(e.toLocalizedString(context))));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => SettingsProfilePage(
|
||||||
|
pronounsController: _pronounsController,
|
||||||
|
save: _save,
|
||||||
|
timezone: _timezone,
|
||||||
|
isLoading: _isLoading,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1898,7 +1898,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.16"
|
version: "0.6.16"
|
||||||
timezone:
|
timezone:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: timezone
|
name: timezone
|
||||||
sha256: dd14a3b83cfd7cb19e7888f1cbc20f258b8d71b54c06f79ac585f14093a287d1
|
sha256: dd14a3b83cfd7cb19e7888f1cbc20f258b8d71b54c06f79ac585f14093a287d1
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ dependencies:
|
||||||
sqflite_common_ffi: ^2.3.7+1
|
sqflite_common_ffi: ^2.3.7+1
|
||||||
sqlcipher_flutter_libs: ^0.6.8
|
sqlcipher_flutter_libs: ^0.6.8
|
||||||
swipe_to_action: ^0.3.0
|
swipe_to_action: ^0.3.0
|
||||||
|
timezone: ^0.10.1
|
||||||
unifiedpush: ^6.2.0
|
unifiedpush: ^6.2.0
|
||||||
unifiedpush_ui: ^0.2.0
|
unifiedpush_ui: ^0.2.0
|
||||||
universal_html: ^2.3.0
|
universal_html: ^2.3.0
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue