page.dart 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import 'package:flutter/material.dart';
  2. import 'package:go_router/go_router.dart';
  3. import 'package:maxkey_flutter/maxkey/maxkey.dart';
  4. import 'package:maxkey_flutter/maxkey/services/users.service.dart';
  5. import 'package:maxkey_flutter/utils.dart';
  6. import 'package:flutter_gen/gen_l10n/app_localizations.dart';
  7. part 'package:maxkey_flutter/pages/user_page/full_user_info_dialog.dart';
  8. class UserPage extends StatelessWidget {
  9. const UserPage({super.key, this.user});
  10. final MaxKeyUser? user;
  11. @override
  12. Widget build(BuildContext context) {
  13. final scheme = Theme.of(context).colorScheme;
  14. return Scaffold(
  15. appBar: AppBar(title: Text(AppLocalizations.of(context)!.userPageTitle)),
  16. body: SafeArea(
  17. child: Padding(
  18. padding: const EdgeInsets.symmetric(horizontal: 16.0),
  19. child: Column(children: [
  20. if (user != null)
  21. Ink(
  22. decoration: BoxDecoration(
  23. color: scheme.surfaceContainer,
  24. borderRadius: BorderRadius.circular(8.0),
  25. ),
  26. child: Padding(
  27. padding: const EdgeInsets.all(8.0),
  28. child: Column(children: [
  29. _UserCard(user: user!),
  30. _UserPageButtonTile(
  31. title: AppLocalizations.of(context)!.userPageUserInfoBtn,
  32. trailing: const Icon(Icons.info),
  33. onTap: () async {
  34. final userInfo = await MaxKey.instance.usersService
  35. .getFullUserInfo();
  36. if (userInfo == null) return;
  37. if (context.mounted) {
  38. showDialog(
  39. context: context,
  40. builder: (context) =>
  41. _FullUserInfoDialog(userInfo: userInfo),
  42. );
  43. }
  44. },
  45. ),
  46. ]),
  47. ),
  48. ),
  49. const SizedBox(height: 8.0),
  50. _UserPageButtonTile(
  51. title: AppLocalizations.of(context)!.userPageSettingsBtn,
  52. trailing: const Icon(Icons.settings),
  53. onTap: () {
  54. context.push(RoutePath.settingsPage);
  55. },
  56. ),
  57. const SizedBox(height: 8.0),
  58. const _LogoutBtn(),
  59. ]),
  60. ),
  61. ),
  62. );
  63. }
  64. }
  65. class _LogoutBtn extends StatefulWidget {
  66. const _LogoutBtn({super.key});
  67. @override
  68. State<_LogoutBtn> createState() => _LogoutBtnState();
  69. }
  70. class _LogoutBtnState extends State<_LogoutBtn> {
  71. bool isLogouting = false;
  72. @override
  73. Widget build(BuildContext context) {
  74. return _UserPageButtonTile(
  75. title: AppLocalizations.of(context)!.userPageLogoutBtn,
  76. trailing: isLogouting
  77. ? const SizedBox(
  78. width: 18,
  79. height: 18,
  80. child: CircularProgressIndicator(strokeWidth: 2),
  81. )
  82. : const Icon(Icons.logout),
  83. onTap: isLogouting
  84. ? null
  85. : () async {
  86. setState(() {
  87. isLogouting = true;
  88. });
  89. await MaxKey.instance.authnService.logout();
  90. setState(() {
  91. isLogouting = false;
  92. });
  93. if (context.mounted) {
  94. Navigator.of(context).pop();
  95. context.pushReplacement(RoutePath.loginPage);
  96. }
  97. },
  98. );
  99. }
  100. }
  101. class _UserPageButtonTile extends StatelessWidget {
  102. const _UserPageButtonTile({
  103. super.key,
  104. required this.title,
  105. required this.trailing,
  106. this.onTap,
  107. });
  108. final String title;
  109. final Widget trailing;
  110. final void Function()? onTap;
  111. @override
  112. Widget build(BuildContext context) {
  113. final scheme = Theme.of(context).colorScheme;
  114. return ListTile(
  115. shape: RoundedRectangleBorder(
  116. borderRadius: BorderRadius.circular(8.0),
  117. ),
  118. tileColor: scheme.surfaceContainer,
  119. title: Text(title),
  120. trailing: trailing,
  121. onTap: onTap,
  122. );
  123. }
  124. }
  125. class _UserCard extends StatelessWidget {
  126. const _UserCard({super.key, required this.user});
  127. final MaxKeyUser user;
  128. @override
  129. Widget build(BuildContext context) {
  130. return Padding(
  131. padding: const EdgeInsets.all(8.0),
  132. child: Row(
  133. children: [
  134. ClipOval(
  135. child: user.picture == null
  136. ? Image.asset("assets/logo.jpg", width: 64, height: 64)
  137. : Image.memory(user.picture!, width: 64, height: 64),
  138. ),
  139. const SizedBox(width: 8),
  140. Expanded(
  141. child: Text(
  142. user.displayName,
  143. style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
  144. ),
  145. ),
  146. ],
  147. ),
  148. );
  149. }
  150. }