Skip to content

Commit

Permalink
Show badges on package pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Rexios80 committed Jan 27, 2025
1 parent a3260a9 commit f2f1ae7
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 38 deletions.
2 changes: 1 addition & 1 deletion pub_stats/lib/controller/data_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class DataController {
package: package,
stats: stats,
firstScan: firstScan,
overallRank: data.overallRank,
data: data,
);
}

Expand Down
5 changes: 3 additions & 2 deletions pub_stats/lib/model/package_stats.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import 'package:pub_stats/model/package_score_snapshot.dart';
import 'package:pub_stats_core/pub_stats_core.dart';

class PackageStats {
final String package;
final List<PackageScoreSnapshot> stats;
final DateTime firstScan;
final int? overallRank;
final PackageData data;

PackageStats({
required this.package,
required this.stats,
required this.firstScan,
required this.overallRank,
required this.data,
});
}
66 changes: 66 additions & 0 deletions pub_stats/lib/view/widget/stats/shields_badge.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart';
import 'package:pub_stats/constant/app_image.dart';
import 'package:pub_stats_core/pub_stats_core.dart';
import 'package:recase/recase.dart';

class ShieldsBadge extends StatelessWidget {
final String package;
final BadgeType type;
final Object? value;

const ShieldsBadge({
super.key,
required this.package,
required this.type,
required this.value,
});

@override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: BorderRadius.circular(4),
child: InkWell(
onTap: () => _createBadge(context),
child: Row(
children: [
ColoredBox(
color: const Color(0xFF555555),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
child: Row(
spacing: 4,
children: [
SvgPicture.asset(AppImage.logo, height: 14),
Text(type.name),
],
),
),
),
ColoredBox(
color: const Color(0xFF007EC6),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
child: Text(value?.toString() ?? 'N/A'),
),
),
],
),
),
);
}

void _createBadge(BuildContext context) {
final hint = type.name.titleCase;
Clipboard.setData(
ClipboardData(
text:
'[![PubStats $hint](https://pubstats.dev/badges/packages/$package/$type.svg)](https://pubstats.dev/packages/$package)',
),
);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Badge markdown copied to clipboard')),
);
}
}
61 changes: 26 additions & 35 deletions pub_stats/lib/view/widget/stats/stats_charts.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'package:collection/collection.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pub_stats/constant/app_colors.dart';
import 'package:pub_stats/constant/app_theme.dart';
import 'package:pub_stats/constant/constants.dart';
Expand All @@ -10,8 +9,8 @@ import 'package:pub_stats/model/package_score_snapshot.dart';
import 'package:pub_stats/model/package_stats.dart';
import 'package:fast_ui/fast_ui.dart';
import 'package:pub_stats/view/widget/stats/base_stat_chart.dart';
import 'package:pub_stats/view/widget/stats/shields_badge.dart';
import 'package:pub_stats_core/pub_stats_core.dart';
import 'package:recase/recase.dart';
import 'package:url_launcher/url_launcher_string.dart';

class StatsCharts extends StatelessWidget {
Expand Down Expand Up @@ -69,7 +68,7 @@ class StatsCharts extends StatelessWidget {
final lastUpdated = packageStats.isNotEmpty
? Formatting.timeAgo(packageStats.last.timestamp)
: 'never';
final overallRank = stats.first.overallRank;
final data = stats.first.data;
return [
InkWell(
borderRadius: AppTheme.pillRadius,
Expand All @@ -79,43 +78,35 @@ class StatsCharts extends StatelessWidget {
child: Text(package, style: context.textTheme.titleLarge),
),
),
if (overallRank != null)
Text(
'Rank ${overallRank + 1}',
style: context.textTheme.labelSmall,
),
Text('Last updated $lastUpdated', style: context.textTheme.bodySmall),
const SizedBox(height: 12),
PopupMenuButton(
itemBuilder: (context) => [
for (final type in BadgeType.values)
PopupMenuItem(
onTap: () =>
_createBadge(context: context, package: package, type: type),
child: Text(type.name.titleCase),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 8,
children: [
ShieldsBadge(
package: package,
type: BadgeType.popularity,
value: data.popularityScore,
),
ShieldsBadge(
package: package,
type: BadgeType.rank,
value: data.overallRank,
),
ShieldsBadge(
package: package,
type: BadgeType.dependents,
value: data.numDependents,
),
],
child: const Text('Create Badge'),
),
const SizedBox(height: 12),
Text('Last updated $lastUpdated', style: context.textTheme.bodySmall),
];
}

void _createBadge({
required BuildContext context,
required String package,
required BadgeType type,
}) {
final hint = type.name.titleCase;
Clipboard.setData(
ClipboardData(
text:
'[![PubStats $hint](https://pubstats.dev/badges/packages/$package/$type.svg)](https://pubstats.dev/packages/$package)',
Text(
'Click a badge to copy its markdown',
style: context.textTheme.bodySmall,
),
);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Badge markdown copied to clipboard')),
);
];
}

List<Widget> _buildCompareHeader(BuildContext context) {
Expand Down

0 comments on commit f2f1ae7

Please sign in to comment.