✨ Explore shuffle post
This commit is contained in:
@@ -637,6 +637,7 @@
|
||||
"realmJoinSuccess": "Successfully joined the realm.",
|
||||
"discoverRealms": "Realms",
|
||||
"discoverPublishers": "Publishers",
|
||||
"discoverShuffledPost": "Random Posts",
|
||||
"search": "Search",
|
||||
"publisherMembers": "Collaborators",
|
||||
"developerHub": "Developer Hub",
|
||||
|
@@ -7,7 +7,7 @@ part of 'room_detail.dart';
|
||||
// **************************************************************************
|
||||
|
||||
String _$totalMessagesCountHash() =>
|
||||
r'a15c03461f25c2d4d39c0926509bf626ae2550a6';
|
||||
r'd55f1507aba2acdce5e468c1c2e15dba7640c571';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
@@ -399,39 +399,48 @@ class _DiscoveryActivityItem extends StatelessWidget {
|
||||
final items = data['items'] as List;
|
||||
final type = items.firstOrNull?['type'] ?? 'unknown';
|
||||
|
||||
return Card(
|
||||
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Symbols.explore, size: 19),
|
||||
const Gap(8),
|
||||
Text(
|
||||
(switch (type) {
|
||||
'realm' => 'discoverRealms',
|
||||
'publisher' => 'discoverPublishers',
|
||||
'article' => 'discoverWebArticles',
|
||||
_ => 'unknown',
|
||||
}).tr(),
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
).padding(top: 1),
|
||||
],
|
||||
).padding(horizontal: 20, top: 8, bottom: 4),
|
||||
SizedBox(
|
||||
height: 180,
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxHeight: 200),
|
||||
child: CarouselView.weighted(
|
||||
flexWeights:
|
||||
isWideScreen(context) ? <int>[3, 2, 1] : <int>[4, 1],
|
||||
var flexWeights = isWideScreen(context) ? <int>[3, 2, 1] : <int>[4, 1];
|
||||
if (type == 'post') flexWeights = <int>[3, 2];
|
||||
|
||||
final height = type == 'post' ? 280.0 : 180.0;
|
||||
|
||||
final contentWidget = switch (type) {
|
||||
'post' => ListView.separated(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: items.length,
|
||||
separatorBuilder: (context, index) => const Gap(12),
|
||||
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
itemBuilder: (context, index) {
|
||||
final item = items[index];
|
||||
return Container(
|
||||
width: 320,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
width: 1 / MediaQuery.of(context).devicePixelRatio,
|
||||
color: Theme.of(context).dividerColor.withOpacity(0.5),
|
||||
),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
child: SingleChildScrollView(
|
||||
child: PostActionableItem(
|
||||
item: SnPost.fromJson(item['data']),
|
||||
isCompact: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
_ => CarouselView.weighted(
|
||||
flexWeights: flexWeights,
|
||||
consumeMaxWeight: false,
|
||||
enableSplash: false,
|
||||
shape: RoundedRectangleBorder(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
),
|
||||
itemSnapping: false,
|
||||
children: [
|
||||
for (final item in items)
|
||||
switch (type) {
|
||||
@@ -447,11 +456,43 @@ class _DiscoveryActivityItem extends StatelessWidget {
|
||||
article: SnWebArticle.fromJson(item['data']),
|
||||
maxWidth: 280,
|
||||
),
|
||||
_ => Placeholder(),
|
||||
_ => const Placeholder(),
|
||||
},
|
||||
],
|
||||
),
|
||||
),
|
||||
};
|
||||
|
||||
return Card(
|
||||
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(switch (type) {
|
||||
'realm' => Symbols.public,
|
||||
'publisher' => Symbols.account_circle,
|
||||
'article' => Symbols.auto_stories,
|
||||
'post' => Symbols.shuffle,
|
||||
_ => Symbols.explore,
|
||||
}, size: 19),
|
||||
const Gap(8),
|
||||
Text(
|
||||
(switch (type) {
|
||||
'realm' => 'discoverRealms',
|
||||
'publisher' => 'discoverPublishers',
|
||||
'article' => 'discoverWebArticles',
|
||||
'post' => 'discoverShuffledPost',
|
||||
_ => 'unknown',
|
||||
}).tr(),
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
).padding(top: 1),
|
||||
],
|
||||
).padding(horizontal: 20, top: 8, bottom: 4),
|
||||
SizedBox(
|
||||
height: height,
|
||||
child: contentWidget,
|
||||
).padding(bottom: 8, horizontal: 8),
|
||||
],
|
||||
),
|
||||
@@ -569,7 +610,8 @@ class ActivityListNotifier extends _$ActivityListNotifier
|
||||
if (cursor != null) 'cursor': cursor,
|
||||
'take': take,
|
||||
if (filter != null) 'filter': filter,
|
||||
if (kDebugMode) 'debugInclude': 'realms,publishers,articles',
|
||||
if (kDebugMode)
|
||||
'debugInclude': 'realms,publishers,articles,shuffledPosts',
|
||||
};
|
||||
|
||||
final response = await client.get(
|
||||
@@ -584,12 +626,13 @@ class ActivityListNotifier extends _$ActivityListNotifier
|
||||
|
||||
final hasMore = (items.firstOrNull?.type ?? 'empty') != 'empty';
|
||||
final nextCursor =
|
||||
items
|
||||
items.isNotEmpty
|
||||
? items
|
||||
.map((x) => x.createdAt)
|
||||
.lastOrNull
|
||||
?.toUtc()
|
||||
.reduce((a, b) => a.isAfter(b) ? a : b)
|
||||
.toUtc()
|
||||
.toIso8601String()
|
||||
.toString();
|
||||
: null;
|
||||
|
||||
return CursorPagingData(
|
||||
items: items,
|
||||
|
@@ -7,7 +7,7 @@ part of 'explore.dart';
|
||||
// **************************************************************************
|
||||
|
||||
String _$activityListNotifierHash() =>
|
||||
r'b75fd5c08d5f84ca433e16b7387d317ea72b91c9';
|
||||
r'a4968856ac34b59d47cfd4a7cbb39289aef2a1b1';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
@@ -36,6 +36,7 @@ class PostActionableItem extends HookConsumerWidget {
|
||||
final bool isShowReference;
|
||||
final bool isEmbedReply;
|
||||
final bool isEmbedOpenable;
|
||||
final bool isCompact;
|
||||
final double? borderRadius;
|
||||
final VoidCallback? onRefresh;
|
||||
final Function(SnPost)? onUpdate;
|
||||
@@ -48,6 +49,7 @@ class PostActionableItem extends HookConsumerWidget {
|
||||
this.isShowReference = true,
|
||||
this.isEmbedReply = true,
|
||||
this.isEmbedOpenable = false,
|
||||
this.isCompact = false,
|
||||
this.borderRadius,
|
||||
this.onRefresh,
|
||||
this.onUpdate,
|
||||
@@ -76,6 +78,7 @@ class PostActionableItem extends HookConsumerWidget {
|
||||
isEmbedReply: isEmbedReply,
|
||||
isEmbedOpenable: isEmbedOpenable,
|
||||
isTextSelectable: false,
|
||||
isCompact: isCompact,
|
||||
onRefresh: onRefresh,
|
||||
onUpdate: onUpdate,
|
||||
onOpen: onOpen,
|
||||
@@ -298,6 +301,7 @@ class PostItem extends HookConsumerWidget {
|
||||
final bool isEmbedOpenable;
|
||||
final bool isTextSelectable;
|
||||
final bool isTranslatable;
|
||||
final bool isCompact;
|
||||
final VoidCallback? onRefresh;
|
||||
final Function(SnPost)? onUpdate;
|
||||
final VoidCallback? onOpen;
|
||||
@@ -311,6 +315,7 @@ class PostItem extends HookConsumerWidget {
|
||||
this.isEmbedOpenable = false,
|
||||
this.isTextSelectable = true,
|
||||
this.isTranslatable = true,
|
||||
this.isCompact = false,
|
||||
this.onRefresh,
|
||||
this.onUpdate,
|
||||
this.onOpen,
|
||||
@@ -465,8 +470,12 @@ class PostItem extends HookConsumerWidget {
|
||||
PostHeader(
|
||||
item: item,
|
||||
isFullPost: isFullPost,
|
||||
isCompact: isCompact,
|
||||
renderingPadding: renderingPadding,
|
||||
trailing: IconButton(
|
||||
trailing:
|
||||
isCompact
|
||||
? null
|
||||
: IconButton(
|
||||
icon:
|
||||
mostReaction == null
|
||||
? const Icon(Symbols.add_reaction)
|
||||
@@ -482,7 +491,8 @@ class PostItem extends HookConsumerWidget {
|
||||
backgroundColor: Theme.of(
|
||||
context,
|
||||
).colorScheme.primary.withOpacity(0.75),
|
||||
textColor: Theme.of(context).colorScheme.onPrimary,
|
||||
textColor:
|
||||
Theme.of(context).colorScheme.onPrimary,
|
||||
child: Text(
|
||||
kReactionTemplates[mostReaction]?.icon ?? '',
|
||||
style: const TextStyle(fontSize: 20),
|
||||
@@ -491,7 +501,9 @@ class PostItem extends HookConsumerWidget {
|
||||
style: ButtonStyle(
|
||||
backgroundColor: WidgetStatePropertyAll(
|
||||
(item.reactionsMade[mostReaction] ?? false)
|
||||
? Theme.of(context).colorScheme.primary.withOpacity(0.5)
|
||||
? Theme.of(
|
||||
context,
|
||||
).colorScheme.primary.withOpacity(0.5)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
@@ -511,7 +523,10 @@ class PostItem extends HookConsumerWidget {
|
||||
);
|
||||
},
|
||||
padding: EdgeInsets.zero,
|
||||
visualDensity: const VisualDensity(horizontal: -3, vertical: -3),
|
||||
visualDensity: const VisualDensity(
|
||||
horizontal: -3,
|
||||
vertical: -3,
|
||||
),
|
||||
),
|
||||
),
|
||||
PostBody(
|
||||
|
@@ -532,6 +532,7 @@ class PostHeader extends StatelessWidget {
|
||||
final bool isInteractive;
|
||||
final EdgeInsets renderingPadding;
|
||||
final bool isRelativeTime;
|
||||
final bool isCompact;
|
||||
|
||||
const PostHeader({
|
||||
super.key,
|
||||
@@ -541,6 +542,7 @@ class PostHeader extends StatelessWidget {
|
||||
this.isInteractive = true,
|
||||
this.renderingPadding = EdgeInsets.zero,
|
||||
this.isRelativeTime = true,
|
||||
this.isCompact = false,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -584,11 +586,27 @@ class PostHeader extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Text(item.publisher.nick).bold(),
|
||||
Flexible(
|
||||
child:
|
||||
Text(
|
||||
item.publisher.nick,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
).bold(),
|
||||
),
|
||||
if (item.publisher.verification != null)
|
||||
VerificationMark(mark: item.publisher.verification!),
|
||||
if (item.realm == null)
|
||||
Text('@${item.publisher.name}').fontSize(11)
|
||||
Flexible(
|
||||
child:
|
||||
isCompact
|
||||
? const SizedBox.shrink()
|
||||
: Text(
|
||||
'@${item.publisher.name}',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
).fontSize(11),
|
||||
)
|
||||
else
|
||||
...([
|
||||
const Icon(Symbols.arrow_right, size: 14),
|
||||
|
Reference in New Issue
Block a user