22using System . Collections . Generic ;
33using System . Linq ;
44using System . Text ;
5- using System . Threading . Tasks ;
65using GraphQL . Builders ;
7- using GraphQL . Types ;
86using GraphQL . Types . Relay . DataObjects ;
7+ using Umbraco . Core . Models ;
98
109namespace Our . Umbraco . GraphQL . Types
1110{
@@ -21,24 +20,64 @@ public static Connection<TSource> ToConnection<TSource, TParent>(this IEnumerabl
2120 public static Connection < TSource > ToConnection < TSource , TParent > ( this IEnumerable < TSource > source ,
2221 ResolveConnectionContext < TParent > context , int totalCount )
2322 {
24- // TODO: Implement paging logic
25- var items = source . Select ( x => new Edge < TSource >
26- {
27- Node = x
28- } ) . ToList ( ) ;
23+ var items = source . ToList ( ) ;
2924
3025 var after = context . After ;
3126 var before = context . Before ;
3227 var first = context . First ;
3328 var last = context . Last ;
3429
30+ int startOffset = 0 ;
31+ int endOffset = items . Count ;
32+
33+ if ( after != null )
34+ {
35+ // cursor starts at 0, so we need to add one to the offset to ensure we don't include the same item
36+ startOffset = CursorToOffset ( after ) + 1 ;
37+ }
38+ if ( before != null )
39+ {
40+ endOffset = CursorToOffset ( before ) ;
41+ }
42+ if ( first . HasValue )
43+ {
44+ endOffset = startOffset + first . Value ;
45+ }
46+ if ( last . HasValue )
47+ {
48+ startOffset = endOffset - last . Value ;
49+ }
50+
51+ // Ensure startOffset is not negative
52+ startOffset = Math . Max ( 0 , startOffset ) ;
53+
54+ var edges = source . Skip ( startOffset ) . Take ( endOffset - startOffset ) . Select ( ( x , i ) => new Edge < TSource >
55+ {
56+ Cursor = OffsetToCursor ( startOffset + i ) ,
57+ Node = x
58+ } ) . ToList ( ) ;
59+
3560 return new Connection < TSource >
3661 {
37- Edges = items ,
62+ Edges = edges ,
3863 PageInfo = new PageInfo
3964 {
65+ EndCursor = edges . LastOrDefault ( ) ? . Cursor ,
66+ HasNextPage = endOffset < items . Count ,
67+ HasPreviousPage = startOffset > 0 ,
68+ StartCursor = edges . FirstOrDefault ( ) ? . Cursor
4069 }
4170 } ;
4271 }
72+
73+ public static int CursorToOffset ( string cursor )
74+ {
75+ return int . Parse ( Encoding . UTF8 . GetString ( Convert . FromBase64String ( cursor ) ) . Substring ( "connection:" . Length ) ) ;
76+ }
77+
78+ public static string OffsetToCursor ( int offset )
79+ {
80+ return Convert . ToBase64String ( Encoding . UTF8 . GetBytes ( $ "connection:{ offset } ") ) ;
81+ }
4382 }
4483}
0 commit comments