mirror of
				https://github.com/TheAnachronism/docspell.git
				synced 2025-10-31 09:30:12 +00:00 
			
		
		
		
	Scroll to the current item when going back from detail
The list view now supports an item id that will be scrolled to and is highlighted with a shadow. When going back from detail view this is now used to scroll to the currently viewed item.
This commit is contained in:
		| @@ -160,7 +160,7 @@ checkPage flags page = | ||||
| defaultPage : Flags -> Page | ||||
| defaultPage flags = | ||||
|     if isSignedIn flags then | ||||
|         HomePage | ||||
|         HomePage Nothing | ||||
|  | ||||
|     else | ||||
|         LoginPage Nothing | ||||
|   | ||||
| @@ -304,8 +304,16 @@ updateLogin lmsg model = | ||||
| updateHome : Page.Home.Data.Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) | ||||
| updateHome lmsg model = | ||||
|     let | ||||
|         mid = | ||||
|             case model.page of | ||||
|                 HomePage x -> | ||||
|                     x | ||||
|  | ||||
|                 _ -> | ||||
|                     Nothing | ||||
|  | ||||
|         ( lm, lc, ls ) = | ||||
|             Page.Home.Update.update model.key model.flags model.uiSettings lmsg model.homeModel | ||||
|             Page.Home.Update.update mid model.key model.flags model.uiSettings lmsg model.homeModel | ||||
|     in | ||||
|     ( { model | ||||
|         | homeModel = lm | ||||
| @@ -330,7 +338,7 @@ updateManageData lmsg model = | ||||
| initPage : Model -> Page -> ( Model, Cmd Msg, Sub Msg ) | ||||
| initPage model page = | ||||
|     case page of | ||||
|         HomePage -> | ||||
|         HomePage mid -> | ||||
|             Util.Update.andThen2 | ||||
|                 [ updateHome Page.Home.Data.Init | ||||
|                 , updateQueue Page.Queue.Data.StopRefresh | ||||
|   | ||||
| @@ -65,7 +65,7 @@ defaultLayout model = | ||||
|             [ div [ class "ui fluid container" ] | ||||
|                 [ a | ||||
|                     [ class "header item narrow-item" | ||||
|                     , Page.href HomePage | ||||
|                     , Page.href (HomePage Nothing) | ||||
|                     ] | ||||
|                     [ img | ||||
|                         [ class "image" | ||||
| @@ -81,7 +81,7 @@ defaultLayout model = | ||||
|             ] | ||||
|         , div [ class "main-content" ] | ||||
|             [ case model.page of | ||||
|                 HomePage -> | ||||
|                 HomePage _ -> | ||||
|                     viewHome model | ||||
|  | ||||
|                 LoginPage _ -> | ||||
| @@ -174,7 +174,16 @@ viewLogin model = | ||||
|  | ||||
| viewHome : Model -> Html Msg | ||||
| viewHome model = | ||||
|     Html.map HomeMsg (Page.Home.View.view model.flags model.uiSettings model.homeModel) | ||||
|     let | ||||
|         mid = | ||||
|             case model.page of | ||||
|                 HomePage x -> | ||||
|                     x | ||||
|  | ||||
|                 _ -> | ||||
|                     Nothing | ||||
|     in | ||||
|     Html.map HomeMsg (Page.Home.View.view mid model.flags model.uiSettings model.homeModel) | ||||
|  | ||||
|  | ||||
| menuEntry : Model -> Page -> List (Html Msg) -> Html Msg | ||||
| @@ -206,7 +215,7 @@ loginInfo model = | ||||
|                             ] | ||||
|                         ] | ||||
|                         [ menuEntry model | ||||
|                             HomePage | ||||
|                             (HomePage Nothing) | ||||
|                             [ img | ||||
|                                 [ class "image icon" | ||||
|                                 , src (model.flags.config.docspellAssetPath ++ "/img/logo-mc-96.png") | ||||
|   | ||||
| @@ -120,26 +120,26 @@ updateDrag dm _ msg model = | ||||
| --- View | ||||
|  | ||||
|  | ||||
| view : UiSettings -> Model -> Html Msg | ||||
| view settings model = | ||||
| view : Maybe String -> UiSettings -> Model -> Html Msg | ||||
| view current settings model = | ||||
|     div [ class "ui container" ] | ||||
|         (List.map (viewGroup settings) model.results.groups) | ||||
|         (List.map (viewGroup current settings) model.results.groups) | ||||
|  | ||||
|  | ||||
| viewGroup : UiSettings -> ItemLightGroup -> Html Msg | ||||
| viewGroup settings group = | ||||
| viewGroup : Maybe String -> UiSettings -> ItemLightGroup -> Html Msg | ||||
| viewGroup current settings group = | ||||
|     div [ class "item-group" ] | ||||
|         [ div [ class "ui horizontal divider header item-list" ] | ||||
|             [ i [ class "calendar alternate outline icon" ] [] | ||||
|             , text group.name | ||||
|             ] | ||||
|         , div [ class "ui stackable three cards" ] | ||||
|             (List.map (viewItem settings) group.items) | ||||
|             (List.map (viewItem current settings) group.items) | ||||
|         ] | ||||
|  | ||||
|  | ||||
| viewItem : UiSettings -> ItemLight -> Html Msg | ||||
| viewItem settings item = | ||||
| viewItem : Maybe String -> UiSettings -> ItemLight -> Html Msg | ||||
| viewItem current settings item = | ||||
|     let | ||||
|         dirIcon = | ||||
|             i [ class (Data.Direction.iconFromMaybe item.direction) ] [] | ||||
| @@ -174,6 +174,7 @@ viewItem settings item = | ||||
|         ([ classList | ||||
|             [ ( "ui fluid card", True ) | ||||
|             , ( newColor, not isConfirmed ) | ||||
|             , ( "current", current == Just item.id ) | ||||
|             ] | ||||
|          , id item.id | ||||
|          , href "#" | ||||
|   | ||||
| @@ -648,7 +648,7 @@ update key flags next msg model = | ||||
|                         noSub ( model, Page.set key (ItemDetailPage id) ) | ||||
|  | ||||
|                     Nothing -> | ||||
|                         noSub ( model, Page.set key HomePage ) | ||||
|                         noSub ( model, Page.set key (HomePage Nothing) ) | ||||
|  | ||||
|             else | ||||
|                 noSub ( model, Cmd.none ) | ||||
|   | ||||
| @@ -99,7 +99,7 @@ renderDetailMenu inav model = | ||||
|               ) | ||||
|             ] | ||||
|         ] | ||||
|         [ a [ class "item", Page.href HomePage ] | ||||
|         [ a [ class "item", Page.href (HomePage (Just model.item.id)) ] | ||||
|             [ i [ class "arrow left icon" ] [] | ||||
|             ] | ||||
|         , a | ||||
|   | ||||
| @@ -24,7 +24,7 @@ import Util.Maybe | ||||
|  | ||||
|  | ||||
| type Page | ||||
|     = HomePage | ||||
|     = HomePage (Maybe String) | ||||
|     | LoginPage (Maybe Page) | ||||
|     | ManageDataPage | ||||
|     | CollectiveSettingPage | ||||
| @@ -39,7 +39,7 @@ type Page | ||||
| isSecured : Page -> Bool | ||||
| isSecured page = | ||||
|     case page of | ||||
|         HomePage -> | ||||
|         HomePage _ -> | ||||
|             True | ||||
|  | ||||
|         LoginPage _ -> | ||||
| @@ -88,7 +88,7 @@ loginPage p = | ||||
| pageName : Page -> String | ||||
| pageName page = | ||||
|     case page of | ||||
|         HomePage -> | ||||
|         HomePage _ -> | ||||
|             "Home" | ||||
|  | ||||
|         LoginPage _ -> | ||||
| @@ -147,7 +147,10 @@ uploadId page = | ||||
| pageToString : Page -> String | ||||
| pageToString page = | ||||
|     case page of | ||||
|         HomePage -> | ||||
|         HomePage (Just id) -> | ||||
|             "/app/home?item=" ++ id | ||||
|  | ||||
|         HomePage Nothing -> | ||||
|             "/app/home" | ||||
|  | ||||
|         LoginPage referer -> | ||||
| @@ -227,7 +230,12 @@ pathPrefix = | ||||
| parser : Parser (Page -> a) a | ||||
| parser = | ||||
|     oneOf | ||||
|         [ Parser.map HomePage (oneOf [ Parser.top, s pathPrefix </> s "home" ]) | ||||
|         [ Parser.map HomePage | ||||
|             (oneOf | ||||
|                 [ Parser.top <?> itemQuery | ||||
|                 , s pathPrefix </> s "home" <?> itemQuery | ||||
|                 ] | ||||
|             ) | ||||
|         , Parser.map LoginPage (s pathPrefix </> s "login" <?> pageQuery) | ||||
|         , Parser.map ManageDataPage (s pathPrefix </> s "managedata") | ||||
|         , Parser.map CollectiveSettingPage (s pathPrefix </> s "csettings") | ||||
| @@ -263,3 +271,8 @@ pageQuery = | ||||
|     in | ||||
|     Query.string "r" | ||||
|         |> Query.map parsePage | ||||
|  | ||||
|  | ||||
| itemQuery : Query.Parser (Maybe String) | ||||
| itemQuery = | ||||
|     Query.string "item" | ||||
|   | ||||
| @@ -8,6 +8,7 @@ import Data.Flags exposing (Flags) | ||||
| import Data.UiSettings exposing (UiSettings) | ||||
| import Page exposing (Page(..)) | ||||
| import Page.Home.Data exposing (..) | ||||
| import Ports | ||||
| import Throttle | ||||
| import Time | ||||
| import Util.Html exposing (KeyCode(..)) | ||||
| @@ -17,12 +18,12 @@ import Util.String | ||||
| import Util.Update | ||||
|  | ||||
|  | ||||
| update : Nav.Key -> Flags -> UiSettings -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) | ||||
| update key flags settings msg model = | ||||
| update : Maybe String -> Nav.Key -> Flags -> UiSettings -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) | ||||
| update mId key flags settings msg model = | ||||
|     case msg of | ||||
|         Init -> | ||||
|             Util.Update.andThen2 | ||||
|                 [ update key flags settings (SearchMenuMsg Comp.SearchMenu.Init) | ||||
|                 [ update mId key flags settings (SearchMenuMsg Comp.SearchMenu.Init) | ||||
|                 , doSearch flags settings | ||||
|                 ] | ||||
|                 model | ||||
| @@ -35,7 +36,7 @@ update key flags settings msg model = | ||||
|                         , searchType = defaultSearchType flags | ||||
|                     } | ||||
|             in | ||||
|             update key flags settings (SearchMenuMsg Comp.SearchMenu.ResetForm) nm | ||||
|             update mId key flags settings (SearchMenuMsg Comp.SearchMenu.ResetForm) nm | ||||
|  | ||||
|         SearchMenuMsg m -> | ||||
|             let | ||||
| @@ -108,7 +109,11 @@ update key flags settings msg model = | ||||
|                         , moreAvailable = list.groups /= [] | ||||
|                     } | ||||
|             in | ||||
|             update key flags settings (ItemCardListMsg (Comp.ItemCardList.SetResults list)) m | ||||
|             Util.Update.andThen2 | ||||
|                 [ update mId key flags settings (ItemCardListMsg (Comp.ItemCardList.SetResults list)) | ||||
|                 , scrollToCard mId | ||||
|                 ] | ||||
|                 m | ||||
|  | ||||
|         ItemSearchAddResp (Ok list) -> | ||||
|             let | ||||
| @@ -123,7 +128,11 @@ update key flags settings msg model = | ||||
|                         , moreAvailable = list.groups /= [] | ||||
|                     } | ||||
|             in | ||||
|             update key flags settings (ItemCardListMsg (Comp.ItemCardList.AddResults list)) m | ||||
|             Util.Update.andThen2 | ||||
|                 [ update mId key flags settings (ItemCardListMsg (Comp.ItemCardList.AddResults list)) | ||||
|                 , scrollToCard mId | ||||
|                 ] | ||||
|                 m | ||||
|  | ||||
|         ItemSearchAddResp (Err _) -> | ||||
|             withSub | ||||
| @@ -185,7 +194,7 @@ update key flags settings msg model = | ||||
|                         ContentOnlySearch -> | ||||
|                             SetContentOnly str | ||||
|             in | ||||
|             update key flags settings smMsg model | ||||
|             update mId key flags settings smMsg model | ||||
|  | ||||
|         SetContentOnly str -> | ||||
|             withSub | ||||
| @@ -207,7 +216,7 @@ update key flags settings msg model = | ||||
|                 ) | ||||
|  | ||||
|         KeyUpMsg (Just Enter) -> | ||||
|             update key flags settings DoSearch model | ||||
|             update mId key flags settings DoSearch model | ||||
|  | ||||
|         KeyUpMsg _ -> | ||||
|             withSub ( model, Cmd.none ) | ||||
| @@ -217,6 +226,16 @@ update key flags settings msg model = | ||||
| --- Helpers | ||||
|  | ||||
|  | ||||
| scrollToCard : Maybe String -> Model -> ( Model, Cmd Msg, Sub Msg ) | ||||
| scrollToCard mId model = | ||||
|     case mId of | ||||
|         Just id -> | ||||
|             ( model, Ports.scrollToElem ( id, 0 ), Sub.none ) | ||||
|  | ||||
|         Nothing -> | ||||
|             ( model, Cmd.none, Sub.none ) | ||||
|  | ||||
|  | ||||
| doSearch : Flags -> UiSettings -> Model -> ( Model, Cmd Msg, Sub Msg ) | ||||
| doSearch flags settings model = | ||||
|     let | ||||
|   | ||||
| @@ -14,8 +14,8 @@ import Page.Home.Data exposing (..) | ||||
| import Util.Html | ||||
|  | ||||
|  | ||||
| view : Flags -> UiSettings -> Model -> Html Msg | ||||
| view flags settings model = | ||||
| view : Maybe String -> Flags -> UiSettings -> Model -> Html Msg | ||||
| view current flags settings model = | ||||
|     div [ class "home-page ui padded grid" ] | ||||
|         [ div | ||||
|             [ classList | ||||
| @@ -82,7 +82,7 @@ view flags settings model = | ||||
|             ] | ||||
|             [ viewSearchBar flags model | ||||
|             , Html.map ItemCardListMsg | ||||
|                 (Comp.ItemCardList.view settings model.itemListModel) | ||||
|                 (Comp.ItemCardList.view current settings model.itemListModel) | ||||
|             ] | ||||
|         , div | ||||
|             [ classList | ||||
|   | ||||
| @@ -6,6 +6,7 @@ import Comp.ItemDetail | ||||
| import Comp.ItemDetail.Update | ||||
| import Data.Flags exposing (Flags) | ||||
| import Page.ItemDetail.Data exposing (Model, Msg(..)) | ||||
| import Ports | ||||
|  | ||||
|  | ||||
| update : Nav.Key -> Flags -> Maybe String -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) | ||||
| @@ -17,7 +18,11 @@ update key flags next msg model = | ||||
|                     Comp.ItemDetail.update key flags next Comp.ItemDetail.Update.Init model.detail | ||||
|             in | ||||
|             ( { model | detail = lm } | ||||
|             , Cmd.batch [ Api.itemDetail flags id ItemResp, Cmd.map ItemDetailMsg lc ] | ||||
|             , Cmd.batch | ||||
|                 [ Api.itemDetail flags id ItemResp | ||||
|                 , Cmd.map ItemDetailMsg lc | ||||
|                 , Ports.scrollToTop () | ||||
|                 ] | ||||
|             , Sub.map ItemDetailMsg ls | ||||
|             ) | ||||
|  | ||||
|   | ||||
| @@ -25,7 +25,7 @@ update referrer flags msg model = | ||||
|         AuthResp (Ok lr) -> | ||||
|             let | ||||
|                 gotoRef = | ||||
|                     Maybe.withDefault HomePage referrer |> Page.goto | ||||
|                     Maybe.withDefault (HomePage Nothing) referrer |> Page.goto | ||||
|             in | ||||
|             if lr.success then | ||||
|                 ( { model | result = Just lr, password = "" }, Cmd.batch [ setAccount lr, gotoRef ], Just lr ) | ||||
|   | ||||
| @@ -77,7 +77,7 @@ renderSuccessMsg public _ = | ||||
|                   else | ||||
|                     p [] | ||||
|                         [ text "Your files have been successfully uploaded. They are now being processed. Check the " | ||||
|                         , a [ class "ui link", Page.href HomePage ] | ||||
|                         , a [ class "ui link", Page.href (HomePage Nothing) ] | ||||
|                             [ text "Items page" | ||||
|                             ] | ||||
|                         , text " later where the files will arrive eventually. Or go to the " | ||||
|   | ||||
| @@ -5,6 +5,7 @@ port module Ports exposing | ||||
|     , onUiSettingsSaved | ||||
|     , removeAccount | ||||
|     , scrollToElem | ||||
|     , scrollToTop | ||||
|     , setAccount | ||||
|     , setAllProgress | ||||
|     , setProgress | ||||
| @@ -30,7 +31,10 @@ port setProgress : ( String, Int ) -> Cmd msg | ||||
| port setAllProgress : ( String, Int ) -> Cmd msg | ||||
|  | ||||
|  | ||||
| port scrollToElem : String -> Cmd msg | ||||
| port scrollToElem : ( String, Int ) -> Cmd msg | ||||
|  | ||||
|  | ||||
| port scrollToTop : () -> Cmd msg | ||||
|  | ||||
|  | ||||
| port saveUiSettings : ( AuthResult, StoredUiSettings ) -> Cmd msg | ||||
|   | ||||
| @@ -41,7 +41,7 @@ | ||||
| } | ||||
|  | ||||
| .default-layout .main-content { | ||||
|     margin-top: 44px; | ||||
|     padding-top: 44px; | ||||
|     padding-bottom: 2em; | ||||
| } | ||||
|  | ||||
| @@ -97,6 +97,10 @@ | ||||
| .default-layout .ui.cards .ui.card .content.search-highlight .ui.list .item .content .description strong > em { | ||||
|     background: rgba(220, 255, 71, 0.6); | ||||
| } | ||||
| .default-layout .ui.cards .ui.card.current { | ||||
|     /* semantic-ui purple */ | ||||
|     box-shadow: 0 0 6px rgba(0,0,0,0.55); | ||||
| } | ||||
|  | ||||
| .default-layout .qr-code svg { | ||||
|     width: 200px; | ||||
|   | ||||
| @@ -32,20 +32,36 @@ elmApp.ports.setAllProgress.subscribe(function(input) { | ||||
|     }, 100); | ||||
| }); | ||||
|  | ||||
| // elmApp.ports.scrollToElem.subscribe(function(id) { | ||||
| //     if (id && id != "") { | ||||
| //         window.setTimeout(function() { | ||||
| //             var el = document.getElementById(id); | ||||
| //             if (el) { | ||||
| //                 if (el["scrollIntoViewIfNeeded"]) { | ||||
| //                     el.scrollIntoViewIfNeeded(); | ||||
| //                 } else { | ||||
| //                     el.scrollIntoView(); | ||||
| //                 } | ||||
| //             } | ||||
| //         }, 20); | ||||
| //     } | ||||
| // }); | ||||
| elmApp.ports.scrollToTop.subscribe(function() { | ||||
|     window.scrollTo(0, 0); | ||||
| }); | ||||
|  | ||||
| elmApp.ports.scrollToElem.subscribe(function(argList) { | ||||
|     var id = argList && argList.length >= 1 | ||||
|         ? argList[0] : null; | ||||
|     var offset = argList && argList.length >= 2 | ||||
|         ? argList[1] : null; | ||||
|  | ||||
|     if (id && id != "") { | ||||
|         window.setTimeout(function() { | ||||
|             var el = document.getElementById(id); | ||||
|             if (el) { | ||||
|                 if (el["scrollIntoViewIfNeeded"]) { | ||||
|                     el.scrollIntoViewIfNeeded(); | ||||
|                 } else { | ||||
|                     el.scrollIntoView({ | ||||
|                         behavior: "auto", | ||||
|                         block: "center", | ||||
|                         inline: "nearest" | ||||
|                     }); | ||||
|                 } | ||||
|                 if (offset && offset != 0) { | ||||
|                     window.scrollBy(0, offset); | ||||
|                 } | ||||
|             } | ||||
|         }, 20); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| elmApp.ports.saveUiSettings.subscribe(function(args) { | ||||
|     if (Array.isArray(args) && args.length == 2) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user