2
2
using System . Collections . Generic ;
3
3
using System . Linq ;
4
4
using System . Text ;
5
- using System . Threading . Tasks ;
6
5
using GraphQL . Builders ;
7
- using GraphQL . Types ;
8
6
using GraphQL . Types . Relay . DataObjects ;
7
+ using Umbraco . Core . Models ;
9
8
10
9
namespace Our . Umbraco . GraphQL . Types
11
10
{
@@ -21,24 +20,64 @@ public static Connection<TSource> ToConnection<TSource, TParent>(this IEnumerabl
21
20
public static Connection < TSource > ToConnection < TSource , TParent > ( this IEnumerable < TSource > source ,
22
21
ResolveConnectionContext < TParent > context , int totalCount )
23
22
{
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 ( ) ;
29
24
30
25
var after = context . After ;
31
26
var before = context . Before ;
32
27
var first = context . First ;
33
28
var last = context . Last ;
34
29
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
+
35
60
return new Connection < TSource >
36
61
{
37
- Edges = items ,
62
+ Edges = edges ,
38
63
PageInfo = new PageInfo
39
64
{
65
+ EndCursor = edges . LastOrDefault ( ) ? . Cursor ,
66
+ HasNextPage = endOffset < items . Count ,
67
+ HasPreviousPage = startOffset > 0 ,
68
+ StartCursor = edges . FirstOrDefault ( ) ? . Cursor
40
69
}
41
70
} ;
42
71
}
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
+ }
43
82
}
44
83
}
0 commit comments