💄 Optimize explore page styles

This commit is contained in:
2025-07-31 01:17:20 +08:00
parent ed90152462
commit f320855348
10 changed files with 145 additions and 137 deletions

View File

@@ -626,8 +626,8 @@
"chatJoin": "Join the Chat", "chatJoin": "Join the Chat",
"realmJoin": "Join the Realm", "realmJoin": "Join the Realm",
"realmJoinSuccess": "Successfully joined the realm.", "realmJoinSuccess": "Successfully joined the realm.",
"discoverRealms": "Discover Realms", "discoverRealms": "Discover realms",
"discoverPublishers": "Discover Publishers", "discoverPublishers": "Discover publishers",
"search": "Search", "search": "Search",
"publisherMembers": "Collaborators", "publisherMembers": "Collaborators",
"developerHub": "Developer Hub", "developerHub": "Developer Hub",

View File

@@ -198,21 +198,23 @@ class ExploreScreen extends HookConsumerWidget {
if (isWider) { if (isWider) {
return Row( return Row(
children: [ children: [
Flexible(flex: 3, child: bodyView), Flexible(flex: 3, child: bodyView.padding(left: 8)),
const VerticalDivider(width: 1),
if (user.value != null) if (user.value != null)
Flexible( Flexible(
flex: 2, flex: 2,
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
children: [ children: [
CheckInWidget(), CheckInWidget(
Card(
margin: EdgeInsets.only( margin: EdgeInsets.only(
left: 16, left: 8,
right: 16, right: 16,
top: 8, top: 16,
bottom: 8,
), ),
),
Card(
margin: EdgeInsets.only(left: 8, right: 16, top: 8),
child: Column( child: Column(
children: [ children: [
// Use the reusable EventCalendarWidget // Use the reusable EventCalendarWidget
@@ -227,6 +229,11 @@ class ExploreScreen extends HookConsumerWidget {
), ),
), ),
FortuneGraphWidget( FortuneGraphWidget(
margin: EdgeInsets.only(
left: 8,
right: 16,
top: 16,
),
events: events, events: events,
constrainWidth: true, constrainWidth: true,
onPointSelected: onDaySelected, onPointSelected: onDaySelected,
@@ -306,7 +313,9 @@ class _DiscoveryActivityItem extends StatelessWidget {
final items = data['items'] as List; final items = data['items'] as List;
final type = items.firstOrNull?['type'] ?? 'unknown'; final type = items.firstOrNull?['type'] ?? 'unknown';
return Column( return Card(
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Row(
@@ -333,29 +342,26 @@ class _DiscoveryActivityItem extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final item = items[index]; final item = items[index];
switch (type) { return switch (type) {
case 'realm': 'realm' => RealmCard(
return RealmCard(
realm: SnRealm.fromJson(item['data']), realm: SnRealm.fromJson(item['data']),
maxWidth: 280, maxWidth: 280,
); ),
case 'publisher': 'publisher' => PublisherCard(
return PublisherCard(
publisher: SnPublisher.fromJson(item['data']), publisher: SnPublisher.fromJson(item['data']),
maxWidth: 280, maxWidth: 280,
); ),
case 'article': 'article' => WebArticleCard(
return WebArticleCard(
article: SnWebArticle.fromJson(item['data']), article: SnWebArticle.fromJson(item['data']),
maxWidth: 280, maxWidth: 280,
); ),
default: _ => Placeholder(),
return Placeholder(); };
}
}, },
), ),
).padding(bottom: 4), ).padding(bottom: 8),
], ],
),
); );
} }
} }
@@ -381,6 +387,7 @@ class _ActivityListView extends HookConsumerWidget {
return CustomScrollView( return CustomScrollView(
slivers: [ slivers: [
SliverGap(12),
if (user.value != null && !contentOnly) if (user.value != null && !contentOnly)
SliverToBoxAdapter(child: CheckInWidget()), SliverToBoxAdapter(child: CheckInWidget()),
SliverList.builder( SliverList.builder(

View File

@@ -67,9 +67,7 @@ class PostDetailScreen extends HookConsumerWidget {
CustomScrollView( CustomScrollView(
slivers: [ slivers: [
SliverToBoxAdapter( SliverToBoxAdapter(
child: Column( child: PostItem(
children: [
PostItem(
item: post!, item: post!,
isFullPost: true, isFullPost: true,
backgroundColor: isWide ? Colors.transparent : null, backgroundColor: isWide ? Colors.transparent : null,
@@ -80,9 +78,6 @@ class PostDetailScreen extends HookConsumerWidget {
.updatePost(newItem); .updatePost(newItem);
}, },
), ),
const Divider(height: 1),
],
),
), ),
PostRepliesList(postId: id), PostRepliesList(postId: id),
SliverGap(MediaQuery.of(context).padding.bottom + 80), SliverGap(MediaQuery.of(context).padding.bottom + 80),

View File

@@ -5,6 +5,7 @@ import 'package:island/models/post.dart';
import 'package:island/pods/network.dart'; import 'package:island/pods/network.dart';
import 'package:island/widgets/app_scaffold.dart'; import 'package:island/widgets/app_scaffold.dart';
import 'package:island/widgets/post/post_item.dart'; import 'package:island/widgets/post/post_item.dart';
import 'package:island/widgets/response.dart';
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart'; import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
final postSearchNotifierProvider = StateNotifierProvider.autoDispose< final postSearchNotifierProvider = StateNotifierProvider.autoDispose<
@@ -141,6 +142,7 @@ class _PostSearchScreenState extends ConsumerState<PostSearchScreen> {
} }
return ListView.builder( return ListView.builder(
padding: EdgeInsets.zero,
itemCount: data.items.length + (data.hasMore ? 1 : 0), itemCount: data.items.length + (data.hasMore ? 1 : 0),
itemBuilder: (context, index) { itemBuilder: (context, index) {
if (index >= data.items.length) { if (index >= data.items.length) {
@@ -151,14 +153,19 @@ class _PostSearchScreenState extends ConsumerState<PostSearchScreen> {
} }
final post = data.items[index]; final post = data.items[index];
return Column( return Card(
children: [PostItem(item: post), const Divider(height: 1)], margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: PostActionableItem(item: post, borderRadius: 8),
); );
}, },
); );
}, },
loading: () => const Center(child: CircularProgressIndicator()), loading: () => const Center(child: CircularProgressIndicator()),
error: (error, stack) => Center(child: Text('Error: $error')), error:
(error, stack) => ResponseErrorWidget(
error: error,
onRetry: () => ref.invalidate(postSearchNotifierProvider),
),
); );
}, },
), ),

View File

@@ -285,33 +285,31 @@ class PublisherProfileScreen extends HookConsumerWidget {
).padding(horizontal: 24, top: 24), ).padding(horizontal: 24, top: 24),
), ),
SliverToBoxAdapter( SliverToBoxAdapter(
child: Card(
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Column( child: Column(
children: [ children: [
if (badges.value?.isNotEmpty ?? false) if (badges.value?.isNotEmpty ?? false)
BadgeList(badges: badges.value!).padding(top: 16), BadgeList(badges: badges.value!).padding(top: 16),
if (data.verification != null) if (data.verification != null)
VerificationStatusCard( VerificationStatusCard(mark: data.verification!),
mark: data.verification!,
).padding(top: 16),
], ],
).padding(horizontal: 24), ),
), ).padding(top: 16),
SliverToBoxAdapter(
child: const Divider(height: 1).padding(vertical: 24),
), ),
SliverToBoxAdapter( SliverToBoxAdapter(
child: Card(
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
Text('bio').tr().bold(), Text('bio').tr().bold().padding(bottom: 2),
Text( Text(
data.bio.isEmpty ? 'descriptionNone'.tr() : data.bio, data.bio.isEmpty ? 'descriptionNone'.tr() : data.bio,
), ),
], ],
).padding(horizontal: 24), ).padding(horizontal: 20, vertical: 16),
), ),
SliverToBoxAdapter(
child: const Divider(height: 1).padding(top: 24),
), ),
SliverPostList(pubName: name), SliverPostList(pubName: name),
SliverGap(MediaQuery.of(context).padding.bottom + 16), SliverGap(MediaQuery.of(context).padding.bottom + 16),

View File

@@ -140,9 +140,7 @@ class VerificationStatusCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Card( return Column(
margin: EdgeInsets.zero,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Icon( Icon(
@@ -163,7 +161,6 @@ class VerificationStatusCard extends StatelessWidget {
'Verified by\n${mark.verifiedBy ?? 'No one verified it'}', 'Verified by\n${mark.verifiedBy ?? 'No one verified it'}',
).fontSize(11).opacity(0.8), ).fontSize(11).opacity(0.8),
], ],
).padding(horizontal: 24, vertical: 16), ).padding(horizontal: 24, vertical: 16);
);
} }
} }

View File

@@ -26,6 +26,8 @@ class FortuneGraphWidget extends HookConsumerWidget {
final String? eventCalanderUser; final String? eventCalanderUser;
final EdgeInsets? margin;
const FortuneGraphWidget({ const FortuneGraphWidget({
super.key, super.key,
required this.events, required this.events,
@@ -34,6 +36,7 @@ class FortuneGraphWidget extends HookConsumerWidget {
this.height = 180, this.height = 180,
this.onPointSelected, this.onPointSelected,
this.eventCalanderUser, this.eventCalanderUser,
this.margin,
}); });
@override @override
@@ -249,7 +252,7 @@ class FortuneGraphWidget extends HookConsumerWidget {
if (constrainWidth) { if (constrainWidth) {
return ConstrainedBox( return ConstrainedBox(
constraints: BoxConstraints(maxWidth: maxWidth), constraints: BoxConstraints(maxWidth: maxWidth),
child: Card(margin: EdgeInsets.all(16), child: content), child: Card(margin: margin ?? EdgeInsets.all(16), child: content),
).center(); ).center();
} }

View File

@@ -35,7 +35,8 @@ Future<SnCheckInResult?> checkInResultToday(Ref ref) async {
} }
class CheckInWidget extends HookConsumerWidget { class CheckInWidget extends HookConsumerWidget {
const CheckInWidget({super.key}); final EdgeInsets? margin;
const CheckInWidget({super.key, this.margin});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
@@ -66,7 +67,8 @@ class CheckInWidget extends HookConsumerWidget {
} }
return Card( return Card(
margin: EdgeInsets.only(left: 16, right: 16, top: 16, bottom: 8), margin:
margin ?? EdgeInsets.only(left: 16, right: 16, top: 16, bottom: 8),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
spacing: 16, spacing: 16,

View File

@@ -94,9 +94,7 @@ class SliverPostList extends HookConsumerWidget {
final post = data.items[index]; final post = data.items[index];
return Column( return _buildPostItem(post);
children: [_buildPostItem(post), const Divider(height: 1)],
);
}, },
), ),
); );
@@ -114,7 +112,10 @@ class SliverPostList extends HookConsumerWidget {
onUpdate: onUpdate, onUpdate: onUpdate,
); );
case PostItemType.regular: case PostItemType.regular:
return PostItem(item: post); return Card(
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: PostActionableItem(item: post, borderRadius: 8),
);
} }
} }
} }

View File

@@ -93,16 +93,14 @@ class PostRepliesList extends HookConsumerWidget {
return endItemView; return endItemView;
} }
return Column( return Card(
children: [ margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
PostItem( child: PostActionableItem(
item: data.items[index], item: data.items[index],
backgroundColor: backgroundColor:
backgroundColor ?? (isWide ? Colors.transparent : null), backgroundColor ?? (isWide ? Colors.transparent : null),
isShowReference: false, isShowReference: false,
), ),
const Divider(height: 1),
],
); );
}, },
); );