mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-04-05 19:09:32 +00:00
Merge pull request #1583 from eikek/share-paging
Add paging to share view
This commit is contained in:
commit
0738bcf31b
@ -50,7 +50,7 @@ trait DatabaseTest
|
|||||||
|
|
||||||
lazy val h2DataSource = ResourceSuiteLocalFixture(
|
lazy val h2DataSource = ResourceSuiteLocalFixture(
|
||||||
"h2DataSource", {
|
"h2DataSource", {
|
||||||
val jdbc = StoreFixture.memoryDB("test")
|
val jdbc = StoreFixture.memoryDB(UUID.randomUUID().toString)
|
||||||
StoreFixture.dataSource(jdbc).map(ds => (jdbc, ds))
|
StoreFixture.dataSource(jdbc).map(ds => (jdbc, ds))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -12,6 +12,7 @@ module Comp.ItemCardList exposing
|
|||||||
, init
|
, init
|
||||||
, nextItem
|
, nextItem
|
||||||
, prevItem
|
, prevItem
|
||||||
|
, size
|
||||||
, update
|
, update
|
||||||
, updateDrag
|
, updateDrag
|
||||||
, view
|
, view
|
||||||
@ -71,6 +72,11 @@ prevItem model id =
|
|||||||
|> Util.List.findPrev (\i -> i.id == id)
|
|> Util.List.findPrev (\i -> i.id == id)
|
||||||
|
|
||||||
|
|
||||||
|
size : Model -> Int
|
||||||
|
size model =
|
||||||
|
Data.Items.length model.results
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Update
|
--- Update
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@ type alias Texts =
|
|||||||
, listView : String
|
, listView : String
|
||||||
, tileView : String
|
, tileView : String
|
||||||
, downloadAllLabel : String
|
, downloadAllLabel : String
|
||||||
|
, loadMore : String
|
||||||
|
, thatsAll : String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -53,6 +55,8 @@ gb tz =
|
|||||||
, listView = "List view"
|
, listView = "List view"
|
||||||
, tileView = "Tile view"
|
, tileView = "Tile view"
|
||||||
, downloadAllLabel = "Download all"
|
, downloadAllLabel = "Download all"
|
||||||
|
, loadMore = "Load more…"
|
||||||
|
, thatsAll = "That's all"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -73,6 +77,8 @@ de tz =
|
|||||||
, listView = "Listenansicht"
|
, listView = "Listenansicht"
|
||||||
, tileView = "Kachelansicht"
|
, tileView = "Kachelansicht"
|
||||||
, downloadAllLabel = "Alles herunterladen"
|
, downloadAllLabel = "Alles herunterladen"
|
||||||
|
, loadMore = "Mehr laden…"
|
||||||
|
, thatsAll = "Mehr gibt es nicht"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -93,4 +99,6 @@ fr tz =
|
|||||||
, listView = "Affichage liste"
|
, listView = "Affichage liste"
|
||||||
, tileView = "Affichage tuile"
|
, tileView = "Affichage tuile"
|
||||||
, downloadAllLabel = "Télécharger tout"
|
, downloadAllLabel = "Télécharger tout"
|
||||||
|
, loadMore = "Charger plus..."
|
||||||
|
, thatsAll = "C'est tout !"
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ module Page.Share.Data exposing
|
|||||||
, TopContentModel(..)
|
, TopContentModel(..)
|
||||||
, init
|
, init
|
||||||
, initCmd
|
, initCmd
|
||||||
|
, pageSizes
|
||||||
)
|
)
|
||||||
|
|
||||||
import Api
|
import Api
|
||||||
@ -75,6 +76,9 @@ type alias Model =
|
|||||||
, showGroups : Bool
|
, showGroups : Bool
|
||||||
, arrange : ItemArrange
|
, arrange : ItemArrange
|
||||||
, rowsOpen : Set String
|
, rowsOpen : Set String
|
||||||
|
, pageSizeMenuOpen : Bool
|
||||||
|
, pageSize : Int
|
||||||
|
, offset : Int
|
||||||
}
|
}
|
||||||
, topContent : TopContentModel
|
, topContent : TopContentModel
|
||||||
}
|
}
|
||||||
@ -99,6 +103,9 @@ emptyModel flags =
|
|||||||
, showGroups = True
|
, showGroups = True
|
||||||
, arrange = Data.ItemArrange.Cards
|
, arrange = Data.ItemArrange.Cards
|
||||||
, rowsOpen = Set.empty
|
, rowsOpen = Set.empty
|
||||||
|
, pageSizeMenuOpen = False
|
||||||
|
, pageSize = pageSizes flags |> List.head |> Maybe.withDefault 20
|
||||||
|
, offset = 0
|
||||||
}
|
}
|
||||||
, topContent = TopContentHidden
|
, topContent = TopContentHidden
|
||||||
}
|
}
|
||||||
@ -126,6 +133,7 @@ initCmd shareId flags =
|
|||||||
type Msg
|
type Msg
|
||||||
= VerifyResp (Result Http.Error ShareVerifyResult)
|
= VerifyResp (Result Http.Error ShareVerifyResult)
|
||||||
| SearchResp (Result Http.Error ItemLightList)
|
| SearchResp (Result Http.Error ItemLightList)
|
||||||
|
| AddSearchResp (Result Http.Error ItemLightList)
|
||||||
| StatsResp Bool (Result Http.Error SearchStats)
|
| StatsResp Bool (Result Http.Error SearchStats)
|
||||||
| UiSettingsResp (Result Http.Error UiSettings)
|
| UiSettingsResp (Result Http.Error UiSettings)
|
||||||
| PasswordMsg Comp.SharePasswordForm.Msg
|
| PasswordMsg Comp.SharePasswordForm.Msg
|
||||||
@ -141,3 +149,32 @@ type Msg
|
|||||||
| ToggleShowGroups
|
| ToggleShowGroups
|
||||||
| DownloadAllMsg Comp.DownloadAll.Msg
|
| DownloadAllMsg Comp.DownloadAll.Msg
|
||||||
| ToggleDownloadAll
|
| ToggleDownloadAll
|
||||||
|
| TogglePageSizeMenu
|
||||||
|
| SetPageSize Int
|
||||||
|
| LoadNextPage
|
||||||
|
|
||||||
|
|
||||||
|
pageSizes : Flags -> List Int
|
||||||
|
pageSizes flags =
|
||||||
|
let
|
||||||
|
maxSize =
|
||||||
|
flags.config.maxPageSize
|
||||||
|
|
||||||
|
high =
|
||||||
|
min maxSize 60 // 10 * 10
|
||||||
|
|
||||||
|
low =
|
||||||
|
20
|
||||||
|
|
||||||
|
gen n res =
|
||||||
|
if n > high then
|
||||||
|
res
|
||||||
|
|
||||||
|
else
|
||||||
|
gen (n + low) (n :: res)
|
||||||
|
in
|
||||||
|
if maxSize <= low then
|
||||||
|
[ maxSize ]
|
||||||
|
|
||||||
|
else
|
||||||
|
List.reverse (gen low [])
|
||||||
|
55
modules/webapp/src/main/elm/Page/Share/LoadMore.elm
Normal file
55
modules/webapp/src/main/elm/Page/Share/LoadMore.elm
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
{-
|
||||||
|
Copyright 2020 Eike K. & Contributors
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
-}
|
||||||
|
|
||||||
|
|
||||||
|
module Page.Share.LoadMore exposing (view)
|
||||||
|
|
||||||
|
import Comp.Basic as B
|
||||||
|
import Comp.ItemCardList
|
||||||
|
import Html exposing (Html, div)
|
||||||
|
import Html.Attributes exposing (class, href)
|
||||||
|
import Html.Events exposing (onClick)
|
||||||
|
import Messages.Page.Share exposing (Texts)
|
||||||
|
import Page.Share.Data exposing (Model, Msg(..))
|
||||||
|
|
||||||
|
|
||||||
|
view : Texts -> Model -> Html Msg
|
||||||
|
view texts model =
|
||||||
|
let
|
||||||
|
noMore =
|
||||||
|
requestedResultSize model > currentResultSize model
|
||||||
|
in
|
||||||
|
div [ class "py-8 flex flex-row items-center justify-center" ]
|
||||||
|
[ B.secondaryBasicButton
|
||||||
|
{ label =
|
||||||
|
if noMore then
|
||||||
|
texts.thatsAll
|
||||||
|
|
||||||
|
else
|
||||||
|
texts.loadMore
|
||||||
|
, icon =
|
||||||
|
if model.searchInProgress then
|
||||||
|
"fa fa-circle-notch animate-spin"
|
||||||
|
|
||||||
|
else
|
||||||
|
"fa fa-angle-double-down"
|
||||||
|
, disabled = noMore
|
||||||
|
, handler = onClick LoadNextPage
|
||||||
|
, attrs =
|
||||||
|
[ href "#"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
requestedResultSize : Model -> Int
|
||||||
|
requestedResultSize model =
|
||||||
|
model.viewMode.offset + model.viewMode.pageSize
|
||||||
|
|
||||||
|
|
||||||
|
currentResultSize : Model -> Int
|
||||||
|
currentResultSize model =
|
||||||
|
Comp.ItemCardList.size model.itemListModel
|
@ -16,7 +16,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick, onInput)
|
import Html.Events exposing (onClick, onInput)
|
||||||
import Messages.Page.Share exposing (Texts)
|
import Messages.Page.Share exposing (Texts)
|
||||||
import Page.Share.Data exposing (Model, Msg(..), SearchBarMode(..))
|
import Page.Share.Data exposing (Model, Msg(..), SearchBarMode(..), pageSizes)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.Html
|
import Util.Html
|
||||||
|
|
||||||
@ -95,7 +95,29 @@ view texts flags model =
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
, end =
|
, end =
|
||||||
[ MB.CustomElement <|
|
[ MB.Dropdown
|
||||||
|
{ linkIcon = "fa fa-caret-down"
|
||||||
|
, label = String.fromInt model.viewMode.pageSize
|
||||||
|
, linkClass =
|
||||||
|
[ ( S.secondaryBasicButton, True )
|
||||||
|
]
|
||||||
|
, toggleMenu = TogglePageSizeMenu
|
||||||
|
, menuOpen = model.viewMode.pageSizeMenuOpen
|
||||||
|
, items =
|
||||||
|
List.map
|
||||||
|
(\n ->
|
||||||
|
{ icon = i [] []
|
||||||
|
, label = String.fromInt n
|
||||||
|
, disabled = False
|
||||||
|
, attrs =
|
||||||
|
[ href "#"
|
||||||
|
, onClick (SetPageSize n)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
(pageSizes flags)
|
||||||
|
}
|
||||||
|
, MB.CustomElement <|
|
||||||
B.secondaryBasicButton
|
B.secondaryBasicButton
|
||||||
{ label = ""
|
{ label = ""
|
||||||
, icon =
|
, icon =
|
||||||
|
@ -23,7 +23,6 @@ import Page.Share.Data exposing (..)
|
|||||||
import Process
|
import Process
|
||||||
import Set
|
import Set
|
||||||
import Task
|
import Task
|
||||||
import Time
|
|
||||||
import Util.Html
|
import Util.Html
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
import Util.Update
|
import Util.Update
|
||||||
@ -49,7 +48,7 @@ update flags settings shareId msg model =
|
|||||||
, searchInProgress = True
|
, searchInProgress = True
|
||||||
}
|
}
|
||||||
, Cmd.batch
|
, Cmd.batch
|
||||||
[ makeSearchCmd flags True model
|
[ makeSearchCmd flags True False model
|
||||||
, Api.clientSettingsShare flags res.token UiSettingsResp
|
, Api.clientSettingsShare flags res.token UiSettingsResp
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ -82,6 +81,16 @@ update flags settings shareId msg model =
|
|||||||
SearchResp (Err err) ->
|
SearchResp (Err err) ->
|
||||||
noSub ( { model | pageError = PageErrorHttp err, searchInProgress = False }, Cmd.none )
|
noSub ( { model | pageError = PageErrorHttp err, searchInProgress = False }, Cmd.none )
|
||||||
|
|
||||||
|
AddSearchResp (Ok list) ->
|
||||||
|
update flags
|
||||||
|
settings
|
||||||
|
shareId
|
||||||
|
(ItemListMsg (Comp.ItemCardList.AddResults list))
|
||||||
|
{ model | searchInProgress = False, pageError = PageErrorNone }
|
||||||
|
|
||||||
|
AddSearchResp (Err err) ->
|
||||||
|
noSub ( { model | pageError = PageErrorHttp err, searchInProgress = False }, Cmd.none )
|
||||||
|
|
||||||
StatsResp doInit (Ok stats) ->
|
StatsResp doInit (Ok stats) ->
|
||||||
let
|
let
|
||||||
lm =
|
lm =
|
||||||
@ -121,18 +130,27 @@ update flags settings shareId msg model =
|
|||||||
res =
|
res =
|
||||||
Comp.SearchMenu.update flags settings lm model.searchMenuModel
|
Comp.SearchMenu.update flags settings lm model.searchMenuModel
|
||||||
|
|
||||||
nextModel =
|
vm =
|
||||||
|
model.viewMode
|
||||||
|
|
||||||
|
nextVm =
|
||||||
|
{ vm | offset = 0 }
|
||||||
|
|
||||||
|
nextModel1 =
|
||||||
{ model | searchMenuModel = res.model }
|
{ model | searchMenuModel = res.model }
|
||||||
|
|
||||||
( initSearch, searchCmd ) =
|
nextModelSearch =
|
||||||
|
{ nextModel1 | viewMode = nextVm }
|
||||||
|
|
||||||
|
( initSearch, searchCmd, model_ ) =
|
||||||
if res.stateChange && not model.searchInProgress then
|
if res.stateChange && not model.searchInProgress then
|
||||||
( True, makeSearchCmd flags False nextModel )
|
( True, makeSearchCmd flags False False nextModelSearch, nextModelSearch )
|
||||||
|
|
||||||
else
|
else
|
||||||
( False, Cmd.none )
|
( False, Cmd.none, nextModel1 )
|
||||||
in
|
in
|
||||||
noSub
|
noSub
|
||||||
( { nextModel | searchInProgress = initSearch }
|
( { model_ | searchInProgress = initSearch }
|
||||||
, Cmd.batch [ Cmd.map SearchMenuMsg res.cmd, searchCmd ]
|
, Cmd.batch [ Cmd.map SearchMenuMsg res.cmd, searchCmd ]
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -141,8 +159,14 @@ update flags settings shareId msg model =
|
|||||||
res =
|
res =
|
||||||
Comp.PowerSearchInput.update lm model.powerSearchInput
|
Comp.PowerSearchInput.update lm model.powerSearchInput
|
||||||
|
|
||||||
|
vm =
|
||||||
|
model.viewMode
|
||||||
|
|
||||||
|
nextVm =
|
||||||
|
{ vm | offset = 0 }
|
||||||
|
|
||||||
nextModel =
|
nextModel =
|
||||||
{ model | powerSearchInput = res.model }
|
{ model | powerSearchInput = res.model, viewMode = nextVm }
|
||||||
|
|
||||||
( initSearch, searchCmd ) =
|
( initSearch, searchCmd ) =
|
||||||
case res.action of
|
case res.action of
|
||||||
@ -150,7 +174,7 @@ update flags settings shareId msg model =
|
|||||||
( False, Cmd.none )
|
( False, Cmd.none )
|
||||||
|
|
||||||
Comp.PowerSearchInput.SubmitSearch ->
|
Comp.PowerSearchInput.SubmitSearch ->
|
||||||
( True, makeSearchCmd flags False nextModel )
|
( True, makeSearchCmd flags False False nextModel )
|
||||||
in
|
in
|
||||||
{ model = { nextModel | searchInProgress = initSearch }
|
{ model = { nextModel | searchInProgress = initSearch }
|
||||||
, cmd = Cmd.batch [ Cmd.map PowerSearchMsg res.cmd, searchCmd ]
|
, cmd = Cmd.batch [ Cmd.map PowerSearchMsg res.cmd, searchCmd ]
|
||||||
@ -159,11 +183,18 @@ update flags settings shareId msg model =
|
|||||||
|
|
||||||
ResetSearch ->
|
ResetSearch ->
|
||||||
let
|
let
|
||||||
|
vm =
|
||||||
|
model.viewMode
|
||||||
|
|
||||||
|
nextVm =
|
||||||
|
{ vm | offset = 0 }
|
||||||
|
|
||||||
nm =
|
nm =
|
||||||
{ model
|
{ model
|
||||||
| powerSearchInput = Comp.PowerSearchInput.init
|
| powerSearchInput = Comp.PowerSearchInput.init
|
||||||
, contentSearch = Nothing
|
, contentSearch = Nothing
|
||||||
, pageError = PageErrorNone
|
, pageError = PageErrorNone
|
||||||
|
, viewMode = nextVm
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
update flags settings shareId (SearchMenuMsg Comp.SearchMenu.ResetForm) nm
|
update flags settings shareId (SearchMenuMsg Comp.SearchMenu.ResetForm) nm
|
||||||
@ -215,7 +246,14 @@ update flags settings shareId msg model =
|
|||||||
noSub ( { model | contentSearch = Util.Maybe.fromString q }, Cmd.none )
|
noSub ( { model | contentSearch = Util.Maybe.fromString q }, Cmd.none )
|
||||||
|
|
||||||
ContentSearchKey (Just Util.Html.Enter) ->
|
ContentSearchKey (Just Util.Html.Enter) ->
|
||||||
noSub ( model, makeSearchCmd flags False model )
|
let
|
||||||
|
vm =
|
||||||
|
model.viewMode
|
||||||
|
|
||||||
|
nextVm =
|
||||||
|
{ vm | offset = 0 }
|
||||||
|
in
|
||||||
|
noSub ( { model | viewMode = nextVm, searchInProgress = True }, makeSearchCmd flags False False model )
|
||||||
|
|
||||||
ContentSearchKey _ ->
|
ContentSearchKey _ ->
|
||||||
noSub ( model, Cmd.none )
|
noSub ( model, Cmd.none )
|
||||||
@ -240,6 +278,16 @@ update flags settings shareId msg model =
|
|||||||
in
|
in
|
||||||
noSub ( { model | viewMode = next }, Cmd.none )
|
noSub ( { model | viewMode = next }, Cmd.none )
|
||||||
|
|
||||||
|
TogglePageSizeMenu ->
|
||||||
|
let
|
||||||
|
vm =
|
||||||
|
model.viewMode
|
||||||
|
|
||||||
|
next =
|
||||||
|
{ vm | pageSizeMenuOpen = not vm.pageSizeMenuOpen }
|
||||||
|
in
|
||||||
|
noSub ( { model | viewMode = next }, Cmd.none )
|
||||||
|
|
||||||
ToggleArrange am ->
|
ToggleArrange am ->
|
||||||
let
|
let
|
||||||
vm =
|
vm =
|
||||||
@ -318,6 +366,29 @@ update flags settings shareId msg model =
|
|||||||
TopContentDownload _ ->
|
TopContentDownload _ ->
|
||||||
noSub ( { model | topContent = TopContentHidden, viewMode = nextVm }, Cmd.none )
|
noSub ( { model | topContent = TopContentHidden, viewMode = nextVm }, Cmd.none )
|
||||||
|
|
||||||
|
SetPageSize n ->
|
||||||
|
let
|
||||||
|
vm =
|
||||||
|
model.viewMode
|
||||||
|
|
||||||
|
next =
|
||||||
|
{ vm | pageSize = n, pageSizeMenuOpen = False }
|
||||||
|
in
|
||||||
|
noSub ( { model | viewMode = next }, Cmd.none )
|
||||||
|
|
||||||
|
LoadNextPage ->
|
||||||
|
let
|
||||||
|
vm =
|
||||||
|
model.viewMode
|
||||||
|
|
||||||
|
nextVm =
|
||||||
|
{ vm | offset = vm.offset + vm.pageSize }
|
||||||
|
|
||||||
|
nextModel =
|
||||||
|
{ model | viewMode = nextVm, searchInProgress = True }
|
||||||
|
in
|
||||||
|
noSub ( nextModel, makeSearchCmd flags False True nextModel )
|
||||||
|
|
||||||
|
|
||||||
noSub : ( Model, Cmd Msg ) -> UpdateResult
|
noSub : ( Model, Cmd Msg ) -> UpdateResult
|
||||||
noSub ( m, c ) =
|
noSub ( m, c ) =
|
||||||
@ -342,22 +413,30 @@ createQuery flags model =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
makeSearchCmd : Flags -> Bool -> Model -> Cmd Msg
|
makeSearchCmd : Flags -> Bool -> Bool -> Model -> Cmd Msg
|
||||||
makeSearchCmd flags doInit model =
|
makeSearchCmd flags doInit addResults model =
|
||||||
let
|
let
|
||||||
xq =
|
xq =
|
||||||
createQuery flags model
|
createQuery flags model
|
||||||
|
|
||||||
request mq =
|
request mq =
|
||||||
{ offset = Nothing
|
{ offset = Just model.viewMode.offset
|
||||||
, limit = Nothing
|
, limit = Just model.viewMode.pageSize
|
||||||
, withDetails = Just True
|
, withDetails = Just True
|
||||||
, query = Q.renderMaybe mq
|
, query = Q.renderMaybe mq
|
||||||
, searchMode = Just (Data.SearchMode.asString Data.SearchMode.Normal)
|
, searchMode = Just (Data.SearchMode.asString Data.SearchMode.Normal)
|
||||||
}
|
}
|
||||||
|
|
||||||
searchCmd =
|
searchCmd =
|
||||||
Api.searchShare flags model.verifyResult.token (request xq) SearchResp
|
Api.searchShare flags
|
||||||
|
model.verifyResult.token
|
||||||
|
(request xq)
|
||||||
|
(if addResults then
|
||||||
|
AddSearchResp
|
||||||
|
|
||||||
|
else
|
||||||
|
SearchResp
|
||||||
|
)
|
||||||
|
|
||||||
statsCmd =
|
statsCmd =
|
||||||
Api.searchShareStats flags model.verifyResult.token (request xq) (StatsResp doInit)
|
Api.searchShareStats flags model.verifyResult.token (request xq) (StatsResp doInit)
|
||||||
|
@ -16,6 +16,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Messages.Page.Share exposing (Texts)
|
import Messages.Page.Share exposing (Texts)
|
||||||
import Page.Share.Data exposing (..)
|
import Page.Share.Data exposing (..)
|
||||||
|
import Page.Share.LoadMore as LoadMore
|
||||||
import Page.Share.Menubar as Menubar
|
import Page.Share.Menubar as Menubar
|
||||||
import Page.Share.Results as Results
|
import Page.Share.Results as Results
|
||||||
import Page.Share.Sidebar as Sidebar
|
import Page.Share.Sidebar as Sidebar
|
||||||
@ -83,6 +84,7 @@ mainContent texts flags shareId model =
|
|||||||
, errorMessage texts model
|
, errorMessage texts model
|
||||||
, TopContent.view texts flags model
|
, TopContent.view texts flags model
|
||||||
, Results.view texts model.uiSettings flags shareId model
|
, Results.view texts model.uiSettings flags shareId model
|
||||||
|
, LoadMore.view texts model
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user