mirror of
https://github.com/jhillyerd/inbucket.git
synced 2026-08-08 13:38:52 +00:00
Merge branch 'release/3.0.0-rc1'
This commit is contained in:
@@ -0,0 +1,44 @@
|
|||||||
|
name: Build and Release
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "master", "develop" ]
|
||||||
|
tags: [ "v*" ]
|
||||||
|
pull_request:
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Setup Go
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: 1.15
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: '10.x'
|
||||||
|
- name: Setup Elm
|
||||||
|
uses: jorelali/setup-elm@v2
|
||||||
|
with:
|
||||||
|
elm-version: 0.19.1
|
||||||
|
- name: Build frontend
|
||||||
|
run: |
|
||||||
|
npm ci
|
||||||
|
npm run build
|
||||||
|
working-directory: ./ui
|
||||||
|
- name: Test build release
|
||||||
|
uses: goreleaser/goreleaser-action@v2
|
||||||
|
if: "!startsWith(github.ref, 'refs/tags/v')"
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
args: release --snapshot
|
||||||
|
- name: Build and publish release
|
||||||
|
uses: goreleaser/goreleaser-action@v2
|
||||||
|
if: "startsWith(github.ref, 'refs/tags/v')"
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
args: release
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
-16
@@ -25,22 +25,6 @@ jobs:
|
|||||||
script:
|
script:
|
||||||
- "elm-format --validate ."
|
- "elm-format --validate ."
|
||||||
- "npm run build"
|
- "npm run build"
|
||||||
- stage: deploy
|
|
||||||
go: "1.15.x"
|
|
||||||
before_install:
|
|
||||||
- "nvm install 10.19.0"
|
|
||||||
install:
|
|
||||||
- "cd ui"
|
|
||||||
- "npm ci"
|
|
||||||
- "npm run build"
|
|
||||||
- "cd .."
|
|
||||||
script: "curl -sL https://git.io/goreleaser | bash"
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- rpm
|
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- test
|
- test
|
||||||
- name: deploy
|
|
||||||
if: tag IS present
|
|
||||||
|
|||||||
@@ -4,6 +4,17 @@ Change Log
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
## [v3.0.0-rc1]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Refresh button to reload mailbox contents
|
||||||
|
- Improved keyboard (tab) focus highlights
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- The UI now includes the Open Sans webfont instead of relying on browser/OS
|
||||||
|
fonts
|
||||||
|
|
||||||
|
|
||||||
## [v3.0.0-beta3]
|
## [v3.0.0-beta3]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@@ -228,6 +239,7 @@ No change from beta1.
|
|||||||
specific message.
|
specific message.
|
||||||
|
|
||||||
[Unreleased]: https://github.com/inbucket/inbucket/compare/master...develop
|
[Unreleased]: https://github.com/inbucket/inbucket/compare/master...develop
|
||||||
|
[v3.0.0-rc1]: https://github.com/inbucket/inbucket/compare/v3.0.0-beta3...v3.0.0-rc1
|
||||||
[v3.0.0-beta3]: https://github.com/inbucket/inbucket/compare/v3.0.0-beta2...v3.0.0-beta3
|
[v3.0.0-beta3]: https://github.com/inbucket/inbucket/compare/v3.0.0-beta2...v3.0.0-beta3
|
||||||
[v3.0.0-beta2]: https://github.com/inbucket/inbucket/compare/v3.0.0-beta1...v3.0.0-beta2
|
[v3.0.0-beta2]: https://github.com/inbucket/inbucket/compare/v3.0.0-beta1...v3.0.0-beta2
|
||||||
[v3.0.0-beta1]: https://github.com/inbucket/inbucket/compare/v2.1.0...v3.0.0-beta1
|
[v3.0.0-beta1]: https://github.com/inbucket/inbucket/compare/v2.1.0...v3.0.0-beta1
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
Inbucket
|
Inbucket
|
||||||
=============================================================================
|
=============================================================================
|
||||||
[][Build Status]
|
[][Build Status]
|
||||||
|
[][Docker Image]
|
||||||
|
|
||||||
Inbucket is an email testing service; it will accept messages for any email
|
Inbucket is an email testing service; it will accept messages for any email
|
||||||
address and make them available via web, REST and POP3. Once compiled,
|
address and make them available via web, REST and POP3 interfaces. Once
|
||||||
Inbucket does not have any external dependencies (HTTP, SMTP, POP3 and storage
|
compiled, Inbucket does not have any external dependencies - HTTP, SMTP, POP3
|
||||||
are all built in).
|
and storage are all built in.
|
||||||
|
|
||||||
A Go client for the REST API is available in
|
A Go client for the REST API is available in
|
||||||
`github.com/inbucket/inbucket/pkg/rest/client` - [Go API docs]
|
`github.com/inbucket/inbucket/pkg/rest/client` - [Go API docs]
|
||||||
@@ -14,6 +15,7 @@ Read more at the [Inbucket Website]
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## Development Status
|
## Development Status
|
||||||
|
|
||||||
Inbucket is currently production quality: it is being used for real work.
|
Inbucket is currently production quality: it is being used for real work.
|
||||||
@@ -29,15 +31,6 @@ tracks our `master` branch (releases), `latest` tracks our unstable
|
|||||||
`development` branch.
|
`development` branch.
|
||||||
|
|
||||||
|
|
||||||
## Homebrew Tap
|
|
||||||
|
|
||||||
(currently broken, being tracked in [issue
|
|
||||||
#68](https://github.com/inbucket/inbucket/issues/68))
|
|
||||||
|
|
||||||
Inbucket has an OS X [Homebrew] tap available as [jhillyerd/inbucket][Homebrew Tap],
|
|
||||||
see the `README.md` there for installation instructions.
|
|
||||||
|
|
||||||
|
|
||||||
## Building from Source
|
## Building from Source
|
||||||
|
|
||||||
You will need functioning [Go] and [Node.js] installations for this to work.
|
You will need functioning [Go] and [Node.js] installations for this to work.
|
||||||
@@ -45,17 +38,20 @@ You will need functioning [Go] and [Node.js] installations for this to work.
|
|||||||
```sh
|
```sh
|
||||||
git clone https://github.com/inbucket/inbucket.git
|
git clone https://github.com/inbucket/inbucket.git
|
||||||
cd inbucket/ui
|
cd inbucket/ui
|
||||||
npm i
|
npm ci
|
||||||
npm run build
|
npm run build
|
||||||
cd ..
|
cd ..
|
||||||
go build ./cmd/inbucket
|
go build ./cmd/inbucket
|
||||||
```
|
```
|
||||||
|
|
||||||
_Note:_ You may also use the included Makefile to build and test the Go binaries.
|
For more information on building and development flows, check out the
|
||||||
|
[Development Quickstart] page of our wiki.
|
||||||
|
|
||||||
|
### Configure and Launch
|
||||||
|
|
||||||
Inbucket reads its configuration from environment variables, but comes with
|
Inbucket reads its configuration from environment variables, but comes with
|
||||||
built in sane defaults. It should work on most Unix and OS X machines as is.
|
reasonable defaults built-in. It should work on most Unix and OS X machines as
|
||||||
Launch the daemon:
|
is. Launch the daemon:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./inbucket
|
./inbucket
|
||||||
@@ -65,27 +61,29 @@ By default the SMTP server will be listening on localhost port 2500 and
|
|||||||
the web interface will be available at [localhost:9000](http://localhost:9000/).
|
the web interface will be available at [localhost:9000](http://localhost:9000/).
|
||||||
|
|
||||||
See doc/[config.md] for more information on configuring Inbucket, but you will
|
See doc/[config.md] for more information on configuring Inbucket, but you will
|
||||||
likely find the [Configurator] tool easier to use.
|
likely find the [Configurator] tool the easiest way to generate a configuration.
|
||||||
|
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
Inbucket is written in [Go]
|
Inbucket is written in [Go] and [Elm].
|
||||||
|
|
||||||
Inbucket is open source software released under the MIT License. The latest
|
Inbucket is open source software released under the MIT License. The latest
|
||||||
version can be found at https://github.com/inbucket/inbucket
|
version can be found at https://github.com/inbucket/inbucket
|
||||||
|
|
||||||
[Build Status]: https://travis-ci.org/inbucket/inbucket
|
[Build Status]: https://travis-ci.org/inbucket/inbucket
|
||||||
[Change Log]: https://github.com/inbucket/inbucket/blob/master/CHANGELOG.md
|
[Change Log]: https://github.com/inbucket/inbucket/blob/master/CHANGELOG.md
|
||||||
[config.md]: https://github.com/inbucket/inbucket/blob/master/doc/config.md
|
[config.md]: https://github.com/inbucket/inbucket/blob/master/doc/config.md
|
||||||
[Configurator]: https://www.inbucket.org/configurator/
|
[Configurator]: https://www.inbucket.org/configurator/
|
||||||
[CONTRIBUTING.md]: https://github.com/inbucket/inbucket/blob/develop/CONTRIBUTING.md
|
[CONTRIBUTING.md]: https://github.com/inbucket/inbucket/blob/develop/CONTRIBUTING.md
|
||||||
[Docker Image]: https://www.inbucket.org/binaries/docker.html
|
[Development Quickstart]: https://github.com/inbucket/inbucket/wiki/Development-Quickstart
|
||||||
[From Source]: https://www.inbucket.org/installation/from-source.html
|
[Docker Image]: https://www.inbucket.org/binaries/docker.html
|
||||||
[Go]: https://golang.org/
|
[Elm]: https://elm-lang.org/
|
||||||
[Go API docs]: https://godoc.org/github.com/inbucket/inbucket/pkg/rest/client
|
[From Source]: https://www.inbucket.org/installation/from-source.html
|
||||||
[Homebrew]: http://brew.sh/
|
[Go]: https://golang.org/
|
||||||
[Homebrew Tap]: https://github.com/inbucket/homebrew-inbucket
|
[Go API docs]: https://pkg.go.dev/github.com/inbucket/inbucket/pkg/rest/client
|
||||||
[Inbucket Website]: https://www.inbucket.org/
|
[Homebrew]: http://brew.sh/
|
||||||
[Issues List]: https://github.com/inbucket/inbucket/issues?state=open
|
[Homebrew Tap]: https://github.com/inbucket/homebrew-inbucket
|
||||||
[Node.js]: https://nodejs.org/en/
|
[Inbucket Website]: https://www.inbucket.org/
|
||||||
|
[Issues List]: https://github.com/inbucket/inbucket/issues?state=open
|
||||||
|
[Node.js]: https://nodejs.org/en/
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ require (
|
|||||||
github.com/microcosm-cc/bluemonday v1.0.4
|
github.com/microcosm-cc/bluemonday v1.0.4
|
||||||
github.com/olekukonko/tablewriter v0.0.4 // indirect
|
github.com/olekukonko/tablewriter v0.0.4 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/rs/zerolog v1.19.0
|
github.com/rs/zerolog v1.20.0
|
||||||
github.com/stretchr/testify v1.6.1
|
github.com/stretchr/testify v1.6.1
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202
|
golang.org/x/net v0.0.0-20200923182212-328152dc79b1
|
||||||
golang.org/x/text v0.3.3 // indirect
|
golang.org/x/text v0.3.3 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||||
github.com/rs/zerolog v1.19.0 h1:hYz4ZVdUgjXTBUmrkrw55j1nHx68LfOKIQk5IYtyScg=
|
github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs=
|
||||||
github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo=
|
github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo=
|
||||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
|
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
|
||||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
|
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
|
||||||
@@ -66,8 +66,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
golang.org/x/net v0.0.0-20200923182212-328152dc79b1 h1:Iu68XRPd67wN4aRGGWwwq6bZo/25jR6uu52l/j2KkUE=
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200923182212-328152dc79b1/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
|||||||
Generated
+224
-257
@@ -25,19 +25,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/core": {
|
"@babel/core": {
|
||||||
"version": "7.11.4",
|
"version": "7.11.6",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.4.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.6.tgz",
|
||||||
"integrity": "sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg==",
|
"integrity": "sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/code-frame": "^7.10.4",
|
"@babel/code-frame": "^7.10.4",
|
||||||
"@babel/generator": "^7.11.4",
|
"@babel/generator": "^7.11.6",
|
||||||
"@babel/helper-module-transforms": "^7.11.0",
|
"@babel/helper-module-transforms": "^7.11.0",
|
||||||
"@babel/helpers": "^7.10.4",
|
"@babel/helpers": "^7.10.4",
|
||||||
"@babel/parser": "^7.11.4",
|
"@babel/parser": "^7.11.5",
|
||||||
"@babel/template": "^7.10.4",
|
"@babel/template": "^7.10.4",
|
||||||
"@babel/traverse": "^7.11.0",
|
"@babel/traverse": "^7.11.5",
|
||||||
"@babel/types": "^7.11.0",
|
"@babel/types": "^7.11.5",
|
||||||
"convert-source-map": "^1.7.0",
|
"convert-source-map": "^1.7.0",
|
||||||
"debug": "^4.1.0",
|
"debug": "^4.1.0",
|
||||||
"gensync": "^1.0.0-beta.1",
|
"gensync": "^1.0.0-beta.1",
|
||||||
@@ -46,23 +46,15 @@
|
|||||||
"resolve": "^1.3.2",
|
"resolve": "^1.3.2",
|
||||||
"semver": "^5.4.1",
|
"semver": "^5.4.1",
|
||||||
"source-map": "^0.5.0"
|
"source-map": "^0.5.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.20",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
|
||||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/generator": {
|
"@babel/generator": {
|
||||||
"version": "7.11.4",
|
"version": "7.11.6",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.6.tgz",
|
||||||
"integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==",
|
"integrity": "sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/types": "^7.11.0",
|
"@babel/types": "^7.11.5",
|
||||||
"jsesc": "^2.5.1",
|
"jsesc": "^2.5.1",
|
||||||
"source-map": "^0.5.0"
|
"source-map": "^0.5.0"
|
||||||
}
|
}
|
||||||
@@ -133,14 +125,6 @@
|
|||||||
"@babel/helper-function-name": "^7.10.4",
|
"@babel/helper-function-name": "^7.10.4",
|
||||||
"@babel/types": "^7.10.5",
|
"@babel/types": "^7.10.5",
|
||||||
"lodash": "^4.17.19"
|
"lodash": "^4.17.19"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.20",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
|
||||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/helper-explode-assignable-expression": {
|
"@babel/helper-explode-assignable-expression": {
|
||||||
@@ -212,14 +196,6 @@
|
|||||||
"@babel/template": "^7.10.4",
|
"@babel/template": "^7.10.4",
|
||||||
"@babel/types": "^7.11.0",
|
"@babel/types": "^7.11.0",
|
||||||
"lodash": "^4.17.19"
|
"lodash": "^4.17.19"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.20",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
|
||||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/helper-optimise-call-expression": {
|
"@babel/helper-optimise-call-expression": {
|
||||||
@@ -244,14 +220,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"lodash": "^4.17.19"
|
"lodash": "^4.17.19"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.20",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
|
||||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/helper-remap-async-to-generator": {
|
"@babel/helper-remap-async-to-generator": {
|
||||||
@@ -347,9 +315,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/parser": {
|
"@babel/parser": {
|
||||||
"version": "7.11.4",
|
"version": "7.11.5",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz",
|
||||||
"integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==",
|
"integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@babel/plugin-proposal-async-generator-functions": {
|
"@babel/plugin-proposal-async-generator-functions": {
|
||||||
@@ -909,9 +877,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/preset-env": {
|
"@babel/preset-env": {
|
||||||
"version": "7.11.0",
|
"version": "7.11.5",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.5.tgz",
|
||||||
"integrity": "sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg==",
|
"integrity": "sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/compat-data": "^7.11.0",
|
"@babel/compat-data": "^7.11.0",
|
||||||
@@ -976,7 +944,7 @@
|
|||||||
"@babel/plugin-transform-unicode-escapes": "^7.10.4",
|
"@babel/plugin-transform-unicode-escapes": "^7.10.4",
|
||||||
"@babel/plugin-transform-unicode-regex": "^7.10.4",
|
"@babel/plugin-transform-unicode-regex": "^7.10.4",
|
||||||
"@babel/preset-modules": "^0.1.3",
|
"@babel/preset-modules": "^0.1.3",
|
||||||
"@babel/types": "^7.11.0",
|
"@babel/types": "^7.11.5",
|
||||||
"browserslist": "^4.12.0",
|
"browserslist": "^4.12.0",
|
||||||
"core-js-compat": "^3.6.2",
|
"core-js-compat": "^3.6.2",
|
||||||
"invariant": "^2.2.2",
|
"invariant": "^2.2.2",
|
||||||
@@ -1018,47 +986,31 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/traverse": {
|
"@babel/traverse": {
|
||||||
"version": "7.11.0",
|
"version": "7.11.5",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz",
|
||||||
"integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==",
|
"integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/code-frame": "^7.10.4",
|
"@babel/code-frame": "^7.10.4",
|
||||||
"@babel/generator": "^7.11.0",
|
"@babel/generator": "^7.11.5",
|
||||||
"@babel/helper-function-name": "^7.10.4",
|
"@babel/helper-function-name": "^7.10.4",
|
||||||
"@babel/helper-split-export-declaration": "^7.11.0",
|
"@babel/helper-split-export-declaration": "^7.11.0",
|
||||||
"@babel/parser": "^7.11.0",
|
"@babel/parser": "^7.11.5",
|
||||||
"@babel/types": "^7.11.0",
|
"@babel/types": "^7.11.5",
|
||||||
"debug": "^4.1.0",
|
"debug": "^4.1.0",
|
||||||
"globals": "^11.1.0",
|
"globals": "^11.1.0",
|
||||||
"lodash": "^4.17.19"
|
"lodash": "^4.17.19"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.20",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
|
||||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/types": {
|
"@babel/types": {
|
||||||
"version": "7.11.0",
|
"version": "7.11.5",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz",
|
||||||
"integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
|
"integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/helper-validator-identifier": "^7.10.4",
|
"@babel/helper-validator-identifier": "^7.10.4",
|
||||||
"lodash": "^4.17.19",
|
"lodash": "^4.17.19",
|
||||||
"to-fast-properties": "^2.0.0"
|
"to-fast-properties": "^2.0.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.20",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
|
||||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@fortawesome/fontawesome-free": {
|
"@fortawesome/fontawesome-free": {
|
||||||
@@ -1084,9 +1036,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/html-minifier-terser": {
|
"@types/html-minifier-terser": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz",
|
||||||
"integrity": "sha512-iYCgjm1dGPRuo12+BStjd1HiVQqhlRhWDOQigNxn023HcjnhsiFz9pc6CzJj4HwDCSQca9bxTL4PxJDbkdm3PA==",
|
"integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/json-schema": {
|
"@types/json-schema": {
|
||||||
@@ -1137,9 +1089,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/webpack": {
|
"@types/webpack": {
|
||||||
"version": "4.41.21",
|
"version": "4.41.22",
|
||||||
"resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.21.tgz",
|
"resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.22.tgz",
|
||||||
"integrity": "sha512-2j9WVnNrr/8PLAB5csW44xzQSJwS26aOnICsP3pSGCEdsu6KYtfQ6QJsVUKHWRnm1bL7HziJsfh5fHqth87yKA==",
|
"integrity": "sha512-JQDJK6pj8OMV9gWOnN1dcLCyU9Hzs6lux0wBO4lr1+gyEhIBR9U3FMrz12t2GPkg110XAxEAw2WHF6g7nZIbRQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/anymatch": "*",
|
"@types/anymatch": "*",
|
||||||
@@ -1762,6 +1714,16 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"bindings": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"file-uri-to-path": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"bluebird": {
|
"bluebird": {
|
||||||
"version": "3.7.2",
|
"version": "3.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||||
@@ -1987,15 +1949,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"version": "4.14.0",
|
"version": "4.14.4",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.4.tgz",
|
||||||
"integrity": "sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==",
|
"integrity": "sha512-7FOuawafVdEwa5Jv4nzeik/PepAjVte6HmVGHsjt2bC237jeL9QlcTBDF3PnHEvcC6uHwLGYPwZHNZMB7wWAnw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"caniuse-lite": "^1.0.30001111",
|
"caniuse-lite": "^1.0.30001135",
|
||||||
"electron-to-chromium": "^1.3.523",
|
"electron-to-chromium": "^1.3.570",
|
||||||
"escalade": "^3.0.2",
|
"escalade": "^3.1.0",
|
||||||
"node-releases": "^1.1.60"
|
"node-releases": "^1.1.61"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"buffer": {
|
"buffer": {
|
||||||
@@ -2075,12 +2037,6 @@
|
|||||||
"once": "^1.3.0",
|
"once": "^1.3.0",
|
||||||
"path-is-absolute": "^1.0.0"
|
"path-is-absolute": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"y18n": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2111,10 +2067,16 @@
|
|||||||
"tslib": "^1.10.0"
|
"tslib": "^1.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"camelcase": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"caniuse-lite": {
|
"caniuse-lite": {
|
||||||
"version": "1.0.30001120",
|
"version": "1.0.30001135",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001120.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001135.tgz",
|
||||||
"integrity": "sha512-JBP68okZs1X8D7MQTY602jxMYBmXEKOFkzTBaNSkubooMPFOAv2TXWaKle7qgHpjLDhUzA/TMT0qsNleVyXGUQ==",
|
"integrity": "sha512-ziNcheTGTHlu9g34EVoHQdIu5g4foc8EsxMGC7Xkokmvw0dqNtX8BS8RgCgFBaAiSp2IdjvBxNdh0ssib28eVQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"chalk": {
|
"chalk": {
|
||||||
@@ -2527,9 +2489,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"css-loader": {
|
"css-loader": {
|
||||||
"version": "4.2.2",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz",
|
||||||
"integrity": "sha512-omVGsTkZPVwVRpckeUnLshPp12KsmMSLqYxs12+RzM9jRR5Y+Idn/tBffjXRvOE+qW7if24cuceFJqYR5FmGBg==",
|
"integrity": "sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"camelcase": "^6.0.0",
|
"camelcase": "^6.0.0",
|
||||||
@@ -2542,14 +2504,14 @@
|
|||||||
"postcss-modules-scope": "^2.2.0",
|
"postcss-modules-scope": "^2.2.0",
|
||||||
"postcss-modules-values": "^3.0.0",
|
"postcss-modules-values": "^3.0.0",
|
||||||
"postcss-value-parser": "^4.1.0",
|
"postcss-value-parser": "^4.1.0",
|
||||||
"schema-utils": "^2.7.0",
|
"schema-utils": "^2.7.1",
|
||||||
"semver": "^7.3.2"
|
"semver": "^7.3.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": {
|
"ajv": {
|
||||||
"version": "6.12.4",
|
"version": "6.12.5",
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz",
|
||||||
"integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==",
|
"integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"fast-deep-equal": "^3.1.1",
|
"fast-deep-equal": "^3.1.1",
|
||||||
@@ -2564,50 +2526,21 @@
|
|||||||
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"big.js": {
|
|
||||||
"version": "5.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
|
|
||||||
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"camelcase": {
|
|
||||||
"version": "6.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz",
|
|
||||||
"integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"emojis-list": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"fast-deep-equal": {
|
"fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"loader-utils": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"big.js": "^5.2.2",
|
|
||||||
"emojis-list": "^3.0.0",
|
|
||||||
"json5": "^2.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"schema-utils": {
|
"schema-utils": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
|
||||||
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
|
"integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/json-schema": "^7.0.4",
|
"@types/json-schema": "^7.0.5",
|
||||||
"ajv": "^6.12.2",
|
"ajv": "^6.12.4",
|
||||||
"ajv-keywords": "^3.4.1"
|
"ajv-keywords": "^3.5.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
@@ -2864,9 +2797,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"domelementtype": {
|
"domelementtype": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.2.tgz",
|
||||||
"integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==",
|
"integrity": "sha512-wFwTwCVebUrMgGeAwRL/NhZtHAUyT9n9yg4IMDwf10+6iCMxSkVq9MGCVEH+QZWo1nNidy8kNvwmv4zWHDTqvA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2931,9 +2864,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"electron-to-chromium": {
|
"electron-to-chromium": {
|
||||||
"version": "1.3.555",
|
"version": "1.3.571",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.555.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.571.tgz",
|
||||||
"integrity": "sha512-/55x3nF2feXFZ5tdGUOr00TxnUjUgdxhrn+eCJ1FAcoAt+cKQTjQkUC5XF4frMWE1R5sjHk+JueuBalimfe5Pg==",
|
"integrity": "sha512-UYEQ2Gtc50kqmyOmOVtj6Oqi38lm5yRJY3pLuWt6UIot0No1L09uu6Ja6/1XKwmz/p0eJFZTUZi+khd1PV1hHA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"elliptic": {
|
"elliptic": {
|
||||||
@@ -3019,9 +2952,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"emojis-list": {
|
"emojis-list": {
|
||||||
"version": "2.1.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
|
||||||
"integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
|
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"encodeurl": {
|
"encodeurl": {
|
||||||
@@ -3131,9 +3064,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"escalade": {
|
"escalade": {
|
||||||
"version": "3.0.2",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.0.tgz",
|
||||||
"integrity": "sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==",
|
"integrity": "sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"escape-html": {
|
"escape-html": {
|
||||||
@@ -3159,12 +3092,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"esrecurse": {
|
"esrecurse": {
|
||||||
"version": "4.2.1",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
|
||||||
"integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
|
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"estraverse": "^4.1.0"
|
"estraverse": "^5.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"estraverse": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"estraverse": {
|
"estraverse": {
|
||||||
@@ -3174,9 +3115,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"esutils": {
|
"esutils": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
||||||
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
|
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"etag": {
|
"etag": {
|
||||||
@@ -3465,19 +3406,19 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"file-loader": {
|
"file-loader": {
|
||||||
"version": "6.0.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.1.0.tgz",
|
||||||
"integrity": "sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ==",
|
"integrity": "sha512-26qPdHyTsArQ6gU4P1HJbAbnFTyT2r0pG7czh1GFAd9TZbj0n94wWbupgixZH/ET/meqi2/5+F7DhW4OAXD+Lg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"loader-utils": "^2.0.0",
|
"loader-utils": "^2.0.0",
|
||||||
"schema-utils": "^2.6.5"
|
"schema-utils": "^2.7.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": {
|
"ajv": {
|
||||||
"version": "6.12.4",
|
"version": "6.12.5",
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz",
|
||||||
"integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==",
|
"integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"fast-deep-equal": "^3.1.1",
|
"fast-deep-equal": "^3.1.1",
|
||||||
@@ -3492,48 +3433,32 @@
|
|||||||
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"big.js": {
|
|
||||||
"version": "5.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
|
|
||||||
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"emojis-list": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"fast-deep-equal": {
|
"fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"loader-utils": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"big.js": "^5.2.2",
|
|
||||||
"emojis-list": "^3.0.0",
|
|
||||||
"json5": "^2.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"schema-utils": {
|
"schema-utils": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
|
||||||
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
|
"integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/json-schema": "^7.0.4",
|
"@types/json-schema": "^7.0.5",
|
||||||
"ajv": "^6.12.2",
|
"ajv": "^6.12.4",
|
||||||
"ajv-keywords": "^3.4.1"
|
"ajv-keywords": "^3.5.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"file-uri-to-path": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"fill-range": {
|
"fill-range": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
||||||
@@ -4007,9 +3932,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"html-webpack-plugin": {
|
"html-webpack-plugin": {
|
||||||
"version": "4.4.1",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz",
|
||||||
"integrity": "sha512-nEtdEIsIGXdXGG7MjTTZlmhqhpHU9pJFc1OYxcP36c5/ZKP6b0BJMww2QTvJGQYA9aMxUnjDujpZdYcVOXiBCQ==",
|
"integrity": "sha512-MouoXEYSjTzCrjIxWwg8gxL5fE2X2WZJLmBYXlaJhQUH5K/b5OrqmV7T4dB7iu0xkmJ6JlUuV6fFVtnqbPopZw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/html-minifier-terser": "^5.0.0",
|
"@types/html-minifier-terser": "^5.0.0",
|
||||||
@@ -4023,6 +3948,26 @@
|
|||||||
"util.promisify": "1.0.0"
|
"util.promisify": "1.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"json5": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"loader-utils": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"big.js": "^5.2.2",
|
||||||
|
"emojis-list": "^3.0.0",
|
||||||
|
"json5": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tapable": {
|
"tapable": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
|
||||||
@@ -4284,9 +4229,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"is-callable": {
|
"is-callable": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
|
||||||
"integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==",
|
"integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"is-data-descriptor": {
|
"is-data-descriptor": {
|
||||||
@@ -4535,39 +4480,14 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"loader-utils": {
|
"loader-utils": {
|
||||||
"version": "1.2.3",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
|
||||||
"integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
|
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"big.js": "^5.2.2",
|
"big.js": "^5.2.2",
|
||||||
"emojis-list": "^2.0.0",
|
"emojis-list": "^3.0.0",
|
||||||
"json5": "^1.0.1"
|
"json5": "^2.1.2"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"big.js": {
|
|
||||||
"version": "5.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
|
|
||||||
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"json5": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"minimist": "^1.2.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"minimist": {
|
|
||||||
"version": "1.2.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"locate-path": {
|
"locate-path": {
|
||||||
@@ -4862,6 +4782,13 @@
|
|||||||
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
|
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"nan": {
|
||||||
|
"version": "2.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
|
||||||
|
"integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"nanomatch": {
|
"nanomatch": {
|
||||||
"version": "1.2.13",
|
"version": "1.2.13",
|
||||||
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
|
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
|
||||||
@@ -4975,9 +4902,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node-releases": {
|
"node-releases": {
|
||||||
"version": "1.1.60",
|
"version": "1.1.61",
|
||||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz",
|
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.61.tgz",
|
||||||
"integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==",
|
"integrity": "sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"normalize-path": {
|
"normalize-path": {
|
||||||
@@ -5192,6 +5119,11 @@
|
|||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"opensans-npm-webfont": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/opensans-npm-webfont/-/opensans-npm-webfont-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-2ehgrX+NpoxLOil30tYGr0cDsDXSJn9gon6PfM1Ki0CxZF6ui9Mi6Dm5DGglKyK2QiX0gMb6Ch7VmRHwfc4M6Q=="
|
||||||
|
},
|
||||||
"opn": {
|
"opn": {
|
||||||
"version": "5.5.0",
|
"version": "5.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
|
||||||
@@ -5465,9 +5397,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"postcss": {
|
"postcss": {
|
||||||
"version": "7.0.32",
|
"version": "7.0.34",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.34.tgz",
|
||||||
"integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==",
|
"integrity": "sha512-H/7V2VeNScX9KE83GDrDZNiGT1m2H+UTnlinIzhjlLX9hfMUn1mHNnGeX81a1c8JSBdBvqk7c2ZOG6ZPn5itGw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"chalk": "^2.4.2",
|
"chalk": "^2.4.2",
|
||||||
@@ -5534,14 +5466,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"postcss-selector-parser": {
|
"postcss-selector-parser": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.3.tgz",
|
||||||
"integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==",
|
"integrity": "sha512-0ClFaY4X1ra21LRqbW6y3rUbWcxnSVkDFG57R7Nxus9J9myPFlv+jYDMohzpkBx0RrjjiqjtycpchQ+PLGmZ9w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"cssesc": "^3.0.0",
|
"cssesc": "^3.0.0",
|
||||||
"indexes-of": "^1.0.1",
|
"indexes-of": "^1.0.1",
|
||||||
"uniq": "^1.0.1"
|
"uniq": "^1.0.1",
|
||||||
|
"util-deprecate": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"postcss-value-parser": {
|
"postcss-value-parser": {
|
||||||
@@ -5750,9 +5683,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"regenerate": {
|
"regenerate": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz",
|
||||||
"integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==",
|
"integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"regenerate-unicode-properties": {
|
"regenerate-unicode-properties": {
|
||||||
@@ -5859,9 +5792,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"regexpu-core": {
|
"regexpu-core": {
|
||||||
"version": "4.7.0",
|
"version": "4.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz",
|
||||||
"integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==",
|
"integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"regenerate": "^1.4.0",
|
"regenerate": "^1.4.0",
|
||||||
@@ -5945,9 +5878,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"resolve": {
|
"resolve": {
|
||||||
"version": "1.12.0",
|
"version": "1.17.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
|
||||||
"integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
|
"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"path-parse": "^1.0.6"
|
"path-parse": "^1.0.6"
|
||||||
@@ -7342,7 +7275,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
|
||||||
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
|
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"bindings": "^1.5.0",
|
||||||
|
"nan": "^2.12.1"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"glob-parent": {
|
"glob-parent": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
@@ -7401,9 +7338,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"webpack": {
|
"webpack": {
|
||||||
"version": "4.44.1",
|
"version": "4.44.2",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz",
|
||||||
"integrity": "sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ==",
|
"integrity": "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@webassemblyjs/ast": "1.9.0",
|
"@webassemblyjs/ast": "1.9.0",
|
||||||
@@ -7432,9 +7369,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": {
|
"ajv": {
|
||||||
"version": "6.12.4",
|
"version": "6.12.5",
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz",
|
||||||
"integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==",
|
"integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"fast-deep-equal": "^3.1.1",
|
"fast-deep-equal": "^3.1.1",
|
||||||
@@ -7455,6 +7392,26 @@
|
|||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"json5": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"loader-utils": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"big.js": "^5.2.2",
|
||||||
|
"emojis-list": "^3.0.0",
|
||||||
|
"json5": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tapable": {
|
"tapable": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
|
||||||
@@ -7785,7 +7742,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
|
||||||
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
|
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"bindings": "^1.5.0",
|
||||||
|
"nan": "^2.12.1"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"get-caller-file": {
|
"get-caller-file": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
@@ -8029,6 +7990,12 @@
|
|||||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"y18n": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||||
|
|||||||
+11
-8
@@ -4,26 +4,29 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"clean": "rm -rf dist elm-stuff",
|
||||||
"build": "webpack --mode production",
|
"build": "webpack --mode production",
|
||||||
"watch": "webpack --mode development --watch",
|
"watch": "webpack --mode development --watch",
|
||||||
"dev": "webpack-dev-server --mode development --host 0.0.0.0 --port 3000 --hot",
|
"dev": "webpack-dev-server --mode development --port 3000 --hot --watch",
|
||||||
"errors": "webpack --mode development --display-error-details"
|
"errors": "webpack --mode development --display-error-details"
|
||||||
},
|
},
|
||||||
"dependencies": {},
|
"dependencies": {
|
||||||
|
"opensans-npm-webfont": "^1.0.0"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.11.4",
|
"@babel/core": "^7.11.6",
|
||||||
"@babel/preset-env": "^7.11.0",
|
"@babel/preset-env": "^7.11.5",
|
||||||
"@fortawesome/fontawesome-free": "^5.14.0",
|
"@fortawesome/fontawesome-free": "^5.14.0",
|
||||||
"@webcomponents/webcomponentsjs": "^2.4.4",
|
"@webcomponents/webcomponentsjs": "^2.4.4",
|
||||||
"babel-loader": "^8.1.0",
|
"babel-loader": "^8.1.0",
|
||||||
"css-loader": "^4.2.2",
|
"css-loader": "^4.3.0",
|
||||||
"elm-hot-webpack-loader": "^1.1.7",
|
"elm-hot-webpack-loader": "^1.1.7",
|
||||||
"elm-webpack-loader": "^7.0.1",
|
"elm-webpack-loader": "^7.0.1",
|
||||||
"file-loader": "^6.0.0",
|
"file-loader": "^6.1.0",
|
||||||
"html-webpack-plugin": "^4.4.1",
|
"html-webpack-plugin": "^4.5.0",
|
||||||
"node-elm-compiler": "^5.0.5",
|
"node-elm-compiler": "^5.0.5",
|
||||||
"style-loader": "^1.2.1",
|
"style-loader": "^1.2.1",
|
||||||
"webpack": "^4.44.1",
|
"webpack": "^4.44.2",
|
||||||
"webpack-cli": "^3.3.12",
|
"webpack-cli": "^3.3.12",
|
||||||
"webpack-dev-server": "^3.11.0"
|
"webpack-dev-server": "^3.11.0"
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -1,5 +1,7 @@
|
|||||||
module Api exposing
|
module Api exposing
|
||||||
( deleteMessage
|
( DataResult
|
||||||
|
, HttpResult
|
||||||
|
, deleteMessage
|
||||||
, getGreeting
|
, getGreeting
|
||||||
, getHeaderList
|
, getHeaderList
|
||||||
, getMessage
|
, getMessage
|
||||||
|
|||||||
@@ -0,0 +1,370 @@
|
|||||||
|
module Effect exposing
|
||||||
|
( Effect
|
||||||
|
, addRecent
|
||||||
|
, append
|
||||||
|
, batch
|
||||||
|
, clearFlash
|
||||||
|
, deleteMessage
|
||||||
|
, disableRouting
|
||||||
|
, enableRouting
|
||||||
|
, focusModal
|
||||||
|
, focusModalResult
|
||||||
|
, getGreeting
|
||||||
|
, getHeaderList
|
||||||
|
, getMessage
|
||||||
|
, getServerConfig
|
||||||
|
, getServerMetrics
|
||||||
|
, map
|
||||||
|
, markMessageSeen
|
||||||
|
, navigateRoute
|
||||||
|
, none
|
||||||
|
, perform
|
||||||
|
, posixTime
|
||||||
|
, purgeMailbox
|
||||||
|
, schedule
|
||||||
|
, showFlash
|
||||||
|
, updateRoute
|
||||||
|
)
|
||||||
|
|
||||||
|
import Api exposing (DataResult, HttpResult)
|
||||||
|
import Browser.Navigation as Nav
|
||||||
|
import Data.Message exposing (Message)
|
||||||
|
import Data.MessageHeader exposing (MessageHeader)
|
||||||
|
import Data.Metrics exposing (Metrics)
|
||||||
|
import Data.ServerConfig exposing (ServerConfig)
|
||||||
|
import Data.Session as Session exposing (Session)
|
||||||
|
import Modal
|
||||||
|
import Route exposing (Route)
|
||||||
|
import Task
|
||||||
|
import Time
|
||||||
|
import Timer exposing (Timer)
|
||||||
|
|
||||||
|
|
||||||
|
type Effect msg
|
||||||
|
= None
|
||||||
|
| ApiEffect (ApiEffect msg)
|
||||||
|
| Batch (List (Effect msg))
|
||||||
|
| ModalFocus (Modal.Msg -> msg)
|
||||||
|
| PosixTime (Time.Posix -> msg)
|
||||||
|
| RouteNavigate Bool Route
|
||||||
|
| RouteUpdate Route
|
||||||
|
| ScheduleTimer (Timer -> msg) Timer Float
|
||||||
|
| SessionEffect SessionEffect
|
||||||
|
|
||||||
|
|
||||||
|
type ApiEffect msg
|
||||||
|
= DeleteMessage (HttpResult msg) String String
|
||||||
|
| GetGreeting (DataResult msg String)
|
||||||
|
| GetServerConfig (DataResult msg ServerConfig)
|
||||||
|
| GetServerMetrics (DataResult msg Metrics)
|
||||||
|
| GetHeaderList (DataResult msg (List MessageHeader)) String
|
||||||
|
| GetMessage (DataResult msg Message) String String
|
||||||
|
| MarkMessageSeen (HttpResult msg) String String
|
||||||
|
| PurgeMailbox (HttpResult msg) String
|
||||||
|
|
||||||
|
|
||||||
|
type SessionEffect
|
||||||
|
= FlashClear
|
||||||
|
| FlashShow Session.Flash
|
||||||
|
| ModalFocusResult Modal.Msg
|
||||||
|
| RecentAdd String
|
||||||
|
| RoutingDisable
|
||||||
|
| RoutingEnable
|
||||||
|
|
||||||
|
|
||||||
|
{-| Appends a new effect to a model/effect tuple.
|
||||||
|
-}
|
||||||
|
append : Effect msg -> ( a, Effect msg ) -> ( a, Effect msg )
|
||||||
|
append e ( model, effect ) =
|
||||||
|
( model, batch [ effect, e ] )
|
||||||
|
|
||||||
|
|
||||||
|
{-| Packs a List of Effects into a single Effect
|
||||||
|
-}
|
||||||
|
batch : List (Effect msg) -> Effect msg
|
||||||
|
batch effects =
|
||||||
|
Batch effects
|
||||||
|
|
||||||
|
|
||||||
|
{-| Transform message types produced by an effect.
|
||||||
|
-}
|
||||||
|
map : (a -> b) -> Effect a -> Effect b
|
||||||
|
map f effect =
|
||||||
|
case effect of
|
||||||
|
None ->
|
||||||
|
None
|
||||||
|
|
||||||
|
Batch effects ->
|
||||||
|
Batch <| List.map (map f) effects
|
||||||
|
|
||||||
|
ModalFocus toMsg ->
|
||||||
|
ModalFocus <| toMsg >> f
|
||||||
|
|
||||||
|
PosixTime toMsg ->
|
||||||
|
PosixTime <| toMsg >> f
|
||||||
|
|
||||||
|
ScheduleTimer toMsg timer millis ->
|
||||||
|
ScheduleTimer (toMsg >> f) timer millis
|
||||||
|
|
||||||
|
RouteNavigate pushHistory route ->
|
||||||
|
RouteNavigate pushHistory route
|
||||||
|
|
||||||
|
RouteUpdate route ->
|
||||||
|
RouteUpdate route
|
||||||
|
|
||||||
|
ApiEffect apiEffect ->
|
||||||
|
ApiEffect <| mapApi f apiEffect
|
||||||
|
|
||||||
|
SessionEffect sessionEffect ->
|
||||||
|
SessionEffect sessionEffect
|
||||||
|
|
||||||
|
|
||||||
|
mapApi : (a -> b) -> ApiEffect a -> ApiEffect b
|
||||||
|
mapApi f effect =
|
||||||
|
case effect of
|
||||||
|
DeleteMessage result mailbox id ->
|
||||||
|
DeleteMessage (result >> f) mailbox id
|
||||||
|
|
||||||
|
GetGreeting result ->
|
||||||
|
GetGreeting (result >> f)
|
||||||
|
|
||||||
|
GetServerConfig result ->
|
||||||
|
GetServerConfig (result >> f)
|
||||||
|
|
||||||
|
GetServerMetrics result ->
|
||||||
|
GetServerMetrics (result >> f)
|
||||||
|
|
||||||
|
GetHeaderList result mailbox ->
|
||||||
|
GetHeaderList (result >> f) mailbox
|
||||||
|
|
||||||
|
GetMessage result mailbox id ->
|
||||||
|
GetMessage (result >> f) mailbox id
|
||||||
|
|
||||||
|
MarkMessageSeen result mailbox id ->
|
||||||
|
MarkMessageSeen (result >> f) mailbox id
|
||||||
|
|
||||||
|
PurgeMailbox result mailbox ->
|
||||||
|
PurgeMailbox (result >> f) mailbox
|
||||||
|
|
||||||
|
|
||||||
|
{-| Applies an effect by updating the session and/or producing a Cmd.
|
||||||
|
-}
|
||||||
|
perform : ( Session, Effect msg ) -> ( Session, Cmd msg )
|
||||||
|
perform ( session, effect ) =
|
||||||
|
case effect of
|
||||||
|
None ->
|
||||||
|
( session, Cmd.none )
|
||||||
|
|
||||||
|
Batch effects ->
|
||||||
|
List.foldl batchPerform ( session, [] ) effects
|
||||||
|
|> Tuple.mapSecond Cmd.batch
|
||||||
|
|
||||||
|
ModalFocus toMsg ->
|
||||||
|
( session, Modal.resetFocusCmd toMsg )
|
||||||
|
|
||||||
|
PosixTime toMsg ->
|
||||||
|
( session, Task.perform toMsg Time.now )
|
||||||
|
|
||||||
|
ScheduleTimer toMsg timer millis ->
|
||||||
|
( session, Timer.schedule toMsg timer millis )
|
||||||
|
|
||||||
|
RouteNavigate pushHistory route ->
|
||||||
|
let
|
||||||
|
url =
|
||||||
|
session.router.toPath route
|
||||||
|
in
|
||||||
|
( Session.enableRouting session
|
||||||
|
, if pushHistory then
|
||||||
|
Nav.pushUrl session.key url
|
||||||
|
|
||||||
|
else
|
||||||
|
Nav.replaceUrl session.key url
|
||||||
|
)
|
||||||
|
|
||||||
|
RouteUpdate route ->
|
||||||
|
( Session.disableRouting session
|
||||||
|
, session.router.toPath route
|
||||||
|
|> Nav.replaceUrl session.key
|
||||||
|
)
|
||||||
|
|
||||||
|
ApiEffect apiEffect ->
|
||||||
|
performApi ( session, apiEffect )
|
||||||
|
|
||||||
|
SessionEffect sessionEffect ->
|
||||||
|
performSession ( session, sessionEffect )
|
||||||
|
|
||||||
|
|
||||||
|
performApi : ( Session, ApiEffect msg ) -> ( Session, Cmd msg )
|
||||||
|
performApi ( session, effect ) =
|
||||||
|
case effect of
|
||||||
|
DeleteMessage toMsg mailbox id ->
|
||||||
|
( session, Api.deleteMessage session toMsg mailbox id )
|
||||||
|
|
||||||
|
GetGreeting toMsg ->
|
||||||
|
( session, Api.getGreeting session toMsg )
|
||||||
|
|
||||||
|
GetServerConfig toMsg ->
|
||||||
|
( session, Api.getServerConfig session toMsg )
|
||||||
|
|
||||||
|
GetServerMetrics toMsg ->
|
||||||
|
( session, Api.getServerMetrics session toMsg )
|
||||||
|
|
||||||
|
GetHeaderList toMsg mailbox ->
|
||||||
|
( session, Api.getHeaderList session toMsg mailbox )
|
||||||
|
|
||||||
|
GetMessage toMsg mailbox id ->
|
||||||
|
( session, Api.getMessage session toMsg mailbox id )
|
||||||
|
|
||||||
|
MarkMessageSeen toMsg mailbox id ->
|
||||||
|
( session, Api.markMessageSeen session toMsg mailbox id )
|
||||||
|
|
||||||
|
PurgeMailbox toMsg mailbox ->
|
||||||
|
( session, Api.purgeMailbox session toMsg mailbox )
|
||||||
|
|
||||||
|
|
||||||
|
performSession : ( Session, SessionEffect ) -> ( Session, Cmd msg )
|
||||||
|
performSession ( session, effect ) =
|
||||||
|
case effect of
|
||||||
|
RecentAdd mailbox ->
|
||||||
|
( Session.addRecent mailbox session, Cmd.none )
|
||||||
|
|
||||||
|
FlashClear ->
|
||||||
|
( Session.clearFlash session, Cmd.none )
|
||||||
|
|
||||||
|
FlashShow flash ->
|
||||||
|
( Session.showFlash flash session, Cmd.none )
|
||||||
|
|
||||||
|
ModalFocusResult result ->
|
||||||
|
( Modal.updateSession result session, Cmd.none )
|
||||||
|
|
||||||
|
RoutingDisable ->
|
||||||
|
( Session.disableRouting session, Cmd.none )
|
||||||
|
|
||||||
|
RoutingEnable ->
|
||||||
|
( Session.enableRouting session, Cmd.none )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- EFFECT CONSTRUCTORS
|
||||||
|
|
||||||
|
|
||||||
|
none : Effect msg
|
||||||
|
none =
|
||||||
|
None
|
||||||
|
|
||||||
|
|
||||||
|
{-| Adds specified mailbox to the recently viewed list
|
||||||
|
-}
|
||||||
|
addRecent : String -> Effect msg
|
||||||
|
addRecent mailbox =
|
||||||
|
SessionEffect (RecentAdd mailbox)
|
||||||
|
|
||||||
|
|
||||||
|
disableRouting : Effect msg
|
||||||
|
disableRouting =
|
||||||
|
SessionEffect RoutingDisable
|
||||||
|
|
||||||
|
|
||||||
|
enableRouting : Effect msg
|
||||||
|
enableRouting =
|
||||||
|
SessionEffect RoutingEnable
|
||||||
|
|
||||||
|
|
||||||
|
clearFlash : Effect msg
|
||||||
|
clearFlash =
|
||||||
|
SessionEffect FlashClear
|
||||||
|
|
||||||
|
|
||||||
|
showFlash : Session.Flash -> Effect msg
|
||||||
|
showFlash flash =
|
||||||
|
SessionEffect (FlashShow flash)
|
||||||
|
|
||||||
|
|
||||||
|
{-| Locks focus to the `modal-dialog` dom ID.
|
||||||
|
-}
|
||||||
|
focusModal : (Modal.Msg -> msg) -> Effect msg
|
||||||
|
focusModal toMsg =
|
||||||
|
ModalFocus toMsg
|
||||||
|
|
||||||
|
|
||||||
|
focusModalResult : Modal.Msg -> Effect msg
|
||||||
|
focusModalResult msg =
|
||||||
|
SessionEffect (ModalFocusResult msg)
|
||||||
|
|
||||||
|
|
||||||
|
deleteMessage : HttpResult msg -> String -> String -> Effect msg
|
||||||
|
deleteMessage toMsg mailboxName id =
|
||||||
|
ApiEffect (DeleteMessage toMsg mailboxName id)
|
||||||
|
|
||||||
|
|
||||||
|
getGreeting : DataResult msg String -> Effect msg
|
||||||
|
getGreeting toMsg =
|
||||||
|
ApiEffect (GetGreeting toMsg)
|
||||||
|
|
||||||
|
|
||||||
|
getHeaderList : DataResult msg (List MessageHeader) -> String -> Effect msg
|
||||||
|
getHeaderList toMsg mailboxName =
|
||||||
|
ApiEffect (GetHeaderList toMsg mailboxName)
|
||||||
|
|
||||||
|
|
||||||
|
getServerConfig : DataResult msg ServerConfig -> Effect msg
|
||||||
|
getServerConfig toMsg =
|
||||||
|
ApiEffect (GetServerConfig toMsg)
|
||||||
|
|
||||||
|
|
||||||
|
getServerMetrics : DataResult msg Metrics -> Effect msg
|
||||||
|
getServerMetrics toMsg =
|
||||||
|
ApiEffect (GetServerMetrics toMsg)
|
||||||
|
|
||||||
|
|
||||||
|
getMessage : DataResult msg Message -> String -> String -> Effect msg
|
||||||
|
getMessage toMsg mailboxName id =
|
||||||
|
ApiEffect (GetMessage toMsg mailboxName id)
|
||||||
|
|
||||||
|
|
||||||
|
markMessageSeen : HttpResult msg -> String -> String -> Effect msg
|
||||||
|
markMessageSeen toMsg mailboxName id =
|
||||||
|
ApiEffect (MarkMessageSeen toMsg mailboxName id)
|
||||||
|
|
||||||
|
|
||||||
|
posixTime : (Time.Posix -> msg) -> Effect msg
|
||||||
|
posixTime toMsg =
|
||||||
|
PosixTime toMsg
|
||||||
|
|
||||||
|
|
||||||
|
purgeMailbox : HttpResult msg -> String -> Effect msg
|
||||||
|
purgeMailbox toMsg mailboxName =
|
||||||
|
ApiEffect (PurgeMailbox toMsg mailboxName)
|
||||||
|
|
||||||
|
|
||||||
|
{-| Schedules a Timer to fire after the specified delay.
|
||||||
|
-}
|
||||||
|
schedule : (Timer -> msg) -> Timer -> Float -> Effect msg
|
||||||
|
schedule toMsg timer millis =
|
||||||
|
ScheduleTimer toMsg timer millis
|
||||||
|
|
||||||
|
|
||||||
|
{-| Updates the browsers displayed URL to the specified route, and triggers the route to be
|
||||||
|
handled by the frontend.
|
||||||
|
-}
|
||||||
|
navigateRoute : Bool -> Route -> Effect msg
|
||||||
|
navigateRoute pushHistory route =
|
||||||
|
RouteNavigate pushHistory route
|
||||||
|
|
||||||
|
|
||||||
|
{-| Updates the browsers displayed URL to the specified route. Does not trigger our own route
|
||||||
|
handling.
|
||||||
|
-}
|
||||||
|
updateRoute : Route -> Effect msg
|
||||||
|
updateRoute route =
|
||||||
|
RouteUpdate route
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- UTILITY
|
||||||
|
|
||||||
|
|
||||||
|
batchPerform : Effect msg -> ( Session, List (Cmd msg) ) -> ( Session, List (Cmd msg) )
|
||||||
|
batchPerform effect ( session, cmds ) =
|
||||||
|
perform ( session, effect )
|
||||||
|
|> Tuple.mapSecond (\cmd -> cmd :: cmds)
|
||||||
+17
-35
@@ -1,7 +1,7 @@
|
|||||||
module Layout exposing (Model, Msg, Page(..), frame, init, reset, update)
|
module Layout exposing (Model, Msg, Page(..), frame, init, reset, update)
|
||||||
|
|
||||||
import Browser.Navigation as Nav
|
|
||||||
import Data.Session as Session exposing (Session)
|
import Data.Session as Session exposing (Session)
|
||||||
|
import Effect exposing (Effect)
|
||||||
import Html
|
import Html
|
||||||
exposing
|
exposing
|
||||||
( Attribute
|
( Attribute
|
||||||
@@ -39,7 +39,7 @@ import Html.Attributes
|
|||||||
)
|
)
|
||||||
import Html.Events as Events
|
import Html.Events as Events
|
||||||
import Modal
|
import Modal
|
||||||
import Route exposing (Route)
|
import Route
|
||||||
import Timer exposing (Timer)
|
import Timer exposing (Timer)
|
||||||
|
|
||||||
|
|
||||||
@@ -96,46 +96,31 @@ type Msg
|
|||||||
| RecentMenuToggled
|
| RecentMenuToggled
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model msg -> Session -> ( Model msg, Session, Cmd msg )
|
update : Msg -> Model msg -> ( Model msg, Effect msg )
|
||||||
update msg model session =
|
update msg model =
|
||||||
case msg of
|
case msg of
|
||||||
ClearFlash ->
|
ClearFlash ->
|
||||||
( model
|
( model, Effect.clearFlash )
|
||||||
, Session.clearFlash session
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
MainMenuToggled ->
|
MainMenuToggled ->
|
||||||
( { model | mainMenuVisible = not model.mainMenuVisible }
|
( { model | mainMenuVisible = not model.mainMenuVisible }, Effect.none )
|
||||||
, session
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
ModalFocused message ->
|
ModalFocused message ->
|
||||||
( model
|
( model, Effect.focusModalResult message )
|
||||||
, Modal.updateSession message session
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
ModalUnfocused ->
|
ModalUnfocused ->
|
||||||
( model, session, Modal.resetFocusCmd (ModalFocused >> model.mapMsg) )
|
( model, Effect.focusModal (ModalFocused >> model.mapMsg) )
|
||||||
|
|
||||||
OnMailboxNameInput name ->
|
OnMailboxNameInput name ->
|
||||||
( { model | mailboxName = name }
|
( { model | mailboxName = name }, Effect.none )
|
||||||
, session
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
OpenMailbox ->
|
OpenMailbox ->
|
||||||
if model.mailboxName == "" then
|
if model.mailboxName == "" then
|
||||||
( model, session, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
else
|
else
|
||||||
( model
|
( model
|
||||||
, session
|
, Effect.navigateRoute True (Route.Mailbox model.mailboxName)
|
||||||
, Route.Mailbox model.mailboxName
|
|
||||||
|> session.router.toPath
|
|
||||||
|> Nav.pushUrl session.key
|
|
||||||
)
|
)
|
||||||
|
|
||||||
RecentMenuMouseOver ->
|
RecentMenuMouseOver ->
|
||||||
@@ -143,20 +128,19 @@ update msg model session =
|
|||||||
| recentMenuVisible = True
|
| recentMenuVisible = True
|
||||||
, recentMenuTimer = Timer.cancel model.recentMenuTimer
|
, recentMenuTimer = Timer.cancel model.recentMenuTimer
|
||||||
}
|
}
|
||||||
, session
|
, Effect.none
|
||||||
, Cmd.none
|
|
||||||
)
|
)
|
||||||
|
|
||||||
RecentMenuMouseOut ->
|
RecentMenuMouseOut ->
|
||||||
let
|
let
|
||||||
|
-- Keep the recent menu open for a moment even if the mouse leaves it.
|
||||||
newTimer =
|
newTimer =
|
||||||
Timer.replace model.recentMenuTimer
|
Timer.replace model.recentMenuTimer
|
||||||
in
|
in
|
||||||
( { model
|
( { model
|
||||||
| recentMenuTimer = newTimer
|
| recentMenuTimer = newTimer
|
||||||
}
|
}
|
||||||
, session
|
, Effect.schedule (RecentMenuTimeout >> model.mapMsg) newTimer 400
|
||||||
, Timer.schedule (RecentMenuTimeout >> model.mapMsg) newTimer 400
|
|
||||||
)
|
)
|
||||||
|
|
||||||
RecentMenuTimeout timer ->
|
RecentMenuTimeout timer ->
|
||||||
@@ -165,18 +149,16 @@ update msg model session =
|
|||||||
| recentMenuVisible = False
|
| recentMenuVisible = False
|
||||||
, recentMenuTimer = Timer.cancel timer
|
, recentMenuTimer = Timer.cancel timer
|
||||||
}
|
}
|
||||||
, session
|
, Effect.none
|
||||||
, Cmd.none
|
|
||||||
)
|
)
|
||||||
|
|
||||||
else
|
else
|
||||||
-- Timer was no longer valid.
|
-- Timer was no longer valid.
|
||||||
( model, session, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
RecentMenuToggled ->
|
RecentMenuToggled ->
|
||||||
( { model | recentMenuVisible = not model.recentMenuVisible }
|
( { model | recentMenuVisible = not model.recentMenuVisible }
|
||||||
, session
|
, Effect.none
|
||||||
, Cmd.none
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+58
-50
@@ -4,6 +4,7 @@ import Browser exposing (Document, UrlRequest)
|
|||||||
import Browser.Navigation as Nav
|
import Browser.Navigation as Nav
|
||||||
import Data.AppConfig as AppConfig exposing (AppConfig)
|
import Data.AppConfig as AppConfig exposing (AppConfig)
|
||||||
import Data.Session as Session exposing (Session)
|
import Data.Session as Session exposing (Session)
|
||||||
|
import Effect exposing (Effect)
|
||||||
import Html exposing (Html)
|
import Html exposing (Html)
|
||||||
import Json.Decode as D exposing (Value)
|
import Json.Decode as D exposing (Value)
|
||||||
import Layout
|
import Layout
|
||||||
@@ -58,6 +59,8 @@ init configValue location key =
|
|||||||
Session.initError key location (D.errorToString error)
|
Session.initError key location (D.errorToString error)
|
||||||
|
|
||||||
( subModel, _ ) =
|
( subModel, _ ) =
|
||||||
|
-- Home.init effect is discarded because this subModel will be immediately replaced
|
||||||
|
-- when we change routes to the specified location.
|
||||||
Home.init session
|
Home.init session
|
||||||
|
|
||||||
initModel =
|
initModel =
|
||||||
@@ -67,11 +70,9 @@ init configValue location key =
|
|||||||
|
|
||||||
route =
|
route =
|
||||||
session.router.fromUrl location
|
session.router.fromUrl location
|
||||||
|
|
||||||
( model, cmd ) =
|
|
||||||
changeRouteTo route initModel
|
|
||||||
in
|
in
|
||||||
( model, Cmd.batch [ cmd, Task.perform TimeZoneLoaded Time.here ] )
|
changeRouteTo route initModel
|
||||||
|
|> Tuple.mapSecond (\cmd -> Cmd.batch [ cmd, Task.perform TimeZoneLoaded Time.here ])
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
type Msg
|
||||||
@@ -198,20 +199,18 @@ updateMain msg model session =
|
|||||||
|
|
||||||
LayoutMsg subMsg ->
|
LayoutMsg subMsg ->
|
||||||
let
|
let
|
||||||
( layout, newSession, cmd ) =
|
( layout, effect ) =
|
||||||
Layout.update subMsg model.layout session
|
Layout.update subMsg model.layout
|
||||||
in
|
in
|
||||||
( updateSession { model | layout = layout } newSession
|
( { model | layout = layout }, effect ) |> performEffects
|
||||||
, cmd
|
|
||||||
)
|
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
updatePage msg model
|
updatePage msg model |> performEffects
|
||||||
|
|
||||||
|
|
||||||
{-| Delegate incoming messages to their respective sub-pages.
|
{-| Delegate incoming messages to their respective sub-pages.
|
||||||
-}
|
-}
|
||||||
updatePage : Msg -> Model -> ( Model, Cmd Msg )
|
updatePage : Msg -> Model -> ( Model, Effect Msg )
|
||||||
updatePage msg model =
|
updatePage msg model =
|
||||||
case ( msg, model.page ) of
|
case ( msg, model.page ) of
|
||||||
( HomeMsg subMsg, Home subModel ) ->
|
( HomeMsg subMsg, Home subModel ) ->
|
||||||
@@ -232,61 +231,70 @@ updatePage msg model =
|
|||||||
|
|
||||||
( _, _ ) ->
|
( _, _ ) ->
|
||||||
-- Disregard messages destined for the wrong page.
|
-- Disregard messages destined for the wrong page.
|
||||||
( model, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
|
|
||||||
changeRouteTo : Route -> Model -> ( Model, Cmd Msg )
|
changeRouteTo : Route -> Model -> ( Model, Cmd Msg )
|
||||||
changeRouteTo route model =
|
changeRouteTo route model =
|
||||||
let
|
let
|
||||||
session =
|
session =
|
||||||
getSession model |> Session.clearFlash
|
Session.clearFlash (getSession model)
|
||||||
|
|
||||||
newModel =
|
newModel =
|
||||||
{ model | layout = Layout.reset model.layout }
|
{ model | layout = Layout.reset model.layout }
|
||||||
in
|
in
|
||||||
case route of
|
performEffects <|
|
||||||
Route.Home ->
|
case route of
|
||||||
Home.init session
|
Route.Home ->
|
||||||
|> updateWith Home HomeMsg newModel
|
Home.init session
|
||||||
|
|> updateWith Home HomeMsg newModel
|
||||||
|
|
||||||
Route.Mailbox name ->
|
Route.Mailbox name ->
|
||||||
Mailbox.init session name Nothing
|
Mailbox.init session name Nothing
|
||||||
|> updateWith Mailbox MailboxMsg newModel
|
|> updateWith Mailbox MailboxMsg newModel
|
||||||
|
|
||||||
Route.Message mailbox id ->
|
Route.Message mailbox id ->
|
||||||
Mailbox.init session mailbox (Just id)
|
Mailbox.init session mailbox (Just id)
|
||||||
|> updateWith Mailbox MailboxMsg newModel
|
|> updateWith Mailbox MailboxMsg newModel
|
||||||
|
|
||||||
Route.Monitor ->
|
Route.Monitor ->
|
||||||
if session.config.monitorVisible then
|
if session.config.monitorVisible then
|
||||||
Monitor.init session
|
Monitor.init session
|
||||||
|> updateWith Monitor MonitorMsg newModel
|
|> updateWith Monitor MonitorMsg newModel
|
||||||
|
|
||||||
else
|
else
|
||||||
|
let
|
||||||
|
flash =
|
||||||
|
{ title = "Disabled route requested"
|
||||||
|
, table = [ ( "Error", "Monitor disabled by configuration." ) ]
|
||||||
|
}
|
||||||
|
in
|
||||||
|
( applyToModelSession (Session.showFlash flash) newModel
|
||||||
|
, Effect.none
|
||||||
|
)
|
||||||
|
|
||||||
|
Route.Status ->
|
||||||
|
Status.init session
|
||||||
|
|> updateWith Status StatusMsg newModel
|
||||||
|
|
||||||
|
Route.Unknown path ->
|
||||||
|
-- Unknown routes display Home with an error flash.
|
||||||
let
|
let
|
||||||
flash =
|
flash =
|
||||||
{ title = "Disabled route requested"
|
{ title = "Unknown route requested"
|
||||||
, table = [ ( "Error", "Monitor disabled by configuration." ) ]
|
, table = [ ( "Path", path ) ]
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
( applyToModelSession (Session.showFlash flash) newModel
|
Home.init (Session.showFlash flash session)
|
||||||
, Cmd.none
|
|> updateWith Home HomeMsg newModel
|
||||||
)
|
|
||||||
|
|
||||||
Route.Status ->
|
|
||||||
Status.init session
|
|
||||||
|> updateWith Status StatusMsg newModel
|
|
||||||
|
|
||||||
Route.Unknown path ->
|
{-| Perform effects by updating model and/or producing Cmds to be executed.
|
||||||
-- Unknown routes display Home with an error flash.
|
-}
|
||||||
let
|
performEffects : ( Model, Effect Msg ) -> ( Model, Cmd Msg )
|
||||||
flash =
|
performEffects ( model, effect ) =
|
||||||
{ title = "Unknown route requested"
|
Effect.perform ( getSession model, effect )
|
||||||
, table = [ ( "Path", path ) ]
|
|> Tuple.mapFirst (\newSession -> updateSession model newSession)
|
||||||
}
|
|
||||||
in
|
|
||||||
Home.init (Session.showFlash flash session)
|
|
||||||
|> updateWith Home HomeMsg newModel
|
|
||||||
|
|
||||||
|
|
||||||
getSession : Model -> Session
|
getSession : Model -> Session
|
||||||
@@ -332,11 +340,11 @@ updateWith :
|
|||||||
(subModel -> PageModel)
|
(subModel -> PageModel)
|
||||||
-> (subMsg -> Msg)
|
-> (subMsg -> Msg)
|
||||||
-> Model
|
-> Model
|
||||||
-> ( subModel, Cmd subMsg )
|
-> ( subModel, Effect subMsg )
|
||||||
-> ( Model, Cmd Msg )
|
-> ( Model, Effect Msg )
|
||||||
updateWith toPage toMsg model ( subModel, subCmd ) =
|
updateWith toPage toMsg model ( subModel, subEffect ) =
|
||||||
( { model | page = toPage subModel }
|
( { model | page = toPage subModel }
|
||||||
, Cmd.map toMsg subCmd
|
, Effect.map toMsg subEffect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
module Page.Home exposing (Model, Msg, init, update, view)
|
module Page.Home exposing (Model, Msg, init, update, view)
|
||||||
|
|
||||||
import Api
|
import Data.Session exposing (Session)
|
||||||
import Data.Session as Session exposing (Session)
|
import Effect exposing (Effect)
|
||||||
import Html exposing (Html)
|
import Html exposing (Html)
|
||||||
import Html.Attributes exposing (class, property)
|
import Html.Attributes exposing (class, property)
|
||||||
import HttpUtil
|
import HttpUtil
|
||||||
@@ -18,9 +18,9 @@ type alias Model =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
init : Session -> ( Model, Cmd Msg )
|
init : Session -> ( Model, Effect Msg )
|
||||||
init session =
|
init session =
|
||||||
( Model session "", Api.getGreeting session GreetingLoaded )
|
( Model session "", Effect.getGreeting GreetingLoaded )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -31,16 +31,14 @@ type Msg
|
|||||||
= GreetingLoaded (Result HttpUtil.Error String)
|
= GreetingLoaded (Result HttpUtil.Error String)
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
update : Msg -> Model -> ( Model, Effect Msg )
|
||||||
update msg model =
|
update msg model =
|
||||||
case msg of
|
case msg of
|
||||||
GreetingLoaded (Ok greeting) ->
|
GreetingLoaded (Ok greeting) ->
|
||||||
( { model | greeting = greeting }, Cmd.none )
|
( { model | greeting = greeting }, Effect.none )
|
||||||
|
|
||||||
GreetingLoaded (Err err) ->
|
GreetingLoaded (Err err) ->
|
||||||
( { model | session = Session.showFlash (HttpUtil.errorFlash err) model.session }
|
( model, Effect.showFlash (HttpUtil.errorFlash err) )
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+176
-155
@@ -1,12 +1,12 @@
|
|||||||
module Page.Mailbox exposing (Model, Msg, init, load, subscriptions, update, view)
|
module Page.Mailbox exposing (Model, Msg, init, subscriptions, update, view)
|
||||||
|
|
||||||
import Api
|
import Api
|
||||||
import Browser.Navigation as Nav
|
|
||||||
import Data.Message as Message exposing (Message)
|
import Data.Message as Message exposing (Message)
|
||||||
import Data.MessageHeader exposing (MessageHeader)
|
import Data.MessageHeader exposing (MessageHeader)
|
||||||
import Data.Session as Session exposing (Session)
|
import Data.Session exposing (Session)
|
||||||
import DateFormat as DF
|
import DateFormat as DF
|
||||||
import DateFormat.Relative as Relative
|
import DateFormat.Relative as Relative
|
||||||
|
import Effect exposing (Effect)
|
||||||
import Html
|
import Html
|
||||||
exposing
|
exposing
|
||||||
( Attribute
|
( Attribute
|
||||||
@@ -54,7 +54,6 @@ import Json.Decode as D
|
|||||||
import Json.Encode as E
|
import Json.Encode as E
|
||||||
import Modal
|
import Modal
|
||||||
import Route
|
import Route
|
||||||
import Task
|
|
||||||
import Time exposing (Posix)
|
import Time exposing (Posix)
|
||||||
import Timer exposing (Timer)
|
import Timer exposing (Timer)
|
||||||
|
|
||||||
@@ -95,6 +94,7 @@ type alias Model =
|
|||||||
{ session : Session
|
{ session : Session
|
||||||
, mailboxName : String
|
, mailboxName : String
|
||||||
, state : State
|
, state : State
|
||||||
|
, socketConnected : Bool
|
||||||
, bodyMode : Body
|
, bodyMode : Body
|
||||||
, searchInput : String
|
, searchInput : String
|
||||||
, promptPurge : Bool
|
, promptPurge : Bool
|
||||||
@@ -103,27 +103,27 @@ type alias Model =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
init : Session -> String -> Maybe MessageID -> ( Model, Cmd Msg )
|
type alias ServeUrl =
|
||||||
|
List String -> String
|
||||||
|
|
||||||
|
|
||||||
|
init : Session -> String -> Maybe MessageID -> ( Model, Effect Msg )
|
||||||
init session mailboxName selection =
|
init session mailboxName selection =
|
||||||
( { session = session
|
( { session = session
|
||||||
, mailboxName = mailboxName
|
, mailboxName = mailboxName
|
||||||
, state = LoadingList selection
|
, state = LoadingList selection
|
||||||
|
, socketConnected = False
|
||||||
, bodyMode = SafeHtmlBody
|
, bodyMode = SafeHtmlBody
|
||||||
, searchInput = ""
|
, searchInput = ""
|
||||||
, promptPurge = False
|
, promptPurge = False
|
||||||
, markSeenTimer = Timer.empty
|
, markSeenTimer = Timer.empty
|
||||||
, now = Time.millisToPosix 0
|
, now = Time.millisToPosix 0
|
||||||
}
|
}
|
||||||
, load session mailboxName
|
, Effect.batch
|
||||||
)
|
[ Effect.posixTime Tick
|
||||||
|
, Effect.getHeaderList ListLoaded mailboxName
|
||||||
|
|
||||||
load : Session -> String -> Cmd Msg
|
|
||||||
load session mailboxName =
|
|
||||||
Cmd.batch
|
|
||||||
[ Task.perform Tick Time.now
|
|
||||||
, Api.getHeaderList session ListLoaded mailboxName
|
|
||||||
]
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -142,6 +142,7 @@ subscriptions _ =
|
|||||||
type Msg
|
type Msg
|
||||||
= ListLoaded (Result HttpUtil.Error (List MessageHeader))
|
= ListLoaded (Result HttpUtil.Error (List MessageHeader))
|
||||||
| ClickMessage MessageID
|
| ClickMessage MessageID
|
||||||
|
| ClickRefresh
|
||||||
| ListKeyPress String Int
|
| ListKeyPress String Int
|
||||||
| CloseMessage
|
| CloseMessage
|
||||||
| MessageLoaded (Result HttpUtil.Error Message)
|
| MessageLoaded (Result HttpUtil.Error Message)
|
||||||
@@ -159,38 +160,49 @@ type Msg
|
|||||||
| ModalFocused Modal.Msg
|
| ModalFocused Modal.Msg
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
update : Msg -> Model -> ( Model, Effect Msg )
|
||||||
update msg model =
|
update msg model =
|
||||||
case msg of
|
case msg of
|
||||||
ClickMessage id ->
|
ClickMessage id ->
|
||||||
( updateSelected { model | session = Session.disableRouting model.session } id
|
( updateSelected model id
|
||||||
, Cmd.batch
|
, Effect.batch
|
||||||
[ -- Update browser location.
|
[ -- Update browser location.
|
||||||
Route.Message model.mailboxName id
|
Effect.updateRoute (Route.Message model.mailboxName id)
|
||||||
|> model.session.router.toPath
|
, Effect.getMessage MessageLoaded model.mailboxName id
|
||||||
|> Nav.replaceUrl model.session.key
|
|
||||||
, Api.getMessage model.session MessageLoaded model.mailboxName id
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ClickRefresh ->
|
||||||
|
let
|
||||||
|
selection =
|
||||||
|
case model.state of
|
||||||
|
ShowingList _ (ShowingMessage message) ->
|
||||||
|
Just message.id
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
Nothing
|
||||||
|
in
|
||||||
|
-- Reset to loading state, preserving the current message selection.
|
||||||
|
( { model | state = LoadingList selection }
|
||||||
|
, Effect.getHeaderList ListLoaded model.mailboxName
|
||||||
|
)
|
||||||
|
|
||||||
CloseMessage ->
|
CloseMessage ->
|
||||||
case model.state of
|
case model.state of
|
||||||
ShowingList list _ ->
|
ShowingList list _ ->
|
||||||
( { model | state = ShowingList list NoMessage }, Cmd.none )
|
( { model | state = ShowingList list NoMessage }, Effect.none )
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( model, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
DeleteMessage message ->
|
DeleteMessage message ->
|
||||||
updateDeleteMessage model message
|
updateDeleteMessage model message
|
||||||
|
|
||||||
DeletedMessage (Ok _) ->
|
DeletedMessage (Ok _) ->
|
||||||
( model, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
DeletedMessage (Err err) ->
|
DeletedMessage (Err err) ->
|
||||||
( { model | session = Session.showFlash (HttpUtil.errorFlash err) model.session }
|
( model, Effect.showFlash (HttpUtil.errorFlash err) )
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
ListKeyPress id keyCode ->
|
ListKeyPress id keyCode ->
|
||||||
case keyCode of
|
case keyCode of
|
||||||
@@ -198,79 +210,49 @@ update msg model =
|
|||||||
updateOpenMessage model id
|
updateOpenMessage model id
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( model, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
ListLoaded (Ok headers) ->
|
ListLoaded (Ok headers) ->
|
||||||
case model.state of
|
updateListLoaded model headers
|
||||||
LoadingList selection ->
|
|
||||||
let
|
|
||||||
newModel =
|
|
||||||
{ model
|
|
||||||
| state = ShowingList (MessageList headers Nothing "") NoMessage
|
|
||||||
}
|
|
||||||
in
|
|
||||||
case selection of
|
|
||||||
Just id ->
|
|
||||||
updateOpenMessage newModel id
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
( { newModel
|
|
||||||
| session = Session.addRecent model.mailboxName model.session
|
|
||||||
}
|
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
( model, Cmd.none )
|
|
||||||
|
|
||||||
ListLoaded (Err err) ->
|
ListLoaded (Err err) ->
|
||||||
( { model | session = Session.showFlash (HttpUtil.errorFlash err) model.session }
|
( model, Effect.showFlash (HttpUtil.errorFlash err) )
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
MarkSeenLoaded (Ok _) ->
|
MarkSeenLoaded (Ok _) ->
|
||||||
( model, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
MarkSeenLoaded (Err err) ->
|
MarkSeenLoaded (Err err) ->
|
||||||
( { model | session = Session.showFlash (HttpUtil.errorFlash err) model.session }
|
( model, Effect.showFlash (HttpUtil.errorFlash err) )
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
MessageLoaded (Ok message) ->
|
MessageLoaded (Ok message) ->
|
||||||
updateMessageResult model message
|
updateMessageResult model message
|
||||||
|
|
||||||
MessageLoaded (Err err) ->
|
MessageLoaded (Err err) ->
|
||||||
( { model | session = Session.showFlash (HttpUtil.errorFlash err) model.session }
|
( model, Effect.showFlash (HttpUtil.errorFlash err) )
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
MessageBody bodyMode ->
|
MessageBody bodyMode ->
|
||||||
( { model | bodyMode = bodyMode }, Cmd.none )
|
( { model | bodyMode = bodyMode }, Effect.none )
|
||||||
|
|
||||||
ModalFocused message ->
|
ModalFocused message ->
|
||||||
( { model | session = Modal.updateSession message model.session }
|
( model, Effect.focusModalResult message )
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
OnSearchInput searchInput ->
|
OnSearchInput searchInput ->
|
||||||
updateSearchInput model searchInput
|
updateSearchInput model searchInput
|
||||||
|
|
||||||
PurgeMailboxPrompt ->
|
PurgeMailboxPrompt ->
|
||||||
( { model | promptPurge = True }, Modal.resetFocusCmd ModalFocused )
|
( { model | promptPurge = True }, Effect.focusModal ModalFocused )
|
||||||
|
|
||||||
PurgeMailboxCanceled ->
|
PurgeMailboxCanceled ->
|
||||||
( { model | promptPurge = False }, Cmd.none )
|
( { model | promptPurge = False }, Effect.none )
|
||||||
|
|
||||||
PurgeMailboxConfirmed ->
|
PurgeMailboxConfirmed ->
|
||||||
updateTriggerPurge model
|
updateTriggerPurge model
|
||||||
|
|
||||||
PurgedMailbox (Ok _) ->
|
PurgedMailbox (Ok _) ->
|
||||||
( model, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
PurgedMailbox (Err err) ->
|
PurgedMailbox (Err err) ->
|
||||||
( { model | session = Session.showFlash (HttpUtil.errorFlash err) model.session }
|
( model, Effect.showFlash (HttpUtil.errorFlash err) )
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
MarkSeenTriggered timer ->
|
MarkSeenTriggered timer ->
|
||||||
if timer == model.markSeenTimer then
|
if timer == model.markSeenTimer then
|
||||||
@@ -278,15 +260,42 @@ update msg model =
|
|||||||
updateMarkMessageSeen model
|
updateMarkMessageSeen model
|
||||||
|
|
||||||
else
|
else
|
||||||
( model, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
Tick now ->
|
Tick now ->
|
||||||
( { model | now = now }, Cmd.none )
|
( { model | now = now }, Effect.none )
|
||||||
|
|
||||||
|
|
||||||
|
updateListLoaded : Model -> List MessageHeader -> ( Model, Effect Msg )
|
||||||
|
updateListLoaded model headers =
|
||||||
|
case model.state of
|
||||||
|
LoadingList selection ->
|
||||||
|
let
|
||||||
|
newModel =
|
||||||
|
{ model
|
||||||
|
| state = ShowingList (MessageList headers Nothing "") NoMessage
|
||||||
|
}
|
||||||
|
in
|
||||||
|
Effect.append (Effect.addRecent newModel.mailboxName) <|
|
||||||
|
case selection of
|
||||||
|
Just id ->
|
||||||
|
-- Don't try to load selected message if not present in headers.
|
||||||
|
if List.any (\header -> Just header.id == selection) headers then
|
||||||
|
updateOpenMessage newModel id
|
||||||
|
|
||||||
|
else
|
||||||
|
( newModel, Effect.updateRoute (Route.Mailbox model.mailboxName) )
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
( newModel, Effect.none )
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
( model, Effect.none )
|
||||||
|
|
||||||
|
|
||||||
{-| Replace the currently displayed message.
|
{-| Replace the currently displayed message.
|
||||||
-}
|
-}
|
||||||
updateMessageResult : Model -> Message -> ( Model, Cmd Msg )
|
updateMessageResult : Model -> Message -> ( Model, Effect Msg )
|
||||||
updateMessageResult model message =
|
updateMessageResult model message =
|
||||||
let
|
let
|
||||||
bodyMode =
|
bodyMode =
|
||||||
@@ -298,7 +307,7 @@ updateMessageResult model message =
|
|||||||
in
|
in
|
||||||
case model.state of
|
case model.state of
|
||||||
LoadingList _ ->
|
LoadingList _ ->
|
||||||
( model, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
ShowingList list _ ->
|
ShowingList list _ ->
|
||||||
let
|
let
|
||||||
@@ -314,38 +323,26 @@ updateMessageResult model message =
|
|||||||
, markSeenTimer = newTimer
|
, markSeenTimer = newTimer
|
||||||
}
|
}
|
||||||
-- Set 1500ms delay before reporting message as seen to backend.
|
-- Set 1500ms delay before reporting message as seen to backend.
|
||||||
, Timer.schedule MarkSeenTriggered newTimer 1500
|
, Effect.schedule MarkSeenTriggered newTimer 1500
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
{-| Updates model and triggers commands to purge this mailbox.
|
{-| Updates model and triggers commands to purge this mailbox.
|
||||||
-}
|
-}
|
||||||
updateTriggerPurge : Model -> ( Model, Cmd Msg )
|
updateTriggerPurge : Model -> ( Model, Effect Msg )
|
||||||
updateTriggerPurge model =
|
updateTriggerPurge model =
|
||||||
let
|
( { model
|
||||||
cmd =
|
| promptPurge = False
|
||||||
Cmd.batch
|
, state = ShowingList (MessageList [] Nothing "") NoMessage
|
||||||
[ Route.Mailbox model.mailboxName
|
}
|
||||||
|> model.session.router.toPath
|
, Effect.batch
|
||||||
|> Nav.replaceUrl model.session.key
|
[ Effect.updateRoute (Route.Mailbox model.mailboxName)
|
||||||
, Api.purgeMailbox model.session PurgedMailbox model.mailboxName
|
, Effect.purgeMailbox PurgedMailbox model.mailboxName
|
||||||
]
|
]
|
||||||
in
|
)
|
||||||
case model.state of
|
|
||||||
ShowingList _ _ ->
|
|
||||||
( { model
|
|
||||||
| promptPurge = False
|
|
||||||
, session = Session.disableRouting model.session
|
|
||||||
, state = ShowingList (MessageList [] Nothing "") NoMessage
|
|
||||||
}
|
|
||||||
, cmd
|
|
||||||
)
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
( model, cmd )
|
|
||||||
|
|
||||||
|
|
||||||
updateSearchInput : Model -> String -> ( Model, Cmd Msg )
|
updateSearchInput : Model -> String -> ( Model, Effect Msg )
|
||||||
updateSearchInput model searchInput =
|
updateSearchInput model searchInput =
|
||||||
let
|
let
|
||||||
searchFilter =
|
searchFilter =
|
||||||
@@ -357,14 +354,14 @@ updateSearchInput model searchInput =
|
|||||||
in
|
in
|
||||||
case model.state of
|
case model.state of
|
||||||
LoadingList _ ->
|
LoadingList _ ->
|
||||||
( model, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
ShowingList list messageState ->
|
ShowingList list messageState ->
|
||||||
( { model
|
( { model
|
||||||
| searchInput = searchInput
|
| searchInput = searchInput
|
||||||
, state = ShowingList { list | searchFilter = searchFilter } messageState
|
, state = ShowingList { list | searchFilter = searchFilter } messageState
|
||||||
}
|
}
|
||||||
, Cmd.none
|
, Effect.none
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -396,7 +393,7 @@ updateSelected model id =
|
|||||||
{ model | state = ShowingList newList (Transitioning visible) }
|
{ model | state = ShowingList newList (Transitioning visible) }
|
||||||
|
|
||||||
|
|
||||||
updateDeleteMessage : Model -> Message -> ( Model, Cmd Msg )
|
updateDeleteMessage : Model -> Message -> ( Model, Effect Msg )
|
||||||
updateDeleteMessage model message =
|
updateDeleteMessage model message =
|
||||||
let
|
let
|
||||||
filter f messageList =
|
filter f messageList =
|
||||||
@@ -404,26 +401,20 @@ updateDeleteMessage model message =
|
|||||||
in
|
in
|
||||||
case model.state of
|
case model.state of
|
||||||
ShowingList list _ ->
|
ShowingList list _ ->
|
||||||
( { model
|
( { model | state = ShowingList (filter (\x -> x.id /= message.id) list) NoMessage }
|
||||||
| session = Session.disableRouting model.session
|
, Effect.batch
|
||||||
, state =
|
[ Effect.deleteMessage DeletedMessage message.mailbox message.id
|
||||||
ShowingList (filter (\x -> x.id /= message.id) list) NoMessage
|
, Effect.updateRoute (Route.Mailbox model.mailboxName)
|
||||||
}
|
|
||||||
, Cmd.batch
|
|
||||||
[ Api.deleteMessage model.session DeletedMessage message.mailbox message.id
|
|
||||||
, Route.Mailbox model.mailboxName
|
|
||||||
|> model.session.router.toPath
|
|
||||||
|> Nav.replaceUrl model.session.key
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( model, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
|
|
||||||
{-| Updates both the active message, and the message list to mark the currently viewed message as seen.
|
{-| Updates both the active message, and the message list to mark the currently viewed message as seen.
|
||||||
-}
|
-}
|
||||||
updateMarkMessageSeen : Model -> ( Model, Cmd Msg )
|
updateMarkMessageSeen : Model -> ( Model, Effect Msg )
|
||||||
updateMarkMessageSeen model =
|
updateMarkMessageSeen model =
|
||||||
case model.state of
|
case model.state of
|
||||||
ShowingList messages (ShowingMessage visibleMessage) ->
|
ShowingList messages (ShowingMessage visibleMessage) ->
|
||||||
@@ -442,21 +433,17 @@ updateMarkMessageSeen model =
|
|||||||
| state =
|
| state =
|
||||||
ShowingList newMessages (ShowingMessage { visibleMessage | seen = True })
|
ShowingList newMessages (ShowingMessage { visibleMessage | seen = True })
|
||||||
}
|
}
|
||||||
, Api.markMessageSeen model.session MarkSeenLoaded visibleMessage.mailbox visibleMessage.id
|
, Effect.markMessageSeen MarkSeenLoaded visibleMessage.mailbox visibleMessage.id
|
||||||
)
|
)
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( model, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
|
|
||||||
updateOpenMessage : Model -> String -> ( Model, Cmd Msg )
|
updateOpenMessage : Model -> String -> ( Model, Effect Msg )
|
||||||
updateOpenMessage model id =
|
updateOpenMessage model id =
|
||||||
let
|
( updateSelected model id
|
||||||
newModel =
|
, Effect.getMessage MessageLoaded model.mailboxName id
|
||||||
{ model | session = Session.addRecent model.mailboxName model.session }
|
|
||||||
in
|
|
||||||
( updateSelected newModel id
|
|
||||||
, Api.getMessage model.session MessageLoaded model.mailboxName id
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -467,6 +454,10 @@ updateOpenMessage model id =
|
|||||||
view : Model -> { title : String, modal : Maybe (Html Msg), content : List (Html Msg) }
|
view : Model -> { title : String, modal : Maybe (Html Msg), content : List (Html Msg) }
|
||||||
view model =
|
view model =
|
||||||
let
|
let
|
||||||
|
serveUrl : ServeUrl
|
||||||
|
serveUrl =
|
||||||
|
Api.serveUrl model.session
|
||||||
|
|
||||||
mode =
|
mode =
|
||||||
case model.state of
|
case model.state of
|
||||||
ShowingList _ (ShowingMessage _) ->
|
ShowingList _ (ShowingMessage _) ->
|
||||||
@@ -479,26 +470,7 @@ view model =
|
|||||||
, modal = viewModal model.promptPurge
|
, modal = viewModal model.promptPurge
|
||||||
, content =
|
, content =
|
||||||
[ div [ class ("mailbox " ++ mode) ]
|
[ div [ class ("mailbox " ++ mode) ]
|
||||||
[ aside [ class "message-list-controls" ]
|
[ viewMessageListControls model
|
||||||
[ input
|
|
||||||
[ type_ "text"
|
|
||||||
, placeholder "search"
|
|
||||||
, Events.onInput OnSearchInput
|
|
||||||
, value model.searchInput
|
|
||||||
]
|
|
||||||
[]
|
|
||||||
, button
|
|
||||||
[ Events.onClick (OnSearchInput "")
|
|
||||||
, disabled (model.searchInput == "")
|
|
||||||
, alt "Clear Search"
|
|
||||||
]
|
|
||||||
[ i [ class "fas fa-times" ] [] ]
|
|
||||||
, button
|
|
||||||
[ Events.onClick PurgeMailboxPrompt
|
|
||||||
, alt "Purge Mailbox"
|
|
||||||
]
|
|
||||||
[ i [ class "fas fa-trash" ] [] ]
|
|
||||||
]
|
|
||||||
, viewMessageList model
|
, viewMessageList model
|
||||||
, main_
|
, main_
|
||||||
[ class "message" ]
|
[ class "message" ]
|
||||||
@@ -510,10 +482,10 @@ view model =
|
|||||||
)
|
)
|
||||||
|
|
||||||
ShowingList _ (ShowingMessage message) ->
|
ShowingList _ (ShowingMessage message) ->
|
||||||
viewMessage model.session model.session.zone message model.bodyMode
|
viewMessage serveUrl model.session.zone message model.bodyMode
|
||||||
|
|
||||||
ShowingList _ (Transitioning message) ->
|
ShowingList _ (Transitioning message) ->
|
||||||
viewMessage model.session model.session.zone message model.bodyMode
|
viewMessage serveUrl model.session.zone message model.bodyMode
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
text ""
|
text ""
|
||||||
@@ -539,6 +511,53 @@ viewModal promptPurge =
|
|||||||
Nothing
|
Nothing
|
||||||
|
|
||||||
|
|
||||||
|
viewMessageListControls : Model -> Html Msg
|
||||||
|
viewMessageListControls model =
|
||||||
|
let
|
||||||
|
clearButton =
|
||||||
|
Just <|
|
||||||
|
button
|
||||||
|
[ Events.onClick (OnSearchInput "")
|
||||||
|
, disabled (model.searchInput == "")
|
||||||
|
, alt "Clear Search"
|
||||||
|
]
|
||||||
|
[ i [ class "fas fa-times" ] [] ]
|
||||||
|
|
||||||
|
purgeButton =
|
||||||
|
Just <|
|
||||||
|
button
|
||||||
|
[ Events.onClick PurgeMailboxPrompt
|
||||||
|
, alt "Purge Mailbox"
|
||||||
|
]
|
||||||
|
[ i [ class "fas fa-trash" ] [] ]
|
||||||
|
|
||||||
|
refreshButton =
|
||||||
|
if model.socketConnected then
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
else
|
||||||
|
Just <|
|
||||||
|
button
|
||||||
|
[ Events.onClick ClickRefresh
|
||||||
|
, alt "Refresh Mailbox"
|
||||||
|
]
|
||||||
|
[ i [ class "fas fa-sync" ] [] ]
|
||||||
|
|
||||||
|
searchInput =
|
||||||
|
Just <|
|
||||||
|
input
|
||||||
|
[ type_ "text"
|
||||||
|
, placeholder "search"
|
||||||
|
, Events.onInput OnSearchInput
|
||||||
|
, value model.searchInput
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
in
|
||||||
|
[ searchInput, clearButton, refreshButton, purgeButton ]
|
||||||
|
|> List.filterMap identity
|
||||||
|
|> aside [ class "message-list-controls" ]
|
||||||
|
|
||||||
|
|
||||||
viewMessageList : Model -> Html Msg
|
viewMessageList : Model -> Html Msg
|
||||||
viewMessageList model =
|
viewMessageList model =
|
||||||
aside [ class "message-list" ] <|
|
aside [ class "message-list" ] <|
|
||||||
@@ -571,14 +590,14 @@ messageChip model selected message =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewMessage : Session -> Time.Zone -> Message -> Body -> Html Msg
|
viewMessage : ServeUrl -> Time.Zone -> Message -> Body -> Html Msg
|
||||||
viewMessage session zone message bodyMode =
|
viewMessage serveUrl zone message bodyMode =
|
||||||
let
|
let
|
||||||
htmlUrl =
|
htmlUrl =
|
||||||
Api.serveUrl session [ "mailbox", message.mailbox, message.id, "html" ]
|
serveUrl [ "mailbox", message.mailbox, message.id, "html" ]
|
||||||
|
|
||||||
sourceUrl =
|
sourceUrl =
|
||||||
Api.serveUrl session [ "mailbox", message.mailbox, message.id, "source" ]
|
serveUrl [ "mailbox", message.mailbox, message.id, "source" ]
|
||||||
|
|
||||||
htmlButton =
|
htmlButton =
|
||||||
if message.html == "" then
|
if message.html == "" then
|
||||||
@@ -609,7 +628,7 @@ viewMessage session zone message bodyMode =
|
|||||||
]
|
]
|
||||||
, messageErrors message
|
, messageErrors message
|
||||||
, messageBody message bodyMode
|
, messageBody message bodyMode
|
||||||
, attachments session message
|
, attachments serveUrl message
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -672,20 +691,22 @@ messageBody message bodyMode =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
attachments : Session -> Message -> Html Msg
|
attachments : ServeUrl -> Message -> Html Msg
|
||||||
attachments session message =
|
attachments serveUrl message =
|
||||||
if List.isEmpty message.attachments then
|
if List.isEmpty message.attachments then
|
||||||
div [] []
|
text ""
|
||||||
|
|
||||||
else
|
else
|
||||||
table [ class "attachments well" ] (List.map (attachmentRow session message) message.attachments)
|
message.attachments
|
||||||
|
|> List.map (attachmentRow serveUrl message)
|
||||||
|
|> table [ class "attachments well" ]
|
||||||
|
|
||||||
|
|
||||||
attachmentRow : Session -> Message -> Message.Attachment -> Html Msg
|
attachmentRow : ServeUrl -> Message -> Message.Attachment -> Html Msg
|
||||||
attachmentRow session message attach =
|
attachmentRow serveUrl message attach =
|
||||||
let
|
let
|
||||||
url =
|
url =
|
||||||
Api.serveUrl session
|
serveUrl
|
||||||
[ "mailbox"
|
[ "mailbox"
|
||||||
, message.mailbox
|
, message.mailbox
|
||||||
, message.id
|
, message.id
|
||||||
|
|||||||
+13
-17
@@ -1,10 +1,10 @@
|
|||||||
module Page.Monitor exposing (Model, Msg, init, update, view)
|
module Page.Monitor exposing (Model, Msg, init, update, view)
|
||||||
|
|
||||||
import Api
|
import Api
|
||||||
import Browser.Navigation as Nav
|
|
||||||
import Data.MessageHeader as MessageHeader exposing (MessageHeader)
|
import Data.MessageHeader as MessageHeader exposing (MessageHeader)
|
||||||
import Data.Session as Session exposing (Session)
|
import Data.Session exposing (Session)
|
||||||
import DateFormat as DF
|
import DateFormat as DF
|
||||||
|
import Effect exposing (Effect)
|
||||||
import Html
|
import Html
|
||||||
exposing
|
exposing
|
||||||
( Attribute
|
( Attribute
|
||||||
@@ -41,9 +41,9 @@ type alias Model =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
init : Session -> ( Model, Cmd Msg )
|
init : Session -> ( Model, Effect Msg )
|
||||||
init session =
|
init session =
|
||||||
( Model session False [], Cmd.none )
|
( Model session False [], Effect.none )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -58,20 +58,20 @@ type Msg
|
|||||||
| MessageKeyPress MessageHeader Int
|
| MessageKeyPress MessageHeader Int
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
update : Msg -> Model -> ( Model, Effect Msg )
|
||||||
update msg model =
|
update msg model =
|
||||||
case msg of
|
case msg of
|
||||||
Connected True ->
|
Connected True ->
|
||||||
( { model | connected = True, messages = [] }, Cmd.none )
|
( { model | connected = True, messages = [] }, Effect.none )
|
||||||
|
|
||||||
Connected False ->
|
Connected False ->
|
||||||
( { model | connected = False }, Cmd.none )
|
( { model | connected = False }, Effect.none )
|
||||||
|
|
||||||
MessageReceived value ->
|
MessageReceived value ->
|
||||||
case D.decodeValue (MessageHeader.decoder |> D.at [ "detail" ]) value of
|
case D.decodeValue (MessageHeader.decoder |> D.at [ "detail" ]) value of
|
||||||
Ok header ->
|
Ok header ->
|
||||||
( { model | messages = header :: List.take 500 model.messages }
|
( { model | messages = header :: List.take 500 model.messages }
|
||||||
, Cmd.none
|
, Effect.none
|
||||||
)
|
)
|
||||||
|
|
||||||
Err err ->
|
Err err ->
|
||||||
@@ -81,12 +81,10 @@ update msg model =
|
|||||||
, table = [ ( "Error", D.errorToString err ) ]
|
, table = [ ( "Error", D.errorToString err ) ]
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
( { model | session = Session.showFlash flash model.session }
|
( model, Effect.showFlash flash )
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
Clear ->
|
Clear ->
|
||||||
( { model | messages = [] }, Cmd.none )
|
( { model | messages = [] }, Effect.none )
|
||||||
|
|
||||||
OpenMessage header ->
|
OpenMessage header ->
|
||||||
openMessage header model
|
openMessage header model
|
||||||
@@ -97,15 +95,13 @@ update msg model =
|
|||||||
openMessage header model
|
openMessage header model
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
( model, Cmd.none )
|
( model, Effect.none )
|
||||||
|
|
||||||
|
|
||||||
openMessage : MessageHeader -> Model -> ( Model, Cmd Msg )
|
openMessage : MessageHeader -> Model -> ( Model, Effect Msg )
|
||||||
openMessage header model =
|
openMessage header model =
|
||||||
( model
|
( model
|
||||||
, Route.Message header.mailbox header.id
|
, Effect.navigateRoute True (Route.Message header.mailbox header.id)
|
||||||
|> model.session.router.toPath
|
|
||||||
|> Nav.replaceUrl model.session.key
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+15
-18
@@ -1,10 +1,10 @@
|
|||||||
module Page.Status exposing (Model, Msg, init, subscriptions, update, view)
|
module Page.Status exposing (Model, Msg, init, subscriptions, update, view)
|
||||||
|
|
||||||
import Api
|
|
||||||
import Data.Metrics exposing (Metrics)
|
import Data.Metrics exposing (Metrics)
|
||||||
import Data.ServerConfig exposing (ServerConfig)
|
import Data.ServerConfig exposing (ServerConfig)
|
||||||
import Data.Session as Session exposing (Session)
|
import Data.Session exposing (Session)
|
||||||
import DateFormat.Relative as Relative
|
import DateFormat.Relative as Relative
|
||||||
|
import Effect exposing (Effect)
|
||||||
import Filesize
|
import Filesize
|
||||||
import Html
|
import Html
|
||||||
exposing
|
exposing
|
||||||
@@ -19,7 +19,6 @@ import Html.Attributes exposing (class)
|
|||||||
import HttpUtil
|
import HttpUtil
|
||||||
import Sparkline as Spark
|
import Sparkline as Spark
|
||||||
import Svg.Attributes as SvgAttrib
|
import Svg.Attributes as SvgAttrib
|
||||||
import Task
|
|
||||||
import Time exposing (Posix)
|
import Time exposing (Posix)
|
||||||
|
|
||||||
|
|
||||||
@@ -60,7 +59,7 @@ type alias Metric =
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
init : Session -> ( Model, Cmd Msg )
|
init : Session -> ( Model, Effect Msg )
|
||||||
init session =
|
init session =
|
||||||
( { session = session
|
( { session = session
|
||||||
, now = Time.millisToPosix 0
|
, now = Time.millisToPosix 0
|
||||||
@@ -82,9 +81,9 @@ init session =
|
|||||||
, retainedCount = Metric "Stored Messages" 0 fmtInt graphZero initDataSet 60
|
, retainedCount = Metric "Stored Messages" 0 fmtInt graphZero initDataSet 60
|
||||||
, retainedSize = Metric "Store Size" 0 Filesize.format graphZero initDataSet 60
|
, retainedSize = Metric "Store Size" 0 Filesize.format graphZero initDataSet 60
|
||||||
}
|
}
|
||||||
, Cmd.batch
|
, Effect.batch
|
||||||
[ Task.perform Tick Time.now
|
[ Effect.posixTime Tick
|
||||||
, Api.getServerConfig session ServerConfigLoaded
|
, Effect.getServerConfig ServerConfigLoaded
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -114,27 +113,25 @@ type Msg
|
|||||||
| Tick Posix
|
| Tick Posix
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
update : Msg -> Model -> ( Model, Effect Msg )
|
||||||
update msg model =
|
update msg model =
|
||||||
case msg of
|
case msg of
|
||||||
MetricsReceived (Ok metrics) ->
|
MetricsReceived (Ok metrics) ->
|
||||||
( updateMetrics metrics model, Cmd.none )
|
( updateMetrics metrics model, Effect.none )
|
||||||
|
|
||||||
MetricsReceived (Err err) ->
|
MetricsReceived (Err err) ->
|
||||||
( { model | session = Session.showFlash (HttpUtil.errorFlash err) model.session }
|
( model, Effect.showFlash (HttpUtil.errorFlash err) )
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
ServerConfigLoaded (Ok config) ->
|
ServerConfigLoaded (Ok config) ->
|
||||||
( { model | config = Just config }, Cmd.none )
|
( { model | config = Just config }, Effect.none )
|
||||||
|
|
||||||
ServerConfigLoaded (Err err) ->
|
ServerConfigLoaded (Err err) ->
|
||||||
( { model | session = Session.showFlash (HttpUtil.errorFlash err) model.session }
|
( model, Effect.showFlash (HttpUtil.errorFlash err) )
|
||||||
, Cmd.none
|
|
||||||
)
|
|
||||||
|
|
||||||
Tick time ->
|
Tick time ->
|
||||||
( { model | now = time }, Api.getServerMetrics model.session MetricsReceived )
|
( { model | now = time }
|
||||||
|
, Effect.getServerMetrics MetricsReceived
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
{-| Update all metrics in Model; increment xCounter.
|
{-| Update all metrics in Model; increment xCounter.
|
||||||
@@ -416,7 +413,7 @@ viewMetric metric =
|
|||||||
, div [ class "value" ] [ text (metric.formatter metric.value) ]
|
, div [ class "value" ] [ text (metric.formatter metric.value) ]
|
||||||
, div [ class "graph" ]
|
, div [ class "graph" ]
|
||||||
[ metric.graph metric.history
|
[ metric.graph metric.history
|
||||||
, text ("(" ++ String.fromInt metric.minutes ++ "min)")
|
, text (" (" ++ String.fromInt metric.minutes ++ "min)")
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ cancel previous =
|
|||||||
previous
|
previous
|
||||||
|
|
||||||
|
|
||||||
|
{-| Increments the timer identity, preventing integer overflow.
|
||||||
|
-}
|
||||||
next : Int -> Int
|
next : Int -> Int
|
||||||
next index =
|
next index =
|
||||||
if index > 2 ^ 30 then
|
if index > 2 ^ 30 then
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import './mailbox.css'
|
|||||||
import './navbar.css'
|
import './navbar.css'
|
||||||
import '@fortawesome/fontawesome-free/css/all.css'
|
import '@fortawesome/fontawesome-free/css/all.css'
|
||||||
import '@webcomponents/webcomponentsjs/webcomponents-bundle'
|
import '@webcomponents/webcomponentsjs/webcomponents-bundle'
|
||||||
|
import 'opensans-npm-webfont'
|
||||||
import { Elm } from './Main.elm'
|
import { Elm } from './Main.elm'
|
||||||
import './monitorMessages'
|
import './monitorMessages'
|
||||||
import './renderedHtml'
|
import './renderedHtml'
|
||||||
|
|||||||
@@ -98,9 +98,14 @@
|
|||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-style: none solid solid solid;
|
border-style: none solid solid solid;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
padding: 5px 8px;
|
padding: 5px 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-list-entry:focus {
|
||||||
|
background-color: var(--focused-bg-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
.message-list-entry.selected {
|
.message-list-entry.selected {
|
||||||
background-color: var(--selected-color);
|
background-color: var(--selected-color);
|
||||||
}
|
}
|
||||||
@@ -109,6 +114,10 @@
|
|||||||
border-style: solid;
|
border-style: solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-list-entry:focus .subject {
|
||||||
|
color: var(--focused-color);
|
||||||
|
}
|
||||||
|
|
||||||
.message-list-entry .subject {
|
.message-list-entry .subject {
|
||||||
color: var(--high-color);
|
color: var(--high-color);
|
||||||
}
|
}
|
||||||
@@ -117,6 +126,12 @@
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-list-entry:focus .from,
|
||||||
|
.message-list-entry:focus .date {
|
||||||
|
color: var(--focused-color);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
.message-list-entry .from,
|
.message-list-entry .from,
|
||||||
.message-list-entry .date {
|
.message-list-entry .date {
|
||||||
color: var(--low-color);
|
color: var(--low-color);
|
||||||
|
|||||||
+12
-3
@@ -9,6 +9,8 @@
|
|||||||
--border-color: #ddd;
|
--border-color: #ddd;
|
||||||
--placeholder-color: #9f9f9f;
|
--placeholder-color: #9f9f9f;
|
||||||
--selected-color: #eee;
|
--selected-color: #eee;
|
||||||
|
--focused-color: #fff;
|
||||||
|
--focused-bg-color: #337ab7;
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body, div, span, applet, object, iframe,
|
html, body, div, span, applet, object, iframe,
|
||||||
@@ -46,8 +48,9 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body, button, input, table {
|
body, button, input, table {
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
font-family: "Open Sans", Helvetica, Arial, sans-serif;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
line-height: 1.43;
|
line-height: 1.43;
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
@@ -73,7 +76,7 @@ a.button {
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
margin: 4px;
|
margin: 4px;
|
||||||
padding: 3px 8px;
|
padding: 3px 8px 4px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-shadow: 0 -1px 0 rgba(0,0,0,0.2);
|
text-shadow: 0 -1px 0 rgba(0,0,0,0.2);
|
||||||
}
|
}
|
||||||
@@ -245,7 +248,7 @@ h3 {
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 5px 10px;
|
padding: 5px 10px 6px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-shadow: 0 -1px 0 rgba(0,0,0,0.2);
|
text-shadow: 0 -1px 0 rgba(0,0,0,0.2);
|
||||||
@@ -351,3 +354,9 @@ h3 {
|
|||||||
background-color: var(--selected-color);
|
background-color: var(--selected-color);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.monitor tr:focus {
|
||||||
|
color: var(--focused-color);
|
||||||
|
background-color: var(--focused-bg-color);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
.navbar-brand {
|
.navbar-brand {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-toggle {
|
.navbar-toggle {
|
||||||
|
|||||||
@@ -35,12 +35,10 @@ module.exports = (env, argv) => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
include: [/\/src/, /\/node_modules\/@fortawesome\/fontawesome-free\/css/],
|
|
||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
loader: ['style-loader', 'css-loader'],
|
loader: ['style-loader', 'css-loader'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
include: [/\/node_modules\/@fortawesome\/fontawesome-free\/webfonts/],
|
|
||||||
test: /\.(eot|svg|ttf|woff|woff2)$/,
|
test: /\.(eot|svg|ttf|woff|woff2)$/,
|
||||||
loader: 'file-loader',
|
loader: 'file-loader',
|
||||||
options: {
|
options: {
|
||||||
|
|||||||
Reference in New Issue
Block a user