Download multiple files as zip

This commit is contained in:
eikek
2022-04-09 14:01:36 +02:00
parent e65b8de686
commit 4488291319
55 changed files with 2328 additions and 38 deletions

View File

@@ -33,6 +33,7 @@ import Api.Model.ItemLightList exposing (ItemLightList)
import Api.Model.SearchStats exposing (SearchStats)
import Browser.Dom as Dom
import Comp.BookmarkQueryManage
import Comp.DownloadAll
import Comp.ItemCardList
import Comp.ItemDetail.FormChange exposing (FormChange)
import Comp.ItemDetail.MultiEditMenu exposing (SaveNameState(..))
@@ -76,6 +77,7 @@ type alias Model =
type TopWidgetModel
= TopWidgetHidden
| DownloadAll Comp.DownloadAll.Model
| BookmarkQuery Comp.BookmarkQueryManage.Model
@@ -239,7 +241,9 @@ type Msg
| ToggleArrange ItemArrange
| ToggleExpandCollapseRows
| ToggleBookmarkCurrentQueryView
| ToggleDownloadAllView
| BookmarkQueryMsg Comp.BookmarkQueryManage.Msg
| DownloadAllMsg Comp.DownloadAll.Msg
| ItemSelectionChanged

View File

@@ -13,6 +13,7 @@ module Page.Search.Update exposing
import Api
import Api.Model.ItemLightList exposing (ItemLightList)
import Comp.BookmarkQueryManage
import Comp.DownloadAll
import Comp.ItemCardList
import Comp.ItemDetail.FormChange exposing (FormChange(..))
import Comp.ItemDetail.MultiEditMenu exposing (SaveNameState(..))
@@ -892,14 +893,46 @@ update texts bookmarkId lastViewedItemId env msg model =
Nothing ->
resultModelCmd env.selectedItems ( model, Cmd.none )
ToggleDownloadAllView ->
case createQuery env.selectedItems model of
Just q ->
case model.topWidgetModel of
DownloadAll _ ->
resultModelCmd env.selectedItems
( { model
| topWidgetModel = TopWidgetHidden
, viewMenuOpen = False
}
, Cmd.none
)
_ ->
let
( qm, qc ) =
Comp.DownloadAll.init Comp.DownloadAll.AccessUser env.flags (Q.render q)
in
resultModelCmd env.selectedItems
( { model | topWidgetModel = DownloadAll qm, viewMenuOpen = False }
, Cmd.map DownloadAllMsg qc
)
Nothing ->
resultModelCmd env.selectedItems ( model, Cmd.none )
ToggleBookmarkCurrentQueryView ->
case createQuery env.selectedItems model of
Just q ->
case model.topWidgetModel of
BookmarkQuery _ ->
resultModelCmd env.selectedItems ( { model | topWidgetModel = TopWidgetHidden, viewMenuOpen = False }, Cmd.none )
resultModelCmd env.selectedItems
( { model
| topWidgetModel = TopWidgetHidden
, viewMenuOpen = False
}
, Cmd.none
)
TopWidgetHidden ->
_ ->
let
( qm, qc ) =
Comp.BookmarkQueryManage.init (Q.render q)
@@ -947,7 +980,30 @@ update texts bookmarkId lastViewedItemId env msg model =
, Sub.map BookmarkQueryMsg res.sub
)
TopWidgetHidden ->
_ ->
resultModelCmd env.selectedItems ( model, Cmd.none )
DownloadAllMsg lm ->
case model.topWidgetModel of
DownloadAll bm ->
let
res =
Comp.DownloadAll.update env.flags lm bm
nextModel =
if res.closed then
TopWidgetHidden
else
DownloadAll res.model
in
makeResult env.selectedItems
( { model | topWidgetModel = nextModel }
, Cmd.map DownloadAllMsg res.cmd
, Sub.none
)
_ ->
resultModelCmd env.selectedItems ( model, Cmd.none )
PublishViewMsg lmsg ->

View File

@@ -11,6 +11,7 @@ import Api
import Comp.Basic as B
import Comp.BookmarkQueryManage
import Comp.ConfirmModal
import Comp.DownloadAll
import Comp.ItemCardList
import Comp.ItemMerge
import Comp.MenuBar as MB
@@ -108,7 +109,7 @@ mainView texts env model =
bookmarkQueryWidget : Texts -> UiSettings -> Flags -> Model -> List (Html Msg)
bookmarkQueryWidget texts _ _ model =
bookmarkQueryWidget texts _ flags model =
case model.topWidgetModel of
BookmarkQuery m ->
[ div [ class "px-2 mb-4 border-l border-r border-b dark:border-slate-600" ]
@@ -116,6 +117,12 @@ bookmarkQueryWidget texts _ _ model =
]
]
DownloadAll m ->
[ div [ class "mb-4 border-l border-r border-b dark:border-slate-600" ]
[ Html.map DownloadAllMsg (Comp.DownloadAll.view flags texts.downloadAllComp m)
]
]
TopWidgetHidden ->
[]
@@ -437,6 +444,24 @@ defaultMenuBar texts env model =
onClick ToggleBookmarkCurrentQueryView
]
}
, { label = texts.downloadAll
, icon = i [ class "fa fa-download" ] []
, disabled = createQuery env.selectedItems model == Nothing
, attrs =
[ title <|
if createQuery env.selectedItems model == Nothing then
texts.downloadAllQueryNeeded
else
texts.downloadAll
, href "#"
, if createQuery env.selectedItems model == Nothing then
class ""
else
onClick ToggleDownloadAllView
]
}
, { label =
if env.settings.cardPreviewFullWidth then
texts.fullHeightPreviewTitle

View File

@@ -5,13 +5,23 @@
-}
module Page.Share.Data exposing (Mode(..), Model, Msg(..), PageError(..), SearchBarMode(..), init, initCmd)
module Page.Share.Data exposing
( Mode(..)
, Model
, Msg(..)
, PageError(..)
, SearchBarMode(..)
, TopContentModel(..)
, init
, initCmd
)
import Api
import Api.Model.ItemLightList exposing (ItemLightList)
import Api.Model.SearchStats exposing (SearchStats)
import Api.Model.ShareSecret exposing (ShareSecret)
import Api.Model.ShareVerifyResult exposing (ShareVerifyResult)
import Comp.DownloadAll
import Comp.ItemCardList
import Comp.PowerSearchInput
import Comp.SearchMenu
@@ -42,6 +52,11 @@ type SearchBarMode
| SearchBarContent
type TopContentModel
= TopContentHidden
| TopContentDownload Comp.DownloadAll.Model
type alias Model =
{ mode : Mode
, verifyResult : ShareVerifyResult
@@ -61,6 +76,7 @@ type alias Model =
, arrange : ItemArrange
, rowsOpen : Set String
}
, topContent : TopContentModel
}
@@ -84,6 +100,7 @@ emptyModel flags =
, arrange = Data.ItemArrange.Cards
, rowsOpen = Set.empty
}
, topContent = TopContentHidden
}
@@ -122,3 +139,5 @@ type Msg
| ToggleViewMenu
| ToggleArrange ItemArrange
| ToggleShowGroups
| DownloadAllMsg Comp.DownloadAll.Msg
| ToggleDownloadAll

View File

@@ -146,6 +146,15 @@ view texts flags model =
, onClick (ToggleArrange Data.ItemArrange.Cards)
]
}
, { label = texts.downloadAllLabel
, icon = i [ class "fa fa-download" ] []
, disabled = False
, attrs =
[ title texts.downloadAllLabel
, href "#"
, onClick ToggleDownloadAll
]
}
]
}
]

View File

@@ -0,0 +1,28 @@
{-
Copyright 2020 Eike K. & Contributors
SPDX-License-Identifier: AGPL-3.0-or-later
-}
module Page.Share.TopContent exposing (view)
import Comp.DownloadAll
import Data.Flags exposing (Flags)
import Html exposing (Html, div, span, text)
import Html.Attributes exposing (class)
import Messages.Page.Share exposing (Texts)
import Page.Share.Data exposing (Model, Msg(..), TopContentModel(..))
view : Texts -> Flags -> Model -> Html Msg
view texts flags model =
case model.topContent of
TopContentHidden ->
span [ class "hidden" ] []
TopContentDownload dm ->
div [ class "mb-4 border-l border-r border-b dark:border-slate-600" ]
[ Html.map DownloadAllMsg
(Comp.DownloadAll.view flags texts.downloadAll dm)
]

View File

@@ -8,6 +8,7 @@
module Page.Share.Update exposing (UpdateResult, update)
import Api
import Comp.DownloadAll
import Comp.ItemCardList
import Comp.LinkTarget exposing (LinkTarget)
import Comp.PowerSearchInput
@@ -19,7 +20,10 @@ import Data.ItemQuery as Q
import Data.SearchMode
import Data.UiSettings exposing (UiSettings)
import Page.Share.Data exposing (..)
import Process
import Set
import Task
import Time
import Util.Html
import Util.Maybe
import Util.Update
@@ -252,30 +256,97 @@ update flags settings shareId msg model =
UiSettingsResp (Err _) ->
noSub ( model, Cmd.none )
DownloadAllMsg lm ->
case model.topContent of
TopContentDownload dm ->
let
res =
Comp.DownloadAll.update flags lm dm
nextModel =
if res.closed then
TopContentHidden
else
TopContentDownload res.model
-- The share page can't use websockets (not authenticated) so need to poll
-- for new download state
checkSub =
if Comp.DownloadAll.isPreparing res.model then
Process.sleep 3500
|> Task.perform (always (DownloadAllMsg Comp.DownloadAll.checkDownload))
else
Cmd.none
in
{ model = { model | topContent = nextModel }
, cmd =
Cmd.batch
[ Cmd.map DownloadAllMsg res.cmd
, checkSub
]
, sub = Sub.none
}
_ ->
noSub ( model, Cmd.none )
ToggleDownloadAll ->
let
vm =
model.viewMode
nextVm =
{ vm | menuOpen = False }
in
case model.topContent of
TopContentHidden ->
let
query =
createQuery flags model
|> Maybe.withDefault (Q.DateMs Q.Gt 0)
am =
Comp.DownloadAll.AccessShare shareId
( dm, dc ) =
Comp.DownloadAll.init am flags (Q.render query)
in
noSub ( { model | topContent = TopContentDownload dm, viewMode = nextVm }, Cmd.map DownloadAllMsg dc )
TopContentDownload _ ->
noSub ( { model | topContent = TopContentHidden, viewMode = nextVm }, Cmd.none )
noSub : ( Model, Cmd Msg ) -> UpdateResult
noSub ( m, c ) =
UpdateResult m c Sub.none
createQuery : Flags -> Model -> Maybe Q.ItemQuery
createQuery flags model =
Q.and
[ Comp.SearchMenu.getItemQuery Data.ItemIds.empty model.searchMenuModel
, Maybe.map Q.Fragment <|
case model.searchMode of
SearchBarNormal ->
Comp.PowerSearchInput.getSearchString model.powerSearchInput
SearchBarContent ->
if flags.config.fullTextSearchEnabled then
Maybe.map (Q.Contents >> Q.render) model.contentSearch
else
Maybe.map (Q.AllNames >> Q.render) model.contentSearch
]
makeSearchCmd : Flags -> Bool -> Model -> Cmd Msg
makeSearchCmd flags doInit model =
let
xq =
Q.and
[ Comp.SearchMenu.getItemQuery Data.ItemIds.empty model.searchMenuModel
, Maybe.map Q.Fragment <|
case model.searchMode of
SearchBarNormal ->
Comp.PowerSearchInput.getSearchString model.powerSearchInput
SearchBarContent ->
if flags.config.fullTextSearchEnabled then
Maybe.map (Q.Contents >> Q.render) model.contentSearch
else
Maybe.map (Q.AllNames >> Q.render) model.contentSearch
]
createQuery flags model
request mq =
{ offset = Nothing

View File

@@ -19,6 +19,7 @@ import Page.Share.Data exposing (..)
import Page.Share.Menubar as Menubar
import Page.Share.Results as Results
import Page.Share.Sidebar as Sidebar
import Page.Share.TopContent as TopContent
import Styles as S
@@ -80,6 +81,7 @@ mainContent texts flags shareId model =
]
, Menubar.view texts flags model
, errorMessage texts model
, TopContent.view texts flags model
, Results.view texts model.uiSettings flags shareId model
]