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:
Eike Kettner
2020-09-14 18:43:04 +02:00
parent 913bfb611c
commit 3852c69da1
15 changed files with 131 additions and 52 deletions

View File

@ -160,7 +160,7 @@ checkPage flags page =
defaultPage : Flags -> Page
defaultPage flags =
if isSignedIn flags then
HomePage
HomePage Nothing
else
LoginPage Nothing

View File

@ -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

View File

@ -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")

View File

@ -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 "#"

View File

@ -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 )

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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
)

View File

@ -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 )

View File

@ -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 "

View File

@ -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

View File

@ -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;

View File

@ -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) {