11using System ;
22using System . Collections . Generic ;
33using System . Linq ;
4+ using System . Text . RegularExpressions ;
45using Umbraco . Cms . Web . Common . PublishedModels ;
56
67namespace SgfDevs . Dev ;
78
89public class MemberTagDisplayService
910{
11+ private static readonly Regex SupportingMemberRegex = new ( "^(\\ d{4})\\ s+Supporting Member$" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
12+
1013 public IReadOnlyList < string > GetDisplayMemberTags ( Member member )
1114 {
1215 var tags = member ? . MemberTags ? . OfType < Tag > ( ) ?? [ ] ;
@@ -15,15 +18,92 @@ public IReadOnlyList<string> GetDisplayMemberTags(Member member)
1518
1619 public IReadOnlyList < string > GetDisplayMemberTags ( IEnumerable < Tag > tags )
1720 {
18- return ( tags ?? [ ] )
19- . Select ( GetDisplayName )
20- . Where ( tagName => ! string . IsNullOrWhiteSpace ( tagName ) )
21- . Distinct ( StringComparer . OrdinalIgnoreCase )
22- . ToList ( ) ;
21+ return FormatDisplayMemberTags ( ( tags ?? [ ] ) . Select ( GetDisplayName ) ) ;
22+ }
23+
24+ internal IReadOnlyList < string > FormatDisplayMemberTags ( IEnumerable < string > tagNames )
25+ {
26+ var displayTags = new List < string > ( ) ;
27+ var supportingYears = new SortedSet < int > ( ) ;
28+ int ? supportingInsertIndex = null ;
29+
30+ foreach ( var tagName in tagNames ?? [ ] )
31+ {
32+ if ( string . IsNullOrWhiteSpace ( tagName ) )
33+ {
34+ continue ;
35+ }
36+
37+ var supportingYear = GetSupportingMemberYear ( tagName ) ;
38+ if ( supportingYear . HasValue )
39+ {
40+ supportingInsertIndex ??= displayTags . Count ;
41+ supportingYears . Add ( supportingYear . Value ) ;
42+ continue ;
43+ }
44+
45+ if ( ! displayTags . Contains ( tagName , StringComparer . OrdinalIgnoreCase ) )
46+ {
47+ displayTags . Add ( tagName ) ;
48+ }
49+ }
50+
51+ if ( supportingYears . Count > 0 )
52+ {
53+ var combinedSupportingMemberTag = $ "{ FormatSupportingMemberYears ( supportingYears ) } Supporting Member";
54+ displayTags . Insert ( supportingInsertIndex ?? displayTags . Count , combinedSupportingMemberTag ) ;
55+ }
56+
57+ return displayTags ;
2358 }
2459
2560 private static string GetDisplayName ( Tag tag )
2661 {
2762 return ! string . IsNullOrWhiteSpace ( tag ? . DisplayName ) ? tag . DisplayName : tag ? . Name ;
2863 }
64+
65+ private static int ? GetSupportingMemberYear ( string tagName )
66+ {
67+ var match = SupportingMemberRegex . Match ( tagName ) ;
68+ return match . Success ? int . Parse ( match . Groups [ 1 ] . Value ) : null ;
69+ }
70+
71+ private static string FormatSupportingMemberYears ( IEnumerable < int > years )
72+ {
73+ var ranges = new List < string > ( ) ;
74+ int ? rangeStart = null ;
75+ int ? previousYear = null ;
76+
77+ foreach ( var year in years )
78+ {
79+ if ( ! rangeStart . HasValue )
80+ {
81+ rangeStart = year ;
82+ previousYear = year ;
83+ continue ;
84+ }
85+
86+ if ( year == previousYear + 1 )
87+ {
88+ previousYear = year ;
89+ continue ;
90+ }
91+
92+ ranges . Add ( FormatRange ( rangeStart . Value , previousYear ! . Value ) ) ;
93+ rangeStart = year ;
94+ previousYear = year ;
95+ }
96+
97+ if ( rangeStart . HasValue && previousYear . HasValue )
98+ {
99+ ranges . Add ( FormatRange ( rangeStart . Value , previousYear . Value ) ) ;
100+ }
101+
102+ return string . Join ( ", " , ranges ) ;
103+ }
104+
105+ private static string FormatRange ( int startYear , int endYear )
106+ {
107+ return startYear == endYear ? startYear . ToString ( ) : $ "{ startYear } -{ endYear } ";
108+ }
29109}
0 commit comments