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