Compare commits

...

10 Commits

Author SHA1 Message Date
Deluan
be12c12b28 Remove unused Badge component from ActivityPanel icon 2023-05-17 16:29:19 -04:00
Kendall Garner
a19a643c65
Manually add replaygain tags for m4a (#2346)
* manually add replaygain tags for m4a

* Add replaygain tests for m4a, mp4, ogg

* add new valye for bitrate
2023-05-17 16:00:16 -04:00
Deluan
f9b060af18 Removed onBackdropClick deprecated property 2023-05-17 15:48:22 -04:00
Deluan
a3d78e95f2 Fix Monokai theme. Closes #2353 2023-05-17 15:36:30 -04:00
Deluan
d85b06332c Fix build 2023-05-17 13:49:45 -04:00
Deluan
bfa10cab62 Upgrade to Node v18 2023-05-17 13:41:36 -04:00
Deluan
08fcb430e6 Upgrade React-Admin to 3.19.12 2023-05-17 13:18:58 -04:00
Deluan
5d02df62d0 Fix eslint error 2023-05-17 11:57:43 -04:00
Deluan
c3a2e084b3 Update caniuse-lite 2023-05-17 11:54:22 -04:00
Deluan
4296741ec0 Simplify EventStream handling 2023-05-17 11:53:09 -04:00
29 changed files with 392 additions and 359 deletions

View File

@ -4,10 +4,10 @@
"dockerfile": "Dockerfile",
"args": {
// Update the VARIANT arg to pick a version of Go: 1, 1.15, 1.14
"VARIANT": "1.19",
"VARIANT": "1.20",
// Options
"INSTALL_NODE": "true",
"NODE_VERSION": "v16"
"NODE_VERSION": "v18"
}
},
"workspaceMount": "",

View File

@ -80,7 +80,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
node-version: 18
cache: 'npm'
cache-dependency-path: '**/package-lock.json'

2
.nvmrc
View File

@ -1 +1 @@
v16
v18

View File

@ -40,7 +40,7 @@ var _ = Describe("Tags", func() {
Expect(m.Channels()).To(Equal(2))
Expect(m.FilePath()).To(Equal("tests/fixtures/test.mp3"))
Expect(m.Suffix()).To(Equal("mp3"))
Expect(m.Size()).To(Equal(int64(51876)))
Expect(m.Size()).To(Equal(int64(52050)))
Expect(m.RGAlbumGain()).To(Equal(3.21518))
Expect(m.RGAlbumPeak()).To(Equal(0.9125))
Expect(m.RGTrackGain()).To(Equal(-1.48))
@ -53,10 +53,10 @@ var _ = Describe("Tags", func() {
Expect(m.Duration()).To(BeNumerically("~", 1.04, 0.01))
Expect(m.Suffix()).To(Equal("ogg"))
Expect(m.FilePath()).To(Equal("tests/fixtures/test.ogg"))
Expect(m.Size()).To(Equal(int64(5065)))
Expect(m.Size()).To(Equal(int64(5178)))
// TabLib 1.12 returns 18, previous versions return 39.
// See https://github.com/taglib/taglib/commit/2f238921824741b2cfe6fbfbfc9701d9827ab06b
Expect(m.BitRate()).To(BeElementOf(18, 39))
Expect(m.BitRate()).To(BeElementOf(18, 39, 40))
})
})
})

View File

@ -65,7 +65,35 @@ var _ = Describe("Extractor", func() {
// TabLib 1.12 returns 18, previous versions return 39.
// See https://github.com/taglib/taglib/commit/2f238921824741b2cfe6fbfbfc9701d9827ab06b
Expect(m).To(HaveKey("bitrate"))
Expect(m["bitrate"][0]).To(BeElementOf("18", "39"))
Expect(m["bitrate"][0]).To(BeElementOf("18", "39", "40"))
})
Context("ReplayGain", func() {
testGain := func(file, albumGain, albumPeak, trackGain, trackPeak string) {
file = "tests/fixtures/" + file
mds, err := e.Parse(file)
Expect(err).NotTo(HaveOccurred())
Expect(mds).To(HaveLen(1))
m := mds[file]
Expect(m).To(HaveKeyWithValue("replaygain_album_gain", []string{albumGain}))
Expect(m).To(HaveKeyWithValue("replaygain_album_peak", []string{albumPeak}))
Expect(m).To(HaveKeyWithValue("replaygain_track_gain", []string{trackGain}))
Expect(m).To(HaveKeyWithValue("replaygain_track_peak", []string{trackPeak}))
}
It("Correctly parses m4a (aac) gain tags", func() {
testGain("01 Invisible (RED) Edit Version.m4a", "0.37", "0.48", "0.37", "0.48")
})
It("correctly parses mp3 tags", func() {
testGain("test.mp3", "+3.21518 dB", "0.9125", "-1.48 dB", "0.4512")
})
It("correctly parses ogg (vorbis) tags", func() {
testGain("test.ogg", "+7.64 dB", "0.11772506", "+7.64 dB", "0.11772506")
})
})
})

View File

@ -15,6 +15,13 @@
#include "taglib_wrapper.h"
// Tags necessary for M4a parsing
const char *RG_TAGS[] = {
"replaygain_album_gain",
"replaygain_album_peak",
"replaygain_track_gain",
"replaygain_track_peak"};
char has_cover(const TagLib::FileRef f);
int taglib_read(const FILENAME_CHAR_T *filename, unsigned long id) {
@ -70,6 +77,29 @@ int taglib_read(const FILENAME_CHAR_T *filename, unsigned long id) {
}
}
TagLib::MP4::File *m4afile(dynamic_cast<TagLib::MP4::File *>(f.file()));
if (m4afile != NULL)
{
const auto itemListMap = m4afile->tag();
{
char buf[200];
for (const char *key : RG_TAGS)
{
snprintf(buf, sizeof(buf), "----:com.apple.iTunes:%s", key);
const auto item = itemListMap->item(buf);
if (item.isValid())
{
char *dup = ::strdup(key);
char *val = ::strdup(item.toStringList().front().toCString(true));
go_map_put_str(id, dup, val);
free(dup);
free(val);
}
}
}
}
if (has_cover(f)) {
go_map_put_str(id, (char *)"has_picture", (char *)"true");
}

View File

@ -10,11 +10,12 @@ var _ = Describe("TagScanner", func() {
It("return all audio files from the folder", func() {
files, err := loadAllAudioFiles("tests/fixtures")
Expect(err).ToNot(HaveOccurred())
Expect(files).To(HaveLen(4))
Expect(files).To(HaveLen(5))
Expect(files).To(HaveKey("tests/fixtures/test.ogg"))
Expect(files).To(HaveKey("tests/fixtures/test.mp3"))
Expect(files).To(HaveKey("tests/fixtures/test_no_read_permission.ogg"))
Expect(files).To(HaveKey("tests/fixtures/01 Invisible (RED) Edit Version.mp3"))
Expect(files).To(HaveKey("tests/fixtures/01 Invisible (RED) Edit Version.m4a"))
Expect(files).ToNot(HaveKey("tests/fixtures/._02 Invisible.mp3"))
Expect(files).ToNot(HaveKey("tests/fixtures/playlist.m3u"))
})

View File

@ -36,7 +36,7 @@ var _ = Describe("walk_dir_tree", func() {
Expect(collected[baseDir]).To(MatchFields(IgnoreExtras, Fields{
"Images": BeEmpty(),
"HasPlaylist": BeFalse(),
"AudioFilesCount": BeNumerically("==", 5),
"AudioFilesCount": BeNumerically("==", 6),
}))
Expect(collected[filepath.Join(baseDir, "artist", "an-album")]).To(MatchFields(IgnoreExtras, Fields{
"Images": ConsistOf("cover.jpg", "front.png", "artist.png"),

Binary file not shown.

Binary file not shown.

Binary file not shown.

468
ui/package-lock.json generated
View File

@ -23,10 +23,10 @@
"lodash.throttle": "^4.1.1",
"navidrome-music-player": "4.25.1",
"prop-types": "^15.7.2",
"ra-data-json-server": "^3.18.3",
"ra-i18n-polyglot": "^3.18.3",
"ra-data-json-server": "^3.19.12",
"ra-i18n-polyglot": "^3.19.12",
"react": "^17.0.2",
"react-admin": "^3.18.3",
"react-admin": "^3.19.12",
"react-dnd": "^14.0.4",
"react-dnd-html5-backend": "^14.0.2",
"react-dom": "^17.0.2",
@ -49,7 +49,7 @@
"@testing-library/user-event": "^13.5.0",
"css-mediaquery": "^0.1.2",
"prettier": "2.8.2",
"ra-test": "^3.18.3",
"ra-test": "^3.19.12",
"react-scripts": "5.0.1",
"workbox-cli": "^6.3.0"
}
@ -1982,11 +1982,11 @@
}
},
"node_modules/@babel/runtime": {
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz",
"integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==",
"version": "7.21.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz",
"integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
"regenerator-runtime": "^0.13.11"
},
"engines": {
"node": ">=6.9.0"
@ -3203,15 +3203,16 @@
"dev": true
},
"node_modules/@material-ui/core": {
"version": "4.11.4",
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.4.tgz",
"integrity": "sha512-oqb+lJ2Dl9HXI9orc6/aN8ZIAMkeThufA5iZELf2LQeBn2NtjVilF5D2w7e9RpntAzDb4jK5DsVhkfOvFY/8fg==",
"version": "4.12.4",
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.12.4.tgz",
"integrity": "sha512-tr7xekNlM9LjA6pagJmL8QCgZXaubWUwkJnoYcMKd4gw/t4XiyvnTkjdGrUVicyB2BsdaAv1tvow45bPM4sSwQ==",
"deprecated": "Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5.",
"dependencies": {
"@babel/runtime": "^7.4.4",
"@material-ui/styles": "^4.11.4",
"@material-ui/system": "^4.11.3",
"@material-ui/styles": "^4.11.5",
"@material-ui/system": "^4.12.2",
"@material-ui/types": "5.1.0",
"@material-ui/utils": "^4.11.2",
"@material-ui/utils": "^4.11.3",
"@types/react-transition-group": "^4.2.0",
"clsx": "^1.0.4",
"hoist-non-react-statics": "^3.3.2",
@ -3222,6 +3223,20 @@
},
"engines": {
"node": ">=8.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/material-ui"
},
"peerDependencies": {
"@types/react": "^16.8.6 || ^17.0.0",
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@material-ui/icons": {
@ -3292,17 +3307,31 @@
}
},
"node_modules/@material-ui/system": {
"version": "4.11.3",
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz",
"integrity": "sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw==",
"version": "4.12.2",
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.12.2.tgz",
"integrity": "sha512-6CSKu2MtmiJgcCGf6nBQpM8fLkuB9F55EKfbdTC80NND5wpTmKzwdhLYLH3zL4cLlK0gVaaltW7/wMuyTnN0Lw==",
"dependencies": {
"@babel/runtime": "^7.4.4",
"@material-ui/utils": "^4.11.2",
"@material-ui/utils": "^4.11.3",
"csstype": "^2.5.2",
"prop-types": "^15.7.2"
},
"engines": {
"node": ">=8.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/material-ui"
},
"peerDependencies": {
"@types/react": "^16.8.6 || ^17.0.0",
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@material-ui/types": {
@ -5244,11 +5273,11 @@
}
},
"node_modules/autosuggest-highlight": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/autosuggest-highlight/-/autosuggest-highlight-3.1.1.tgz",
"integrity": "sha512-MQ6GNIGMMZbeA5FlBLXXgkZEthysCdYNkMV4MahB2/qB/9cwBnVsePUPnIqkMuzjzclTtDa67xln7cgLDu2f/g==",
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/autosuggest-highlight/-/autosuggest-highlight-3.3.4.tgz",
"integrity": "sha512-j6RETBD2xYnrVcoV1S5R4t3WxOlWZKyDQjkwnggDPSjF5L4jV98ZltBpvPvbkM1HtoSe5o+bNrTHyjPbieGeYA==",
"dependencies": {
"diacritic": "0.0.2"
"remove-accents": "^0.4.2"
}
},
"node_modules/axe-core": {
@ -5976,9 +6005,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001470",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001470.tgz",
"integrity": "sha512-065uNwY6QtHCBOExzbV6m236DDhYCCtPmQUCoQtwkVqzud8v5QPidoMr6CoMkC2nfp6nksjttqWQRRh75LqUmA==",
"version": "1.0.30001488",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001488.tgz",
"integrity": "sha512-NORIQuuL4xGpIy6iCCQGN4iFjlBXtfKWIenlUuyZJumLRIindLb7wXM+GO8erEhb7vXfcnf4BAg2PrSDN5TNLQ==",
"dev": true,
"funding": [
{
@ -5988,6 +6017,10 @@
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
]
},
@ -6083,9 +6116,9 @@
"dev": true
},
"node_modules/classnames": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"node_modules/clean-css": {
"version": "5.3.1",
@ -6391,9 +6424,9 @@
"dev": true
},
"node_modules/compute-scroll-into-view": {
"version": "1.0.17",
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz",
"integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg=="
"version": "1.0.20",
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz",
"integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg=="
},
"node_modules/concat-map": {
"version": "0.0.1",
@ -7295,11 +7328,6 @@
"node": ">=0.8.0"
}
},
"node_modules/diacritic": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/diacritic/-/diacritic-0.0.2.tgz",
"integrity": "sha1-/CqIe1pbwKCoVPthTHwvIJBh7gQ="
},
"node_modules/didyoumean": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
@ -7477,6 +7505,11 @@
}
]
},
"node_modules/dompurify": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.5.tgz",
"integrity": "sha512-jggCCd+8Iqp4Tsz0nIvpcb22InKEBrGz5dw3EQJMs8HPJDsKbFIO3STYtAvCfDx26Muevn1MHVI0XxjgFfmiSA=="
},
"node_modules/domutils": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
@ -8963,9 +8996,9 @@
}
},
"node_modules/file-selector/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
},
"node_modules/filelist": {
"version": "1.0.4",
@ -9019,19 +9052,23 @@
}
},
"node_modules/final-form": {
"version": "4.20.2",
"resolved": "https://registry.npmjs.org/final-form/-/final-form-4.20.2.tgz",
"integrity": "sha512-5i0IxqwjjPG1nUNCjWhqPCvQJJ2R+QwTwaAnjPmFnLbyjIHWuBPU8u+Ps4G3TcX2Sjno+O5xCZJzYcMJEzzfCQ==",
"version": "4.20.9",
"resolved": "https://registry.npmjs.org/final-form/-/final-form-4.20.9.tgz",
"integrity": "sha512-shA1X/7v8RmukWMNRHx0l7+Bm41hOivY78IvOiBrPVHjyWFIyqqIEMCz7yTVRc9Ea+EU4WkZ5r4MH6whSo5taw==",
"dependencies": {
"@babel/runtime": "^7.10.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/final-form"
}
},
"node_modules/final-form-arrays": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/final-form-arrays/-/final-form-arrays-3.0.2.tgz",
"integrity": "sha512-TfO8aZNz3RrsZCDx8GHMQcyztDNpGxSSi9w4wpSNKlmv2PfFWVVM8P7Yj5tj4n0OWax+x5YwTLhT5BnqSlCi+w==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/final-form-arrays/-/final-form-arrays-3.1.0.tgz",
"integrity": "sha512-TWBvun+AopgBLw9zfTFHBllnKMVNEwCEyDawphPuBGGqNsuhGzhT7yewHys64KFFwzIs6KEteGLpKOwvTQEscQ==",
"peerDependencies": {
"final-form": "^4.18.2"
"final-form": "^4.20.8"
}
},
"node_modules/finalhandler": {
@ -13939,11 +13976,6 @@
"react-dom": ">=16.9.0"
}
},
"node_modules/navidrome-music-player/node_modules/classnames": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@ -16211,14 +16243,14 @@
}
},
"node_modules/ra-core": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/ra-core/-/ra-core-3.18.3.tgz",
"integrity": "sha512-DRIsbf1G7Zvvzs55TiMJvZ56psDk5Syj/PxPBhmMmhVoSavZ/i23J+ObKrGUKWNk4cwNg3IZR8IxZCGyMEe1Qg==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/ra-core/-/ra-core-3.19.12.tgz",
"integrity": "sha512-E0cM6OjEUtccaR+dR5mL1MLiVVYML0Yf7aPhpLEq4iue73X3+CKcLztInoBhWgeevPbFQwgAtsXhlpedeyrNNg==",
"dependencies": {
"classnames": "~2.2.5",
"classnames": "~2.3.1",
"date-fns": "^1.29.0",
"eventemitter3": "^3.0.0",
"inflection": "~1.12.0",
"inflection": "~1.13.1",
"lodash": "~4.17.5",
"prop-types": "^15.6.1",
"query-string": "^5.1.1",
@ -16227,6 +16259,7 @@
"peerDependencies": {
"connected-react-router": "^6.5.2",
"final-form": "^4.20.2",
"history": "^4.7.2",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0",
"react-final-form": "^6.5.2",
@ -16237,48 +16270,40 @@
"redux-saga": "^1.0.0"
}
},
"node_modules/ra-core/node_modules/inflection": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz",
"integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=",
"engines": [
"node >= 0.4.0"
]
},
"node_modules/ra-data-json-server": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/ra-data-json-server/-/ra-data-json-server-3.18.3.tgz",
"integrity": "sha512-OuZPAMcb8FwnIV9sl78pyyM5I0oIxs4H6UNvYxAgk2zSgrmtQ4/a1kjuczAOWBfVm3yA3m2uiLfLpMJvYECnGw==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/ra-data-json-server/-/ra-data-json-server-3.19.12.tgz",
"integrity": "sha512-SEa0ueZd9LUG6iuPnHd+MHWf7BTgLKjx3Eky16VvTsqf6ueHkMU8AZiH1pHzrdxV6ku5VL34MCYWVSIbm2iDnw==",
"dependencies": {
"query-string": "^5.1.1",
"ra-core": "^3.18.3"
"ra-core": "^3.19.12"
}
},
"node_modules/ra-i18n-polyglot": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/ra-i18n-polyglot/-/ra-i18n-polyglot-3.18.3.tgz",
"integrity": "sha512-nUMtFguhMzy6iYw1MlKcVYkTFHces/tEhEgOi6SAGsBgcQ652g7G0UDVdJh6kWDYUiu4UvoREfmZhIorihuoDA==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/ra-i18n-polyglot/-/ra-i18n-polyglot-3.19.12.tgz",
"integrity": "sha512-7VkNybY+RYVL5aDf8MdefYpRMkaELOjSXx7rrRY7PzVwmQzVe5ESoKBcH4Cob2M8a52pAlXY32dwmA3dZ91l/Q==",
"dependencies": {
"node-polyglot": "^2.2.2",
"ra-core": "^3.18.3"
"ra-core": "^3.19.12"
}
},
"node_modules/ra-language-english": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/ra-language-english/-/ra-language-english-3.18.3.tgz",
"integrity": "sha512-w3020CLLmiammZOSKI4CsIWyD9ZFs/oNFWKSnPzvN6EqQI2dtSxxiycKjaxnwjKN7jmzNWe/5uzna0FIND4wgA==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/ra-language-english/-/ra-language-english-3.19.12.tgz",
"integrity": "sha512-aYY0ma74eXLuflPT9iXEQtVEDZxebw1NiQZ5pPGiBCpsq+hoiDWuzerLU13OdBHbySD5FHLuk89SkyAdfMtUaQ==",
"dependencies": {
"ra-core": "^3.18.3"
"ra-core": "^3.19.12"
}
},
"node_modules/ra-test": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/ra-test/-/ra-test-3.18.3.tgz",
"integrity": "sha512-TcJgH1Eh1vMqW/QaoDf9ArFb15p4ToQRDntZofRF368/7xSXuuub1WdlLddGaRj2A4xITRUvnFyel7RVZ9QTtw==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/ra-test/-/ra-test-3.19.12.tgz",
"integrity": "sha512-SX6oi+VPADIeQeQlGWUVj2kgEYgLbizpzYMq+oacCmnAqvHezwnQ2MXrLDRK6C56YIl+t8DyY/ipYBiRPZnHbA==",
"dev": true,
"dependencies": {
"@testing-library/react": "^11.2.3",
"classnames": "~2.2.5",
"classnames": "~2.3.1",
"lodash": "~4.17.5"
},
"peerDependencies": {
@ -16344,16 +16369,17 @@
}
},
"node_modules/ra-ui-materialui": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/ra-ui-materialui/-/ra-ui-materialui-3.18.3.tgz",
"integrity": "sha512-rzeK0hm/CmL6EvNRDfk9PKcf1l/T25J/vCLALDvUhzDDa4QeMJ/tTC4CeHCmBS2dKhbV7tq3uz67fuoOHNZEDQ==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/ra-ui-materialui/-/ra-ui-materialui-3.19.12.tgz",
"integrity": "sha512-8Zz88r5yprmUxOw9/F0A/kjjVmFMb2n+sjpel8fuOWtS6y++JWonDsvTwo4yIuSF9mC0fht3f/hd2KEHQdmj6Q==",
"dependencies": {
"autosuggest-highlight": "^3.1.1",
"classnames": "~2.2.5",
"connected-react-router": "^6.5.2",
"css-mediaquery": "^0.1.2",
"dompurify": "^2.4.3",
"downshift": "3.2.7",
"inflection": "~1.12.0",
"inflection": "~1.13.1",
"jsonexport": "^2.4.1",
"lodash": "~4.17.5",
"prop-types": "^15.7.0",
@ -16362,9 +16388,9 @@
"react-transition-group": "^4.4.1"
},
"peerDependencies": {
"@material-ui/core": "^4.11.2",
"@material-ui/core": "^4.12.1",
"@material-ui/icons": "^4.11.2",
"@material-ui/styles": "^4.11.2",
"@material-ui/styles": "^4.11.4",
"final-form": "^4.20.2",
"final-form-arrays": "^3.0.2",
"ra-core": "^3.14.0",
@ -16378,13 +16404,10 @@
"redux": "^3.7.2 || ^4.0.3"
}
},
"node_modules/ra-ui-materialui/node_modules/inflection": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz",
"integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=",
"engines": [
"node >= 0.4.0"
]
"node_modules/ra-ui-materialui/node_modules/classnames": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
},
"node_modules/raf": {
"version": "3.4.1",
@ -16555,21 +16578,21 @@
}
},
"node_modules/react-admin": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/react-admin/-/react-admin-3.18.3.tgz",
"integrity": "sha512-Oml8q6hQboa026zY4k9T5UDWDWK6YA3ltxMPLuh1oRYmCYy+oAcUFGcoGu2nzkzVh/fUoz0HSZV75eWW5Foi+g==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/react-admin/-/react-admin-3.19.12.tgz",
"integrity": "sha512-LanWS3Yjie7n5GZI8v7oP73DSvQyCeZD0dpkC65IC0+UOhkInxa1zedJc8CyD3+ZwlgVC+CGqi6jQ1fo73Cdqw==",
"dependencies": {
"@material-ui/core": "^4.11.2",
"@material-ui/core": "^4.12.1",
"@material-ui/icons": "^4.11.2",
"@material-ui/styles": "^4.11.2",
"connected-react-router": "^6.5.2",
"final-form": "^4.20.2",
"final-form": "^4.20.4",
"final-form-arrays": "^3.0.2",
"ra-core": "^3.18.3",
"ra-i18n-polyglot": "^3.18.3",
"ra-language-english": "^3.18.3",
"ra-ui-materialui": "^3.18.3",
"react-final-form": "^6.5.2",
"ra-core": "^3.19.12",
"ra-i18n-polyglot": "^3.19.12",
"ra-language-english": "^3.19.12",
"ra-ui-materialui": "^3.19.12",
"react-final-form": "^6.5.7",
"react-final-form-arrays": "^3.1.3",
"react-redux": "^7.1.0",
"react-router": "^5.1.0",
@ -16833,24 +16856,32 @@
"dev": true
},
"node_modules/react-final-form": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/react-final-form/-/react-final-form-6.5.3.tgz",
"integrity": "sha512-FCs6GC0AMWJl2p6YX7kM+a0AvuSLAZUgbVNtRBskOs4g984t/It0qGtx51O+9vgqnqk6JyoxmIzxKMq+7ch/vg==",
"version": "6.5.9",
"resolved": "https://registry.npmjs.org/react-final-form/-/react-final-form-6.5.9.tgz",
"integrity": "sha512-x3XYvozolECp3nIjly+4QqxdjSSWfcnpGEL5K8OBT6xmGrq5kBqbA6+/tOqoom9NwqIPPbxPNsOViFlbKgowbA==",
"dependencies": {
"@babel/runtime": "^7.12.1"
"@babel/runtime": "^7.15.4"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/final-form"
},
"peerDependencies": {
"final-form": "^4.20.4",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-final-form-arrays": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/react-final-form-arrays/-/react-final-form-arrays-3.1.3.tgz",
"integrity": "sha512-dzBiLfbr9l1YRExARBpJ8uA/djBenCvFrbrsXjd362joDl3vT+WhmMKKr6HDQMJffjA8T4gZ3n5+G9M59yZfuQ==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/react-final-form-arrays/-/react-final-form-arrays-3.1.4.tgz",
"integrity": "sha512-siVFAolUAe29rMR6u8VwepoysUcUdh6MLV2OWnCtKpsPRUdT9VUgECjAPaVMAH2GROZNiVB9On1H9MMrm9gdpg==",
"dependencies": {
"@babel/runtime": "^7.12.1"
"@babel/runtime": "^7.19.4"
},
"peerDependencies": {
"final-form": "^4.15.0",
"final-form-arrays": ">=1.0.4",
"react": "^16.8.0 || ^17.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react-final-form": "^6.2.1"
}
},
@ -17340,9 +17371,9 @@
}
},
"node_modules/regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
"node_modules/regenerator-transform": {
"version": "0.15.0",
@ -17464,6 +17495,11 @@
"node": ">= 0.10"
}
},
"node_modules/remove-accents": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.4.tgz",
"integrity": "sha512-EpFcOa/ISetVHEXqu+VwI96KZBmq+a8LJnGkaeFw45epGlxIZz5dhEEnNZMsQXgORu3qaMoLX4qJCzOik6ytAg=="
},
"node_modules/renderkid": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz",
@ -22115,11 +22151,11 @@
}
},
"@babel/runtime": {
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz",
"integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==",
"version": "7.21.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz",
"integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==",
"requires": {
"regenerator-runtime": "^0.13.4"
"regenerator-runtime": "^0.13.11"
}
},
"@babel/runtime-corejs3": {
@ -23010,15 +23046,15 @@
"dev": true
},
"@material-ui/core": {
"version": "4.11.4",
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.4.tgz",
"integrity": "sha512-oqb+lJ2Dl9HXI9orc6/aN8ZIAMkeThufA5iZELf2LQeBn2NtjVilF5D2w7e9RpntAzDb4jK5DsVhkfOvFY/8fg==",
"version": "4.12.4",
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.12.4.tgz",
"integrity": "sha512-tr7xekNlM9LjA6pagJmL8QCgZXaubWUwkJnoYcMKd4gw/t4XiyvnTkjdGrUVicyB2BsdaAv1tvow45bPM4sSwQ==",
"requires": {
"@babel/runtime": "^7.4.4",
"@material-ui/styles": "^4.11.4",
"@material-ui/system": "^4.11.3",
"@material-ui/styles": "^4.11.5",
"@material-ui/system": "^4.12.2",
"@material-ui/types": "5.1.0",
"@material-ui/utils": "^4.11.2",
"@material-ui/utils": "^4.11.3",
"@types/react-transition-group": "^4.2.0",
"clsx": "^1.0.4",
"hoist-non-react-statics": "^3.3.2",
@ -23072,12 +23108,12 @@
}
},
"@material-ui/system": {
"version": "4.11.3",
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz",
"integrity": "sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw==",
"version": "4.12.2",
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.12.2.tgz",
"integrity": "sha512-6CSKu2MtmiJgcCGf6nBQpM8fLkuB9F55EKfbdTC80NND5wpTmKzwdhLYLH3zL4cLlK0gVaaltW7/wMuyTnN0Lw==",
"requires": {
"@babel/runtime": "^7.4.4",
"@material-ui/utils": "^4.11.2",
"@material-ui/utils": "^4.11.3",
"csstype": "^2.5.2",
"prop-types": "^15.7.2"
}
@ -24648,11 +24684,11 @@
}
},
"autosuggest-highlight": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/autosuggest-highlight/-/autosuggest-highlight-3.1.1.tgz",
"integrity": "sha512-MQ6GNIGMMZbeA5FlBLXXgkZEthysCdYNkMV4MahB2/qB/9cwBnVsePUPnIqkMuzjzclTtDa67xln7cgLDu2f/g==",
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/autosuggest-highlight/-/autosuggest-highlight-3.3.4.tgz",
"integrity": "sha512-j6RETBD2xYnrVcoV1S5R4t3WxOlWZKyDQjkwnggDPSjF5L4jV98ZltBpvPvbkM1HtoSe5o+bNrTHyjPbieGeYA==",
"requires": {
"diacritic": "0.0.2"
"remove-accents": "^0.4.2"
}
},
"axe-core": {
@ -25240,9 +25276,9 @@
}
},
"caniuse-lite": {
"version": "1.0.30001470",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001470.tgz",
"integrity": "sha512-065uNwY6QtHCBOExzbV6m236DDhYCCtPmQUCoQtwkVqzud8v5QPidoMr6CoMkC2nfp6nksjttqWQRRh75LqUmA==",
"version": "1.0.30001488",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001488.tgz",
"integrity": "sha512-NORIQuuL4xGpIy6iCCQGN4iFjlBXtfKWIenlUuyZJumLRIindLb7wXM+GO8erEhb7vXfcnf4BAg2PrSDN5TNLQ==",
"dev": true
},
"case-sensitive-paths-webpack-plugin": {
@ -25314,9 +25350,9 @@
"dev": true
},
"classnames": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
},
"clean-css": {
"version": "5.3.1",
@ -25562,9 +25598,9 @@
}
},
"compute-scroll-into-view": {
"version": "1.0.17",
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz",
"integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg=="
"version": "1.0.20",
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz",
"integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg=="
},
"concat-map": {
"version": "0.0.1",
@ -26220,11 +26256,6 @@
"minimist": "^1.2.6"
}
},
"diacritic": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/diacritic/-/diacritic-0.0.2.tgz",
"integrity": "sha1-/CqIe1pbwKCoVPthTHwvIJBh7gQ="
},
"didyoumean": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
@ -26380,6 +26411,11 @@
}
}
},
"dompurify": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.5.tgz",
"integrity": "sha512-jggCCd+8Iqp4Tsz0nIvpcb22InKEBrGz5dw3EQJMs8HPJDsKbFIO3STYtAvCfDx26Muevn1MHVI0XxjgFfmiSA=="
},
"domutils": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
@ -27511,9 +27547,9 @@
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
}
}
},
@ -27562,17 +27598,17 @@
}
},
"final-form": {
"version": "4.20.2",
"resolved": "https://registry.npmjs.org/final-form/-/final-form-4.20.2.tgz",
"integrity": "sha512-5i0IxqwjjPG1nUNCjWhqPCvQJJ2R+QwTwaAnjPmFnLbyjIHWuBPU8u+Ps4G3TcX2Sjno+O5xCZJzYcMJEzzfCQ==",
"version": "4.20.9",
"resolved": "https://registry.npmjs.org/final-form/-/final-form-4.20.9.tgz",
"integrity": "sha512-shA1X/7v8RmukWMNRHx0l7+Bm41hOivY78IvOiBrPVHjyWFIyqqIEMCz7yTVRc9Ea+EU4WkZ5r4MH6whSo5taw==",
"requires": {
"@babel/runtime": "^7.10.0"
}
},
"final-form-arrays": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/final-form-arrays/-/final-form-arrays-3.0.2.tgz",
"integrity": "sha512-TfO8aZNz3RrsZCDx8GHMQcyztDNpGxSSi9w4wpSNKlmv2PfFWVVM8P7Yj5tj4n0OWax+x5YwTLhT5BnqSlCi+w==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/final-form-arrays/-/final-form-arrays-3.1.0.tgz",
"integrity": "sha512-TWBvun+AopgBLw9zfTFHBllnKMVNEwCEyDawphPuBGGqNsuhGzhT7yewHys64KFFwzIs6KEteGLpKOwvTQEscQ==",
"requires": {}
},
"finalhandler": {
@ -31380,13 +31416,6 @@
"rc-switch": "^3.2.2",
"react-draggable": "^4.4.3",
"sortablejs": "^1.13.0"
},
"dependencies": {
"classnames": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
}
}
},
"negotiator": {
@ -32913,61 +32942,54 @@
"dev": true
},
"ra-core": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/ra-core/-/ra-core-3.18.3.tgz",
"integrity": "sha512-DRIsbf1G7Zvvzs55TiMJvZ56psDk5Syj/PxPBhmMmhVoSavZ/i23J+ObKrGUKWNk4cwNg3IZR8IxZCGyMEe1Qg==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/ra-core/-/ra-core-3.19.12.tgz",
"integrity": "sha512-E0cM6OjEUtccaR+dR5mL1MLiVVYML0Yf7aPhpLEq4iue73X3+CKcLztInoBhWgeevPbFQwgAtsXhlpedeyrNNg==",
"requires": {
"classnames": "~2.2.5",
"classnames": "~2.3.1",
"date-fns": "^1.29.0",
"eventemitter3": "^3.0.0",
"inflection": "~1.12.0",
"inflection": "~1.13.1",
"lodash": "~4.17.5",
"prop-types": "^15.6.1",
"query-string": "^5.1.1",
"reselect": "~3.0.0"
},
"dependencies": {
"inflection": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz",
"integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY="
}
}
},
"ra-data-json-server": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/ra-data-json-server/-/ra-data-json-server-3.18.3.tgz",
"integrity": "sha512-OuZPAMcb8FwnIV9sl78pyyM5I0oIxs4H6UNvYxAgk2zSgrmtQ4/a1kjuczAOWBfVm3yA3m2uiLfLpMJvYECnGw==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/ra-data-json-server/-/ra-data-json-server-3.19.12.tgz",
"integrity": "sha512-SEa0ueZd9LUG6iuPnHd+MHWf7BTgLKjx3Eky16VvTsqf6ueHkMU8AZiH1pHzrdxV6ku5VL34MCYWVSIbm2iDnw==",
"requires": {
"query-string": "^5.1.1",
"ra-core": "^3.18.3"
"ra-core": "^3.19.12"
}
},
"ra-i18n-polyglot": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/ra-i18n-polyglot/-/ra-i18n-polyglot-3.18.3.tgz",
"integrity": "sha512-nUMtFguhMzy6iYw1MlKcVYkTFHces/tEhEgOi6SAGsBgcQ652g7G0UDVdJh6kWDYUiu4UvoREfmZhIorihuoDA==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/ra-i18n-polyglot/-/ra-i18n-polyglot-3.19.12.tgz",
"integrity": "sha512-7VkNybY+RYVL5aDf8MdefYpRMkaELOjSXx7rrRY7PzVwmQzVe5ESoKBcH4Cob2M8a52pAlXY32dwmA3dZ91l/Q==",
"requires": {
"node-polyglot": "^2.2.2",
"ra-core": "^3.18.3"
"ra-core": "^3.19.12"
}
},
"ra-language-english": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/ra-language-english/-/ra-language-english-3.18.3.tgz",
"integrity": "sha512-w3020CLLmiammZOSKI4CsIWyD9ZFs/oNFWKSnPzvN6EqQI2dtSxxiycKjaxnwjKN7jmzNWe/5uzna0FIND4wgA==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/ra-language-english/-/ra-language-english-3.19.12.tgz",
"integrity": "sha512-aYY0ma74eXLuflPT9iXEQtVEDZxebw1NiQZ5pPGiBCpsq+hoiDWuzerLU13OdBHbySD5FHLuk89SkyAdfMtUaQ==",
"requires": {
"ra-core": "^3.18.3"
"ra-core": "^3.19.12"
}
},
"ra-test": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/ra-test/-/ra-test-3.18.3.tgz",
"integrity": "sha512-TcJgH1Eh1vMqW/QaoDf9ArFb15p4ToQRDntZofRF368/7xSXuuub1WdlLddGaRj2A4xITRUvnFyel7RVZ9QTtw==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/ra-test/-/ra-test-3.19.12.tgz",
"integrity": "sha512-SX6oi+VPADIeQeQlGWUVj2kgEYgLbizpzYMq+oacCmnAqvHezwnQ2MXrLDRK6C56YIl+t8DyY/ipYBiRPZnHbA==",
"dev": true,
"requires": {
"@testing-library/react": "^11.2.3",
"classnames": "~2.2.5",
"classnames": "~2.3.1",
"lodash": "~4.17.5"
},
"dependencies": {
@ -33010,16 +33032,17 @@
}
},
"ra-ui-materialui": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/ra-ui-materialui/-/ra-ui-materialui-3.18.3.tgz",
"integrity": "sha512-rzeK0hm/CmL6EvNRDfk9PKcf1l/T25J/vCLALDvUhzDDa4QeMJ/tTC4CeHCmBS2dKhbV7tq3uz67fuoOHNZEDQ==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/ra-ui-materialui/-/ra-ui-materialui-3.19.12.tgz",
"integrity": "sha512-8Zz88r5yprmUxOw9/F0A/kjjVmFMb2n+sjpel8fuOWtS6y++JWonDsvTwo4yIuSF9mC0fht3f/hd2KEHQdmj6Q==",
"requires": {
"autosuggest-highlight": "^3.1.1",
"classnames": "~2.2.5",
"connected-react-router": "^6.5.2",
"css-mediaquery": "^0.1.2",
"dompurify": "^2.4.3",
"downshift": "3.2.7",
"inflection": "~1.12.0",
"inflection": "~1.13.1",
"jsonexport": "^2.4.1",
"lodash": "~4.17.5",
"prop-types": "^15.7.0",
@ -33028,10 +33051,10 @@
"react-transition-group": "^4.4.1"
},
"dependencies": {
"inflection": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz",
"integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY="
"classnames": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
}
}
},
@ -33184,21 +33207,21 @@
}
},
"react-admin": {
"version": "3.18.3",
"resolved": "https://registry.npmjs.org/react-admin/-/react-admin-3.18.3.tgz",
"integrity": "sha512-Oml8q6hQboa026zY4k9T5UDWDWK6YA3ltxMPLuh1oRYmCYy+oAcUFGcoGu2nzkzVh/fUoz0HSZV75eWW5Foi+g==",
"version": "3.19.12",
"resolved": "https://registry.npmjs.org/react-admin/-/react-admin-3.19.12.tgz",
"integrity": "sha512-LanWS3Yjie7n5GZI8v7oP73DSvQyCeZD0dpkC65IC0+UOhkInxa1zedJc8CyD3+ZwlgVC+CGqi6jQ1fo73Cdqw==",
"requires": {
"@material-ui/core": "^4.11.2",
"@material-ui/core": "^4.12.1",
"@material-ui/icons": "^4.11.2",
"@material-ui/styles": "^4.11.2",
"connected-react-router": "^6.5.2",
"final-form": "^4.20.2",
"final-form": "^4.20.4",
"final-form-arrays": "^3.0.2",
"ra-core": "^3.18.3",
"ra-i18n-polyglot": "^3.18.3",
"ra-language-english": "^3.18.3",
"ra-ui-materialui": "^3.18.3",
"react-final-form": "^6.5.2",
"ra-core": "^3.19.12",
"ra-i18n-polyglot": "^3.19.12",
"ra-language-english": "^3.19.12",
"ra-ui-materialui": "^3.19.12",
"react-final-form": "^6.5.7",
"react-final-form-arrays": "^3.1.3",
"react-redux": "^7.1.0",
"react-router": "^5.1.0",
@ -33388,19 +33411,19 @@
"dev": true
},
"react-final-form": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/react-final-form/-/react-final-form-6.5.3.tgz",
"integrity": "sha512-FCs6GC0AMWJl2p6YX7kM+a0AvuSLAZUgbVNtRBskOs4g984t/It0qGtx51O+9vgqnqk6JyoxmIzxKMq+7ch/vg==",
"version": "6.5.9",
"resolved": "https://registry.npmjs.org/react-final-form/-/react-final-form-6.5.9.tgz",
"integrity": "sha512-x3XYvozolECp3nIjly+4QqxdjSSWfcnpGEL5K8OBT6xmGrq5kBqbA6+/tOqoom9NwqIPPbxPNsOViFlbKgowbA==",
"requires": {
"@babel/runtime": "^7.12.1"
"@babel/runtime": "^7.15.4"
}
},
"react-final-form-arrays": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/react-final-form-arrays/-/react-final-form-arrays-3.1.3.tgz",
"integrity": "sha512-dzBiLfbr9l1YRExARBpJ8uA/djBenCvFrbrsXjd362joDl3vT+WhmMKKr6HDQMJffjA8T4gZ3n5+G9M59yZfuQ==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/react-final-form-arrays/-/react-final-form-arrays-3.1.4.tgz",
"integrity": "sha512-siVFAolUAe29rMR6u8VwepoysUcUdh6MLV2OWnCtKpsPRUdT9VUgECjAPaVMAH2GROZNiVB9On1H9MMrm9gdpg==",
"requires": {
"@babel/runtime": "^7.12.1"
"@babel/runtime": "^7.19.4"
}
},
"react-ga": {
@ -33759,9 +33782,9 @@
}
},
"regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
"regenerator-transform": {
"version": "0.15.0",
@ -33855,6 +33878,11 @@
"integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
"dev": true
},
"remove-accents": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.4.tgz",
"integrity": "sha512-EpFcOa/ISetVHEXqu+VwI96KZBmq+a8LJnGkaeFw45epGlxIZz5dhEEnNZMsQXgORu3qaMoLX4qJCzOik6ytAg=="
},
"renderkid": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz",

View File

@ -18,10 +18,10 @@
"lodash.throttle": "^4.1.1",
"navidrome-music-player": "4.25.1",
"prop-types": "^15.7.2",
"ra-data-json-server": "^3.18.3",
"ra-i18n-polyglot": "^3.18.3",
"ra-data-json-server": "^3.19.12",
"ra-i18n-polyglot": "^3.19.12",
"react": "^17.0.2",
"react-admin": "^3.18.3",
"react-admin": "^3.19.12",
"react-dnd": "^14.0.4",
"react-dnd-html5-backend": "^14.0.2",
"react-dom": "^17.0.2",
@ -44,7 +44,7 @@
"@testing-library/user-event": "^13.5.0",
"css-mediaquery": "^0.1.2",
"prettier": "2.8.2",
"ra-test": "^3.18.3",
"ra-test": "^3.19.12",
"react-scripts": "5.0.1",
"workbox-cli": "^6.3.0"
},
@ -58,7 +58,7 @@
"update-workbox": "bin/update-workbox.sh"
},
"homepage": ".",
"proxy": "http://localhost:4633/",
"proxy": "http://127.0.0.1:4633/",
"eslintConfig": {
"extends": [
"react-app",

View File

@ -1,4 +1,3 @@
import React, { useEffect } from 'react'
import ReactGA from 'react-ga'
import { Provider } from 'react-redux'
import { createHashHistory } from 'history'
@ -34,7 +33,6 @@ import {
import createAdminStore from './store/createAdminStore'
import { i18nProvider } from './i18n'
import config, { shareInfo } from './config'
import { setDispatch, startEventStream, stopEventStream } from './eventStream'
import { keyMap } from './hotkeys'
import useChangeThemeColor from './useChangeThemeColor'
import SharePlayer from './share/SharePlayer'
@ -76,18 +74,6 @@ const App = () => (
const Admin = (props) => {
useChangeThemeColor()
useEffect(() => {
if (config.devActivityPanel) {
setDispatch(adminStore.dispatch)
authProvider
.checkAuth()
.then(() => startEventStream(adminStore.dispatch))
.catch(() => {})
}
return () => {
stopEventStream()
}
}, [])
return (
<RAAdmin

View File

@ -2,13 +2,10 @@ export const EVENT_SCAN_STATUS = 'scanStatus'
export const EVENT_SERVER_START = 'serverStart'
export const EVENT_REFRESH_RESOURCE = 'refreshResource'
export const processEvent = (type, data) => {
return {
export const processEvent = (type, data) => ({
type,
data: data,
}
}
})
export const scanStatusUpdate = (data) => ({
type: EVENT_SCAN_STATUS,
data: data,

View File

@ -1,7 +1,6 @@
import jwtDecode from 'jwt-decode'
import { baseUrl } from './utils'
import config from './config'
import { startEventStream, stopEventStream } from './eventStream'
// config sent from server may contain authentication info, for example when the user is authenticated
// by a reverse proxy request header
@ -48,9 +47,6 @@ const authProvider = {
storeAuthenticationInfo(response)
// Avoid "going to create admin" dialog after logout/login without a refresh
config.firstTime = false
if (config.devActivityPanel) {
startEventStream()
}
return response
})
.catch((error) => {
@ -66,7 +62,6 @@ const authProvider = {
},
logout: () => {
stopEventStream()
removeItems()
return Promise.resolve()
},
@ -90,11 +85,11 @@ const authProvider = {
},
getIdentity: () => {
return {
return Promise.resolve({
id: localStorage.getItem('username'),
fullName: localStorage.getItem('name'),
avatar: localStorage.getItem('avatar'),
}
})
},
}

View File

@ -52,12 +52,7 @@ const LinkToVersion = ({ version }) => {
const AboutDialog = ({ open, onClose }) => {
const translate = useTranslate()
return (
<Dialog
onClose={onClose}
onBackdropClick={onClose}
aria-labelledby="about-dialog-title"
open={open}
>
<Dialog onClose={onClose} aria-labelledby="about-dialog-title" open={open}>
<DialogTitle id="about-dialog-title" onClose={onClose}>
Navidrome Music Server
</DialogTitle>

View File

@ -139,7 +139,6 @@ export const AddToPlaylistDialog = () => {
<Dialog
open={open}
onClose={handleClickClose}
onBackdropClick={handleClickClose}
aria-labelledby="form-dialog-new-playlist"
fullWidth={true}
maxWidth={'sm'}

View File

@ -44,7 +44,6 @@ const DownloadMenuDialog = () => {
<Dialog
open={open}
onClose={handleClose}
onBackdropClick={handleClose}
aria-labelledby="download-dialog"
fullWidth={true}
maxWidth={'sm'}

View File

@ -21,7 +21,6 @@ const DuplicateSongDialog = ({
<Dialog
open={open}
onClose={handleClickClose}
onBackdropClick={handleClickClose}
aria-labelledby="form-dialog-duplicate-song"
>
<DialogTitle id="form-dialog-duplicate-song">

View File

@ -25,7 +25,6 @@ const ExpandInfoDialog = ({ title, content }) => {
<Dialog
open={open}
onClose={handleClose}
onBackdropClick={handleClose}
aria-labelledby="info-dialog-album"
fullWidth={true}
maxWidth={'sm'}

View File

@ -73,11 +73,7 @@ export const HelpDialog = (props) => {
return (
<>
<GlobalHotKeys keyMap={keyMap} handlers={handlers} allowChanges />
<HelpTable
open={open}
onClose={handleClickClose}
onBackdropClick={handleClickClose}
/>
<HelpTable open={open} onClose={handleClickClose} />
</>
)
}

View File

@ -82,7 +82,6 @@ export const ListenBrainzTokenDialog = ({ setLinked }) => {
<Dialog
open={open}
onClose={handleClickClose}
onBackdropClick={handleClickClose}
aria-labelledby="form-dialog-listenbrainz-token"
fullWidth={true}
maxWidth="md"

View File

@ -93,7 +93,6 @@ export const ShareDialog = () => {
<Dialog
open={open}
onClose={handleClose}
onBackdropClick={handleClose}
aria-labelledby="share-dialog"
fullWidth={true}
maxWidth={'sm'}

View File

@ -1,83 +1,42 @@
import { baseUrl } from './utils'
import throttle from 'lodash.throttle'
import { processEvent, serverDown } from './actions'
import { httpClient } from './dataProvider'
import { REST_URL } from './consts'
const defaultIntervalCheck = 20000
const reconnectIntervalCheck = 2000
let currentIntervalCheck = reconnectIntervalCheck
let es = null
let dispatch = null
let timeout = null
const getEventStream = async () => {
if (!es) {
// Call `keepalive` to refresh the jwt token
await httpClient(`${REST_URL}/keepalive/keepalive`)
const newEventStream = async () => {
let url = baseUrl(`${REST_URL}/events`)
if (localStorage.getItem('token')) {
url = url + `?jwt=${localStorage.getItem('token')}`
}
es = new EventSource(url)
}
return es
return new EventSource(url)
}
// Reestablish the event stream after 20 secs of inactivity
const setTimeout = (value) => {
currentIntervalCheck = value
if (timeout) {
window.clearTimeout(timeout)
}
timeout = window.setTimeout(async () => {
es?.close()
es = null
await startEventStream()
}, currentIntervalCheck)
}
const stopEventStream = () => {
es?.close()
es = null
if (timeout) {
window.clearTimeout(timeout)
}
timeout = null
console.log('eventSource closed') // TODO For debug purposes. Remove later
}
const setDispatch = (dispatchFunc) => {
dispatch = dispatchFunc
}
const eventHandler = (event) => {
const eventHandler = (dispatchFn) => (event) => {
const data = JSON.parse(event.data)
if (event.type !== 'keepAlive') {
dispatch(processEvent(event.type, data))
dispatchFn(processEvent(event.type, data))
}
setTimeout(defaultIntervalCheck) // Reset timeout on every received message
}
const throttledEventHandler = throttle(eventHandler, 100, { trailing: true })
const throttledEventHandler = (dispatchFn) =>
throttle(eventHandler(dispatchFn), 100, { trailing: true })
const startEventStream = async () => {
setTimeout(currentIntervalCheck)
const startEventStream = async (dispatchFn) => {
if (!localStorage.getItem('is-authenticated')) {
return Promise.resolve()
}
return getEventStream()
return newEventStream()
.then((newStream) => {
newStream.addEventListener('serverStart', eventHandler)
newStream.addEventListener('scanStatus', throttledEventHandler)
newStream.addEventListener('refreshResource', eventHandler)
newStream.addEventListener('keepAlive', eventHandler)
newStream.addEventListener('serverStart', eventHandler(dispatchFn))
newStream.addEventListener(
'scanStatus',
throttledEventHandler(dispatchFn)
)
newStream.addEventListener('refreshResource', eventHandler(dispatchFn))
newStream.addEventListener('keepAlive', eventHandler(dispatchFn))
newStream.onerror = (e) => {
console.log('EventStream error', e)
es?.close()
es = null
setTimeout(reconnectIntervalCheck)
dispatch(serverDown())
dispatchFn(serverDown())
}
return newStream
})
@ -86,4 +45,4 @@ const startEventStream = async () => {
})
}
export { setDispatch, startEventStream, stopEventStream }
export { startEventStream }

View File

@ -3,7 +3,6 @@ import { useDispatch, useSelector } from 'react-redux'
import { useNotify, useTranslate } from 'react-admin'
import {
Popover,
Badge,
CircularProgress,
IconButton,
makeStyles,
@ -94,9 +93,7 @@ const ActivityPanel = () => {
<div className={classes.wrapper}>
<Tooltip title={translate('activity.title')}>
<IconButton className={classes.button} onClick={handleMenuOpen}>
<Badge badgeContent={null} color="secondary">
{up ? <FiActivity size={'20'} /> : <BiError size={'20'} />}
</Badge>
</IconButton>
</Tooltip>
{scanStatus.scanning && (

View File

@ -1,5 +1,11 @@
import * as React from 'react'
import { Children, cloneElement, isValidElement, useState } from 'react'
import {
Children,
cloneElement,
isValidElement,
useEffect,
useState,
} from 'react'
import PropTypes from 'prop-types'
import { useTranslate, useGetIdentity } from 'react-admin'
import {
@ -16,6 +22,9 @@ import {
import { makeStyles } from '@material-ui/core/styles'
import AccountCircle from '@material-ui/icons/AccountCircle'
import config from '../config'
import authProvider from '../authProvider'
import { startEventStream } from '../eventStream'
import { useDispatch } from 'react-redux'
const useStyles = makeStyles((theme) => ({
user: {},
@ -40,8 +49,19 @@ const UserMenu = (props) => {
const translate = useTranslate()
const { loaded, identity } = useGetIdentity()
const classes = useStyles(props)
const dispatch = useDispatch()
const { children, label, icon, logout } = props
useEffect(() => {
if (config.devActivityPanel) {
authProvider
.checkAuth()
.then(() => startEventStream(dispatch))
.catch(() => {})
}
}, [dispatch])
if (!logout && !children) return null
const open = Boolean(anchorEl)

View File

@ -4,17 +4,24 @@
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom/extend-expect'
class LocalStorageMock {
constructor() {
this.store = {}
}
getItem(key) {
return this.store[key] || null
}
setItem(key, value) {
this.store[key] = String(value)
}
}
const localStorageMock = (function () {
let store = {}
return {
getItem: function (key) {
return store[key] || null
},
setItem: function (key, value) {
store[key] = value.toString()
},
clear: function () {
store = {}
},
}
})()
Object.defineProperty(window, 'localStorage', {
value: localStorageMock,
})
global.localStorage = new LocalStorageMock()
localStorage.setItem('username', 'admin')

View File

@ -98,7 +98,7 @@ export default {
},
},
player: {
theme: 'monokai',
theme: 'dark',
stylesheet: require('./monokai.css.js'),
},
}