pifi 0.4.9 → 0.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/pifi/public/asset-manifest.json +10 -10
- data/lib/pifi/public/index.html +1 -1
- data/lib/pifi/public/{precache-manifest.fcc3d04ae31f62d65a121704ace339bd.js → precache-manifest.7164537a626dea8757b9c96b06c8c33d.js} +8 -8
- data/lib/pifi/public/service-worker.js +1 -1
- data/lib/pifi/public/static/css/2.1781c263.chunk.css +2 -0
- data/lib/pifi/public/static/css/2.1781c263.chunk.css.map +1 -0
- data/lib/pifi/public/static/css/main.48912641.chunk.css +2 -0
- data/lib/pifi/public/static/css/main.48912641.chunk.css.map +1 -0
- data/lib/pifi/public/static/js/main.21a62959.chunk.js +2 -0
- data/lib/pifi/public/static/js/main.21a62959.chunk.js.map +1 -0
- data/lib/pifi/version.rb +1 -1
- metadata +9 -9
- data/lib/pifi/public/static/css/2.d34346ea.chunk.css +0 -2
- data/lib/pifi/public/static/css/2.d34346ea.chunk.css.map +0 -1
- data/lib/pifi/public/static/css/main.221e80d3.chunk.css +0 -2
- data/lib/pifi/public/static/css/main.221e80d3.chunk.css.map +0 -1
- data/lib/pifi/public/static/js/main.6c9ebb8a.chunk.js +0 -2
- data/lib/pifi/public/static/js/main.6c9ebb8a.chunk.js.map +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4dc79fc2366bf2fa58a43af2c9a5771f47407bf57c3935a293fb947417cc8a3
|
4
|
+
data.tar.gz: 5de137d51ec40045814c8f9e58cd4ae41b5e8bb52009d1030fffc606ec3eb8c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a97c702c8d9fd8819bf7b9e375096043520b9a16e279a2274621f5406cf0fae701e1f486e68ac9857cc118962507a816392f47099ca1bcaa4042064356181b6
|
7
|
+
data.tar.gz: bbdee92c38748951cd8f4106b709fc1c17d2c40e9933145c13d9f69e34acc23a44edbeeb4dfbb4d35c00982a0a933808607526b9a6267c7ff519323d43929c84
|
data/README.md
CHANGED
@@ -164,7 +164,7 @@ The default language for PiFi is English, so you should use it as a reference.
|
|
164
164
|
|
165
165
|
If you find PiFi useful, you can show your support here:
|
166
166
|
|
167
|
-
<a href="https://
|
167
|
+
<a href="https://rafaelc.org/coffee" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" width="200" ></a>
|
168
168
|
|
169
169
|
## License
|
170
170
|
|
@@ -1,27 +1,27 @@
|
|
1
1
|
{
|
2
2
|
"files": {
|
3
|
-
"main.css": "/static/css/main.
|
4
|
-
"main.js": "/static/js/main.
|
5
|
-
"main.js.map": "/static/js/main.
|
3
|
+
"main.css": "/static/css/main.48912641.chunk.css",
|
4
|
+
"main.js": "/static/js/main.21a62959.chunk.js",
|
5
|
+
"main.js.map": "/static/js/main.21a62959.chunk.js.map",
|
6
6
|
"runtime-main.js": "/static/js/runtime-main.5aae5a31.js",
|
7
7
|
"runtime-main.js.map": "/static/js/runtime-main.5aae5a31.js.map",
|
8
|
-
"static/css/2.
|
8
|
+
"static/css/2.1781c263.chunk.css": "/static/css/2.1781c263.chunk.css",
|
9
9
|
"static/js/2.6c0ded8a.chunk.js": "/static/js/2.6c0ded8a.chunk.js",
|
10
10
|
"static/js/2.6c0ded8a.chunk.js.map": "/static/js/2.6c0ded8a.chunk.js.map",
|
11
11
|
"index.html": "/index.html",
|
12
|
-
"precache-manifest.
|
12
|
+
"precache-manifest.7164537a626dea8757b9c96b06c8c33d.js": "/precache-manifest.7164537a626dea8757b9c96b06c8c33d.js",
|
13
13
|
"service-worker.js": "/service-worker.js",
|
14
|
-
"static/css/2.
|
15
|
-
"static/css/main.
|
14
|
+
"static/css/2.1781c263.chunk.css.map": "/static/css/2.1781c263.chunk.css.map",
|
15
|
+
"static/css/main.48912641.chunk.css.map": "/static/css/main.48912641.chunk.css.map",
|
16
16
|
"static/js/2.6c0ded8a.chunk.js.LICENSE.txt": "/static/js/2.6c0ded8a.chunk.js.LICENSE.txt",
|
17
17
|
"static/media/getFetch.cjs": "/static/media/getFetch.5e98861f.cjs",
|
18
18
|
"static/media/logo.svg": "/static/media/logo.91554ce9.svg"
|
19
19
|
},
|
20
20
|
"entrypoints": [
|
21
21
|
"static/js/runtime-main.5aae5a31.js",
|
22
|
-
"static/css/2.
|
22
|
+
"static/css/2.1781c263.chunk.css",
|
23
23
|
"static/js/2.6c0ded8a.chunk.js",
|
24
|
-
"static/css/main.
|
25
|
-
"static/js/main.
|
24
|
+
"static/css/main.48912641.chunk.css",
|
25
|
+
"static/js/main.21a62959.chunk.js"
|
26
26
|
]
|
27
27
|
}
|
data/lib/pifi/public/index.html
CHANGED
@@ -1 +1 @@
|
|
1
|
-
<!doctype html><html><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="description" content="MPD web client to listen to radio"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="manifest" href="/manifest.json"><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"><meta name="apple-mobile-web-app-title" content="PiFi Radio"><meta name="application-name" content="PiFi Radio"><meta name="msapplication-TileColor" content="#2b5797"><meta name="theme-color" content="#375a7f"><title>PiFi Radio</title><link rel="preload" href="https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/darkly/bootstrap.min.css" as="style"><link href="https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/darkly/bootstrap.min.css" rel="stylesheet" title="theme"><link href="/static/css/2.
|
1
|
+
<!doctype html><html><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="description" content="MPD web client to listen to radio"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="manifest" href="/manifest.json"><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"><meta name="apple-mobile-web-app-title" content="PiFi Radio"><meta name="application-name" content="PiFi Radio"><meta name="msapplication-TileColor" content="#2b5797"><meta name="theme-color" content="#375a7f"><title>PiFi Radio</title><link rel="preload" href="https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/darkly/bootstrap.min.css" as="style"><link href="https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/darkly/bootstrap.min.css" rel="stylesheet" title="theme"><link href="/static/css/2.1781c263.chunk.css" rel="stylesheet"><link href="/static/css/main.48912641.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>var isIE=window.document.documentMode,unsupportedMsg='<img src="/assets/logo80.png" class="mx-auto d-block my-5">';if(unsupportedMsg+='<h5 class="text-center my-5">This browser is not supported</h5>',isIE){var root=document.getElementById("root");root.innerHTML=unsupportedMsg,root.setAttribute("id","")}</script><script>!function(e){function r(r){for(var n,f,i=r[0],l=r[1],p=r[2],c=0,s=[];c<i.length;c++)f=i[c],Object.prototype.hasOwnProperty.call(o,f)&&o[f]&&s.push(o[f][0]),o[f]=0;for(n in l)Object.prototype.hasOwnProperty.call(l,n)&&(e[n]=l[n]);for(a&&a(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var l=t[i];0!==o[l]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={1:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var i=this.webpackJsonppifi_frontend=this.webpackJsonppifi_frontend||[],l=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var a=l;t()}([])</script><script src="/static/js/2.6c0ded8a.chunk.js"></script><script src="/static/js/main.21a62959.chunk.js"></script></body></html>
|
@@ -1,18 +1,18 @@
|
|
1
1
|
self.__precacheManifest = (self.__precacheManifest || []).concat([
|
2
2
|
{
|
3
|
-
"revision": "
|
3
|
+
"revision": "19b492bc2ecc8c8ce1fcaa3d2d7ce285",
|
4
4
|
"url": "/index.html"
|
5
5
|
},
|
6
6
|
{
|
7
|
-
"revision": "
|
8
|
-
"url": "/static/css/2.
|
7
|
+
"revision": "59d428a63666535e7576",
|
8
|
+
"url": "/static/css/2.1781c263.chunk.css"
|
9
9
|
},
|
10
10
|
{
|
11
|
-
"revision": "
|
12
|
-
"url": "/static/css/main.
|
11
|
+
"revision": "ab3bef23cc7a2926b1ca",
|
12
|
+
"url": "/static/css/main.48912641.chunk.css"
|
13
13
|
},
|
14
14
|
{
|
15
|
-
"revision": "
|
15
|
+
"revision": "59d428a63666535e7576",
|
16
16
|
"url": "/static/js/2.6c0ded8a.chunk.js"
|
17
17
|
},
|
18
18
|
{
|
@@ -20,8 +20,8 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
|
|
20
20
|
"url": "/static/js/2.6c0ded8a.chunk.js.LICENSE.txt"
|
21
21
|
},
|
22
22
|
{
|
23
|
-
"revision": "
|
24
|
-
"url": "/static/js/main.
|
23
|
+
"revision": "ab3bef23cc7a2926b1ca",
|
24
|
+
"url": "/static/js/main.21a62959.chunk.js"
|
25
25
|
},
|
26
26
|
{
|
27
27
|
"revision": "af7ed8886109d8666769",
|
@@ -14,7 +14,7 @@
|
|
14
14
|
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
|
15
15
|
|
16
16
|
importScripts(
|
17
|
-
"/precache-manifest.
|
17
|
+
"/precache-manifest.7164537a626dea8757b9c96b06c8c33d.js"
|
18
18
|
);
|
19
19
|
|
20
20
|
self.addEventListener('message', (event) => {
|
@@ -0,0 +1,2 @@
|
|
1
|
+
.Toastify__toast-container{z-index:9999;-webkit-transform:translateZ(9999px);position:fixed;padding:4px;width:320px;box-sizing:border-box;color:#fff}.Toastify__toast-container--top-left{top:1em;left:1em}.Toastify__toast-container--top-center{top:1em;left:50%;transform:translateX(-50%)}.Toastify__toast-container--top-right{top:1em;right:1em}.Toastify__toast-container--bottom-left{bottom:1em;left:1em}.Toastify__toast-container--bottom-center{bottom:1em;left:50%;transform:translateX(-50%)}.Toastify__toast-container--bottom-right{bottom:1em;right:1em}@media only screen and (max-width:480px){.Toastify__toast-container{width:100vw;padding:0;left:0;margin:0}.Toastify__toast-container--top-center,.Toastify__toast-container--top-left,.Toastify__toast-container--top-right{top:0;transform:translateX(0)}.Toastify__toast-container--bottom-center,.Toastify__toast-container--bottom-left,.Toastify__toast-container--bottom-right{bottom:0;transform:translateX(0)}.Toastify__toast-container--rtl{right:0;left:auto}}.Toastify__toast{position:relative;min-height:64px;box-sizing:border-box;margin-bottom:1rem;padding:8px;border-radius:1px;box-shadow:0 1px 10px 0 rgba(0,0,0,.1),0 2px 15px 0 rgba(0,0,0,.05);display:flex;justify-content:space-between;max-height:800px;overflow:hidden;font-family:sans-serif;cursor:pointer;direction:ltr}.Toastify__toast--rtl{direction:rtl}.Toastify__toast--dark{background:#121212;color:#fff}.Toastify__toast--default{background:#fff;color:#aaa}.Toastify__toast--info{background:#3498db}.Toastify__toast--success{background:#07bc0c}.Toastify__toast--warning{background:#f1c40f}.Toastify__toast--error{background:#e74c3c}.Toastify__toast-body{margin:auto 0;flex:1 1 auto}@media only screen and (max-width:480px){.Toastify__toast{margin-bottom:0}}.Toastify__close-button{color:#fff;background:transparent;outline:none;border:none;padding:0;cursor:pointer;opacity:.7;transition:.3s ease;align-self:flex-start}.Toastify__close-button--default{color:#000;opacity:.3}.Toastify__close-button>svg{fill:currentColor;height:16px;width:14px}.Toastify__close-button:focus,.Toastify__close-button:hover{opacity:1}@keyframes Toastify__trackProgress{0%{transform:scaleX(1)}to{transform:scaleX(0)}}.Toastify__progress-bar{position:absolute;bottom:0;left:0;width:100%;height:5px;z-index:9999;opacity:.7;background-color:hsla(0,0%,100%,.7);transform-origin:left}.Toastify__progress-bar--animated{animation:Toastify__trackProgress linear 1 forwards}.Toastify__progress-bar--controlled{transition:transform .2s}.Toastify__progress-bar--rtl{right:0;left:auto;transform-origin:right}.Toastify__progress-bar--default{background:linear-gradient(90deg,#4cd964,#5ac8fa,#007aff,#34aadc,#5856d6,#ff2d55)}.Toastify__progress-bar--dark{background:#bb86fc}@keyframes Toastify__bounceInRight{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(3000px,0,0)}60%{opacity:1;transform:translate3d(-25px,0,0)}75%{transform:translate3d(10px,0,0)}90%{transform:translate3d(-5px,0,0)}to{transform:none}}@keyframes Toastify__bounceOutRight{20%{opacity:1;transform:translate3d(-20px,0,0)}to{opacity:0;transform:translate3d(2000px,0,0)}}@keyframes Toastify__bounceInLeft{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(-3000px,0,0)}60%{opacity:1;transform:translate3d(25px,0,0)}75%{transform:translate3d(-10px,0,0)}90%{transform:translate3d(5px,0,0)}to{transform:none}}@keyframes Toastify__bounceOutLeft{20%{opacity:1;transform:translate3d(20px,0,0)}to{opacity:0;transform:translate3d(-2000px,0,0)}}@keyframes Toastify__bounceInUp{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(0,3000px,0)}60%{opacity:1;transform:translate3d(0,-20px,0)}75%{transform:translate3d(0,10px,0)}90%{transform:translate3d(0,-5px,0)}to{transform:translateZ(0)}}@keyframes Toastify__bounceOutUp{20%{transform:translate3d(0,-10px,0)}40%,45%{opacity:1;transform:translate3d(0,20px,0)}to{opacity:0;transform:translate3d(0,-2000px,0)}}@keyframes Toastify__bounceInDown{0%,60%,75%,90%,to{animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(0,-3000px,0)}60%{opacity:1;transform:translate3d(0,25px,0)}75%{transform:translate3d(0,-10px,0)}90%{transform:translate3d(0,5px,0)}to{transform:none}}@keyframes Toastify__bounceOutDown{20%{transform:translate3d(0,10px,0)}40%,45%{opacity:1;transform:translate3d(0,-20px,0)}to{opacity:0;transform:translate3d(0,2000px,0)}}.Toastify__bounce-enter--bottom-left,.Toastify__bounce-enter--top-left{animation-name:Toastify__bounceInLeft}.Toastify__bounce-enter--bottom-right,.Toastify__bounce-enter--top-right{animation-name:Toastify__bounceInRight}.Toastify__bounce-enter--top-center{animation-name:Toastify__bounceInDown}.Toastify__bounce-enter--bottom-center{animation-name:Toastify__bounceInUp}.Toastify__bounce-exit--bottom-left,.Toastify__bounce-exit--top-left{animation-name:Toastify__bounceOutLeft}.Toastify__bounce-exit--bottom-right,.Toastify__bounce-exit--top-right{animation-name:Toastify__bounceOutRight}.Toastify__bounce-exit--top-center{animation-name:Toastify__bounceOutUp}.Toastify__bounce-exit--bottom-center{animation-name:Toastify__bounceOutDown}@keyframes Toastify__zoomIn{0%{opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes Toastify__zoomOut{0%{opacity:1}50%{opacity:0;transform:scale3d(.3,.3,.3)}to{opacity:0}}.Toastify__zoom-enter{animation-name:Toastify__zoomIn}.Toastify__zoom-exit{animation-name:Toastify__zoomOut}@keyframes Toastify__flipIn{0%{transform:perspective(400px) rotateX(90deg);animation-timing-function:ease-in;opacity:0}40%{transform:perspective(400px) rotateX(-20deg);animation-timing-function:ease-in}60%{transform:perspective(400px) rotateX(10deg);opacity:1}80%{transform:perspective(400px) rotateX(-5deg)}to{transform:perspective(400px)}}@keyframes Toastify__flipOut{0%{transform:perspective(400px)}30%{transform:perspective(400px) rotateX(-20deg);opacity:1}to{transform:perspective(400px) rotateX(90deg);opacity:0}}.Toastify__flip-enter{animation-name:Toastify__flipIn}.Toastify__flip-exit{animation-name:Toastify__flipOut}@keyframes Toastify__slideInRight{0%{transform:translate3d(110%,0,0);visibility:visible}to{transform:translateZ(0)}}@keyframes Toastify__slideInLeft{0%{transform:translate3d(-110%,0,0);visibility:visible}to{transform:translateZ(0)}}@keyframes Toastify__slideInUp{0%{transform:translate3d(0,110%,0);visibility:visible}to{transform:translateZ(0)}}@keyframes Toastify__slideInDown{0%{transform:translate3d(0,-110%,0);visibility:visible}to{transform:translateZ(0)}}@keyframes Toastify__slideOutRight{0%{transform:translateZ(0)}to{visibility:hidden;transform:translate3d(110%,0,0)}}@keyframes Toastify__slideOutLeft{0%{transform:translateZ(0)}to{visibility:hidden;transform:translate3d(-110%,0,0)}}@keyframes Toastify__slideOutDown{0%{transform:translateZ(0)}to{visibility:hidden;transform:translate3d(0,500px,0)}}@keyframes Toastify__slideOutUp{0%{transform:translateZ(0)}to{visibility:hidden;transform:translate3d(0,-500px,0)}}.Toastify__slide-enter--bottom-left,.Toastify__slide-enter--top-left{animation-name:Toastify__slideInLeft}.Toastify__slide-enter--bottom-right,.Toastify__slide-enter--top-right{animation-name:Toastify__slideInRight}.Toastify__slide-enter--top-center{animation-name:Toastify__slideInDown}.Toastify__slide-enter--bottom-center{animation-name:Toastify__slideInUp}.Toastify__slide-exit--bottom-left,.Toastify__slide-exit--top-left{animation-name:Toastify__slideOutLeft}.Toastify__slide-exit--bottom-right,.Toastify__slide-exit--top-right{animation-name:Toastify__slideOutRight}.Toastify__slide-exit--top-center{animation-name:Toastify__slideOutUp}.Toastify__slide-exit--bottom-center{animation-name:Toastify__slideOutDown}
|
2
|
+
/*# sourceMappingURL=2.1781c263.chunk.css.map */
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../scss/_toastContainer.scss","../scss/_variables.scss","ReactToastify.css","../scss/_toast.scss","../scss/_closeButton.scss","../scss/_progressBar.scss","../scss/animations/_bounce.scss","../scss/animations/_zoom.scss","../scss/animations/_flip.scss","../scss/animations/_slide.scss"],"names":[],"mappings":"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","file":"2.1781c263.chunk.css"}
|
@@ -0,0 +1,2 @@
|
|
1
|
+
.navbar{position:-webkit-sticky!important;position:sticky!important;top:0;z-index:5;margin-bottom:2rem;padding:.8rem 1rem;min-height:4.7793rem}.loader{height:100vh}.backdrop,.loader{z-index:10;display:flex;justify-content:center;align-items:center}.backdrop{position:fixed;width:100%;height:100%;background-color:#222;opacity:0;visibility:hidden;transition:all .2s ease;cursor:default;flex-direction:column;text-align:center}.backdrop--visible{opacity:.94;visibility:visible}.body--backdrop{overflow:hidden}.player{width:100%;max-width:450px;display:flex;flex-direction:column;justify-content:space-between;align-items:center}.player-logo{width:130px}@media (max-height:430px){.player-logo{display:none}}.streams{max-width:450px}.streams__header{font-size:1.3rem;margin-top:1em;padding:.5rem 1.25rem}.streams__item{padding:0}.streams__btn{padding:.75rem 1.25rem;width:100%;text-align:left}.mini-player{display:flex;align-items:center;justify-content:space-between}.mini-player button{padding:10px 20px}.mini-player__left{max-width:calc(100vw - 160px);margin-right:1rem}.drawer{z-index:5!important;height:5rem;cursor:pointer;touch-action:none;display:flex;align-items:center;transition:height .25s ease-out}.drawer>.mini-player{flex-grow:1;margin:0 .5rem 0 .25rem}.drawer--open{height:100%;flex-direction:column;justify-content:flex-end}.drawer--open .player{flex-grow:1}.drawer--open .drawer__toggler{margin-bottom:20px}@media (max-width:770px){.body--drawer{overflow:hidden}}.main__primary{padding-bottom:7rem}.main__primary .player{display:none}.main__primary .streams{margin:0 auto}@media (min-width:770px){.main__primary{padding-bottom:2rem;display:flex;justify-content:space-between}.main__primary>*{min-width:0;width:100%}.main__primary .player{display:inherit;position:-webkit-sticky;position:sticky;top:6.7793rem;margin-left:2rem;height:calc(100vh - 8.7793rem);max-height:550px}.main__primary .streams{margin:0}.drawer{display:none}}html{height:100%}body{min-height:100%;overflow-y:scroll}button[disabled]{cursor:default}.ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
2
|
+
/*# sourceMappingURL=main.48912641.chunk.css.map */
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["navBar.scss","../_variables.scss","loader.scss","backdrop.scss","player.scss","streams.scss","miniPlayer.scss","drawer.scss","main.scss","index.scss"],"names":[],"mappings":"AAEA,QACE,iCAA2B,CAA3B,yBAA2B,CAC3B,KAAM,CACN,SAAU,CACV,kBCFe,CDKf,kBAAoB,CAEpB,oBCRoB,CCHtB,QAKE,YAAa,CCLf,kBDCE,UAAW,CACX,YAAa,CACb,sBAAuB,CACvB,kBCUkB,CAdpB,UAEE,cAAe,CACf,UAAW,CACX,WAAY,CACZ,qBAAyB,CACzB,SAAU,CACV,iBAAkB,CAClB,uBAAyB,CACzB,cAAe,CAEf,qBAAsB,CAGtB,iBAAkB,CAElB,mBACE,WAAa,CACb,kBAAmB,CACpB,gBAID,eAAgB,CCrBlB,QACE,UAAW,CACX,eAAgB,CAChB,YAAa,CACb,qBAAsB,CACtB,6BAA8B,CAC9B,kBAAmB,CACpB,aAGC,WAAY,CACb,0BAGC,aACE,YAAa,CACd,CChBH,SACE,eAAgB,CACjB,iBAGC,gBAAiB,CACjB,cAAe,CACf,qBAAuB,CACxB,eAGC,SAAU,CACX,cAGC,sBAAwB,CACxB,UAAW,CACX,eAAgB,CCnBlB,aACE,YAAa,CACb,kBAAmB,CACnB,6BAA8B,CAHhC,oBAMI,iBAAkB,CACnB,mBAKD,6BAA8B,CAC9B,iBAAkB,CCXpB,QACE,mBAAqB,CACrB,WNFkB,CMGlB,cAAe,CACf,iBAAkB,CAClB,YAAa,CACb,kBAAmB,CACnB,+BAAiC,CAPnC,qBAUI,WAAY,CACZ,uBAA0B,CAC3B,cAGC,WAAY,CACZ,qBAAsB,CACtB,wBAAyB,CAH1B,sBAMG,WAAY,CANf,+BAUG,kBAAmB,CACpB,yBAOH,cACE,eAAgB,CACjB,CChCH,eAGE,mBAAwC,CAH1C,uBAMI,YAAa,CANjB,wBAUI,aAAc,CACf,yBAID,eACE,mBAlBS,CAmBT,YAAa,CACb,6BAA8B,CAHhC,iBAMI,WAAY,CACZ,UAAW,CAPf,uBAWI,eAAgB,CAChB,uBAAgB,CAAhB,eAAgB,CAChB,aP3B8B,CO4B9B,gBAAiB,CACjB,8BAA4C,CAC5C,gBAAiB,CAhBrB,wBAoBI,QAAS,CACV,QAID,YAAa,CACd,CC7CH,KACE,WAAY,CACb,KAGC,eAAgB,CAChB,iBAAkB,CACnB,iBAGC,cAAe,CAChB,UAGC,kBAAmB,CACnB,eAAgB,CAChB,sBAAuB","file":"main.48912641.chunk.css","sourcesContent":["@import '../variables';\n\n.navbar {\n position: sticky !important;\n top: 0;\n z-index: 5;\n margin-bottom: $nav-margin;\n // The following let us have the same height on all themes.\n // 1. prevent lux to increment padding\n padding: 0.8rem 1rem;\n // 2. make darkly as high as lux\n min-height: $nav-height;\n}\n","$for-medium-up: 770px;\n$for-short-down: 430px;\n$drawer-height: 5rem;\n$nav-height: 4.7793rem; // calculated value for higher theme\n$nav-margin: 2rem;\n$nav-size: $nav-height + $nav-margin;\n",".loader {\n z-index: 10;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n}\n",".backdrop {\n z-index: 10;\n position: fixed;\n width: 100%;\n height: 100%;\n background-color: #222222;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n cursor: default;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n text-align: center;\n\n &--visible {\n opacity: 0.94;\n visibility: visible;\n }\n}\n\n.body--backdrop {\n overflow: hidden;\n}\n","@import '../../variables';\n\n.player {\n width: 100%;\n max-width: 450px;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n align-items: center;\n}\n\n.player-logo {\n width: 130px;\n}\n\n@media(max-height: $for-short-down) {\n .player-logo {\n display: none;\n }\n}\n","@import '../variables';\n\n.streams {\n max-width: 450px;\n}\n\n.streams__header {\n font-size: 1.3rem;\n margin-top: 1em;\n padding: 0.5rem 1.25rem;\n}\n\n.streams__item {\n padding: 0; // transfer .list-group-item padding to .streams__btn\n}\n\n.streams__btn {\n padding: 0.75rem 1.25rem;\n width: 100%;\n text-align: left;\n}\n",".mini-player {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n button {\n padding: 10px 20px;\n }\n}\n\n.mini-player__left {\n // Dirty workaround for ellipsis to work\n max-width: calc(100vw - 160px);\n margin-right: 1rem;\n}\n","@import '../variables';\n\n.drawer {\n z-index: 5 !important;\n height: $drawer-height;\n cursor: pointer;\n touch-action: none; // don't scroll on touch\n display: flex;\n align-items: center;\n transition: height 0.25s ease-out;\n\n & > .mini-player {\n flex-grow: 1;\n margin: 0 0.5rem 0 0.25rem;\n }\n\n &--open {\n height: 100%;\n flex-direction: column;\n justify-content: flex-end;\n\n .player {\n flex-grow: 1;\n }\n\n .drawer__toggler {\n margin-bottom: 20px;\n }\n }\n}\n\n// The media query is for the edge case of an open drawer and the\n// window resized past the breakpoint. This brings the scrollbar back.\n@media (max-width: $for-medium-up) {\n .body--drawer {\n overflow: hidden;\n }\n}\n","@import '../variables';\n\n$margin: 2rem;\n\n.main__primary {\n // Use padding instead of margin.\n // This is as workaround for Chrome 87 ignoring margin-bottom on .main__primary.\n padding-bottom: $margin + $drawer-height;\n\n .player {\n display: none;\n }\n\n .streams {\n margin: 0 auto;\n }\n}\n\n@media (min-width: $for-medium-up) {\n .main__primary {\n padding-bottom: $margin; /* no drawer */\n display: flex;\n justify-content: space-between;\n\n & > * {\n min-width: 0; /* don't get bigger when text overflows */\n width: 100%; /* divide space equally */\n }\n\n .player {\n display: inherit;\n position: sticky;\n top: $nav-size;\n margin-left: 2rem;\n height: calc(100vh - #{$nav-size + $margin});\n max-height: 550px;\n }\n\n .streams {\n margin: 0;\n }\n }\n\n .drawer {\n display: none;\n }\n}\n","html {\n height: 100%;\n}\n\nbody {\n min-height: 100%;\n overflow-y: scroll; // so elements don't move if page fits view\n}\n\nbutton[disabled] {\n cursor: default;\n}\n\n.ellipsis {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n"]}
|
@@ -0,0 +1,2 @@
|
|
1
|
+
(this.webpackJsonppifi_frontend=this.webpackJsonppifi_frontend||[]).push([[0],{13:function(e){e.exports=JSON.parse('{"b":["en","de-DE","fr-FR","nl-NL","pl-PL","pt-BR"],"c":1000,"a":2500,"d":3000}')},30:function(e,t,a){e.exports=a.p+"static/media/logo.91554ce9.svg"},50:function(e,t,a){e.exports=a(94)},56:function(e,t,a){},79:function(e,t,a){},80:function(e,t,a){},83:function(e,t,a){},84:function(e,t,a){},85:function(e,t,a){},86:function(e,t,a){},87:function(e,t,a){},89:function(e,t,a){},94:function(e,t,a){"use strict";a.r(t);var n=a(0),r=a.n(n),l=a(12),o=a.n(l),c=a(2),s=a.n(c),i=a(8),u=a(9),m=a(10),d=a(19),p=a(20),b=a(3),f=a(98),v=a(26),h=(a(56),a(30)),g=a.n(h),y=function(){var e=Object(v.a)().t;return r.a.createElement("nav",{className:"navbar navbar-expand-sm navbar-dark bg-primary"},r.a.createElement("div",{className:"container"},r.a.createElement("a",{className:"navbar-brand",href:"/"},r.a.createElement("img",{src:g.a,width:"30",height:"30",className:"d-inline-block align-text-bottom mr-2",alt:""}),"PiFi Radio"),r.a.createElement("button",{className:"navbar-toggler",type:"button","data-toggle":"collapse","data-target":"#navbarNavAltMarkup","aria-controls":"navbarNavAltMarkup","aria-expanded":"false","aria-label":"Toggle navigation"},r.a.createElement("span",{className:"navbar-toggler-icon"})),r.a.createElement("div",{className:"collapse navbar-collapse",id:"navbarNavAltMarkup"},r.a.createElement("div",{className:"navbar-nav pt-1 ml-2"},r.a.createElement("button",{className:"btn btn-link nav-link","data-toggle":"modal","data-target":"#url-dialog"},e("playURL")),r.a.createElement("button",{className:"btn btn-link nav-link","data-toggle":"modal","data-target":"#settings"},e("settings")),r.a.createElement("button",{className:"btn btn-link nav-link","data-toggle":"modal","data-target":"#about"},e("about"))))))},E=a(15),k=a(48),N=a(44),S=a.n(N),w=function(e){var t=e.id,a=e.title,n=e.footer,l=e.children,o=Object(v.a)().t,c=r.a.createElement("button",{className:"btn btn-secondary","data-dismiss":"modal"},o("close"));return r.a.createElement("div",{className:"modal fade",id:t,tabIndex:"-1",role:"dialog","aria-labelledby":"staticBackdropLabel","aria-hidden":"true"},r.a.createElement("div",{className:"modal-dialog",role:"document"},r.a.createElement("div",{className:"modal-content"},r.a.createElement("div",{className:"modal-header"},r.a.createElement("h5",{className:"modal-title",id:"staticBackdropLabel"},a),r.a.createElement("button",{type:"button",className:"close","data-dismiss":"modal","aria-label":"Close"},r.a.createElement("span",{"aria-hidden":"true"},"\xd7"))),r.a.createElement("div",{className:"modal-body"},l),r.a.createElement("div",{className:"modal-footer"},n||c))))},O=a(49),j=function(e){var t=e.id,a=e.label,n=e.row,l=e.data,o=Object(O.a)(e,["id","label","row","data"]);return r.a.createElement("div",{className:n?"form-group row":"form-group"},r.a.createElement("label",{htmlFor:t,className:"col-sm-2 col-form-label"},a),r.a.createElement("div",{className:"col-sm-10"},r.a.createElement("select",Object.assign({id:t,className:"form-control"},o),l.map((function(e){return r.a.createElement("option",{key:e.id||e,value:e.id||e},e.name||e)})))))},C=[{id:"darkly",name:"Darkly",themeColor:"#375a7f"},{id:"lux",name:"Lux",themeColor:"#1a1a1a"}];function _(){var e=x(),t=function(e){return"https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/".concat(e,"/bootstrap.min.css")}(e),a=C.find((function(t){return t.id===e})).themeColor;document.querySelector('link[title="theme"]').setAttribute("href",t),document.querySelector('meta[name="theme-color"]').setAttribute("content",a)}function x(){var e=localStorage.getItem("theme");return""===e?"darkly":0===C.filter((function(t){return t.id===e})).length?(localStorage.removeItem("theme"),"darkly"):e}var T={availableThemes:C,getCurrentId:x,change:function(e){localStorage.setItem("theme",e),_()},apply:_},L=a(13),P=function(){var e=Object(v.a)(),t=e.t,a=e.i18n,l=Object(n.useState)(""),o=Object(E.a)(l,2),c=o[0],s=o[1],i=L.b.sort().map((function(e){var t=e.slice(0,2);return{id:e,name:"".concat(S()(e)," ").concat(k.a.getNativeName(t))}}));return Object(n.useEffect)((function(){s(T.getCurrentId())}),[]),r.a.createElement(w,{id:"settings",title:t("settings")},r.a.createElement(j,{id:"theme-select",label:t("theme"),data:T.availableThemes,row:!0,value:c,onChange:function(e){return function(e){var t=e.target.value;T.change(t),s(t)}(e)}}),r.a.createElement(j,{id:"language-select",label:t("language"),data:i,row:!0,value:a.language,onChange:function(e){return a.changeLanguage(e.target.value)}}))},R=a(24),A=a.n(R),B=a(97);A.a.defaults.baseURL="/api",A.a.interceptors.response.use(null,(function(e){var t=e.response&&e.response.status>=400&&e.response.status<500;return document.querySelector(".Toastify")&&(t||b.b.error(r.a.createElement(B.a,null,(function(e){return e("errorUnexpected")}))),e.response&&403===e.response.status&&b.b.error(r.a.createElement(B.a,null,(function(e){return e("errorForbidden")})))),Promise.reject(e)}));var D={get:A.a.get,post:A.a.post};function I(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,a=new FormData;return a.set("method",e),t&&a.set("params",t),a}function F(){return D.post("/player",I("play"))}function U(){return D.post("/player",I("stop"))}function M(e){return D.post("/player",I("change_vol",e))}function q(e){return D.post("/player",I("play_radios",e))}function W(e){return D.post("/player",I("play_urls",e))}var Y=function(){var e=Object(n.useState)(""),t=Object(E.a)(e,2),a=t[0],l=t[1],o=Object(v.a)().t,c=function(){""!==a&&(u(a),l(""))},u=function(){var e=Object(i.a)(s.a.mark((function e(t){var a,n;return s.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a={type:b.b.TYPE.ERROR,render:o("errorNotFound")},n=Object(b.b)(o("tryingURL")),e.prev=2,e.next=5,W(t);case 5:e.next=10;break;case 7:e.prev=7,e.t0=e.catch(2),e.t0.response&&400===e.t0.response.status&&b.b.update(n,a);case 10:case"end":return e.stop()}}),e,null,[[2,7]])})));return function(t){return e.apply(this,arguments)}}();return r.a.createElement(w,{id:"url-dialog",title:o("playURL"),footer:r.a.createElement(r.a.Fragment,null,r.a.createElement("button",{className:"btn btn-primary","data-dismiss":"modal",onClick:c},o("ok")),r.a.createElement("button",{className:"btn btn-secondary",onClick:function(){return l("")},"data-dismiss":"modal"},o("cancel")))},r.a.createElement("input",{className:"form-control mb-4",type:"text",placeholder:"URL",value:a,onChange:function(e){var t=e.target;l(t.value)},onKeyDown:function(e){"Enter"===e.key&&c()}}))};function K(){return D.get("/config")}a(79);var V=function(){return r.a.createElement("div",{className:"loader"},r.a.createElement("div",{className:"spinner-border",role:"status"},r.a.createElement("span",{className:"sr-only"},"Loading...")))},H=function(){var e=Object(v.a)().t,t=Object(n.useState)({}),a=Object(E.a)(t,2),l=a[0],o=a[1],c=Object(n.useState)(!0),u=Object(E.a)(c,2),m=u[0],d=u[1];Object(n.useEffect)((function(){function e(){return(e=Object(i.a)(s.a.mark((function e(){var t,a;return s.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,K();case 2:t=e.sent,a=t.data,o(a),d(!1);case 6:case"end":return e.stop()}}),e)})))).apply(this,arguments)}!function(){e.apply(this,arguments)}()}),[]);var p=[{label:e("mpdHost"),value:l.mpd_host},{label:e("mpdPort"),value:l.mpd_port},{label:e("environment"),value:l.environment},{label:e("version"),value:l.version}],b=r.a.createElement("div",{className:"copyright small mt-5"},r.a.createElement("p",null,r.a.createElement("a",{href:"https://rafaelc.org/pifi",target:"_blank",rel:"noopener noreferrer",style:{color:"inherit"}},e("goToDocs"))),r.a.createElement("p",null,"Copyright \xa9 2017-2020\xa0",r.a.createElement("a",{href:"https://rafaelc.org/",target:"_blank",rel:"noopener noreferrer",style:{color:"inherit"}},"Rafael Cavalcanti"))),f=r.a.createElement("div",{className:"coffee mt-5"},r.a.createElement("p",null,e("coffee")),r.a.createElement("a",{href:"https://rafaelc.org/coffee",target:"_blank",rel:"noopener noreferrer"},r.a.createElement("img",{src:"https://cdn.buymeacoffee.com/buttons/default-blue.png",alt:"Buy Me A Coffee",style:{height:51,width:217}})));return r.a.createElement(w,{id:"about",title:e("about")},m?r.a.createElement(V,null):r.a.createElement("table",{className:"table"},r.a.createElement("tbody",null,p.map((function(e){return r.a.createElement("tr",{key:e.label},r.a.createElement("th",{scope:"row"},e.label),r.a.createElement("td",null,e.value))})))),f,b)},J=(a(80),function(){return window.innerWidth-document.documentElement.clientWidth}),G=function(e){var t=e.title,a=e.body,n=t,l=document.body.classList.contains("body--backdrop");n&&!l?(document.body.style.paddingRight=J()+"px",document.body.classList.add("body--backdrop")):!n&&l&&(document.body.style.paddingRight=0,document.body.classList.remove("body--backdrop"));var o="backdrop p-2 text-white"+(n?" backdrop--visible":"");return r.a.createElement("div",{className:o},r.a.createElement("h3",{className:"text-white"},t),r.a.createElement("h5",{className:"text-white"},a))},$=function(e){var t=e.playerStatus,a=t.playing,n=t.title,l=Object(v.a)().t;return r.a.createElement("div",{className:"text-center w-100"},r.a.createElement("h5",{className:"small text-uppercase"},l(a?"playing":"stopped")),r.a.createElement("h3",{className:"ellipsis"},n))},z=a(14),Q=a(11),X=function(e){return e.playing?r.a.createElement("button",{className:"btn btn-danger",onClick:U,"aria-label":"Stop"},r.a.createElement(z.a,{icon:Q.d})):r.a.createElement("button",{className:"btn btn-dark",onClick:F,"aria-label":"Play"},r.a.createElement(z.a,{icon:Q.c}))},Z=function(e){var t=e.playerStatus,a=Object(v.a)().t,n=null==t.vol,l=function(){var e=Object(i.a)(s.a.mark((function e(t){var n,r,l,o;return s.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,M(t);case 2:n=e.sent,r=n.data,"vol",l="".concat(a("volume"),": ").concat(r,"%"),o={toastId:"vol",autoClose:L.d},b.b.isActive("vol")?b.b.update("vol",{render:l}):b.b.info(l,o);case 8:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),o=function(e,t,a){return r.a.createElement("button",{className:"btn btn-dark p-3",disabled:n,onClick:function(){return l(e)},"aria-label":a},r.a.createElement(z.a,{icon:t}))};return r.a.createElement("div",{className:"player-controls btn-group w-100 m-2",onClick:function(e){return e.stopPropagation()}},o("-5",Q.e,"Volume down"),o("+5",Q.f,"Volume up"),r.a.createElement(X,{playing:t.playing}))},ee=(a(83),function(e){var t=e.playerStatus;return r.a.createElement("div",{className:"player"},r.a.createElement($,{playerStatus:t}),r.a.createElement("img",{src:a(30),alt:"Logo",className:"player-logo m-4"}),r.a.createElement(Z,{playerStatus:t}))}),te=function(e){var t=e.value,a=e.onChange,n=Object(v.a)().t;return r.a.createElement("input",{className:"form-control mb-4",type:"text",id:"query",placeholder:n("search"),"aria-label":n("search"),autoComplete:"off",value:t,onChange:function(e){return a(e.target.value)},onFocus:function(){return a("")}})};a(84);var ae=function(e){Object(p.a)(a,e);var t=Object(d.a)(a);function a(){var e;Object(u.a)(this,a);for(var n=arguments.length,r=new Array(n),l=0;l<n;l++)r[l]=arguments[l];return(e=t.call.apply(t,[this].concat(r))).state={streams:{},loading:!0,query:""},e.isPlaying=function(t){return t===e.props.playerStatus.title&&e.props.playerStatus.playing},e.handleItemClick=function(){var t=Object(i.a)(s.a.mark((function t(a){var n,r,l;return s.a.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(n=e.props,r=n.t,l=n.onBackdrop,!e.isPlaying(a)){t.next=3;break}return t.abrupt("return");case 3:return l(r("tuning"),a),t.prev=4,t.next=7,q(a);case 7:t.next=12;break;case 9:t.prev=9,t.t0=t.catch(4),t.t0.response&&400===t.t0.response.status&&b.b.error(r("errorNotFound"));case 12:case"end":return t.stop()}}),t,null,[[4,9]])})));return function(e){return t.apply(this,arguments)}}(),e.getItemClasses=function(t){var a="streams__item list-group-item ";return e.isPlaying(t)?a+"active":a+"list-group-item-action"},e.handleSearch=function(t){e.setState({query:t})},e}return Object(m.a)(a,[{key:"componentDidMount",value:function(){var e=Object(i.a)(s.a.mark((function e(){var t,a;return s.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,D.get("/streams");case 2:t=e.sent,a=t.data,this.setState({streams:a,loading:!1});case 5:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"filteredStreams",value:function(){var e=this.state,t=e.streams,a=e.query;if(""===a)return t;var n={};for(var r in t)r.toLowerCase().includes(a.toLowerCase())&&!t[r]&&(n[r]=t[r]);return n}},{key:"renderList",value:function(){var e=this,t=this.filteredStreams();return 0===Object.keys(t).length?r.a.createElement("h4",{className:"p-4"},this.props.t("noStreams")):r.a.createElement("ul",{className:"list-group list-group-flush"},Object.keys(t).map((function(a){return t[a]?r.a.createElement("li",{className:"streams__header ellipsis",key:a},a):r.a.createElement("li",{className:e.getItemClasses(a),key:a},r.a.createElement("button",{className:"streams__btn btn btn-outline ellipsis",onClick:function(){return e.handleItemClick(a)},disabled:e.isPlaying(a)},a))})))}},{key:"render",value:function(){return this.state.loading?r.a.createElement(V,null):r.a.createElement("div",{className:"streams"},r.a.createElement(te,{value:this.state.query,onChange:this.handleSearch}),this.renderList())}}]),a}(n.Component),ne=Object(f.a)()(ae),re=(a(85),function(e){var t=e.playerStatus,a=t.title,n=t.playing;return r.a.createElement("div",{className:"mini-player"},r.a.createElement("div",{className:"mini-player__left ellipsis"},a),r.a.createElement("div",{className:"mini-player__right",onClick:function(e){return e.stopPropagation()}},r.a.createElement(X,{playing:n})))}),le=(a(86),function(e){Object(p.a)(a,e);var t=Object(d.a)(a);function a(){var e;Object(u.a)(this,a);for(var n=arguments.length,l=new Array(n),o=0;o<n;o++)l[o]=arguments[o];return(e=t.call.apply(t,[this].concat(l))).state={open:!1},e.toggle=function(){e.setState({open:!e.state.open})},e.handleClick=function(){e.toggle()},e.handleTouchStart=function(t){if(t.touches.length>1)return e.setState({touchStartY:null});e.setState({touchStartY:t.touches[0].clientY})},e.handleTouchMove=function(t){var a=e.state,n=a.open,r=a.touchStartY;if(!(null===r||t.touches.length>1)){var l=t.changedTouches[0].clientY;(l>r&&n||l<r&&!n)&&e.toggle()}},e.renderToggleButton=function(){return r.a.createElement("button",{className:"drawer__toggler btn btn-primary-outline","aria-label":"Toggle player"},r.a.createElement(z.a,{icon:e.state.open?Q.a:Q.b,className:"fa-lg"}))},e}return Object(m.a)(a,[{key:"render",value:function(){var e=this.props.playerStatus,t=this.state.open,a="drawer fixed-bottom bg-secondary shadow-lg p-2";return t?(a+=" drawer--open",document.body.classList.add("body--drawer")):document.body.classList.remove("body--drawer"),r.a.createElement("div",{className:a,onClick:this.handleClick,onTouchStart:this.handleTouchStart,onTouchMove:this.handleTouchMove},this.renderToggleButton(),t?r.a.createElement(ee,{playerStatus:e}):r.a.createElement(re,{playerStatus:e}))}}]),a}(n.Component)),oe=(a(87),function(e){var t=e.playerStatus,a=e.onBackdrop;return r.a.createElement("main",{className:"main"},r.a.createElement(le,{playerStatus:t}),r.a.createElement("div",{className:"main__primary container"},r.a.createElement(ne,{onBackdrop:a,playerStatus:t}),r.a.createElement(ee,{playerStatus:t})))}),ce=(a(88),function(e){Object(p.a)(a,e);var t=Object(d.a)(a);function a(){var e;Object(u.a)(this,a);for(var n=arguments.length,r=new Array(n),l=0;l<n;l++)r[l]=arguments[l];return(e=t.call.apply(t,[this].concat(r))).state={playerStatus:{},loading:!0,networkError:!1,backdrop:{}},e.handleBackdrop=function(t){var a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";e.setState({backdrop:{title:t,body:a}}),setTimeout((function(){return e.setState({backdrop:{}})}),L.a)},e.setDocumentTitle=function(){var t=e.state,a=t.playerStatus;!t.networkError&&a.playing?document.title="PiFi \ud83d\udd0a "+a.title:document.title="PiFi Radio"},e}return Object(m.a)(a,[{key:"componentDidMount",value:function(){this.updatePlayerStatus()}},{key:"componentDidUpdate",value:function(){this.setDocumentTitle()}},{key:"updatePlayerStatus",value:function(){var e=Object(i.a)(s.a.mark((function e(){var t,a,n=this;return s.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,D.get("/player");case 3:t=e.sent,a=t.data,this.setState({playerStatus:a,loading:!1,networkError:!1}),e.next=11;break;case 8:e.prev=8,e.t0=e.catch(0),this.setState({loading:!1,networkError:!0});case 11:setTimeout((function(){return n.updatePlayerStatus()}),L.c);case 12:case"end":return e.stop()}}),e,this,[[0,8]])})));return function(){return e.apply(this,arguments)}}()},{key:"render",value:function(){var e=this.state,t=e.loading,a=e.networkError,n=e.backdrop,l=e.playerStatus,o=this.props.t;return a?r.a.createElement(G,{title:o("errorNetwork")}):t?r.a.createElement(V,null):l.con_mpd?r.a.createElement("div",{className:"app"},r.a.createElement(b.a,{pauseOnFocusLoss:!1}),r.a.createElement(G,{title:n.title,body:n.body}),r.a.createElement(y,null),r.a.createElement(oe,{onBackdrop:this.handleBackdrop,playerStatus:l}),r.a.createElement(Y,null),r.a.createElement(P,null),r.a.createElement(H,null)):r.a.createElement(G,{title:o("disconnectedMPD")})}}]),a}(n.Component)),se=Object(f.a)()(ce);Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/));var ie=a(29),ue=a(21),me=a(47),de=a(46);ie.a.use(me.a).use(de.a).use(ue.f).init({fallbackLng:"en",debug:Object({NODE_ENV:"production",PUBLIC_URL:"",WDS_SOCKET_HOST:void 0,WDS_SOCKET_PATH:void 0,WDS_SOCKET_PORT:void 0,REACT_APP_API_URL:"/api"}).REACT_APP_I18N_DEBUG,load:"currentOnly",returnEmptyString:!1,interpolation:{escapeValue:!1}}),ie.a.on("languageChanged",(function(e){document.documentElement.setAttribute("lang",e)}));ie.a,a(89),a(90),a(91);T.apply(),o.a.render(r.a.createElement(n.Suspense,{fallback:r.a.createElement(V,null)},r.a.createElement(se,null)),document.getElementById("root")),"serviceWorker"in navigator&&navigator.serviceWorker.ready.then((function(e){e.unregister()}))}},[[50,1,2]]]);
|
2
|
+
//# sourceMappingURL=main.21a62959.chunk.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["assets/logo.svg","components/navBar.jsx","components/common/modal.jsx","components/common/select.jsx","theme.js","components/modals/settings.jsx","services/httpService.js","services/playerService.js","components/modals/urlDialog.jsx","services/configService.js","components/common/loader.jsx","components/modals/about.jsx","components/common/backdrop.jsx","components/player/playerStatus.jsx","components/player/playStopControl.jsx","components/player/playerControls.jsx","components/player/player.jsx","components/common/searchBox.jsx","components/streams.jsx","services/streamsService.js","components/player/miniPlayer.jsx","components/drawer.jsx","components/main.jsx","App.js","serviceWorker.js","i18n.js","index.js"],"names":["module","exports","NavBar","t","useTranslation","className","href","src","logo","width","height","alt","type","data-toggle","data-target","aria-controls","aria-expanded","aria-label","id","Modal","title","footer","children","defaultFooter","data-dismiss","tabIndex","role","aria-labelledby","aria-hidden","Select","label","row","data","rest","htmlFor","map","d","key","value","name","availableThemes","themeColor","apply","themeId","getCurrentId","themePath","getThemePath","find","document","querySelector","setAttribute","localId","localStorage","getItem","filter","length","removeItem","change","setItem","Settings","i18n","useState","setThemeId","languagesData","languages","sort","lang","isoCode","slice","localeEmoji","ISO6391","getNativeName","useEffect","theme","onChange","e","newThemeId","target","handleThemeChange","language","changeLanguage","axios","defaults","baseURL","process","interceptors","response","use","error","expectedError","status","toast","Translation","Promise","reject","get","post","body","method","params","FormData","set","play","http","stop","changeVol","delta","playRadio","playURL","url","URLDialog","setURL","handleOK","doPlayURL","a","errorToastOpts","TYPE","ERROR","render","toastId","update","Fragment","onClick","placeholder","input","onKeyDown","getConfig","Loader","About","config","setConfig","loading","setLoading","fetchData","tableData","mpd_host","mpd_port","environment","version","copyright","rel","style","color","coffee","item","scope","getScrollbarWidth","window","innerWidth","documentElement","clientWidth","Backdrop","visible","bodyStyled","classList","contains","paddingRight","add","remove","classes","PlayerStatus","playerStatus","playing","PlayStopControl","icon","faStop","faPlay","PlayerControls","volDisabled","vol","handleVolChange","toastMsg","toastOpts","autoClose","volTimeout","isActive","info","renderVolButton","disabled","stopPropagation","faVolumeDown","faVolumeUp","Player","require","SearchBox","autoComplete","onFocus","Streams","state","streams","query","isPlaying","props","handleItemClick","onBackdrop","getItemClasses","handleSearch","setState","this","filtered","k","toLowerCase","includes","filteredStreams","Object","keys","renderList","Component","withTranslation","MiniPlayer","Drawer","open","toggle","handleClick","handleTouchStart","touches","touchStartY","clientY","handleTouchMove","touchEndY","changedTouches","renderToggleButton","faChevronDown","faChevronUp","onTouchStart","onTouchMove","Main","App","networkError","backdrop","handleBackdrop","setTimeout","backdropTimeout","setDocumentTitle","updatePlayerStatus","updateInterval","con_mpd","pauseOnFocusLoss","Boolean","location","hostname","match","Backend","LanguageDetector","initReactI18next","init","fallbackLng","debug","REACT_APP_I18N_DEBUG","load","returnEmptyString","interpolation","escapeValue","on","ReactDOM","fallback","getElementById","navigator","serviceWorker","ready","then","registration","unregister"],"mappings":"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","file":"static/js/main.21a62959.chunk.js","sourcesContent":["module.exports = __webpack_public_path__ + \"static/media/logo.91554ce9.svg\";","import React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport './navBar.scss';\nimport logo from '../assets/logo.svg';\n\nconst NavBar = () => {\n const { t } = useTranslation();\n\n return (\n <nav className=\"navbar navbar-expand-sm navbar-dark bg-primary\">\n <div className=\"container\">\n <a className=\"navbar-brand\" href=\"/\">\n <img\n src={logo}\n width=\"30\"\n height=\"30\"\n className=\"d-inline-block align-text-bottom mr-2\"\n alt=\"\"\n />\n PiFi Radio\n </a>\n <button\n className=\"navbar-toggler\"\n type=\"button\"\n data-toggle=\"collapse\"\n data-target=\"#navbarNavAltMarkup\"\n aria-controls=\"navbarNavAltMarkup\"\n aria-expanded=\"false\"\n aria-label=\"Toggle navigation\"\n >\n <span className=\"navbar-toggler-icon\"></span>\n </button>\n <div className=\"collapse navbar-collapse\" id=\"navbarNavAltMarkup\">\n <div className=\"navbar-nav pt-1 ml-2\">\n {/* We use buttons and different class names instead of Bootstrap's\n anchor, so we don't get a warning for href=\"#\". */}\n <button\n className=\"btn btn-link nav-link\"\n data-toggle=\"modal\"\n data-target=\"#url-dialog\"\n >\n {t('playURL')}\n </button>\n\n <button\n className=\"btn btn-link nav-link\"\n data-toggle=\"modal\"\n data-target=\"#settings\"\n >\n {t('settings')}\n </button>\n\n <button\n className=\"btn btn-link nav-link\"\n data-toggle=\"modal\"\n data-target=\"#about\"\n >\n {t('about')}\n </button>\n </div>\n </div>\n </div>\n </nav>\n );\n};\nexport default NavBar;\n","import React from 'react';\nimport { useTranslation } from 'react-i18next';\n\nconst Modal = ({ id, title, footer, children }) => {\n const { t } = useTranslation();\n\n const defaultFooter = (\n <button className=\"btn btn-secondary\" data-dismiss=\"modal\">\n {t('close')}\n </button>\n );\n\n return (\n <div\n className=\"modal fade\"\n id={id}\n tabIndex=\"-1\"\n role=\"dialog\"\n aria-labelledby=\"staticBackdropLabel\"\n aria-hidden=\"true\"\n >\n <div className=\"modal-dialog\" role=\"document\">\n <div className=\"modal-content\">\n <div className=\"modal-header\">\n <h5 className=\"modal-title\" id=\"staticBackdropLabel\">\n {title}\n </h5>\n <button\n type=\"button\"\n className=\"close\"\n data-dismiss=\"modal\"\n aria-label=\"Close\"\n >\n <span aria-hidden=\"true\">×</span>\n </button>\n </div>\n <div className=\"modal-body\">{children}</div>\n <div className=\"modal-footer\">{footer ? footer : defaultFooter}</div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default Modal;\n","import React from 'react';\n\nconst Select = ({ id, label, row, data, ...rest }) => (\n <div className={row ? 'form-group row' : 'form-group'}>\n <label htmlFor={id} className=\"col-sm-2 col-form-label\">\n {label}\n </label>\n <div className=\"col-sm-10\">\n <select id={id} className=\"form-control\" {...rest}>\n {data.map(d => (\n <option key={d.id || d} value={d.id || d}>\n {d.name || d}\n </option>\n ))}\n </select>\n </div>\n </div>\n);\n\nexport default Select;\n","const DEFAULT_THEME_ID = 'darkly';\n\nconst STORAGE_KEY = 'theme';\n\nconst getThemePath = themeId =>\n `https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/${themeId}/bootstrap.min.css`;\n\nconst availableThemes = [\n { id: 'darkly', name: 'Darkly', themeColor: '#375a7f' },\n { id: 'lux', name: 'Lux', themeColor: '#1a1a1a' }\n];\n\nfunction change(themeId) {\n localStorage.setItem(STORAGE_KEY, themeId);\n apply();\n}\n\nfunction apply() {\n const themeId = getCurrentId();\n const themePath = getThemePath(themeId);\n const themeColor = availableThemes.find(t => t.id === themeId).themeColor;\n\n const linkEl = document.querySelector('link[title=\"theme\"]');\n linkEl.setAttribute('href', themePath);\n\n const metaEl = document.querySelector('meta[name=\"theme-color\"]');\n metaEl.setAttribute('content', themeColor);\n}\n\nfunction getCurrentId() {\n const localId = localStorage.getItem(STORAGE_KEY);\n\n if (localId === '') return DEFAULT_THEME_ID;\n if (availableThemes.filter(t => t.id === localId).length === 0) {\n localStorage.removeItem(STORAGE_KEY);\n return DEFAULT_THEME_ID;\n }\n\n return localId;\n}\n\nexport default {\n availableThemes,\n getCurrentId,\n change,\n apply\n};\n","import React, { useState, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport ISO6391 from 'iso-639-1';\nimport localeEmoji from 'locale-emoji';\nimport Modal from '../common/modal';\nimport Select from '../common/select';\nimport theme from '../../theme';\nimport { languages } from '../../config.json';\n\nconst Settings = () => {\n const { t, i18n } = useTranslation();\n\n const [themeId, setThemeId] = useState('');\n\n const languagesData = languages.sort().map(lang => {\n const isoCode = lang.slice(0, 2);\n return {\n id: lang,\n name: `${localeEmoji(lang)} ${ISO6391.getNativeName(isoCode)}`\n };\n });\n\n const handleThemeChange = ({ target }) => {\n const newThemeId = target.value;\n theme.change(newThemeId);\n setThemeId(newThemeId);\n };\n\n useEffect(() => {\n setThemeId(theme.getCurrentId());\n }, []);\n\n return (\n <Modal id=\"settings\" title={t('settings')}>\n <Select\n id=\"theme-select\"\n label={t('theme')}\n data={theme.availableThemes}\n row\n value={themeId}\n onChange={e => handleThemeChange(e)}\n />\n <Select\n id=\"language-select\"\n label={t('language')}\n data={languagesData}\n row\n value={i18n.language}\n onChange={e => i18n.changeLanguage(e.target.value)}\n />\n </Modal>\n );\n};\n\nexport default Settings;\n","import React from 'react';\nimport axios from 'axios';\nimport { toast } from 'react-toastify';\nimport { Translation } from 'react-i18next';\n\naxios.defaults.baseURL = process.env.REACT_APP_API_URL;\n\naxios.interceptors.response.use(null, error => {\n const expectedError =\n error.response &&\n error.response.status >= 400 &&\n error.response.status < 500;\n\n // Some errors cause our app to only render a backdrop warning.\n // Queuing toasts would be redundant.\n const hasToastify = document.querySelector('.Toastify');\n\n if (hasToastify) {\n if (!expectedError)\n toast.error(<Translation>{t => t('errorUnexpected')}</Translation>);\n\n // Universal expected error\n if (error.response && error.response.status === 403)\n toast.error(<Translation>{t => t('errorForbidden')}</Translation>);\n }\n\n return Promise.reject(error);\n});\n\nexport default {\n get: axios.get,\n post: axios.post\n};\n","import http from './httpService.js';\n\nconst apiEndpoint = '/player';\n\nfunction body(method, params = null) {\n const body = new FormData();\n body.set('method', method);\n if (params) body.set('params', params);\n return body;\n}\n\nexport function getStatus() {\n return http.get(apiEndpoint);\n}\n\nexport function play() {\n return http.post(apiEndpoint, body('play'));\n}\n\nexport function stop() {\n return http.post(apiEndpoint, body('stop'));\n}\n\nexport function changeVol(delta) {\n return http.post(apiEndpoint, body('change_vol', delta));\n}\n\nexport function playRadio(name) {\n return http.post(apiEndpoint, body('play_radios', name));\n}\n\nexport function playURL(url) {\n return http.post(apiEndpoint, body('play_urls', url));\n}\n","import React, { useState } from 'react';\nimport { toast } from 'react-toastify';\nimport { useTranslation } from 'react-i18next';\nimport Modal from '../common/modal';\nimport { playURL } from '../../services/playerService';\n\nconst URLDialog = () => {\n const [url, setURL] = useState('');\n\n const { t } = useTranslation();\n\n const handleOK = () => {\n if (url === '') return;\n doPlayURL(url);\n setURL('');\n };\n\n const doPlayURL = async url => {\n const errorToastOpts = {\n type: toast.TYPE.ERROR,\n render: t('errorNotFound')\n };\n\n const toastId = toast(t('tryingURL'));\n\n try {\n await playURL(url);\n } catch (ex) {\n if (ex.response && ex.response.status === 400)\n toast.update(toastId, errorToastOpts);\n }\n };\n\n const handleChange = ({ target: input }) => {\n setURL(input.value);\n };\n\n const handleKeyDown = e => {\n if (e.key === 'Enter') handleOK();\n };\n\n const renderFooter = () => (\n <React.Fragment>\n <button\n className=\"btn btn-primary\"\n data-dismiss=\"modal\"\n onClick={handleOK}\n >\n {t('ok')}\n </button>\n <button\n className=\"btn btn-secondary\"\n onClick={() => setURL('')}\n data-dismiss=\"modal\"\n >\n {t('cancel')}\n </button>\n </React.Fragment>\n );\n\n return (\n <Modal id=\"url-dialog\" title={t('playURL')} footer={renderFooter()}>\n <input\n className=\"form-control mb-4\"\n type=\"text\"\n placeholder=\"URL\"\n value={url}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n />\n </Modal>\n );\n};\n\nexport default URLDialog;\n","import http from './httpService';\n\nconst apiEndpoint = '/config';\n\nexport function getConfig() {\n return http.get(apiEndpoint);\n}\n","import React from 'react';\nimport './loader.scss';\n\nconst Loader = () => (\n <div className=\"loader\">\n <div className=\"spinner-border\" role=\"status\">\n <span className=\"sr-only\">Loading...</span>\n </div>\n </div>\n);\n\nexport default Loader;\n","import React from 'react';\nimport { useEffect, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport Modal from '../common/modal';\nimport { getConfig } from '../../services/configService';\nimport Loader from '../common/loader';\n\nconst About = () => {\n const { t } = useTranslation();\n\n const [config, setConfig] = useState({});\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n async function fetchData() {\n const { data: config } = await getConfig();\n setConfig(config);\n setLoading(false);\n }\n fetchData();\n }, []);\n\n const tableData = [\n { label: t('mpdHost'), value: config.mpd_host },\n { label: t('mpdPort'), value: config.mpd_port },\n { label: t('environment'), value: config.environment },\n { label: t('version'), value: config.version },\n ];\n\n const renderTable = () => {\n if (loading) return <Loader />;\n\n return (\n <table className=\"table\">\n <tbody>\n {tableData.map((item) => (\n <tr key={item.label}>\n <th scope=\"row\">{item.label}</th>\n <td>{item.value}</td>\n </tr>\n ))}\n </tbody>\n </table>\n );\n };\n\n const copyright = (\n <div className=\"copyright small mt-5\">\n <p>\n <a\n href=\"https://rafaelc.org/pifi\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ color: 'inherit' }}\n >\n {t('goToDocs')}\n </a>\n </p>\n <p>\n Copyright © 2017-2020 \n {/* Use the default color, as some themes give a different color for links. */}\n <a\n href=\"https://rafaelc.org/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ color: 'inherit' }}\n >\n Rafael Cavalcanti\n </a>\n </p>\n </div>\n );\n\n const coffee = (\n <div className=\"coffee mt-5\">\n <p>{t('coffee')}</p>\n <a\n href=\"https://rafaelc.org/coffee\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <img\n src=\"https://cdn.buymeacoffee.com/buttons/default-blue.png\"\n alt=\"Buy Me A Coffee\"\n style={{ height: 51, width: 217 }}\n />\n </a>\n </div>\n );\n\n return (\n <Modal id=\"about\" title={t('about')}>\n {renderTable()}\n {coffee}\n {copyright}\n </Modal>\n );\n};\n\nexport default About;\n","import React from 'react';\nimport './backdrop.scss';\n\nconst Backdrop = ({ title, body }) => {\n const visible = title;\n const bodyStyled = document.body.classList.contains('body--backdrop');\n\n if (visible && !bodyStyled) {\n // Calculate this BEFORE adding the class.\n document.body.style.paddingRight = getScrollbarWidth() + 'px';\n document.body.classList.add('body--backdrop');\n // We need this check because Bootstrap modals also style paddingRight\n } else if (!visible && bodyStyled) {\n document.body.style.paddingRight = 0;\n document.body.classList.remove('body--backdrop');\n }\n\n const classes =\n 'backdrop p-2 text-white' + (visible ? ' backdrop--visible' : '');\n\n // We need text-white on h* tags because some themes override it\n return (\n <div className={classes}>\n <h3 className=\"text-white\">{title}</h3>\n <h5 className=\"text-white\">{body}</h5>\n </div>\n );\n};\n\nconst getScrollbarWidth = () =>\n window.innerWidth - document.documentElement.clientWidth;\n\nexport default Backdrop;\n","import React from 'react';\nimport { useTranslation } from 'react-i18next';\n\nconst PlayerStatus = ({ playerStatus }) => {\n const { playing, title } = playerStatus;\n\n const { t } = useTranslation();\n\n return (\n <div className=\"text-center w-100\">\n <h5 className=\"small text-uppercase\">\n {playing ? t('playing') : t('stopped')}\n </h5>\n <h3 className=\"ellipsis\">{title}</h3>\n </div>\n );\n};\n\nexport default PlayerStatus;\n","import React from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faStop, faPlay } from '@fortawesome/free-solid-svg-icons';\nimport { play, stop } from '../../services/playerService';\n\nconst PlayStopControl = ({ playing }) =>\n playing ? (\n <button className=\"btn btn-danger\" onClick={stop} aria-label=\"Stop\">\n <FontAwesomeIcon icon={faStop} />\n </button>\n ) : (\n <button className=\"btn btn-dark\" onClick={play} aria-label=\"Play\">\n <FontAwesomeIcon icon={faPlay} />\n </button>\n );\n\nexport default PlayStopControl;\n","import React from 'react';\nimport PlayStopControl from './playStopControl';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faVolumeDown, faVolumeUp } from '@fortawesome/free-solid-svg-icons';\nimport { toast } from 'react-toastify';\nimport { useTranslation } from 'react-i18next';\nimport { changeVol } from '../../services/playerService';\nimport { volTimeout } from '../../config.json';\n\nconst PlayerControls = ({ playerStatus }) => {\n const { t } = useTranslation();\n\n const volDisabled = playerStatus.vol == null;\n\n const handleVolChange = async delta => {\n const { data: vol } = await changeVol(delta);\n\n const toastId = 'vol';\n const toastMsg = `${t('volume')}: ${vol}%`;\n const toastOpts = { toastId, autoClose: volTimeout };\n if (toast.isActive(toastId)) toast.update(toastId, { render: toastMsg });\n else toast.info(toastMsg, toastOpts);\n };\n\n const renderVolButton = (delta, icon, label) => (\n <button\n className=\"btn btn-dark p-3\"\n disabled={volDisabled}\n onClick={() => handleVolChange(delta)}\n aria-label={label}\n >\n <FontAwesomeIcon icon={icon} />\n </button>\n );\n\n return (\n <div\n className=\"player-controls btn-group w-100 m-2\"\n onClick={e => e.stopPropagation()}\n >\n {renderVolButton('-5', faVolumeDown, 'Volume down')}\n {renderVolButton('+5', faVolumeUp, 'Volume up')}\n <PlayStopControl playing={playerStatus.playing} />\n </div>\n );\n};\n\nexport default PlayerControls;\n","import React from 'react';\nimport PlayerStatus from './playerStatus';\nimport PlayerControls from './playerControls';\nimport './player.scss';\n\nconst Player = ({ playerStatus }) => {\n const renderLogo = () => (\n <img\n src={require('../../assets/logo.svg')}\n alt=\"Logo\"\n className=\"player-logo m-4\"\n />\n );\n\n return (\n <div className=\"player\">\n <PlayerStatus playerStatus={playerStatus} />\n {renderLogo()}\n <PlayerControls playerStatus={playerStatus} />\n </div>\n );\n};\n\nexport default Player;\n","import React from 'react';\nimport { useTranslation } from 'react-i18next';\n\nconst SearchBox = ({ value, onChange }) => {\n const { t } = useTranslation();\n\n return (\n <input\n className=\"form-control mb-4\"\n type=\"text\"\n id=\"query\"\n placeholder={t('search')}\n aria-label={t('search')}\n autoComplete=\"off\"\n value={value}\n onChange={e => onChange(e.target.value)}\n onFocus={() => onChange('')}\n ></input>\n );\n};\n\nexport default SearchBox;\n","import React, { Component } from 'react';\nimport { withTranslation } from 'react-i18next';\nimport { toast } from 'react-toastify';\nimport Loader from './common/loader';\nimport SearchBox from './common/searchBox';\nimport { playRadio } from '../services/playerService';\nimport { getStreams } from '../services/streamsService';\nimport './streams.scss';\n\nclass Streams extends Component {\n state = { streams: {}, loading: true, query: '' };\n\n async componentDidMount() {\n const { data: streams } = await getStreams();\n this.setState({ streams, loading: false });\n }\n\n isPlaying = name => {\n return (\n name === this.props.playerStatus.title && this.props.playerStatus.playing\n );\n };\n\n handleItemClick = async name => {\n const { t, onBackdrop } = this.props;\n\n if (this.isPlaying(name)) return;\n\n onBackdrop(t('tuning'), name);\n try {\n await playRadio(name);\n } catch (ex) {\n if (ex.response && ex.response.status === 400)\n toast.error(t('errorNotFound'));\n }\n };\n\n getItemClasses = name => {\n const classes = 'streams__item list-group-item ';\n return this.isPlaying(name)\n ? classes + 'active'\n : classes + 'list-group-item-action';\n };\n\n handleSearch = query => {\n this.setState({ query });\n };\n\n filteredStreams() {\n const { streams, query } = this.state;\n\n if (query === '') return streams;\n\n let filtered = {};\n for (let k in streams) {\n if (k.toLowerCase().includes(query.toLowerCase()) && !streams[k]) {\n filtered[k] = streams[k];\n }\n }\n return filtered;\n }\n\n renderList() {\n const streams = this.filteredStreams();\n\n if (Object.keys(streams).length === 0)\n return <h4 className=\"p-4\">{this.props.t('noStreams')}</h4>;\n\n return (\n <ul className=\"list-group list-group-flush\">\n {Object.keys(streams).map(name =>\n streams[name] ? (\n <li className=\"streams__header ellipsis\" key={name}>\n {name}\n </li>\n ) : (\n <li className={this.getItemClasses(name)} key={name}>\n <button\n className=\"streams__btn btn btn-outline ellipsis\"\n onClick={() => this.handleItemClick(name)}\n disabled={this.isPlaying(name)}\n >\n {name}\n </button>\n </li>\n )\n )}\n </ul>\n );\n }\n\n render() {\n if (this.state.loading) return <Loader />;\n\n return (\n <div className=\"streams\">\n <SearchBox value={this.state.query} onChange={this.handleSearch} />\n {this.renderList()}\n </div>\n );\n }\n}\n\nexport default withTranslation()(Streams);\n","import http from './httpService';\n\nconst apiEndpoint = '/streams';\n\nexport function getStreams() {\n return http.get(apiEndpoint);\n}\n","import React from 'react';\nimport PlayStopControl from './playStopControl';\nimport './miniPlayer.scss';\n\nconst MiniPlayer = ({ playerStatus }) => {\n const { title, playing } = playerStatus;\n\n return (\n <div className=\"mini-player\">\n <div className=\"mini-player__left ellipsis\">\n {title}\n </div>\n <div\n className=\"mini-player__right\"\n onClick={e => e.stopPropagation()}\n >\n <PlayStopControl playing={playing} />\n </div>\n </div>\n );\n};\n\nexport default MiniPlayer;\n","import React, { Component } from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons';\nimport MiniPlayer from './player/miniPlayer';\nimport Player from './player/player';\nimport './drawer.scss';\n\nclass Drawer extends Component {\n state = { open: false };\n\n toggle = () => {\n this.setState({ open: !this.state.open });\n };\n\n handleClick = () => {\n this.toggle();\n };\n\n handleTouchStart = (e) => {\n // Ignore multitouch\n if (e.touches.length > 1) return this.setState({ touchStartY: null });\n\n this.setState({ touchStartY: e.touches[0].clientY });\n };\n\n handleTouchMove = (e) => {\n const { open, touchStartY } = this.state;\n\n // Ignore multitouch\n if (touchStartY === null || e.touches.length > 1) return;\n\n const touchEndY = e.changedTouches[0].clientY;\n const touchUp = touchEndY < touchStartY;\n const touchDown = touchEndY > touchStartY;\n\n if (touchDown && open) this.toggle();\n else if (touchUp && !open) this.toggle();\n };\n\n renderToggleButton = () => (\n <button\n className=\"drawer__toggler btn btn-primary-outline\"\n aria-label=\"Toggle player\"\n >\n <FontAwesomeIcon\n icon={this.state.open ? faChevronDown : faChevronUp}\n className=\"fa-lg\"\n />\n </button>\n );\n\n render() {\n const { playerStatus } = this.props;\n const { open } = this.state;\n\n let classes = 'drawer fixed-bottom bg-secondary shadow-lg p-2';\n\n if (open) {\n classes += ' drawer--open';\n document.body.classList.add('body--drawer');\n } else document.body.classList.remove('body--drawer');\n\n return (\n <div\n className={classes}\n onClick={this.handleClick}\n onTouchStart={this.handleTouchStart}\n onTouchMove={this.handleTouchMove}\n >\n {this.renderToggleButton()}\n {open ? (\n <Player playerStatus={playerStatus} />\n ) : (\n <MiniPlayer playerStatus={playerStatus} />\n )}\n </div>\n );\n }\n}\n\nexport default Drawer;\n","import React from 'react';\nimport Player from './player/player';\nimport Streams from './streams';\nimport Drawer from './drawer';\nimport './main.scss';\n\nconst Main = ({ playerStatus, onBackdrop }) => {\n return (\n <main className=\"main\">\n <Drawer playerStatus={playerStatus} />\n <div className=\"main__primary container\">\n <Streams onBackdrop={onBackdrop} playerStatus={playerStatus} />\n <Player playerStatus={playerStatus} />\n </div>\n </main>\n );\n};\n\nexport default Main;\n","import React, { Component } from 'react';\nimport { ToastContainer } from 'react-toastify';\nimport { withTranslation } from 'react-i18next';\nimport NavBar from './components/navBar';\nimport Settings from './components/modals/settings';\nimport URLDialog from './components/modals/urlDialog';\nimport About from './components/modals/about';\nimport Loader from './components/common/loader';\nimport Backdrop from './components/common/backdrop';\nimport Main from './components/main';\nimport { getStatus } from './services/playerService';\nimport { updateInterval, backdropTimeout } from './config.json';\nimport 'react-toastify/dist/ReactToastify.css';\n\nclass App extends Component {\n state = {\n playerStatus: {},\n loading: true,\n networkError: false,\n backdrop: {},\n };\n\n componentDidMount() {\n this.updatePlayerStatus();\n }\n\n componentDidUpdate() {\n this.setDocumentTitle();\n }\n\n async updatePlayerStatus() {\n try {\n const { data: playerStatus } = await getStatus();\n this.setState({ playerStatus, loading: false, networkError: false });\n } catch (ex) {\n this.setState({ loading: false, networkError: true });\n }\n\n setTimeout(() => this.updatePlayerStatus(), updateInterval);\n }\n\n handleBackdrop = (title, body = '') => {\n this.setState({ backdrop: { title, body } });\n setTimeout(() => this.setState({ backdrop: {} }), backdropTimeout);\n };\n\n setDocumentTitle = () => {\n const { playerStatus: status, networkError } = this.state;\n\n if (!networkError && status.playing)\n document.title = 'PiFi 🔊 ' + status.title;\n else document.title = 'PiFi Radio';\n };\n\n render() {\n const { loading, networkError, backdrop, playerStatus } = this.state;\n const { t } = this.props;\n\n if (networkError) return <Backdrop title={t('errorNetwork')} />;\n if (loading) return <Loader />;\n if (!playerStatus.con_mpd) return <Backdrop title={t('disconnectedMPD')} />;\n\n return (\n <div className=\"app\">\n <ToastContainer pauseOnFocusLoss={false} />\n <Backdrop title={backdrop.title} body={backdrop.body} />\n <NavBar />\n <Main onBackdrop={this.handleBackdrop} playerStatus={playerStatus} />\n <URLDialog />\n <Settings />\n <About />\n </div>\n );\n }\n}\n\nexport default withTranslation()(App);\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\nexport function register(config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl, config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl, config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' }\n })\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister();\n });\n }\n}\n","import i18n from 'i18next';\nimport { initReactI18next } from 'react-i18next';\n\nimport Backend from 'i18next-http-backend';\nimport LanguageDetector from 'i18next-browser-languagedetector';\n// not like to use this?\n// have a look at the Quick start guide\n// for passing in lng and translations on init\n\ni18n\n // load translation using xhr -> see /public/locales\n // learn more: https://github.com/i18next/i18next-xhr-backend\n .use(Backend)\n // detect user language\n // learn more: https://github.com/i18next/i18next-browser-languageDetector\n .use(LanguageDetector)\n // pass the i18n instance to react-i18next.\n .use(initReactI18next)\n // init i18next\n // for all options read: https://www.i18next.com/overview/configuration-options\n .init({\n fallbackLng: 'en',\n debug: process.env.REACT_APP_I18N_DEBUG,\n load: 'currentOnly',\n returnEmptyString: false,\n\n interpolation: {\n escapeValue: false // not needed for react as it escapes by default\n }\n });\n\n// Set language on html tag\ni18n.on('languageChanged', lang => {\n document.documentElement.setAttribute('lang', lang);\n});\n\nexport default i18n;\n","import React, { Suspense } from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\nimport Loader from './components/common/loader';\nimport * as serviceWorker from './serviceWorker';\nimport './i18n';\nimport theme from './theme';\nimport './index.scss';\n// Bootstrap dependencies\nimport 'jquery/dist/jquery.min.js';\nimport 'bootstrap/dist/js/bootstrap.js';\n\ntheme.apply();\n\nReactDOM.render(\n // Suspense needed for i18n\n <Suspense fallback={<Loader />}>\n <App />\n </Suspense>,\n document.getElementById('root')\n);\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.unregister();\n"],"sourceRoot":""}
|
data/lib/pifi/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pifi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rafael Cavalcanti
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -126,19 +126,19 @@ files:
|
|
126
126
|
- lib/pifi/public/mstile-310x150.png
|
127
127
|
- lib/pifi/public/mstile-310x310.png
|
128
128
|
- lib/pifi/public/mstile-70x70.png
|
129
|
-
- lib/pifi/public/precache-manifest.
|
129
|
+
- lib/pifi/public/precache-manifest.7164537a626dea8757b9c96b06c8c33d.js
|
130
130
|
- lib/pifi/public/robots.txt
|
131
131
|
- lib/pifi/public/safari-pinned-tab.svg
|
132
132
|
- lib/pifi/public/service-worker.js
|
133
|
-
- lib/pifi/public/static/css/2.
|
134
|
-
- lib/pifi/public/static/css/2.
|
135
|
-
- lib/pifi/public/static/css/main.
|
136
|
-
- lib/pifi/public/static/css/main.
|
133
|
+
- lib/pifi/public/static/css/2.1781c263.chunk.css
|
134
|
+
- lib/pifi/public/static/css/2.1781c263.chunk.css.map
|
135
|
+
- lib/pifi/public/static/css/main.48912641.chunk.css
|
136
|
+
- lib/pifi/public/static/css/main.48912641.chunk.css.map
|
137
137
|
- lib/pifi/public/static/js/2.6c0ded8a.chunk.js
|
138
138
|
- lib/pifi/public/static/js/2.6c0ded8a.chunk.js.LICENSE.txt
|
139
139
|
- lib/pifi/public/static/js/2.6c0ded8a.chunk.js.map
|
140
|
-
- lib/pifi/public/static/js/main.
|
141
|
-
- lib/pifi/public/static/js/main.
|
140
|
+
- lib/pifi/public/static/js/main.21a62959.chunk.js
|
141
|
+
- lib/pifi/public/static/js/main.21a62959.chunk.js.map
|
142
142
|
- lib/pifi/public/static/js/runtime-main.5aae5a31.js
|
143
143
|
- lib/pifi/public/static/js/runtime-main.5aae5a31.js.map
|
144
144
|
- lib/pifi/public/static/media/getFetch.5e98861f.cjs
|
@@ -1,2 +0,0 @@
|
|
1
|
-
.Toastify__toast-container{z-index:9999;-webkit-transform:translateZ(9999px);position:fixed;padding:4px;width:320px;box-sizing:border-box;color:#fff}.Toastify__toast-container--top-left{top:1em;left:1em}.Toastify__toast-container--top-center{top:1em;left:50%;transform:translateX(-50%)}.Toastify__toast-container--top-right{top:1em;right:1em}.Toastify__toast-container--bottom-left{bottom:1em;left:1em}.Toastify__toast-container--bottom-center{bottom:1em;left:50%;transform:translateX(-50%)}.Toastify__toast-container--bottom-right{bottom:1em;right:1em}@media only screen and (max-width:480px){.Toastify__toast-container{width:100vw;padding:0;left:0;margin:0}.Toastify__toast-container--top-center,.Toastify__toast-container--top-left,.Toastify__toast-container--top-right{top:0;transform:translateX(0)}.Toastify__toast-container--bottom-center,.Toastify__toast-container--bottom-left,.Toastify__toast-container--bottom-right{bottom:0;transform:translateX(0)}.Toastify__toast-container--rtl{right:0;left:auto}}.Toastify__toast{position:relative;min-height:64px;box-sizing:border-box;margin-bottom:1rem;padding:8px;border-radius:1px;box-shadow:0 1px 10px 0 rgba(0,0,0,.1),0 2px 15px 0 rgba(0,0,0,.05);display:flex;justify-content:space-between;max-height:800px;overflow:hidden;font-family:sans-serif;cursor:pointer;direction:ltr}.Toastify__toast--rtl{direction:rtl}.Toastify__toast--dark{background:#121212;color:#fff}.Toastify__toast--default{background:#fff;color:#aaa}.Toastify__toast--info{background:#3498db}.Toastify__toast--success{background:#07bc0c}.Toastify__toast--warning{background:#f1c40f}.Toastify__toast--error{background:#e74c3c}.Toastify__toast-body{margin:auto 0;flex:1 1 auto}@media only screen and (max-width:480px){.Toastify__toast{margin-bottom:0}}.Toastify__close-button{color:#fff;background:transparent;outline:none;border:none;padding:0;cursor:pointer;opacity:.7;transition:.3s ease;align-self:flex-start}.Toastify__close-button--default{color:#000;opacity:.3}.Toastify__close-button>svg{fill:currentColor;height:16px;width:14px}.Toastify__close-button:focus,.Toastify__close-button:hover{opacity:1}@-webkit-keyframes Toastify__trackProgress{0%{transform:scaleX(1)}to{transform:scaleX(0)}}@keyframes Toastify__trackProgress{0%{transform:scaleX(1)}to{transform:scaleX(0)}}.Toastify__progress-bar{position:absolute;bottom:0;left:0;width:100%;height:5px;z-index:9999;opacity:.7;background-color:hsla(0,0%,100%,.7);transform-origin:left}.Toastify__progress-bar--animated{-webkit-animation:Toastify__trackProgress linear 1 forwards;animation:Toastify__trackProgress linear 1 forwards}.Toastify__progress-bar--controlled{transition:transform .2s}.Toastify__progress-bar--rtl{right:0;left:auto;transform-origin:right}.Toastify__progress-bar--default{background:linear-gradient(90deg,#4cd964,#5ac8fa,#007aff,#34aadc,#5856d6,#ff2d55)}.Toastify__progress-bar--dark{background:#bb86fc}@-webkit-keyframes Toastify__bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(3000px,0,0)}60%{opacity:1;transform:translate3d(-25px,0,0)}75%{transform:translate3d(10px,0,0)}90%{transform:translate3d(-5px,0,0)}to{transform:none}}@keyframes Toastify__bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(3000px,0,0)}60%{opacity:1;transform:translate3d(-25px,0,0)}75%{transform:translate3d(10px,0,0)}90%{transform:translate3d(-5px,0,0)}to{transform:none}}@-webkit-keyframes Toastify__bounceOutRight{20%{opacity:1;transform:translate3d(-20px,0,0)}to{opacity:0;transform:translate3d(2000px,0,0)}}@keyframes Toastify__bounceOutRight{20%{opacity:1;transform:translate3d(-20px,0,0)}to{opacity:0;transform:translate3d(2000px,0,0)}}@-webkit-keyframes Toastify__bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(-3000px,0,0)}60%{opacity:1;transform:translate3d(25px,0,0)}75%{transform:translate3d(-10px,0,0)}90%{transform:translate3d(5px,0,0)}to{transform:none}}@keyframes Toastify__bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(-3000px,0,0)}60%{opacity:1;transform:translate3d(25px,0,0)}75%{transform:translate3d(-10px,0,0)}90%{transform:translate3d(5px,0,0)}to{transform:none}}@-webkit-keyframes Toastify__bounceOutLeft{20%{opacity:1;transform:translate3d(20px,0,0)}to{opacity:0;transform:translate3d(-2000px,0,0)}}@keyframes Toastify__bounceOutLeft{20%{opacity:1;transform:translate3d(20px,0,0)}to{opacity:0;transform:translate3d(-2000px,0,0)}}@-webkit-keyframes Toastify__bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(0,3000px,0)}60%{opacity:1;transform:translate3d(0,-20px,0)}75%{transform:translate3d(0,10px,0)}90%{transform:translate3d(0,-5px,0)}to{transform:translateZ(0)}}@keyframes Toastify__bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(0,3000px,0)}60%{opacity:1;transform:translate3d(0,-20px,0)}75%{transform:translate3d(0,10px,0)}90%{transform:translate3d(0,-5px,0)}to{transform:translateZ(0)}}@-webkit-keyframes Toastify__bounceOutUp{20%{transform:translate3d(0,-10px,0)}40%,45%{opacity:1;transform:translate3d(0,20px,0)}to{opacity:0;transform:translate3d(0,-2000px,0)}}@keyframes Toastify__bounceOutUp{20%{transform:translate3d(0,-10px,0)}40%,45%{opacity:1;transform:translate3d(0,20px,0)}to{opacity:0;transform:translate3d(0,-2000px,0)}}@-webkit-keyframes Toastify__bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(0,-3000px,0)}60%{opacity:1;transform:translate3d(0,25px,0)}75%{transform:translate3d(0,-10px,0)}90%{transform:translate3d(0,5px,0)}to{transform:none}}@keyframes Toastify__bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;transform:translate3d(0,-3000px,0)}60%{opacity:1;transform:translate3d(0,25px,0)}75%{transform:translate3d(0,-10px,0)}90%{transform:translate3d(0,5px,0)}to{transform:none}}@-webkit-keyframes Toastify__bounceOutDown{20%{transform:translate3d(0,10px,0)}40%,45%{opacity:1;transform:translate3d(0,-20px,0)}to{opacity:0;transform:translate3d(0,2000px,0)}}@keyframes Toastify__bounceOutDown{20%{transform:translate3d(0,10px,0)}40%,45%{opacity:1;transform:translate3d(0,-20px,0)}to{opacity:0;transform:translate3d(0,2000px,0)}}.Toastify__bounce-enter--bottom-left,.Toastify__bounce-enter--top-left{-webkit-animation-name:Toastify__bounceInLeft;animation-name:Toastify__bounceInLeft}.Toastify__bounce-enter--bottom-right,.Toastify__bounce-enter--top-right{-webkit-animation-name:Toastify__bounceInRight;animation-name:Toastify__bounceInRight}.Toastify__bounce-enter--top-center{-webkit-animation-name:Toastify__bounceInDown;animation-name:Toastify__bounceInDown}.Toastify__bounce-enter--bottom-center{-webkit-animation-name:Toastify__bounceInUp;animation-name:Toastify__bounceInUp}.Toastify__bounce-exit--bottom-left,.Toastify__bounce-exit--top-left{-webkit-animation-name:Toastify__bounceOutLeft;animation-name:Toastify__bounceOutLeft}.Toastify__bounce-exit--bottom-right,.Toastify__bounce-exit--top-right{-webkit-animation-name:Toastify__bounceOutRight;animation-name:Toastify__bounceOutRight}.Toastify__bounce-exit--top-center{-webkit-animation-name:Toastify__bounceOutUp;animation-name:Toastify__bounceOutUp}.Toastify__bounce-exit--bottom-center{-webkit-animation-name:Toastify__bounceOutDown;animation-name:Toastify__bounceOutDown}@-webkit-keyframes Toastify__zoomIn{0%{opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes Toastify__zoomIn{0%{opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}@-webkit-keyframes Toastify__zoomOut{0%{opacity:1}50%{opacity:0;transform:scale3d(.3,.3,.3)}to{opacity:0}}@keyframes Toastify__zoomOut{0%{opacity:1}50%{opacity:0;transform:scale3d(.3,.3,.3)}to{opacity:0}}.Toastify__zoom-enter{-webkit-animation-name:Toastify__zoomIn;animation-name:Toastify__zoomIn}.Toastify__zoom-exit{-webkit-animation-name:Toastify__zoomOut;animation-name:Toastify__zoomOut}@-webkit-keyframes Toastify__flipIn{0%{transform:perspective(400px) rotateX(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{transform:perspective(400px) rotateX(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{transform:perspective(400px) rotateX(10deg);opacity:1}80%{transform:perspective(400px) rotateX(-5deg)}to{transform:perspective(400px)}}@keyframes Toastify__flipIn{0%{transform:perspective(400px) rotateX(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{transform:perspective(400px) rotateX(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{transform:perspective(400px) rotateX(10deg);opacity:1}80%{transform:perspective(400px) rotateX(-5deg)}to{transform:perspective(400px)}}@-webkit-keyframes Toastify__flipOut{0%{transform:perspective(400px)}30%{transform:perspective(400px) rotateX(-20deg);opacity:1}to{transform:perspective(400px) rotateX(90deg);opacity:0}}@keyframes Toastify__flipOut{0%{transform:perspective(400px)}30%{transform:perspective(400px) rotateX(-20deg);opacity:1}to{transform:perspective(400px) rotateX(90deg);opacity:0}}.Toastify__flip-enter{-webkit-animation-name:Toastify__flipIn;animation-name:Toastify__flipIn}.Toastify__flip-exit{-webkit-animation-name:Toastify__flipOut;animation-name:Toastify__flipOut}@-webkit-keyframes Toastify__slideInRight{0%{transform:translate3d(110%,0,0);visibility:visible}to{transform:translateZ(0)}}@keyframes Toastify__slideInRight{0%{transform:translate3d(110%,0,0);visibility:visible}to{transform:translateZ(0)}}@-webkit-keyframes Toastify__slideInLeft{0%{transform:translate3d(-110%,0,0);visibility:visible}to{transform:translateZ(0)}}@keyframes Toastify__slideInLeft{0%{transform:translate3d(-110%,0,0);visibility:visible}to{transform:translateZ(0)}}@-webkit-keyframes Toastify__slideInUp{0%{transform:translate3d(0,110%,0);visibility:visible}to{transform:translateZ(0)}}@keyframes Toastify__slideInUp{0%{transform:translate3d(0,110%,0);visibility:visible}to{transform:translateZ(0)}}@-webkit-keyframes Toastify__slideInDown{0%{transform:translate3d(0,-110%,0);visibility:visible}to{transform:translateZ(0)}}@keyframes Toastify__slideInDown{0%{transform:translate3d(0,-110%,0);visibility:visible}to{transform:translateZ(0)}}@-webkit-keyframes Toastify__slideOutRight{0%{transform:translateZ(0)}to{visibility:hidden;transform:translate3d(110%,0,0)}}@keyframes Toastify__slideOutRight{0%{transform:translateZ(0)}to{visibility:hidden;transform:translate3d(110%,0,0)}}@-webkit-keyframes Toastify__slideOutLeft{0%{transform:translateZ(0)}to{visibility:hidden;transform:translate3d(-110%,0,0)}}@keyframes Toastify__slideOutLeft{0%{transform:translateZ(0)}to{visibility:hidden;transform:translate3d(-110%,0,0)}}@-webkit-keyframes Toastify__slideOutDown{0%{transform:translateZ(0)}to{visibility:hidden;transform:translate3d(0,500px,0)}}@keyframes Toastify__slideOutDown{0%{transform:translateZ(0)}to{visibility:hidden;transform:translate3d(0,500px,0)}}@-webkit-keyframes Toastify__slideOutUp{0%{transform:translateZ(0)}to{visibility:hidden;transform:translate3d(0,-500px,0)}}@keyframes Toastify__slideOutUp{0%{transform:translateZ(0)}to{visibility:hidden;transform:translate3d(0,-500px,0)}}.Toastify__slide-enter--bottom-left,.Toastify__slide-enter--top-left{-webkit-animation-name:Toastify__slideInLeft;animation-name:Toastify__slideInLeft}.Toastify__slide-enter--bottom-right,.Toastify__slide-enter--top-right{-webkit-animation-name:Toastify__slideInRight;animation-name:Toastify__slideInRight}.Toastify__slide-enter--top-center{-webkit-animation-name:Toastify__slideInDown;animation-name:Toastify__slideInDown}.Toastify__slide-enter--bottom-center{-webkit-animation-name:Toastify__slideInUp;animation-name:Toastify__slideInUp}.Toastify__slide-exit--bottom-left,.Toastify__slide-exit--top-left{-webkit-animation-name:Toastify__slideOutLeft;animation-name:Toastify__slideOutLeft}.Toastify__slide-exit--bottom-right,.Toastify__slide-exit--top-right{-webkit-animation-name:Toastify__slideOutRight;animation-name:Toastify__slideOutRight}.Toastify__slide-exit--top-center{-webkit-animation-name:Toastify__slideOutUp;animation-name:Toastify__slideOutUp}.Toastify__slide-exit--bottom-center{-webkit-animation-name:Toastify__slideOutDown;animation-name:Toastify__slideOutDown}
|
2
|
-
/*# sourceMappingURL=2.d34346ea.chunk.css.map */
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../scss/_toastContainer.scss","../scss/_variables.scss","ReactToastify.css","../scss/_toast.scss","../scss/_closeButton.scss","../scss/_progressBar.scss","../scss/animations/_bounce.scss","../scss/animations/_zoom.scss","../scss/animations/_flip.scss","../scss/animations/_slide.scss"],"names":[],"mappings":"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","file":"2.d34346ea.chunk.css"}
|
@@ -1,2 +0,0 @@
|
|
1
|
-
.navbar{position:-webkit-sticky!important;position:sticky!important;top:0;z-index:5;margin-bottom:2rem;padding:.8rem 1rem;min-height:4.7793rem}.loader{height:100vh}.backdrop,.loader{z-index:10;display:flex;justify-content:center;align-items:center}.backdrop{position:fixed;width:100%;height:100%;background-color:#222;opacity:0;visibility:hidden;transition:all .2s ease;cursor:default;flex-direction:column;text-align:center}.backdrop--visible{opacity:.94;visibility:visible}.body--backdrop{overflow:hidden}.player{width:100%;max-width:450px;display:flex;flex-direction:column;justify-content:space-between;align-items:center}.player-logo{width:130px}@media (max-height:430px){.player-logo{display:none}}.streams{max-width:450px}.streams__item{cursor:pointer}.streams__item.active{cursor:default}.streams__header{font-size:1.3rem;margin-top:1em;padding:.5rem 1.25rem}.mini-player{display:flex;align-items:center;justify-content:space-between}.mini-player button{padding:10px 20px}.mini-player__left{max-width:calc(100vw - 160px);margin-right:1rem}.drawer{z-index:5!important;height:5rem;cursor:pointer;touch-action:none;display:flex;align-items:center;transition:height .25s ease-out}.drawer>.mini-player{flex-grow:1;margin:0 .5rem 0 .25rem}.drawer--open{height:100%;flex-direction:column;justify-content:flex-end}.drawer--open .player{flex-grow:1}.drawer--open .drawer__toggler{margin-bottom:20px}@media (max-width:770px){.body--drawer{overflow:hidden}}.main__primary{margin-bottom:7rem}.main__primary .player{display:none}.main__primary .streams{margin:0 auto}@media (min-width:770px){.main__primary{margin-bottom:2rem;display:flex;justify-content:space-between}.main__primary>*{min-width:0;width:100%}.main__primary .player{display:inherit;position:-webkit-sticky;position:sticky;top:6.7793rem;margin-left:2rem;height:calc(100vh - 8.7793rem);max-height:550px}.main__primary .streams{margin:0}.drawer{display:none}}html{height:100%}body{min-height:100%;overflow-y:scroll}button[disabled]{cursor:default}.ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
2
|
-
/*# sourceMappingURL=main.221e80d3.chunk.css.map */
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["navBar.scss","../_variables.scss","loader.scss","backdrop.scss","player.scss","streams.scss","miniPlayer.scss","drawer.scss","main.scss","index.scss"],"names":[],"mappings":"AAEA,QACE,iCAA2B,CAA3B,yBAA2B,CAC3B,KAAM,CACN,SAAU,CACV,kBCFe,CDKf,kBAAoB,CAEpB,oBCRoB,CCHtB,QAKE,YAAa,CCLf,kBDCE,UAAW,CACX,YAAa,CACb,sBAAuB,CACvB,kBCUkB,CAdpB,UAEE,cAAe,CACf,UAAW,CACX,WAAY,CACZ,qBAAyB,CACzB,SAAU,CACV,iBAAkB,CAClB,uBAAyB,CACzB,cAAe,CAEf,qBAAsB,CAGtB,iBAAkB,CAElB,mBACE,WAAa,CACb,kBAAmB,CACpB,gBAID,eAAgB,CCrBlB,QACE,UAAW,CACX,eAAgB,CAChB,YAAa,CACb,qBAAsB,CACtB,6BAA8B,CAC9B,kBAAmB,CACpB,aAGC,WAAY,CACb,0BAGC,aACE,YAAa,CACd,CChBH,SACE,eAAgB,CACjB,eAGC,cAAe,CADjB,sBAII,cAAe,CAChB,iBAID,gBAAiB,CACjB,cAAe,CACf,qBAAuB,CCjBzB,aACE,YAAa,CACb,kBAAmB,CACnB,6BAA8B,CAHhC,oBAMI,iBAAkB,CACnB,mBAKD,6BAA8B,CAC9B,iBAAkB,CCXpB,QACE,mBAAqB,CACrB,WNFkB,CMGlB,cAAe,CACf,iBAAkB,CAClB,YAAa,CACb,kBAAmB,CACnB,+BAAiC,CAPnC,qBAUI,WAAY,CACZ,uBAA0B,CAC3B,cAGC,WAAY,CACZ,qBAAsB,CACtB,wBAAyB,CAH1B,sBAMG,WAAY,CANf,+BAUG,kBAAmB,CACpB,yBAOH,cACE,eAAgB,CACjB,CChCH,eACE,kBAAuC,CADzC,uBAII,YAAa,CAJjB,wBAQI,aAAc,CACf,yBAID,eACE,kBAhBS,CAiBT,YAAa,CACb,6BAA8B,CAHhC,iBAMI,WAAY,CACZ,UAAW,CAPf,uBAWI,eAAgB,CAChB,uBAAgB,CAAhB,eAAgB,CAChB,aPzB8B,CO0B9B,gBAAiB,CACjB,8BAA4C,CAC5C,gBAAiB,CAhBrB,wBAoBI,QAAS,CACV,QAID,YAAa,CACd,CC3CH,KACE,WAAY,CACb,KAGC,eAAgB,CAChB,iBAAkB,CACnB,iBAGC,cAAe,CAChB,UAGC,kBAAmB,CACnB,eAAgB,CAChB,sBAAuB","file":"main.221e80d3.chunk.css","sourcesContent":["@import '../variables';\n\n.navbar {\n position: sticky !important;\n top: 0;\n z-index: 5;\n margin-bottom: $nav-margin;\n // The following let us have the same height on all themes.\n // 1. prevent lux to increment padding\n padding: 0.8rem 1rem;\n // 2. make darkly as high as lux\n min-height: $nav-height;\n}\n","$for-medium-up: 770px;\n$for-short-down: 430px;\n$drawer-height: 5rem;\n$nav-height: 4.7793rem; // calculated value for higher theme\n$nav-margin: 2rem;\n$nav-size: $nav-height + $nav-margin;\n",".loader {\n z-index: 10;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n}\n",".backdrop {\n z-index: 10;\n position: fixed;\n width: 100%;\n height: 100%;\n background-color: #222222;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n cursor: default;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n text-align: center;\n\n &--visible {\n opacity: 0.94;\n visibility: visible;\n }\n}\n\n.body--backdrop {\n overflow: hidden;\n}\n","@import '../../variables';\n\n.player {\n width: 100%;\n max-width: 450px;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n align-items: center;\n}\n\n.player-logo {\n width: 130px;\n}\n\n@media(max-height: $for-short-down) {\n .player-logo {\n display: none;\n }\n}\n","@import '../variables';\n\n.streams {\n max-width: 450px;\n}\n\n.streams__item {\n cursor: pointer;\n\n &.active {\n cursor: default;\n }\n}\n\n.streams__header {\n font-size: 1.3rem;\n margin-top: 1em;\n padding: 0.5rem 1.25rem;\n}\n",".mini-player {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n button {\n padding: 10px 20px;\n }\n}\n\n.mini-player__left {\n // Dirty workaround for ellipsis to work\n max-width: calc(100vw - 160px);\n margin-right: 1rem;\n}\n","@import '../variables';\n\n.drawer {\n z-index: 5 !important;\n height: $drawer-height;\n cursor: pointer;\n touch-action: none; // don't scroll on touch\n display: flex;\n align-items: center;\n transition: height 0.25s ease-out;\n\n & > .mini-player {\n flex-grow: 1;\n margin: 0 0.5rem 0 0.25rem;\n }\n\n &--open {\n height: 100%;\n flex-direction: column;\n justify-content: flex-end;\n\n .player {\n flex-grow: 1;\n }\n\n .drawer__toggler {\n margin-bottom: 20px;\n }\n }\n}\n\n// The media query is for the edge case of an open drawer and the\n// window resized past the breakpoint. This brings the scrollbar back.\n@media (max-width: $for-medium-up) {\n .body--drawer {\n overflow: hidden;\n }\n}\n","@import '../variables';\n\n$margin: 2rem;\n\n.main__primary {\n margin-bottom: $margin + $drawer-height;\n\n .player {\n display: none;\n }\n\n .streams {\n margin: 0 auto;\n }\n}\n\n@media (min-width: $for-medium-up) {\n .main__primary {\n margin-bottom: $margin; /* no drawer */\n display: flex;\n justify-content: space-between;\n\n & > * {\n min-width: 0; /* don't get bigger when text overflows */\n width: 100%; /* divide space equally */\n }\n\n .player {\n display: inherit;\n position: sticky;\n top: $nav-size;\n margin-left: 2rem;\n height: calc(100vh - #{$nav-size + $margin});\n max-height: 550px;\n }\n\n .streams {\n margin: 0;\n }\n }\n\n .drawer {\n display: none;\n }\n}\n","html {\n height: 100%;\n}\n\nbody {\n min-height: 100%;\n overflow-y: scroll; // so elements don't move if page fits view\n}\n\nbutton[disabled] {\n cursor: default;\n}\n\n.ellipsis {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n"]}
|
@@ -1,2 +0,0 @@
|
|
1
|
-
(this.webpackJsonppifi_frontend=this.webpackJsonppifi_frontend||[]).push([[0],{13:function(e){e.exports=JSON.parse('{"b":["en","de-DE","fr-FR","nl-NL","pl-PL","pt-BR"],"c":1000,"a":2500,"d":3000}')},30:function(e,t,a){e.exports=a.p+"static/media/logo.91554ce9.svg"},50:function(e,t,a){e.exports=a(94)},56:function(e,t,a){},79:function(e,t,a){},80:function(e,t,a){},83:function(e,t,a){},84:function(e,t,a){},85:function(e,t,a){},86:function(e,t,a){},87:function(e,t,a){},89:function(e,t,a){},94:function(e,t,a){"use strict";a.r(t);var n=a(0),r=a.n(n),l=a(12),o=a.n(l),c=a(2),s=a.n(c),i=a(8),u=a(9),m=a(10),d=a(19),p=a(20),b=a(3),f=a(98),v=a(26),h=(a(56),a(30)),g=a.n(h),y=function(){var e=Object(v.a)().t;return r.a.createElement("nav",{className:"navbar navbar-expand-sm navbar-dark bg-primary"},r.a.createElement("div",{className:"container"},r.a.createElement("a",{className:"navbar-brand",href:"/"},r.a.createElement("img",{src:g.a,width:"30",height:"30",className:"d-inline-block align-text-bottom mr-2",alt:""}),"PiFi Radio"),r.a.createElement("button",{className:"navbar-toggler",type:"button","data-toggle":"collapse","data-target":"#navbarNavAltMarkup","aria-controls":"navbarNavAltMarkup","aria-expanded":"false","aria-label":"Toggle navigation"},r.a.createElement("span",{className:"navbar-toggler-icon"})),r.a.createElement("div",{className:"collapse navbar-collapse",id:"navbarNavAltMarkup"},r.a.createElement("div",{className:"navbar-nav pt-1 ml-2"},r.a.createElement("button",{className:"btn btn-link nav-link","data-toggle":"modal","data-target":"#url-dialog"},e("playURL")),r.a.createElement("button",{className:"btn btn-link nav-link","data-toggle":"modal","data-target":"#settings"},e("settings")),r.a.createElement("button",{className:"btn btn-link nav-link","data-toggle":"modal","data-target":"#about"},e("about"))))))},E=a(15),k=a(48),N=a(44),S=a.n(N),w=function(e){var t=e.id,a=e.title,n=e.footer,l=e.children,o=Object(v.a)().t,c=r.a.createElement("button",{className:"btn btn-secondary","data-dismiss":"modal"},o("close"));return r.a.createElement("div",{className:"modal fade",id:t,tabIndex:"-1",role:"dialog","aria-labelledby":"staticBackdropLabel","aria-hidden":"true"},r.a.createElement("div",{className:"modal-dialog",role:"document"},r.a.createElement("div",{className:"modal-content"},r.a.createElement("div",{className:"modal-header"},r.a.createElement("h5",{className:"modal-title",id:"staticBackdropLabel"},a),r.a.createElement("button",{type:"button",className:"close","data-dismiss":"modal","aria-label":"Close"},r.a.createElement("span",{"aria-hidden":"true"},"\xd7"))),r.a.createElement("div",{className:"modal-body"},l),r.a.createElement("div",{className:"modal-footer"},n||c))))},O=a(49),j=function(e){var t=e.id,a=e.label,n=e.row,l=e.data,o=Object(O.a)(e,["id","label","row","data"]);return r.a.createElement("div",{className:n?"form-group row":"form-group"},r.a.createElement("label",{htmlFor:t,className:"col-sm-2 col-form-label"},a),r.a.createElement("div",{className:"col-sm-10"},r.a.createElement("select",Object.assign({id:t,className:"form-control"},o),l.map((function(e){return r.a.createElement("option",{key:e.id||e,value:e.id||e},e.name||e)})))))},C=[{id:"darkly",name:"Darkly",themeColor:"#375a7f"},{id:"lux",name:"Lux",themeColor:"#1a1a1a"}];function _(){var e=x(),t=function(e){return"https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/".concat(e,"/bootstrap.min.css")}(e),a=C.find((function(t){return t.id===e})).themeColor;document.querySelector('link[title="theme"]').setAttribute("href",t),document.querySelector('meta[name="theme-color"]').setAttribute("content",a)}function x(){var e=localStorage.getItem("theme");return""===e?"darkly":0===C.filter((function(t){return t.id===e})).length?(localStorage.removeItem("theme"),"darkly"):e}var T={availableThemes:C,getCurrentId:x,change:function(e){localStorage.setItem("theme",e),_()},apply:_},L=a(13),P=function(){var e=Object(v.a)(),t=e.t,a=e.i18n,l=Object(n.useState)(""),o=Object(E.a)(l,2),c=o[0],s=o[1],i=L.b.sort().map((function(e){var t=e.slice(0,2);return{id:e,name:"".concat(S()(e)," ").concat(k.a.getNativeName(t))}}));return Object(n.useEffect)((function(){s(T.getCurrentId())}),[]),r.a.createElement(w,{id:"settings",title:t("settings")},r.a.createElement(j,{id:"theme-select",label:t("theme"),data:T.availableThemes,row:!0,value:c,onChange:function(e){return function(e){var t=e.target.value;T.change(t),s(t)}(e)}}),r.a.createElement(j,{id:"language-select",label:t("language"),data:i,row:!0,value:a.language,onChange:function(e){return a.changeLanguage(e.target.value)}}))},R=a(24),A=a.n(R),B=a(97);A.a.defaults.baseURL="/api",A.a.interceptors.response.use(null,(function(e){var t=e.response&&e.response.status>=400&&e.response.status<500;return document.querySelector(".Toastify")&&(t||b.b.error(r.a.createElement(B.a,null,(function(e){return e("errorUnexpected")}))),e.response&&403===e.response.status&&b.b.error(r.a.createElement(B.a,null,(function(e){return e("errorForbidden")})))),Promise.reject(e)}));var D={get:A.a.get,post:A.a.post};function I(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,a=new FormData;return a.set("method",e),t&&a.set("params",t),a}function F(){return D.post("/player",I("play"))}function U(){return D.post("/player",I("stop"))}function M(e){return D.post("/player",I("change_vol",e))}function q(e){return D.post("/player",I("play_radios",e))}function W(e){return D.post("/player",I("play_urls",e))}var Y=function(){var e=Object(n.useState)(""),t=Object(E.a)(e,2),a=t[0],l=t[1],o=Object(v.a)().t,c=function(){""!==a&&(u(a),l(""))},u=function(){var e=Object(i.a)(s.a.mark((function e(t){var a,n;return s.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a={type:b.b.TYPE.ERROR,render:o("errorNotFound")},n=Object(b.b)(o("tryingURL")),e.prev=2,e.next=5,W(t);case 5:e.next=10;break;case 7:e.prev=7,e.t0=e.catch(2),e.t0.response&&400===e.t0.response.status&&b.b.update(n,a);case 10:case"end":return e.stop()}}),e,null,[[2,7]])})));return function(t){return e.apply(this,arguments)}}();return r.a.createElement(w,{id:"url-dialog",title:o("playURL"),footer:r.a.createElement(r.a.Fragment,null,r.a.createElement("button",{className:"btn btn-primary","data-dismiss":"modal",onClick:c},o("ok")),r.a.createElement("button",{className:"btn btn-secondary",onClick:function(){return l("")},"data-dismiss":"modal"},o("cancel")))},r.a.createElement("input",{className:"form-control mb-4",type:"text",placeholder:"URL",value:a,onChange:function(e){var t=e.target;l(t.value)},onKeyDown:function(e){"Enter"===e.key&&c()}}))};function K(){return D.get("/config")}a(79);var V=function(){return r.a.createElement("div",{className:"loader"},r.a.createElement("div",{className:"spinner-border",role:"status"},r.a.createElement("span",{className:"sr-only"},"Loading...")))},H=function(){var e=Object(v.a)().t,t=Object(n.useState)({}),a=Object(E.a)(t,2),l=a[0],o=a[1],c=Object(n.useState)(!0),u=Object(E.a)(c,2),m=u[0],d=u[1];Object(n.useEffect)((function(){function e(){return(e=Object(i.a)(s.a.mark((function e(){var t,a;return s.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,K();case 2:t=e.sent,a=t.data,o(a),d(!1);case 6:case"end":return e.stop()}}),e)})))).apply(this,arguments)}!function(){e.apply(this,arguments)}()}),[]);var p=[{label:e("mpdHost"),value:l.mpd_host},{label:e("mpdPort"),value:l.mpd_port},{label:e("environment"),value:l.environment},{label:e("version"),value:l.version}],b=r.a.createElement("div",{className:"copyright small mt-5"},r.a.createElement("p",null,r.a.createElement("a",{href:"https://rafaelc.org/pifi",target:"_blank",rel:"noopener noreferrer",style:{color:"inherit"}},e("goToDocs"))),r.a.createElement("p",null,"Copyright \xa9 2017-2020\xa0",r.a.createElement("a",{href:"https://rafaelc.org/",target:"_blank",rel:"noopener noreferrer",style:{color:"inherit"}},"Rafael Cavalcanti"))),f=r.a.createElement("div",{className:"coffee mt-5"},r.a.createElement("p",null,e("coffee")),r.a.createElement("a",{href:"https://www.buymeacoffee.com/rafaelc",target:"_blank",rel:"noopener noreferrer"},r.a.createElement("img",{src:"https://cdn.buymeacoffee.com/buttons/default-blue.png",alt:"Buy Me A Coffee",style:{height:51,width:217}})));return r.a.createElement(w,{id:"about",title:e("about")},m?r.a.createElement(V,null):r.a.createElement("table",{className:"table"},r.a.createElement("tbody",null,p.map((function(e){return r.a.createElement("tr",{key:e.label},r.a.createElement("th",{scope:"row"},e.label),r.a.createElement("td",null,e.value))})))),f,b)},J=(a(80),function(){return window.innerWidth-document.documentElement.clientWidth}),G=function(e){var t=e.title,a=e.body,n=t,l=document.body.classList.contains("body--backdrop");n&&!l?(document.body.style.paddingRight=J()+"px",document.body.classList.add("body--backdrop")):!n&&l&&(document.body.style.paddingRight=0,document.body.classList.remove("body--backdrop"));var o="backdrop p-2 text-white"+(n?" backdrop--visible":"");return r.a.createElement("div",{className:o},r.a.createElement("h3",{className:"text-white"},t),r.a.createElement("h5",{className:"text-white"},a))},$=function(e){var t=e.playerStatus,a=t.playing,n=t.title,l=Object(v.a)().t;return r.a.createElement("div",{className:"text-center w-100"},r.a.createElement("h5",{className:"small text-uppercase"},l(a?"playing":"stopped")),r.a.createElement("h3",{className:"ellipsis"},n))},z=a(14),Q=a(11),X=function(e){return e.playing?r.a.createElement("button",{className:"btn btn-danger",onClick:U,"aria-label":"Stop"},r.a.createElement(z.a,{icon:Q.d})):r.a.createElement("button",{className:"btn btn-dark",onClick:F,"aria-label":"Play"},r.a.createElement(z.a,{icon:Q.c}))},Z=function(e){var t=e.playerStatus,a=Object(v.a)().t,n=null==t.vol,l=function(){var e=Object(i.a)(s.a.mark((function e(t){var n,r,l,o;return s.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,M(t);case 2:n=e.sent,r=n.data,"vol",l="".concat(a("volume"),": ").concat(r,"%"),o={toastId:"vol",autoClose:L.d},b.b.isActive("vol")?b.b.update("vol",{render:l}):b.b.info(l,o);case 8:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),o=function(e,t,a){return r.a.createElement("button",{className:"btn btn-dark p-3",disabled:n,onClick:function(){return l(e)},"aria-label":a},r.a.createElement(z.a,{icon:t}))};return r.a.createElement("div",{className:"player-controls btn-group w-100 m-2",onClick:function(e){return e.stopPropagation()}},o("-5",Q.e,"Volume down"),o("+5",Q.f,"Volume up"),r.a.createElement(X,{playing:t.playing}))},ee=(a(83),function(e){var t=e.playerStatus;return r.a.createElement("div",{className:"player"},r.a.createElement($,{playerStatus:t}),r.a.createElement("img",{src:a(30),alt:"Logo",className:"player-logo m-4"}),r.a.createElement(Z,{playerStatus:t}))}),te=function(e){var t=e.value,a=e.onChange,n=Object(v.a)().t;return r.a.createElement("input",{className:"form-control mb-4",type:"text",id:"query",placeholder:n("search"),"aria-label":n("search"),autoComplete:"off",value:t,onChange:function(e){return a(e.target.value)},onFocus:function(){return a("")}})};a(84);var ae=function(e){Object(p.a)(a,e);var t=Object(d.a)(a);function a(){var e;Object(u.a)(this,a);for(var n=arguments.length,r=new Array(n),l=0;l<n;l++)r[l]=arguments[l];return(e=t.call.apply(t,[this].concat(r))).state={streams:{},loading:!0,query:""},e.isPlaying=function(t){return t===e.props.playerStatus.title&&e.props.playerStatus.playing},e.handleItemClick=function(){var t=Object(i.a)(s.a.mark((function t(a){var n,r,l;return s.a.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(n=e.props,r=n.t,l=n.onBackdrop,!e.isPlaying(a)){t.next=3;break}return t.abrupt("return");case 3:return l(r("tuning"),a),t.prev=4,t.next=7,q(a);case 7:t.next=12;break;case 9:t.prev=9,t.t0=t.catch(4),t.t0.response&&400===t.t0.response.status&&b.b.error(r("errorNotFound"));case 12:case"end":return t.stop()}}),t,null,[[4,9]])})));return function(e){return t.apply(this,arguments)}}(),e.getItemClasses=function(t){var a="streams__item ellipsis list-group-item ";return e.isPlaying(t)?a+"active":a+"list-group-item-action"},e.handleSearch=function(t){e.setState({query:t})},e}return Object(m.a)(a,[{key:"componentDidMount",value:function(){var e=Object(i.a)(s.a.mark((function e(){var t,a;return s.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,D.get("/streams");case 2:t=e.sent,a=t.data,this.setState({streams:a,loading:!1});case 5:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}()},{key:"filteredStreams",value:function(){var e=this.state,t=e.streams,a=e.query;if(""===a)return t;var n={};for(var r in t)r.toLowerCase().includes(a.toLowerCase())&&!t[r]&&(n[r]=t[r]);return n}},{key:"renderList",value:function(){var e=this,t=this.filteredStreams();return 0===Object.keys(t).length?r.a.createElement("h4",{className:"p-4"},this.props.t("noStreams")):r.a.createElement("ul",{className:"list-group list-group-flush"},Object.keys(t).map((function(a){return t[a]?r.a.createElement("li",{className:"streams__header ellipsis",key:a},a):r.a.createElement("li",{className:e.getItemClasses(a),key:a,onClick:function(){return e.handleItemClick(a)}},a)})))}},{key:"render",value:function(){return this.state.loading?r.a.createElement(V,null):r.a.createElement("div",{className:"streams"},r.a.createElement(te,{value:this.state.query,onChange:this.handleSearch}),this.renderList())}}]),a}(n.Component),ne=Object(f.a)()(ae),re=(a(85),function(e){var t=e.playerStatus,a=t.title,n=t.playing;return r.a.createElement("div",{className:"mini-player"},r.a.createElement("div",{className:"mini-player__left ellipsis"},a),r.a.createElement("div",{className:"mini-player__right",onClick:function(e){return e.stopPropagation()}},r.a.createElement(X,{playing:n})))}),le=(a(86),function(e){Object(p.a)(a,e);var t=Object(d.a)(a);function a(){var e;Object(u.a)(this,a);for(var n=arguments.length,l=new Array(n),o=0;o<n;o++)l[o]=arguments[o];return(e=t.call.apply(t,[this].concat(l))).state={open:!1},e.toggle=function(){e.setState({open:!e.state.open})},e.handleClick=function(){e.toggle()},e.handleTouchStart=function(t){if(t.touches.length>1)return e.setState({touchStartY:null});e.setState({touchStartY:t.touches[0].clientY})},e.handleTouchMove=function(t){var a=e.state,n=a.open,r=a.touchStartY;if(!(null===r||t.touches.length>1)){var l=t.changedTouches[0].clientY;(l>r&&n||l<r&&!n)&&e.toggle()}},e.renderToggleButton=function(){return r.a.createElement("button",{className:"drawer__toggler btn btn-primary-outline","aria-label":"Toggle player"},r.a.createElement(z.a,{icon:e.state.open?Q.a:Q.b,className:"fa-lg"}))},e}return Object(m.a)(a,[{key:"render",value:function(){var e=this.props.playerStatus,t=this.state.open,a="drawer fixed-bottom bg-secondary shadow-lg p-2";return t?(a+=" drawer--open",document.body.classList.add("body--drawer")):document.body.classList.remove("body--drawer"),r.a.createElement("div",{className:a,onClick:this.handleClick,onTouchStart:this.handleTouchStart,onTouchMove:this.handleTouchMove},this.renderToggleButton(),t?r.a.createElement(ee,{playerStatus:e}):r.a.createElement(re,{playerStatus:e}))}}]),a}(n.Component)),oe=(a(87),function(e){var t=e.playerStatus,a=e.onBackdrop;return r.a.createElement("main",{className:"main"},r.a.createElement(le,{playerStatus:t}),r.a.createElement("div",{className:"main__primary container"},r.a.createElement(ne,{onBackdrop:a,playerStatus:t}),r.a.createElement(ee,{playerStatus:t})))}),ce=(a(88),function(e){Object(p.a)(a,e);var t=Object(d.a)(a);function a(){var e;Object(u.a)(this,a);for(var n=arguments.length,r=new Array(n),l=0;l<n;l++)r[l]=arguments[l];return(e=t.call.apply(t,[this].concat(r))).state={playerStatus:{},loading:!0,networkError:!1,backdrop:{}},e.handleBackdrop=function(t){var a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";e.setState({backdrop:{title:t,body:a}}),setTimeout((function(){return e.setState({backdrop:{}})}),L.a)},e.setDocumentTitle=function(){var t=e.state,a=t.playerStatus;!t.networkError&&a.playing?document.title="PiFi \ud83d\udd0a "+a.title:document.title="PiFi Radio"},e}return Object(m.a)(a,[{key:"componentDidMount",value:function(){this.updatePlayerStatus()}},{key:"componentDidUpdate",value:function(){this.setDocumentTitle()}},{key:"updatePlayerStatus",value:function(){var e=Object(i.a)(s.a.mark((function e(){var t,a,n=this;return s.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,D.get("/player");case 3:t=e.sent,a=t.data,this.setState({playerStatus:a,loading:!1,networkError:!1}),e.next=11;break;case 8:e.prev=8,e.t0=e.catch(0),this.setState({loading:!1,networkError:!0});case 11:setTimeout((function(){return n.updatePlayerStatus()}),L.c);case 12:case"end":return e.stop()}}),e,this,[[0,8]])})));return function(){return e.apply(this,arguments)}}()},{key:"render",value:function(){var e=this.state,t=e.loading,a=e.networkError,n=e.backdrop,l=e.playerStatus,o=this.props.t;return a?r.a.createElement(G,{title:o("errorNetwork")}):t?r.a.createElement(V,null):l.con_mpd?r.a.createElement("div",{className:"app"},r.a.createElement(b.a,{pauseOnFocusLoss:!1}),r.a.createElement(G,{title:n.title,body:n.body}),r.a.createElement(y,null),r.a.createElement(oe,{onBackdrop:this.handleBackdrop,playerStatus:l}),r.a.createElement(Y,null),r.a.createElement(P,null),r.a.createElement(H,null)):r.a.createElement(G,{title:o("disconnectedMPD")})}}]),a}(n.Component)),se=Object(f.a)()(ce);Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/));var ie=a(29),ue=a(21),me=a(47),de=a(46);ie.a.use(me.a).use(de.a).use(ue.f).init({fallbackLng:"en",debug:Object({NODE_ENV:"production",PUBLIC_URL:"",WDS_SOCKET_HOST:void 0,WDS_SOCKET_PATH:void 0,WDS_SOCKET_PORT:void 0,REACT_APP_API_URL:"/api"}).REACT_APP_I18N_DEBUG,load:"currentOnly",returnEmptyString:!1,interpolation:{escapeValue:!1}}),ie.a.on("languageChanged",(function(e){document.documentElement.setAttribute("lang",e)}));ie.a,a(89),a(90),a(91);T.apply(),o.a.render(r.a.createElement(n.Suspense,{fallback:r.a.createElement(V,null)},r.a.createElement(se,null)),document.getElementById("root")),"serviceWorker"in navigator&&navigator.serviceWorker.ready.then((function(e){e.unregister()}))}},[[50,1,2]]]);
|
2
|
-
//# sourceMappingURL=main.6c9ebb8a.chunk.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["assets/logo.svg","components/navBar.jsx","components/common/modal.jsx","components/common/select.jsx","theme.js","components/modals/settings.jsx","services/httpService.js","services/playerService.js","components/modals/urlDialog.jsx","services/configService.js","components/common/loader.jsx","components/modals/about.jsx","components/common/backdrop.jsx","components/player/playerStatus.jsx","components/player/playStopControl.jsx","components/player/playerControls.jsx","components/player/player.jsx","components/common/searchBox.jsx","components/streams.jsx","services/streamsService.js","components/player/miniPlayer.jsx","components/drawer.jsx","components/main.jsx","App.js","serviceWorker.js","i18n.js","index.js"],"names":["module","exports","NavBar","t","useTranslation","className","href","src","logo","width","height","alt","type","data-toggle","data-target","aria-controls","aria-expanded","aria-label","id","Modal","title","footer","children","defaultFooter","data-dismiss","tabIndex","role","aria-labelledby","aria-hidden","Select","label","row","data","rest","htmlFor","map","d","key","value","name","availableThemes","themeColor","apply","themeId","getCurrentId","themePath","getThemePath","find","document","querySelector","setAttribute","localId","localStorage","getItem","filter","length","removeItem","change","setItem","Settings","i18n","useState","setThemeId","languagesData","languages","sort","lang","isoCode","slice","localeEmoji","ISO6391","getNativeName","useEffect","theme","onChange","e","newThemeId","target","handleThemeChange","language","changeLanguage","axios","defaults","baseURL","process","interceptors","response","use","error","expectedError","status","toast","Translation","Promise","reject","get","post","body","method","params","FormData","set","play","http","stop","changeVol","delta","playRadio","playURL","url","URLDialog","setURL","handleOK","doPlayURL","a","errorToastOpts","TYPE","ERROR","render","toastId","update","Fragment","onClick","placeholder","input","onKeyDown","getConfig","Loader","About","config","setConfig","loading","setLoading","fetchData","tableData","mpd_host","mpd_port","environment","version","copyright","rel","style","color","coffee","item","scope","getScrollbarWidth","window","innerWidth","documentElement","clientWidth","Backdrop","visible","bodyStyled","classList","contains","paddingRight","add","remove","classes","PlayerStatus","playerStatus","playing","PlayStopControl","icon","faStop","faPlay","PlayerControls","volDisabled","vol","handleVolChange","toastMsg","toastOpts","autoClose","volTimeout","isActive","info","renderVolButton","disabled","stopPropagation","faVolumeDown","faVolumeUp","Player","require","SearchBox","autoComplete","onFocus","Streams","state","streams","query","isPlaying","props","handleItemClick","onBackdrop","getItemClasses","handleSearch","setState","this","filtered","k","toLowerCase","includes","filteredStreams","Object","keys","renderList","Component","withTranslation","MiniPlayer","Drawer","open","toggle","handleClick","handleTouchStart","touches","touchStartY","clientY","handleTouchMove","touchEndY","changedTouches","renderToggleButton","faChevronDown","faChevronUp","onTouchStart","onTouchMove","Main","App","networkError","backdrop","handleBackdrop","setTimeout","backdropTimeout","setDocumentTitle","updatePlayerStatus","updateInterval","con_mpd","pauseOnFocusLoss","Boolean","location","hostname","match","Backend","LanguageDetector","initReactI18next","init","fallbackLng","debug","REACT_APP_I18N_DEBUG","load","returnEmptyString","interpolation","escapeValue","on","ReactDOM","fallback","getElementById","navigator","serviceWorker","ready","then","registration","unregister"],"mappings":"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","file":"static/js/main.6c9ebb8a.chunk.js","sourcesContent":["module.exports = __webpack_public_path__ + \"static/media/logo.91554ce9.svg\";","import React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport './navBar.scss';\nimport logo from '../assets/logo.svg';\n\nconst NavBar = () => {\n const { t } = useTranslation();\n\n return (\n <nav className=\"navbar navbar-expand-sm navbar-dark bg-primary\">\n <div className=\"container\">\n <a className=\"navbar-brand\" href=\"/\">\n <img\n src={logo}\n width=\"30\"\n height=\"30\"\n className=\"d-inline-block align-text-bottom mr-2\"\n alt=\"\"\n />\n PiFi Radio\n </a>\n <button\n className=\"navbar-toggler\"\n type=\"button\"\n data-toggle=\"collapse\"\n data-target=\"#navbarNavAltMarkup\"\n aria-controls=\"navbarNavAltMarkup\"\n aria-expanded=\"false\"\n aria-label=\"Toggle navigation\"\n >\n <span className=\"navbar-toggler-icon\"></span>\n </button>\n <div className=\"collapse navbar-collapse\" id=\"navbarNavAltMarkup\">\n <div className=\"navbar-nav pt-1 ml-2\">\n {/* We use buttons and different class names instead of Bootstrap's\n anchor, so we don't get a warning for href=\"#\". */}\n <button\n className=\"btn btn-link nav-link\"\n data-toggle=\"modal\"\n data-target=\"#url-dialog\"\n >\n {t('playURL')}\n </button>\n\n <button\n className=\"btn btn-link nav-link\"\n data-toggle=\"modal\"\n data-target=\"#settings\"\n >\n {t('settings')}\n </button>\n\n <button\n className=\"btn btn-link nav-link\"\n data-toggle=\"modal\"\n data-target=\"#about\"\n >\n {t('about')}\n </button>\n </div>\n </div>\n </div>\n </nav>\n );\n};\nexport default NavBar;\n","import React from 'react';\nimport { useTranslation } from 'react-i18next';\n\nconst Modal = ({ id, title, footer, children }) => {\n const { t } = useTranslation();\n\n const defaultFooter = (\n <button className=\"btn btn-secondary\" data-dismiss=\"modal\">\n {t('close')}\n </button>\n );\n\n return (\n <div\n className=\"modal fade\"\n id={id}\n tabIndex=\"-1\"\n role=\"dialog\"\n aria-labelledby=\"staticBackdropLabel\"\n aria-hidden=\"true\"\n >\n <div className=\"modal-dialog\" role=\"document\">\n <div className=\"modal-content\">\n <div className=\"modal-header\">\n <h5 className=\"modal-title\" id=\"staticBackdropLabel\">\n {title}\n </h5>\n <button\n type=\"button\"\n className=\"close\"\n data-dismiss=\"modal\"\n aria-label=\"Close\"\n >\n <span aria-hidden=\"true\">×</span>\n </button>\n </div>\n <div className=\"modal-body\">{children}</div>\n <div className=\"modal-footer\">{footer ? footer : defaultFooter}</div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default Modal;\n","import React from 'react';\n\nconst Select = ({ id, label, row, data, ...rest }) => (\n <div className={row ? 'form-group row' : 'form-group'}>\n <label htmlFor={id} className=\"col-sm-2 col-form-label\">\n {label}\n </label>\n <div className=\"col-sm-10\">\n <select id={id} className=\"form-control\" {...rest}>\n {data.map(d => (\n <option key={d.id || d} value={d.id || d}>\n {d.name || d}\n </option>\n ))}\n </select>\n </div>\n </div>\n);\n\nexport default Select;\n","const DEFAULT_THEME_ID = 'darkly';\n\nconst STORAGE_KEY = 'theme';\n\nconst getThemePath = themeId =>\n `https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/${themeId}/bootstrap.min.css`;\n\nconst availableThemes = [\n { id: 'darkly', name: 'Darkly', themeColor: '#375a7f' },\n { id: 'lux', name: 'Lux', themeColor: '#1a1a1a' }\n];\n\nfunction change(themeId) {\n localStorage.setItem(STORAGE_KEY, themeId);\n apply();\n}\n\nfunction apply() {\n const themeId = getCurrentId();\n const themePath = getThemePath(themeId);\n const themeColor = availableThemes.find(t => t.id === themeId).themeColor;\n\n const linkEl = document.querySelector('link[title=\"theme\"]');\n linkEl.setAttribute('href', themePath);\n\n const metaEl = document.querySelector('meta[name=\"theme-color\"]');\n metaEl.setAttribute('content', themeColor);\n}\n\nfunction getCurrentId() {\n const localId = localStorage.getItem(STORAGE_KEY);\n\n if (localId === '') return DEFAULT_THEME_ID;\n if (availableThemes.filter(t => t.id === localId).length === 0) {\n localStorage.removeItem(STORAGE_KEY);\n return DEFAULT_THEME_ID;\n }\n\n return localId;\n}\n\nexport default {\n availableThemes,\n getCurrentId,\n change,\n apply\n};\n","import React, { useState, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport ISO6391 from 'iso-639-1';\nimport localeEmoji from 'locale-emoji';\nimport Modal from '../common/modal';\nimport Select from '../common/select';\nimport theme from '../../theme';\nimport { languages } from '../../config.json';\n\nconst Settings = () => {\n const { t, i18n } = useTranslation();\n\n const [themeId, setThemeId] = useState('');\n\n const languagesData = languages.sort().map(lang => {\n const isoCode = lang.slice(0, 2);\n return {\n id: lang,\n name: `${localeEmoji(lang)} ${ISO6391.getNativeName(isoCode)}`\n };\n });\n\n const handleThemeChange = ({ target }) => {\n const newThemeId = target.value;\n theme.change(newThemeId);\n setThemeId(newThemeId);\n };\n\n useEffect(() => {\n setThemeId(theme.getCurrentId());\n }, []);\n\n return (\n <Modal id=\"settings\" title={t('settings')}>\n <Select\n id=\"theme-select\"\n label={t('theme')}\n data={theme.availableThemes}\n row\n value={themeId}\n onChange={e => handleThemeChange(e)}\n />\n <Select\n id=\"language-select\"\n label={t('language')}\n data={languagesData}\n row\n value={i18n.language}\n onChange={e => i18n.changeLanguage(e.target.value)}\n />\n </Modal>\n );\n};\n\nexport default Settings;\n","import React from 'react';\nimport axios from 'axios';\nimport { toast } from 'react-toastify';\nimport { Translation } from 'react-i18next';\n\naxios.defaults.baseURL = process.env.REACT_APP_API_URL;\n\naxios.interceptors.response.use(null, error => {\n const expectedError =\n error.response &&\n error.response.status >= 400 &&\n error.response.status < 500;\n\n // Some errors cause our app to only render a backdrop warning.\n // Queuing toasts would be redundant.\n const hasToastify = document.querySelector('.Toastify');\n\n if (hasToastify) {\n if (!expectedError)\n toast.error(<Translation>{t => t('errorUnexpected')}</Translation>);\n\n // Universal expected error\n if (error.response && error.response.status === 403)\n toast.error(<Translation>{t => t('errorForbidden')}</Translation>);\n }\n\n return Promise.reject(error);\n});\n\nexport default {\n get: axios.get,\n post: axios.post\n};\n","import http from './httpService.js';\n\nconst apiEndpoint = '/player';\n\nfunction body(method, params = null) {\n const body = new FormData();\n body.set('method', method);\n if (params) body.set('params', params);\n return body;\n}\n\nexport function getStatus() {\n return http.get(apiEndpoint);\n}\n\nexport function play() {\n return http.post(apiEndpoint, body('play'));\n}\n\nexport function stop() {\n return http.post(apiEndpoint, body('stop'));\n}\n\nexport function changeVol(delta) {\n return http.post(apiEndpoint, body('change_vol', delta));\n}\n\nexport function playRadio(name) {\n return http.post(apiEndpoint, body('play_radios', name));\n}\n\nexport function playURL(url) {\n return http.post(apiEndpoint, body('play_urls', url));\n}\n","import React, { useState } from 'react';\nimport { toast } from 'react-toastify';\nimport { useTranslation } from 'react-i18next';\nimport Modal from '../common/modal';\nimport { playURL } from '../../services/playerService';\n\nconst URLDialog = () => {\n const [url, setURL] = useState('');\n\n const { t } = useTranslation();\n\n const handleOK = () => {\n if (url === '') return;\n doPlayURL(url);\n setURL('');\n };\n\n const doPlayURL = async url => {\n const errorToastOpts = {\n type: toast.TYPE.ERROR,\n render: t('errorNotFound')\n };\n\n const toastId = toast(t('tryingURL'));\n\n try {\n await playURL(url);\n } catch (ex) {\n if (ex.response && ex.response.status === 400)\n toast.update(toastId, errorToastOpts);\n }\n };\n\n const handleChange = ({ target: input }) => {\n setURL(input.value);\n };\n\n const handleKeyDown = e => {\n if (e.key === 'Enter') handleOK();\n };\n\n const renderFooter = () => (\n <React.Fragment>\n <button\n className=\"btn btn-primary\"\n data-dismiss=\"modal\"\n onClick={handleOK}\n >\n {t('ok')}\n </button>\n <button\n className=\"btn btn-secondary\"\n onClick={() => setURL('')}\n data-dismiss=\"modal\"\n >\n {t('cancel')}\n </button>\n </React.Fragment>\n );\n\n return (\n <Modal id=\"url-dialog\" title={t('playURL')} footer={renderFooter()}>\n <input\n className=\"form-control mb-4\"\n type=\"text\"\n placeholder=\"URL\"\n value={url}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n />\n </Modal>\n );\n};\n\nexport default URLDialog;\n","import http from './httpService';\n\nconst apiEndpoint = '/config';\n\nexport function getConfig() {\n return http.get(apiEndpoint);\n}\n","import React from 'react';\nimport './loader.scss';\n\nconst Loader = () => (\n <div className=\"loader\">\n <div className=\"spinner-border\" role=\"status\">\n <span className=\"sr-only\">Loading...</span>\n </div>\n </div>\n);\n\nexport default Loader;\n","import React from 'react';\nimport { useEffect, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport Modal from '../common/modal';\nimport { getConfig } from '../../services/configService';\nimport Loader from '../common/loader';\n\nconst About = () => {\n const { t } = useTranslation();\n\n const [config, setConfig] = useState({});\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n async function fetchData() {\n const { data: config } = await getConfig();\n setConfig(config);\n setLoading(false);\n }\n fetchData();\n }, []);\n\n const tableData = [\n { label: t('mpdHost'), value: config.mpd_host },\n { label: t('mpdPort'), value: config.mpd_port },\n { label: t('environment'), value: config.environment },\n { label: t('version'), value: config.version },\n ];\n\n const renderTable = () => {\n if (loading) return <Loader />;\n\n return (\n <table className=\"table\">\n <tbody>\n {tableData.map((item) => (\n <tr key={item.label}>\n <th scope=\"row\">{item.label}</th>\n <td>{item.value}</td>\n </tr>\n ))}\n </tbody>\n </table>\n );\n };\n\n const copyright = (\n <div className=\"copyright small mt-5\">\n <p>\n <a\n href=\"https://rafaelc.org/pifi\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ color: 'inherit' }}\n >\n {t('goToDocs')}\n </a>\n </p>\n <p>\n Copyright © 2017-2020 \n {/* Use the default color, as some themes give a different color for links. */}\n <a\n href=\"https://rafaelc.org/\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ color: 'inherit' }}\n >\n Rafael Cavalcanti\n </a>\n </p>\n </div>\n );\n\n const coffee = (\n <div className=\"coffee mt-5\">\n <p>{t('coffee')}</p>\n <a\n href=\"https://www.buymeacoffee.com/rafaelc\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <img\n src=\"https://cdn.buymeacoffee.com/buttons/default-blue.png\"\n alt=\"Buy Me A Coffee\"\n style={{ height: 51, width: 217 }}\n />\n </a>\n </div>\n );\n\n return (\n <Modal id=\"about\" title={t('about')}>\n {renderTable()}\n {coffee}\n {copyright}\n </Modal>\n );\n};\n\nexport default About;\n","import React from 'react';\nimport './backdrop.scss';\n\nconst Backdrop = ({ title, body }) => {\n const visible = title;\n const bodyStyled = document.body.classList.contains('body--backdrop');\n\n if (visible && !bodyStyled) {\n // Calculate this BEFORE adding the class.\n document.body.style.paddingRight = getScrollbarWidth() + 'px';\n document.body.classList.add('body--backdrop');\n // We need this check because Bootstrap modals also style paddingRight\n } else if (!visible && bodyStyled) {\n document.body.style.paddingRight = 0;\n document.body.classList.remove('body--backdrop');\n }\n\n const classes =\n 'backdrop p-2 text-white' + (visible ? ' backdrop--visible' : '');\n\n // We need text-white on h* tags because some themes override it\n return (\n <div className={classes}>\n <h3 className=\"text-white\">{title}</h3>\n <h5 className=\"text-white\">{body}</h5>\n </div>\n );\n};\n\nconst getScrollbarWidth = () =>\n window.innerWidth - document.documentElement.clientWidth;\n\nexport default Backdrop;\n","import React from 'react';\nimport { useTranslation } from 'react-i18next';\n\nconst PlayerStatus = ({ playerStatus }) => {\n const { playing, title } = playerStatus;\n\n const { t } = useTranslation();\n\n return (\n <div className=\"text-center w-100\">\n <h5 className=\"small text-uppercase\">\n {playing ? t('playing') : t('stopped')}\n </h5>\n <h3 className=\"ellipsis\">{title}</h3>\n </div>\n );\n};\n\nexport default PlayerStatus;\n","import React from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faStop, faPlay } from '@fortawesome/free-solid-svg-icons';\nimport { play, stop } from '../../services/playerService';\n\nconst PlayStopControl = ({ playing }) =>\n playing ? (\n <button className=\"btn btn-danger\" onClick={stop} aria-label=\"Stop\">\n <FontAwesomeIcon icon={faStop} />\n </button>\n ) : (\n <button className=\"btn btn-dark\" onClick={play} aria-label=\"Play\">\n <FontAwesomeIcon icon={faPlay} />\n </button>\n );\n\nexport default PlayStopControl;\n","import React from 'react';\nimport PlayStopControl from './playStopControl';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faVolumeDown, faVolumeUp } from '@fortawesome/free-solid-svg-icons';\nimport { toast } from 'react-toastify';\nimport { useTranslation } from 'react-i18next';\nimport { changeVol } from '../../services/playerService';\nimport { volTimeout } from '../../config.json';\n\nconst PlayerControls = ({ playerStatus }) => {\n const { t } = useTranslation();\n\n const volDisabled = playerStatus.vol == null;\n\n const handleVolChange = async delta => {\n const { data: vol } = await changeVol(delta);\n\n const toastId = 'vol';\n const toastMsg = `${t('volume')}: ${vol}%`;\n const toastOpts = { toastId, autoClose: volTimeout };\n if (toast.isActive(toastId)) toast.update(toastId, { render: toastMsg });\n else toast.info(toastMsg, toastOpts);\n };\n\n const renderVolButton = (delta, icon, label) => (\n <button\n className=\"btn btn-dark p-3\"\n disabled={volDisabled}\n onClick={() => handleVolChange(delta)}\n aria-label={label}\n >\n <FontAwesomeIcon icon={icon} />\n </button>\n );\n\n return (\n <div\n className=\"player-controls btn-group w-100 m-2\"\n onClick={e => e.stopPropagation()}\n >\n {renderVolButton('-5', faVolumeDown, 'Volume down')}\n {renderVolButton('+5', faVolumeUp, 'Volume up')}\n <PlayStopControl playing={playerStatus.playing} />\n </div>\n );\n};\n\nexport default PlayerControls;\n","import React from 'react';\nimport PlayerStatus from './playerStatus';\nimport PlayerControls from './playerControls';\nimport './player.scss';\n\nconst Player = ({ playerStatus }) => {\n const renderLogo = () => (\n <img\n src={require('../../assets/logo.svg')}\n alt=\"Logo\"\n className=\"player-logo m-4\"\n />\n );\n\n return (\n <div className=\"player\">\n <PlayerStatus playerStatus={playerStatus} />\n {renderLogo()}\n <PlayerControls playerStatus={playerStatus} />\n </div>\n );\n};\n\nexport default Player;\n","import React from 'react';\nimport { useTranslation } from 'react-i18next';\n\nconst SearchBox = ({ value, onChange }) => {\n const { t } = useTranslation();\n\n return (\n <input\n className=\"form-control mb-4\"\n type=\"text\"\n id=\"query\"\n placeholder={t('search')}\n aria-label={t('search')}\n autoComplete=\"off\"\n value={value}\n onChange={e => onChange(e.target.value)}\n onFocus={() => onChange('')}\n ></input>\n );\n};\n\nexport default SearchBox;\n","import React, { Component } from 'react';\nimport { withTranslation } from 'react-i18next';\nimport { toast } from 'react-toastify';\nimport Loader from './common/loader';\nimport SearchBox from './common/searchBox';\nimport { playRadio } from '../services/playerService';\nimport { getStreams } from '../services/streamsService';\nimport './streams.scss';\n\nclass Streams extends Component {\n state = { streams: {}, loading: true, query: '' };\n\n async componentDidMount() {\n const { data: streams } = await getStreams();\n this.setState({ streams, loading: false });\n }\n\n isPlaying = name => {\n return (\n name === this.props.playerStatus.title && this.props.playerStatus.playing\n );\n };\n\n handleItemClick = async name => {\n const { t, onBackdrop } = this.props;\n\n if (this.isPlaying(name)) return;\n\n onBackdrop(t('tuning'), name);\n try {\n await playRadio(name);\n } catch (ex) {\n if (ex.response && ex.response.status === 400)\n toast.error(t('errorNotFound'));\n }\n };\n\n getItemClasses = name => {\n const classes = 'streams__item ellipsis list-group-item ';\n return this.isPlaying(name)\n ? classes + 'active'\n : classes + 'list-group-item-action';\n };\n\n handleSearch = query => {\n this.setState({ query });\n };\n\n filteredStreams() {\n const { streams, query } = this.state;\n\n if (query === '') return streams;\n\n let filtered = {};\n for (let k in streams) {\n if (k.toLowerCase().includes(query.toLowerCase()) && !streams[k]) {\n filtered[k] = streams[k];\n }\n }\n return filtered;\n }\n\n renderList() {\n const streams = this.filteredStreams();\n\n if (Object.keys(streams).length === 0)\n return <h4 className=\"p-4\">{this.props.t('noStreams')}</h4>;\n\n return (\n <ul className=\"list-group list-group-flush\">\n {Object.keys(streams).map(name =>\n streams[name] ? (\n <li className=\"streams__header ellipsis\" key={name}>\n {name}\n </li>\n ) : (\n <li\n className={this.getItemClasses(name)}\n key={name}\n onClick={() => this.handleItemClick(name)}\n >\n {name}\n </li>\n )\n )}\n </ul>\n );\n }\n\n render() {\n if (this.state.loading) return <Loader />;\n\n return (\n <div className=\"streams\">\n <SearchBox value={this.state.query} onChange={this.handleSearch} />\n {this.renderList()}\n </div>\n );\n }\n}\n\nexport default withTranslation()(Streams);\n","import http from './httpService';\n\nconst apiEndpoint = '/streams';\n\nexport function getStreams() {\n return http.get(apiEndpoint);\n}\n","import React from 'react';\nimport PlayStopControl from './playStopControl';\nimport './miniPlayer.scss';\n\nconst MiniPlayer = ({ playerStatus }) => {\n const { title, playing } = playerStatus;\n\n return (\n <div className=\"mini-player\">\n <div className=\"mini-player__left ellipsis\">\n {title}\n </div>\n <div\n className=\"mini-player__right\"\n onClick={e => e.stopPropagation()}\n >\n <PlayStopControl playing={playing} />\n </div>\n </div>\n );\n};\n\nexport default MiniPlayer;\n","import React, { Component } from 'react';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons';\nimport MiniPlayer from './player/miniPlayer';\nimport Player from './player/player';\nimport './drawer.scss';\n\nclass Drawer extends Component {\n state = { open: false };\n\n toggle = () => {\n this.setState({ open: !this.state.open });\n };\n\n handleClick = () => {\n this.toggle();\n };\n\n handleTouchStart = (e) => {\n // Ignore multitouch\n if (e.touches.length > 1) return this.setState({ touchStartY: null });\n\n this.setState({ touchStartY: e.touches[0].clientY });\n };\n\n handleTouchMove = (e) => {\n const { open, touchStartY } = this.state;\n\n // Ignore multitouch\n if (touchStartY === null || e.touches.length > 1) return;\n\n const touchEndY = e.changedTouches[0].clientY;\n const touchUp = touchEndY < touchStartY;\n const touchDown = touchEndY > touchStartY;\n\n if (touchDown && open) this.toggle();\n else if (touchUp && !open) this.toggle();\n };\n\n renderToggleButton = () => (\n <button\n className=\"drawer__toggler btn btn-primary-outline\"\n aria-label=\"Toggle player\"\n >\n <FontAwesomeIcon\n icon={this.state.open ? faChevronDown : faChevronUp}\n className=\"fa-lg\"\n />\n </button>\n );\n\n render() {\n const { playerStatus } = this.props;\n const { open } = this.state;\n\n let classes = 'drawer fixed-bottom bg-secondary shadow-lg p-2';\n\n if (open) {\n classes += ' drawer--open';\n document.body.classList.add('body--drawer');\n } else document.body.classList.remove('body--drawer');\n\n return (\n <div\n className={classes}\n onClick={this.handleClick}\n onTouchStart={this.handleTouchStart}\n onTouchMove={this.handleTouchMove}\n >\n {this.renderToggleButton()}\n {open ? (\n <Player playerStatus={playerStatus} />\n ) : (\n <MiniPlayer playerStatus={playerStatus} />\n )}\n </div>\n );\n }\n}\n\nexport default Drawer;\n","import React from 'react';\nimport Player from './player/player';\nimport Streams from './streams';\nimport Drawer from './drawer';\nimport './main.scss';\n\nconst Main = ({ playerStatus, onBackdrop }) => {\n return (\n <main className=\"main\">\n <Drawer playerStatus={playerStatus} />\n <div className=\"main__primary container\">\n <Streams onBackdrop={onBackdrop} playerStatus={playerStatus} />\n <Player playerStatus={playerStatus} />\n </div>\n </main>\n );\n};\n\nexport default Main;\n","import React, { Component } from 'react';\nimport { ToastContainer } from 'react-toastify';\nimport { withTranslation } from 'react-i18next';\nimport NavBar from './components/navBar';\nimport Settings from './components/modals/settings';\nimport URLDialog from './components/modals/urlDialog';\nimport About from './components/modals/about';\nimport Loader from './components/common/loader';\nimport Backdrop from './components/common/backdrop';\nimport Main from './components/main';\nimport { getStatus } from './services/playerService';\nimport { updateInterval, backdropTimeout } from './config.json';\nimport 'react-toastify/dist/ReactToastify.css';\n\nclass App extends Component {\n state = {\n playerStatus: {},\n loading: true,\n networkError: false,\n backdrop: {},\n };\n\n componentDidMount() {\n this.updatePlayerStatus();\n }\n\n componentDidUpdate() {\n this.setDocumentTitle();\n }\n\n async updatePlayerStatus() {\n try {\n const { data: playerStatus } = await getStatus();\n this.setState({ playerStatus, loading: false, networkError: false });\n } catch (ex) {\n this.setState({ loading: false, networkError: true });\n }\n\n setTimeout(() => this.updatePlayerStatus(), updateInterval);\n }\n\n handleBackdrop = (title, body = '') => {\n this.setState({ backdrop: { title, body } });\n setTimeout(() => this.setState({ backdrop: {} }), backdropTimeout);\n };\n\n setDocumentTitle = () => {\n const { playerStatus: status, networkError } = this.state;\n\n if (!networkError && status.playing)\n document.title = 'PiFi 🔊 ' + status.title;\n else document.title = 'PiFi Radio';\n };\n\n render() {\n const { loading, networkError, backdrop, playerStatus } = this.state;\n const { t } = this.props;\n\n if (networkError) return <Backdrop title={t('errorNetwork')} />;\n if (loading) return <Loader />;\n if (!playerStatus.con_mpd) return <Backdrop title={t('disconnectedMPD')} />;\n\n return (\n <div className=\"app\">\n <ToastContainer pauseOnFocusLoss={false} />\n <Backdrop title={backdrop.title} body={backdrop.body} />\n <NavBar />\n <Main onBackdrop={this.handleBackdrop} playerStatus={playerStatus} />\n <URLDialog />\n <Settings />\n <About />\n </div>\n );\n }\n}\n\nexport default withTranslation()(App);\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\nexport function register(config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl, config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl, config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' }\n })\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister();\n });\n }\n}\n","import i18n from 'i18next';\nimport { initReactI18next } from 'react-i18next';\n\nimport Backend from 'i18next-http-backend';\nimport LanguageDetector from 'i18next-browser-languagedetector';\n// not like to use this?\n// have a look at the Quick start guide\n// for passing in lng and translations on init\n\ni18n\n // load translation using xhr -> see /public/locales\n // learn more: https://github.com/i18next/i18next-xhr-backend\n .use(Backend)\n // detect user language\n // learn more: https://github.com/i18next/i18next-browser-languageDetector\n .use(LanguageDetector)\n // pass the i18n instance to react-i18next.\n .use(initReactI18next)\n // init i18next\n // for all options read: https://www.i18next.com/overview/configuration-options\n .init({\n fallbackLng: 'en',\n debug: process.env.REACT_APP_I18N_DEBUG,\n load: 'currentOnly',\n returnEmptyString: false,\n\n interpolation: {\n escapeValue: false // not needed for react as it escapes by default\n }\n });\n\n// Set language on html tag\ni18n.on('languageChanged', lang => {\n document.documentElement.setAttribute('lang', lang);\n});\n\nexport default i18n;\n","import React, { Suspense } from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\nimport Loader from './components/common/loader';\nimport * as serviceWorker from './serviceWorker';\nimport './i18n';\nimport theme from './theme';\nimport './index.scss';\n// Bootstrap dependencies\nimport 'jquery/dist/jquery.min.js';\nimport 'bootstrap/dist/js/bootstrap.js';\n\ntheme.apply();\n\nReactDOM.render(\n // Suspense needed for i18n\n <Suspense fallback={<Loader />}>\n <App />\n </Suspense>,\n document.getElementById('root')\n);\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.unregister();\n"],"sourceRoot":""}
|