From f353c05cb558a6dab26569b8245819ce492cf467 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sat, 5 Oct 2024 14:25:57 +0800 Subject: [PATCH] :lipstick: Better way to switch focused realm --- assets/locales/en_us.json | 3 +- assets/locales/zh_cn.json | 3 +- lib/screens/explore.dart | 23 +++--- lib/widgets/account/account_avatar.dart | 13 ++-- lib/widgets/navigation/realm_switcher.dart | 86 ++++++++++++++++++++++ 5 files changed, 107 insertions(+), 21 deletions(-) create mode 100644 lib/widgets/navigation/realm_switcher.dart diff --git a/assets/locales/en_us.json b/assets/locales/en_us.json index 011007b..f53c97c 100644 --- a/assets/locales/en_us.json +++ b/assets/locales/en_us.json @@ -463,5 +463,6 @@ "friendAdd": "Add as friend", "blockUser": "Block user", "unblockUser": "Unblock user", - "learnMoreAboutPerson": "Learn more about that person" + "learnMoreAboutPerson": "Learn more about that person", + "global": "Global" } diff --git a/assets/locales/zh_cn.json b/assets/locales/zh_cn.json index 7cfc434..1fee706 100644 --- a/assets/locales/zh_cn.json +++ b/assets/locales/zh_cn.json @@ -459,5 +459,6 @@ "friendAdd": "添加好友", "blockUser": "屏蔽用户", "unblockUser": "解除屏蔽用户", - "learnMoreAboutPerson": "了解关于 TA 的更多" + "learnMoreAboutPerson": "了解关于 TA 的更多", + "global": "全局" } diff --git a/lib/screens/explore.dart b/lib/screens/explore.dart index 1e58c50..492eeb2 100644 --- a/lib/screens/explore.dart +++ b/lib/screens/explore.dart @@ -10,9 +10,9 @@ import 'package:solian/router.dart'; import 'package:solian/screens/account/notification.dart'; import 'package:solian/theme.dart'; import 'package:solian/widgets/account/signin_required_overlay.dart'; -import 'package:solian/widgets/app_bar_title.dart'; import 'package:solian/widgets/current_state_action.dart'; import 'package:solian/widgets/app_bar_leading.dart'; +import 'package:solian/widgets/navigation/realm_switcher.dart'; import 'package:solian/widgets/posts/post_shuffle_swiper.dart'; import 'package:solian/widgets/posts/post_warped_list.dart'; @@ -55,7 +55,6 @@ class _ExploreScreenState extends State @override Widget build(BuildContext context) { final AuthProvider auth = Get.find(); - final NavigationStateProvider navState = Get.find(); return Material( color: Theme.of(context).colorScheme.surface, @@ -82,8 +81,14 @@ class _ExploreScreenState extends State headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return [ SliverAppBar( - title: AppBarTitle('explore'.tr), - centerTitle: true, + flexibleSpace: SizedBox( + height: 48, + child: const Row( + children: [ + RealmSwitcher(), + ], + ).paddingSymmetric(horizontal: 8), + ).paddingOnly(top: MediaQuery.of(context).padding.top), floating: true, toolbarHeight: AppTheme.toolbarHeight(context), leading: AppBarLeadingButton.adaptive(context), @@ -114,16 +119,6 @@ class _ExploreScreenState extends State return Column( children: [ - if (navState.focusedRealm.value != null) - MaterialBanner( - leading: const Icon(Icons.layers), - content: Text( - 'postBrowsingIn'.trParams({ - 'region': '#${navState.focusedRealm.value!.alias}', - }), - ), - actions: const [SizedBox.shrink()], - ), Expanded( child: TabBarView( physics: const NeverScrollableScrollPhysics(), diff --git a/lib/widgets/account/account_avatar.dart b/lib/widgets/account/account_avatar.dart index 5c92135..53ad0f5 100644 --- a/lib/widgets/account/account_avatar.dart +++ b/lib/widgets/account/account_avatar.dart @@ -7,6 +7,7 @@ class AccountAvatar extends StatelessWidget { final Color? bgColor; final Color? feColor; final double? radius; + final Widget? fallbackWidget; const AccountAvatar({ super.key, @@ -14,6 +15,7 @@ class AccountAvatar extends StatelessWidget { this.bgColor, this.feColor, this.radius, + this.fallbackWidget, }); @override @@ -35,11 +37,12 @@ class AccountAvatar extends StatelessWidget { backgroundColor: bgColor, backgroundImage: !isEmpty ? AutoCacheImage.provider(url) : null, child: isEmpty - ? Icon( - Icons.account_circle, - size: radius != null ? radius! * 1.2 : 24, - color: feColor, - ) + ? (fallbackWidget ?? + Icon( + Icons.account_circle, + size: radius != null ? radius! * 1.2 : 24, + color: feColor, + )) : null, ); } diff --git a/lib/widgets/navigation/realm_switcher.dart b/lib/widgets/navigation/realm_switcher.dart new file mode 100644 index 0000000..4f0dc48 --- /dev/null +++ b/lib/widgets/navigation/realm_switcher.dart @@ -0,0 +1,86 @@ +import 'package:dropdown_button2/dropdown_button2.dart'; +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:get/get.dart'; +import 'package:solian/models/realm.dart'; +import 'package:solian/providers/content/realm.dart'; +import 'package:solian/providers/navigation.dart'; +import 'package:solian/widgets/account/account_avatar.dart'; + +class RealmSwitcher extends StatelessWidget { + const RealmSwitcher({super.key}); + + @override + Widget build(BuildContext context) { + final realms = Get.find(); + final navState = Get.find(); + + return Obx(() { + return DropdownButtonHideUnderline( + child: DropdownButton2( + isExpanded: true, + hint: Text( + 'Select Item', + style: TextStyle( + fontSize: 14, + color: Theme.of(context).hintColor, + ), + ), + items: [null, ...realms.availableRealms] + .map((Realm? item) => DropdownMenuItem( + value: item, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (item != null) + AccountAvatar( + content: item.avatar, + radius: 14, + fallbackWidget: const Icon( + Icons.workspaces, + size: 16, + ), + ) + else + CircleAvatar( + backgroundColor: + Theme.of(context).colorScheme.primary, + radius: 14, + child: const Icon( + Icons.public, + color: Colors.white, + size: 16, + ), + ), + const Gap(8), + Expanded( + child: Text( + item?.name ?? 'global'.tr, + style: const TextStyle( + fontSize: 14, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + )) + .toList(), + value: navState.focusedRealm.value, + onChanged: (Realm? value) { + navState.focusedRealm.value = value; + }, + buttonStyleData: const ButtonStyleData( + padding: EdgeInsets.symmetric(horizontal: 16), + height: 48, + width: 200, + ), + menuItemStyleData: const MenuItemStyleData( + height: 48, + ), + ), + ); + }); + } +}