@@ -70,6 +70,11 @@ graphqlApiUrl =
7070 " http://localhost:7458/graphql"
7171
7272
73+ pageSize : Int
74+ pageSize =
75+ 25
76+
77+
7378dark : List Css .Style -> Css .Style
7479dark =
7580 withMediaQuery [ " (prefers-color-scheme: dark)" ]
@@ -119,6 +124,12 @@ type Msg
119124 | CompleteAffectedRowsResponse ( RemoteData ( Graphql . Http . Error Int ) Int )
120125 | DeleteTask String
121126 | DeleteAffectedRowsResponse ( RemoteData ( Graphql . Http . Error Int ) Int )
127+ | LoadMoreTasks
128+ | GotMoreTasksResponse
129+ ( RemoteData
130+ ( Graphql . Http . Error ( List TodoItem ))
131+ ( List TodoItem )
132+ )
122133 | UrlChanged Url
123134 | ClickedLink Browser . UrlRequest
124135 | NoOp
@@ -134,6 +145,9 @@ type alias Model =
134145 , submissionStatus : RemoteData ( Graphql . Http . Error Int ) Int
135146 , now : Posix
136147 , tags : List String
148+ , offset : Int
149+ , hasMore : Bool
150+ , loadingMore : Bool
137151 }
138152
139153
@@ -510,7 +524,50 @@ viewBody model =
510524 p [] [ text " Loading …" ]
511525
512526 Success todos ->
513- div [] ( todos |> List . map ( viewTodo model. now))
527+ div []
528+ [ div [] ( todos |> List . map ( viewTodo model. now))
529+ , if model. hasMore then
530+ div [ css [ mt_4, text_center ] ]
531+ [ button
532+ [ css
533+ [ cursor_pointer
534+ , px_4
535+ , py_2
536+ , rounded
537+ , border
538+ , border_solid
539+ , border_color gray_400
540+ , bg_color white
541+ , hover
542+ [ bg_color gray_200
543+ , border_color gray_600
544+ ]
545+ , dark
546+ [ bg_color neutral_800
547+ , border_color neutral_500
548+ , text_color neutral_300
549+ , hover
550+ [ bg_color neutral_600
551+ , border_color neutral_300
552+ ]
553+ ]
554+ ]
555+ , onClick LoadMoreTasks
556+ , disabled model. loadingMore
557+ ]
558+ [ text
559+ ( if model. loadingMore then
560+ " Loading …"
561+
562+ else
563+ " Load more"
564+ )
565+ ]
566+ ]
567+
568+ else
569+ text " "
570+ ]
514571
515572 Failure error ->
516573 viewError error
@@ -553,11 +610,18 @@ tasksViewSelection =
553610 |> with Tasks_view_row . recurrence_duration
554611
555612
556- getTodos : Cmd Msg
557- getTodos =
558- Query . tasks_ready ( \ opts -> { opts | limit = Present 100 } ) tasksHeadSelection
613+ getTodos : Int -> (RemoteData (Graphql .Http .Error (List TodoItem )) (List TodoItem ) -> Msg ) -> Cmd Msg
614+ getTodos offset toMsg =
615+ Query . tasks_ready
616+ ( \ opts ->
617+ { opts
618+ | limit = Present pageSize
619+ , offset = Present offset
620+ }
621+ )
622+ tasksHeadSelection
559623 |> Graphql . Http . queryRequest graphqlApiUrl
560- |> Graphql . Http . send ( RemoteData . fromResult >> GotTasksResponse )
624+ |> Graphql . Http . send ( RemoteData . fromResult >> toMsg )
561625
562626
563627{- | Refresh todos based on current view
@@ -566,14 +630,26 @@ refreshTodos : Model -> Cmd Msg
566630refreshTodos model =
567631 case model. tags of
568632 [ tag ] ->
569- getTodosWithTag tag
633+ getTodosWithTag tag 0 GotTasksResponse
570634
571635 _ ->
572- getTodos
636+ getTodos 0 GotTasksResponse
573637
574638
575- getTodosWithTag : String -> Cmd Msg
576- getTodosWithTag tag =
639+ {- | Load more todos based on current view and offset
640+ -}
641+ loadMoreTodos : Model -> Cmd Msg
642+ loadMoreTodos model =
643+ case model. tags of
644+ [ tag ] ->
645+ getTodosWithTag tag model. offset GotMoreTasksResponse
646+
647+ _ ->
648+ getTodos model. offset GotMoreTasksResponse
649+
650+
651+ getTodosWithTag : String -> Int -> (RemoteData (Graphql .Http .Error (List TodoItem )) (List TodoItem ) -> Msg ) -> Cmd Msg
652+ getTodosWithTag tag offset toMsg =
577653 if String . contains " ," tag then
578654 -- TODO: Add support for specifying multiple tags
579655 Cmd . none
@@ -606,12 +682,13 @@ getTodosWithTag tag =
606682 buildTasks_view_order_by
607683 ( \ o -> { o | priority = Present Desc } )
608684 ]
609- , limit = Present 100
685+ , limit = Present pageSize
686+ , offset = Present offset
610687 }
611688 )
612689 tasksViewSelection
613690 |> Graphql . Http . queryRequest graphqlApiUrl
614- |> Graphql . Http . send ( RemoteData . fromResult >> GotTasksResponse )
691+ |> Graphql . Http . send ( RemoteData . fromResult >> toMsg )
615692
616693
617694insertTodo : Posix -> Ulid -> String -> Cmd Msg
@@ -753,13 +830,13 @@ handleRoute route =
753830 case route of
754831 Home ->
755832 Cmd . batch
756- [ getTodos
833+ [ getTodos 0 GotTasksResponse
757834 , Task . perform ReceivedTime Time . now
758835 ]
759836
760837 Tags tagStr ->
761838 Cmd . batch
762- [ getTodosWithTag tagStr
839+ [ getTodosWithTag tagStr 0 GotTasksResponse
763840 , Task . perform ReceivedTime Time . now
764841 ]
765842
@@ -788,6 +865,9 @@ init _ url key =
788865
789866 _ ->
790867 []
868+ , offset = 0
869+ , hasMore = True
870+ , loadingMore = False
791871 }
792872 , handleRoute route
793873 )
@@ -808,7 +888,19 @@ update msg model =
808888 )
809889
810890 GotTasksResponse response ->
811- ( { model | remoteTodos = response }, Cmd . none )
891+ ( { model
892+ | remoteTodos = response
893+ , offset = pageSize
894+ , hasMore =
895+ case response of
896+ Success todos ->
897+ List . length todos >= pageSize
898+
899+ _ ->
900+ False
901+ }
902+ , Cmd . none
903+ )
812904
813905 AddTaskNow ->
814906 ( { model | submissionStatus = RemoteData . Loading }
@@ -891,6 +983,31 @@ update msg model =
891983 , refreshTodos model
892984 )
893985
986+ LoadMoreTasks ->
987+ ( { model | loadingMore = True }
988+ , loadMoreTodos model
989+ )
990+
991+ GotMoreTasksResponse response ->
992+ case response of
993+ Success newTodos ->
994+ ( { model
995+ | remoteTodos =
996+ model. remoteTodos
997+ |> RemoteData . map ( \ todos -> todos ++ newTodos)
998+ , offset = model. offset + pageSize
999+ , hasMore = List . length newTodos >= pageSize
1000+ , loadingMore = False
1001+ }
1002+ , Cmd . none
1003+ )
1004+
1005+ Failure _ ->
1006+ ( { model | loadingMore = False }, Cmd . none )
1007+
1008+ _ ->
1009+ ( model, Cmd . none )
1010+
8941011 UrlChanged url ->
8951012 let
8961013 route =
0 commit comments