Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new community stats #1449

Merged
merged 1 commit into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 45 additions & 19 deletions lib/community/widgets/community_sidebar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
import 'package:lemmy_api_client/v3.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

import 'package:thunder/community/bloc/community_bloc.dart';
import 'package:thunder/community/enums/community_action.dart';
Expand Down Expand Up @@ -43,6 +44,7 @@ class _CommunitySidebarState extends State<CommunitySidebar> {

@override
Widget build(BuildContext context) {
final AppLocalizations l10n = AppLocalizations.of(context)!;
final theme = Theme.of(context);
final bool isUserLoggedIn = context.read<AuthBloc>().state.isLoggedIn;

Expand Down Expand Up @@ -115,18 +117,18 @@ class _CommunitySidebarState extends State<CommunitySidebar> {
imageMaxWidth: (kSidebarWidthFactor - 0.1) * MediaQuery.of(context).size.width,
),
),
const SidebarSectionHeader(value: "Stats"),
SidebarSectionHeader(value: l10n.stats),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: CommunityStatsList(communityView: communityView),
),
const SidebarSectionHeader(value: "Moderators"),
SidebarSectionHeader(value: l10n.moderator(2)),
CommunityModeratorList(getCommunityResponse: widget.getCommunityResponse!),
Container(
child: widget.getCommunityResponse!.site != null
? Column(
children: [
const SidebarSectionHeader(value: "Host Instance"),
SidebarSectionHeader(value: l10n.hostInstance),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: InstanceView(
Expand Down Expand Up @@ -159,43 +161,63 @@ class CommunityStatsList extends StatelessWidget {

@override
Widget build(BuildContext context) {
final AppLocalizations l10n = AppLocalizations.of(context)!;

return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (communityView.community.visibility != null) ...[
SidebarStat(
icon: switch (communityView.community.visibility!) {
CommunityVisibility.public => Icons.language_rounded,
CommunityVisibility.localOnly => Icons.house_rounded,
},
value: l10n.visibility(switch (communityView.community.visibility!) {
CommunityVisibility.public => l10n.public,
CommunityVisibility.localOnly => l10n.localOnly,
}),
),
const SizedBox(height: 8.0),
],
// TODO Make this use device date format
SidebarStat(
icon: Icons.cake_rounded,
value: 'Created ${DateFormat.yMMMMd().format(communityView.community.published)} · ${formatTimeToString(dateTime: communityView.community.published.toIso8601String())} ago',
value: '${l10n.created(DateFormat.yMMMMd().format(communityView.community.published))} · ${l10n.ago(formatTimeToString(dateTime: communityView.community.published.toIso8601String()))}',
),
const SizedBox(height: 8.0),
SidebarStat(
icon: Icons.people_rounded,
value: '${NumberFormat("#,###,###,###").format(communityView.counts.subscribers)} Subscribers',
value: l10n.countSubscribers(NumberFormat("#,###,###,###").format(communityView.counts.subscribers)),
),
if (communityView.counts.subscribersLocal != null)
SidebarStat(
icon: Icons.people_rounded,
value: l10n.countLocalSubscribers(NumberFormat("#,###,###,###").format(communityView.counts.subscribersLocal)),
),
SidebarStat(
icon: Icons.wysiwyg_rounded,
value: '${NumberFormat("#,###,###,###").format(communityView.counts.posts)} Posts',
value: l10n.countPosts(NumberFormat("#,###,###,###").format(communityView.counts.posts)),
),
SidebarStat(
icon: Icons.chat_rounded,
value: '${NumberFormat("#,###,###,###").format(communityView.counts.comments)} Comments',
value: l10n.countComments(NumberFormat("#,###,###,###").format(communityView.counts.comments)),
),
const SizedBox(height: 8.0),
SidebarStat(
icon: Icons.calendar_month_rounded,
value: '${NumberFormat("#,###,###,###").format(communityView.counts.usersActiveHalfYear)} users/6 mo',
value: l10n.countUsersActiveHalfYear(NumberFormat("#,###,###,###").format(communityView.counts.usersActiveHalfYear)),
),
SidebarStat(
icon: Icons.calendar_view_month_rounded,
value: '${NumberFormat("#,###,###,###").format(communityView.counts.usersActiveMonth)} users/mo',
value: l10n.countUsersActiveMonth(NumberFormat("#,###,###,###").format(communityView.counts.usersActiveMonth)),
),
SidebarStat(
icon: Icons.calendar_view_week_rounded,
value: '${NumberFormat("#,###,###,###").format(communityView.counts.usersActiveWeek)} users/wk',
value: l10n.countUsersActiveWeek(NumberFormat("#,###,###,###").format(communityView.counts.usersActiveWeek)),
),
SidebarStat(
icon: Icons.calendar_view_day_rounded,
value: '${NumberFormat("#,###,###,###").format(communityView.counts.usersActiveDay)} users/day',
value: l10n.countUsersActiveDay(NumberFormat("#,###,###,###").format(communityView.counts.usersActiveDay)),
),
],
);
Expand Down Expand Up @@ -276,6 +298,8 @@ class BlockCommunityButton extends StatelessWidget {

@override
Widget build(BuildContext context) {
final AppLocalizations l10n = AppLocalizations.of(context)!;

return BlocBuilder<CommunityBloc, CommunityState>(
builder: (context, state) {
bool blocked = false;
Expand Down Expand Up @@ -305,7 +329,7 @@ class BlockCommunityButton extends StatelessWidget {
children: [
Icon(blocked ? Icons.undo_rounded : Icons.block_rounded),
const SizedBox(width: 4.0),
Text(blocked ? 'Unblock Community' : 'Block Community'),
Text(blocked ? l10n.unblockCommunity : l10n.blockCommunity),
],
),
),
Expand All @@ -323,6 +347,8 @@ class CommunityActions extends StatelessWidget {

@override
Widget build(BuildContext context) {
final AppLocalizations l10n = AppLocalizations.of(context)!;

CommunityView communityView = getCommunityResponse.communityView;

return Row(
Expand All @@ -342,12 +368,12 @@ class CommunityActions extends StatelessWidget {
),
child: Semantics(
focused: true,
child: const Row(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.library_books_rounded),
SizedBox(width: 4.0),
Text('New Post', style: TextStyle(color: null)),
const Icon(Icons.library_books_rounded),
const SizedBox(width: 4.0),
Text(l10n.newPost, style: const TextStyle(color: null)),
],
),
),
Expand Down Expand Up @@ -381,9 +407,9 @@ class CommunityActions extends StatelessWidget {
const SizedBox(width: 4.0),
Text(
switch (communityView.subscribed) {
SubscribedType.notSubscribed => 'Subscribe',
SubscribedType.pending => 'Pending...',
SubscribedType.subscribed => 'Unsubscribe',
SubscribedType.notSubscribed => l10n.subscribe,
SubscribedType.pending => '${l10n.pending}...',
SubscribedType.subscribed => l10n.unsubscribe,
},
),
],
Expand Down
70 changes: 66 additions & 4 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@
"@advanced": {
"description": "Heading for advanced settings"
},
"ago": "{time} ago",
"@ago": {
"description": "Represents a duration in the past"
},
"all": "All",
"@all": {},
"allPosts": "All Posts",
Expand Down Expand Up @@ -475,12 +479,42 @@
"@couldntFindPost": {
"description": "Error message for when we can't load a post."
},
"countSubscribers": "{count} subscribers",
"@countSubscribers": {},
"countComments": "{count} Comments",
"@countComments": {
"description": "Number of comments"
},
"countLocalSubscribers": "{count} Local Subscribers",
"@countLocalSubscribers": {
"description": "Number of local subscribers"
},
"countPosts": "{count} Posts",
"@countPosts": {
"description": "Number of posts"
},
"countSubscribers": "{count} Subscribers",
"@countSubscribers": {
"description": "Number of subscribers"
},
"countUsers": "{count} users",
"@countUsers": {
"description": "Describes a certain number of users"
},
"countUsersActiveDay": "{count} users/day",
"@countUsersActiveDay": {
"description": "Number of users active in the last day"
},
"countUsersActiveHalfYear": "{count} users/6 mo",
"@countUsersActiveHalfYear": {
"description": "Number of users active in the last half year"
},
"countUsersActiveMonth": "{count} users/mo",
"@countUsersActiveMonth": {
"description": "Number of users active in the last month"
},
"countUsersActiveWeek": "{count} users/wk",
"@countUsersActiveWeek": {
"description": "Number of users active in the last week"
},
"createAccount": "Create Account",
"@createAccount": {},
"createComment": "Create Comment",
Expand All @@ -489,6 +523,10 @@
"@createNewCrossPost": {},
"createPost": "Create Post",
"@createPost": {},
"created": "Created {date}",
"@created": {
"description": "The date that something was created"
},
"createdToday": "Created Today",
"@createdToday": {
"description": "An account descriptor for an account with a birthday today"
Expand Down Expand Up @@ -927,6 +965,10 @@
"@hideTopBarOnScroll": {
"description": "Settings toggle to hide the top bar on scroll"
},
"hostInstance": "Host Instance",
"@hostInstance": {
"description": "The instance hosting a community"
},
"hot": "Hot",
"@hot": {},
"image": "Image",
Expand Down Expand Up @@ -1099,6 +1141,10 @@
"@localNotifications": {
"description": "Describes the notification type for Local Notifications"
},
"localOnly": "Local Only",
"@localOnly": {
"description": "Local community visibility"
},
"localPosts": "Local Posts",
"@localPosts": {},
"lockPost": "Lock Post",
Expand Down Expand Up @@ -1213,7 +1259,7 @@
"@moderatedCommunities": {
"description": "Describes a list of communities that are moderated by the current user."
},
"moderator": "Moderator",
"moderator": "{count, plural, zero {Moderator} one {Moderator} other {Moderators}}",
"@moderator": {
"description": "Role name for moderator"
},
Expand Down Expand Up @@ -1539,6 +1585,10 @@
},
"profiles": "Profiles",
"@profiles": {},
"public": "Public",
"@public": {
"description": "Public community visibility"
},
"pureBlack": "Pure Black",
"@pureBlack": {
"description": "Describes using the pure black theme"
Expand Down Expand Up @@ -2067,6 +2117,10 @@
"@standard": {
"description": "Describes a standard visual density"
},
"stats": "Stats",
"@stats": {
"description": "Community statistics"
},
"status": "Status",
"@status": {
"description": "Status of the action"
Expand Down Expand Up @@ -2297,6 +2351,10 @@
"@unbannedUserFromCommunity": {
"description": "Short decription for moderator action to unban a user from a community"
},
"unblockCommunity": "Unblock Community",
"@unblockCommunity": {
"description": "Action to unblock a community"
},
"unblockInstance": "Unblock Instance",
"@unblockInstance": {
"description": "Tooltip for unblocking an instance"
Expand Down Expand Up @@ -2541,6 +2599,10 @@
"@viewingAll": {
"description": "Chip for viewing all possible search results"
},
"visibility": "Visibility: {visibility}",
"@visibility": {
"description": "Visibility heading for community"
},
"visitCommunity": "Visit Community",
"@visitCommunity": {},
"visitInstance": "Visit Instance",
Expand All @@ -2559,7 +2621,7 @@
},
"xUpvotes": "{x} upvotes",
"@xUpvotes": {},
"xYearsOld": "{count, plural, zero {{x} years old} one {{x} year old} other {{x} years old}}",
"xYearsOld": "{count, plural, zero {{x} year old} one {{x} year old} other {{x} years old}}",
"@xYearsOld": {
"description": "An account descriptor representing how old an account is"
},
Expand Down
2 changes: 1 addition & 1 deletion lib/modlog/view/modlog_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class _ModlogFeedViewState extends State<ModlogFeedView> {
case ModlogActionType.adminPurgePerson:
return l10n.admin;
default:
return l10n.moderator;
return l10n.moderator(1);
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/user/utils/user_groups.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ String fetchUserGroupDescriptor(List<UserType> userGroups, Person? person) {
if (userGroups.contains(UserType.op)) descriptors.add(l10n.originalPoster);
if (userGroups.contains(UserType.self)) descriptors.add(l10n.me);
if (userGroups.contains(UserType.admin)) descriptors.add(l10n.admin);
if (userGroups.contains(UserType.moderator)) descriptors.add(l10n.moderator);
if (userGroups.contains(UserType.moderator)) descriptors.add(l10n.moderator(1));
if (userGroups.contains(UserType.bot)) descriptors.add(l10n.bot);
if (descriptors.isNotEmpty) descriptor = ' (${descriptors.join(', ')})';

Expand Down
Loading