Skip to content

Commit a216f19

Browse files
authored
Merge pull request metabrainz#2096 from reosarevok/MBS-11650
MBS-11650: Add tag and rating statistics to profile page
2 parents cfe6812 + a0f60e3 commit a216f19

File tree

3 files changed

+134
-1
lines changed

3 files changed

+134
-1
lines changed

lib/MusicBrainz/Server/Controller/User.pm

+2
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ sub profile : Chained('load') PathPart('') HiddenOnSlaves
447447
my $edit_stats = $c->model('Editor')->various_edit_counts($user->id);
448448
$edit_stats->{last_day_count} = $c->model('Editor')->last_24h_edit_count($user->id);
449449
my $added_entities = $c->model('Editor')->added_entities_counts($user->id);
450+
my $secondary_stats = $c->model('Editor')->secondary_counts($user->id, $c->stash->{viewing_own_profile});
450451

451452
my @ip_hashes;
452453
if ($c->user_exists && $c->user->is_account_admin && !(
@@ -465,6 +466,7 @@ sub profile : Chained('load') PathPart('') HiddenOnSlaves
465466
user => $c->unsanitized_editor_json($user),
466467
votes => $c->stash->{votes},
467468
addedEntities => $added_entities,
469+
secondaryStats => $secondary_stats,
468470
);
469471

470472
$c->stash(

lib/MusicBrainz/Server/Data/Editor.pm

+63
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,69 @@ sub added_entities_counts {
714714
return \%result;
715715
}
716716

717+
sub secondary_counts {
718+
my ($self, $editor_id, $viewing_own_profile) = @_;
719+
720+
my $editor = $self->get_by_id($editor_id);
721+
$self->load_preferences($editor);
722+
723+
my %result;
724+
725+
if ($viewing_own_profile || $editor->preferences->public_tags) {
726+
$result{upvoted_tag_count} = 0;
727+
$result{downvoted_tag_count} = 0;
728+
729+
my @tag_tables = entities_with(
730+
'tags',
731+
take => sub { shift . '_tag_raw' },
732+
);
733+
my $tag_inner_query = join(
734+
' UNION ALL ',
735+
map { "SELECT is_upvote FROM $_ WHERE editor = ?" } @tag_tables
736+
);
737+
738+
my $query = <<~SQL;
739+
SELECT x.is_upvote, count(*)
740+
FROM ($tag_inner_query) x
741+
GROUP BY x.is_upvote
742+
SQL
743+
744+
my $rows = $self->sql->select_list_of_lists(
745+
$query,
746+
($editor_id) x scalar @tag_tables,
747+
);
748+
749+
for my $row (@$rows) {
750+
my ($is_upvote, $count) = @$row;
751+
if ($is_upvote) {
752+
$result{upvoted_tag_count} = $count + 0;
753+
} else {
754+
$result{downvoted_tag_count} = $count + 0;
755+
}
756+
}
757+
}
758+
759+
if ($viewing_own_profile || $editor->preferences->public_ratings) {
760+
my @rating_tables = entities_with(
761+
'ratings',
762+
take => sub { shift . '_rating_raw' },
763+
);
764+
my $rating_inner_query = join(
765+
' UNION ALL ',
766+
map { "SELECT 1 FROM $_ WHERE editor = ?" } @rating_tables
767+
);
768+
769+
my $query = "SELECT count(*) FROM ($rating_inner_query) x";
770+
771+
$result{rating_count} = $self->sql->select_single_value(
772+
$query,
773+
($editor_id) x scalar @rating_tables,
774+
);
775+
}
776+
777+
return \%result;
778+
}
779+
717780
sub last_24h_edit_count
718781
{
719782
my ($self, $editor_id) = @_;

root/user/UserProfile.js

+69-1
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,12 @@ type EditStatsT = {
446446
+rejected_count: number,
447447
};
448448

449+
type SecondaryStatsT = {
450+
+downvoted_tag_count?: number,
451+
+rating_count?: number,
452+
+upvoted_tag_count?: number,
453+
};
454+
449455
type VoteStatsT = Array<{
450456
+all: {
451457
+count: number,
@@ -477,6 +483,7 @@ type UserProfileStatisticsProps = {
477483
+$c: CatalystContextT,
478484
+addedEntities: EntitiesStatsT,
479485
+editStats: EditStatsT,
486+
+secondaryStats: SecondaryStatsT,
480487
+user: UnsanitizedEditorT,
481488
+votes: VoteStatsT,
482489
};
@@ -486,6 +493,7 @@ const UserProfileStatistics = ({
486493
editStats,
487494
user,
488495
votes,
496+
secondaryStats,
489497
addedEntities,
490498
}: UserProfileStatisticsProps) => {
491499
const voteTotals = votes.pop();
@@ -494,6 +502,11 @@ const UserProfileStatistics = ({
494502
editStats.accepted_auto_count;
495503
const hasAddedEntities =
496504
Object.values(addedEntities).some((number) => number !== 0);
505+
const hasPublicRatings = secondaryStats.rating_count != null;
506+
const hasPublicTags = secondaryStats.upvoted_tag_count != null;
507+
const ratingCount = secondaryStats.rating_count ?? 0;
508+
const upvotedTagCount = secondaryStats.upvoted_tag_count ?? 0;
509+
const downvotedTagCount = secondaryStats.downvoted_tag_count ?? 0;
497510

498511
return (
499512
<>
@@ -679,7 +692,7 @@ const UserProfileStatistics = ({
679692
<abbr title={l('Newly applied edits may ' +
680693
'need 24 hours to appear')}
681694
>
682-
{exp.l('Added entities')}
695+
{l('Added entities')}
683696
</abbr>
684697
</th>
685698
</tr>
@@ -709,6 +722,58 @@ const UserProfileStatistics = ({
709722
)}
710723
</tbody>
711724
</table>
725+
726+
{hasPublicTags || hasPublicRatings ? (
727+
<table
728+
className="statistics"
729+
title={l('This table shows a summary ' +
730+
'of secondary data added by this editor.')}
731+
>
732+
<thead>
733+
<tr>
734+
<th colSpan="2">
735+
{l('Tags and ratings')}
736+
</th>
737+
</tr>
738+
</thead>
739+
<tbody>
740+
{hasPublicTags ? (
741+
<>
742+
<UserProfileProperty name={l('Tags upvoted')}>
743+
{$c.user && upvotedTagCount > 0 ? exp.l(
744+
'{count} ({view_url|view})',
745+
{
746+
count: formatCount($c, upvotedTagCount),
747+
view_url: `/user/${encodedName}/tags`,
748+
},
749+
) : formatCount($c, upvotedTagCount)}
750+
</UserProfileProperty>
751+
752+
<UserProfileProperty name={l('Tags downvoted')}>
753+
{$c.user && downvotedTagCount > 0 ? exp.l(
754+
'{count} ({view_url|view})',
755+
{
756+
count: formatCount($c, downvotedTagCount),
757+
view_url: `/user/${encodedName}/tags?show_downvoted=1`,
758+
},
759+
) : formatCount($c, downvotedTagCount)}
760+
</UserProfileProperty>
761+
</>
762+
) : null}
763+
{hasPublicRatings ? (
764+
<UserProfileProperty name={l('Ratings')}>
765+
{$c.user && ratingCount > 0 ? exp.l(
766+
'{count} ({view_url|view})',
767+
{
768+
count: formatCount($c, ratingCount),
769+
view_url: `/user/${encodedName}/ratings`,
770+
},
771+
) : formatCount($c, ratingCount)}
772+
</UserProfileProperty>
773+
) : null}
774+
</tbody>
775+
</table>
776+
) : null}
712777
</>
713778
);
714779
};
@@ -718,6 +783,7 @@ type UserProfileProps = {
718783
+addedEntities: EntitiesStatsT,
719784
+editStats: EditStatsT,
720785
+ipHashes: $ReadOnlyArray<string>,
786+
+secondaryStats: SecondaryStatsT,
721787
+subscribed: boolean,
722788
+subscriberCount: number,
723789
+user: UnsanitizedEditorT,
@@ -728,6 +794,7 @@ const UserProfile = ({
728794
$c,
729795
editStats,
730796
ipHashes,
797+
secondaryStats,
731798
subscribed,
732799
subscriberCount,
733800
user,
@@ -755,6 +822,7 @@ const UserProfile = ({
755822
$c={$c}
756823
addedEntities={addedEntities}
757824
editStats={editStats}
825+
secondaryStats={secondaryStats}
758826
user={user}
759827
votes={votes}
760828
/>

0 commit comments

Comments
 (0)