Refactor code structure and remove redundant sections for improved readability and maintainability
No files matched your search
@@ -1 +1 @@
|
||||
.range-player[data-v-ed9db691]::-webkit-slider-thumb{-webkit-appearance:none;cursor:pointer;background:#fff;border-radius:50%;width:12px;height:12px}.range-vol[data-v-ed9db691]::-webkit-slider-thumb{-webkit-appearance:none;cursor:pointer;background:#fff;border-radius:50%;width:12px;height:12px}.animate-slide-in{animation:.3s ease-out slideIn}@keyframes slideIn{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}*,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content:""}html,:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:Inter,system-ui,sans-serif;line-height:1.5}body{line-height:inherit;margin:0}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:Space Mono,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder{opacity:1;color:#9ca3af}textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.inset-y-0{top:0;bottom:0}.-right-2{right:-.5rem}.-top-2{top:-.5rem}.bottom-0{bottom:0}.bottom-12{bottom:3rem}.bottom-2{bottom:.5rem}.bottom-24{bottom:6rem}.left-0{left:0}.left-12{left:3rem}.left-20{left:5rem}.left-3{left:.75rem}.right-0{right:0}.right-12{right:3rem}.right-2{right:.5rem}.right-20{right:5rem}.right-4{right:1rem}.right-8{right:2rem}.top-0{top:0}.top-16{top:4rem}.top-20{top:5rem}.top-4{top:1rem}.top-8{top:2rem}.top-\[57px\]{top:57px}.top-full{top:100%}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.z-\[100\]{z-index:100}.m-4{margin:1rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-8{margin-left:2rem;margin-right:2rem}.mx-auto{margin-left:auto;margin-right:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.mb-1{margin-bottom:.25rem}.mb-12{margin-bottom:3rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottomLine truncated
|
||||
.range-player[data-v-bb2272cc]::-webkit-slider-thumb{-webkit-appearance:none;cursor:pointer;background:#fff;border-radius:50%;width:12px;height:12px}.range-vol[data-v-bb2272cc]::-webkit-slider-thumb{-webkit-appearance:none;cursor:pointer;background:#fff;border-radius:50%;width:12px;height:12px}.animate-slide-in{animation:.3s ease-out slideIn}@keyframes slideIn{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}*,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content:""}html,:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:Inter,system-ui,sans-serif;line-height:1.5}body{line-height:inherit;margin:0}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:Space Mono,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder{opacity:1;color:#9ca3af}textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.inset-y-0{top:0;bottom:0}.-right-2{right:-.5rem}.-top-2{top:-.5rem}.bottom-0{bottom:0}.bottom-12{bottom:3rem}.bottom-2{bottom:.5rem}.bottom-24{bottom:6rem}.left-0{left:0}.left-12{left:3rem}.left-20{left:5rem}.left-3{left:.75rem}.right-0{right:0}.right-12{right:3rem}.right-2{right:.5rem}.right-20{right:5rem}.right-4{right:1rem}.right-8{right:2rem}.top-0{top:0}.top-16{top:4rem}.top-20{top:5rem}.top-4{top:1rem}.top-8{top:2rem}.top-\[57px\]{top:57px}.top-full{top:100%}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.z-\[100\]{z-index:100}.m-4{margin:1rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-8{margin-left:2rem;margin-right:2rem}.mx-auto{margin-left:auto;margin-right:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.mb-1{margin-bottom:.25rem}.mb-12{margin-bottom:3rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottomLine truncated
|
||||
@@ -6,4 +6,4 @@ var e=Object.defineProperty,t=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=nu
|
||||
`);return e===-1?``:t.stack.slice(e+1)})();try{if(!e.stack)e.stack=n;else if(n){let t=n.indexOf(`
|
||||
`),r=t===-1?-1:n.indexOf(`
|
||||
`,t+1),i=r===-1?``:n.slice(r+1);String(e.stack).endsWith(i)||(e.stack+=`
|
||||
`+n)}}catch{}}throw e}}_request(e,t){typeof e==`string`?(t||={},t.url=e):t=e||{},t=Qd(this.defaults,t);let{transitional:n,paramsSerializer:r,headers:i}=t;n!==void 0&&Of.assertOptions(n,{silentJSONParsing:kf.transitional(kf.boolean),forcedJSONParsing:kf.transitional(kf.boolean),clarifyTimeoutError:kf.transitional(kf.boolean),legacyInterceptorReqResOrdering:kf.transitional(kf.boolean)},!1),r!=null&&(Y.isFunction(r)?t.paramsSerializer={serialize:r}:Of.assertOptions(r,{encode:kf.function,serialize:kf.function},!0)),t.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls===void 0?t.allowAbsoluteUrls=!0:t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls),Of.assertOptions(t,{baseUrl:kf.spelling(`baseURL`),withXsrfToken:kf.spelling(`withXSRFToken`)},!0),t.method=(t.method||this.defaults.method||`get`).toLowerCase();let a=i&&Y.merge(i.common,i[t.method]);i&&Y.forEach([`delete`,`get`,`head`,`post`,`put`,`patch`,`query`,`common`],e=>{delete i[e]}),t.headers=id.concat(a,i);let o=[],s=!0;this.interceptors.request.forEach(function(e){if(typeof e.runWhen==`function`&&e.runWhen(t)===!1)return;s&&=e.synchronous;let n=t.transitional||bd;n&&n.legacyInterceptorReqResOrdering?o.unshift(e.fulfilled,e.rejected):o.push(e.fulfilled,e.rejected)});let c=[];this.interceptors.response.forEach(function(e){c.push(e.fulfilled,e.rejected)});let l,u=0,d;if(!s){let e=[wf.bind(this),void 0];for(e.unshift(...o),e.push(...c),d=e.length,l=Promise.resolve(t);u<d;)l=l.then(e[u++],e[u++]);return l}d=o.length;let f=t;for(;u<d;){let e=o[u++],t=o[u++];try{f=e(f)}catch(e){t.call(this,e);break}}try{l=wf.call(this,f)}catch(e){return Promise.reject(e)}for(u=0,d=c.length;u<d;)l=l.then(c[u++],c[u++]);return l}getUri(e){return e=Qd(this.defaults,e),vd(Xd(e.baseURL,e.url,e.allowAbsoluteUrls),e.params,e.paramsSerializer)}};Y.forEach([`delete`,`get`,`head`,`options`],function(e){Af.prototype[e]=function(t,n){return this.request(Qd(n||{},{method:e,url:t,data:(n||{}).data}))}}),Y.forEach([`post`,`put`,`patch`,`query`],function(e){function t(t){return function(n,r,i){return this.request(Qd(i||{},{method:e,headers:t?{"Content-Type":`multipart/form-data`}:{},url:n,data:r}))}}Af.prototype[e]=t(),e!==`query`&&(Af.prototype[e+`Form`]=t(!0))});var jf=class e{constructor(e){if(typeof e!=`function`)throw TypeError(`executor must be a function.`);let t;this.promise=new Promise(function(e){t=e});let n=this;this.promise.then(e=>{if(!n._listeners)return;let t=n._listeners.length;for(;t-- >0;)n._listeners[t](e);n._listeners=null}),this.promise.then=e=>{let t,r=new Promise(e=>{n.subscribe(e),t=e}).then(e);return r.cancel=function(){n.unsubscribe(t)},r},e(function(e,r,i){n.reason||(n.reason=new Rd(e,r,i),t(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;let t=this._listeners.indexOf(e);t!==-1&&this._listeners.splice(t,1)}toAbortSignal(){let e=new AbortController,t=t=>{e.abort(t)};return this.subscribe(t),e.signal.unsubscribe=()=>this.unsubscribe(t),e.signal}static source(){let t;return{token:new e(function(e){t=e}),cancel:t}}};function Mf(e){return function(t){return e.apply(null,t)}}function Nf(e){return Y.isObject(e)&&e.isAxiosError===!0}var Pf={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(Pf).forEach(([e,t])=>{Pf[t]=e});function Ff(e){let t=new Af(e),n=Al(Af.prototype.request,t);return Y.extend(n,Af.prototype,t,{allOwnKeys:!0}),Y.extend(n,t,null,{allOwnKeys:!0}),n.create=function(t){return Ff(Qd(e,t))},n}var Z=Ff(Fd);Z.Axios=Af,Z.CanceledError=Rd,Z.CancelToken=jf,Z.isCancel=Ld,Z.VERSION=df,Z.toFormData=pd,Z.AxiosError=X,Z.Can
Line truncated
|
||||
`+n)}}catch{}}throw e}}_request(e,t){typeof e==`string`?(t||={},t.url=e):t=e||{},t=Qd(this.defaults,t);let{transitional:n,paramsSerializer:r,headers:i}=t;n!==void 0&&Of.assertOptions(n,{silentJSONParsing:kf.transitional(kf.boolean),forcedJSONParsing:kf.transitional(kf.boolean),clarifyTimeoutError:kf.transitional(kf.boolean),legacyInterceptorReqResOrdering:kf.transitional(kf.boolean)},!1),r!=null&&(Y.isFunction(r)?t.paramsSerializer={serialize:r}:Of.assertOptions(r,{encode:kf.function,serialize:kf.function},!0)),t.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls===void 0?t.allowAbsoluteUrls=!0:t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls),Of.assertOptions(t,{baseUrl:kf.spelling(`baseURL`),withXsrfToken:kf.spelling(`withXSRFToken`)},!0),t.method=(t.method||this.defaults.method||`get`).toLowerCase();let a=i&&Y.merge(i.common,i[t.method]);i&&Y.forEach([`delete`,`get`,`head`,`post`,`put`,`patch`,`query`,`common`],e=>{delete i[e]}),t.headers=id.concat(a,i);let o=[],s=!0;this.interceptors.request.forEach(function(e){if(typeof e.runWhen==`function`&&e.runWhen(t)===!1)return;s&&=e.synchronous;let n=t.transitional||bd;n&&n.legacyInterceptorReqResOrdering?o.unshift(e.fulfilled,e.rejected):o.push(e.fulfilled,e.rejected)});let c=[];this.interceptors.response.forEach(function(e){c.push(e.fulfilled,e.rejected)});let l,u=0,d;if(!s){let e=[wf.bind(this),void 0];for(e.unshift(...o),e.push(...c),d=e.length,l=Promise.resolve(t);u<d;)l=l.then(e[u++],e[u++]);return l}d=o.length;let f=t;for(;u<d;){let e=o[u++],t=o[u++];try{f=e(f)}catch(e){t.call(this,e);break}}try{l=wf.call(this,f)}catch(e){return Promise.reject(e)}for(u=0,d=c.length;u<d;)l=l.then(c[u++],c[u++]);return l}getUri(e){return e=Qd(this.defaults,e),vd(Xd(e.baseURL,e.url,e.allowAbsoluteUrls),e.params,e.paramsSerializer)}};Y.forEach([`delete`,`get`,`head`,`options`],function(e){Af.prototype[e]=function(t,n){return this.request(Qd(n||{},{method:e,url:t,data:(n||{}).data}))}}),Y.forEach([`post`,`put`,`patch`,`query`],function(e){function t(t){return function(n,r,i){return this.request(Qd(i||{},{method:e,headers:t?{"Content-Type":`multipart/form-data`}:{},url:n,data:r}))}}Af.prototype[e]=t(),e!==`query`&&(Af.prototype[e+`Form`]=t(!0))});var jf=class e{constructor(e){if(typeof e!=`function`)throw TypeError(`executor must be a function.`);let t;this.promise=new Promise(function(e){t=e});let n=this;this.promise.then(e=>{if(!n._listeners)return;let t=n._listeners.length;for(;t-- >0;)n._listeners[t](e);n._listeners=null}),this.promise.then=e=>{let t,r=new Promise(e=>{n.subscribe(e),t=e}).then(e);return r.cancel=function(){n.unsubscribe(t)},r},e(function(e,r,i){n.reason||(n.reason=new Rd(e,r,i),t(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;let t=this._listeners.indexOf(e);t!==-1&&this._listeners.splice(t,1)}toAbortSignal(){let e=new AbortController,t=t=>{e.abort(t)};return this.subscribe(t),e.signal.unsubscribe=()=>this.unsubscribe(t),e.signal}static source(){let t;return{token:new e(function(e){t=e}),cancel:t}}};function Mf(e){return function(t){return e.apply(null,t)}}function Nf(e){return Y.isObject(e)&&e.isAxiosError===!0}var Pf={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(Pf).forEach(([e,t])=>{Pf[t]=e});function Ff(e){let t=new Af(e),n=Al(Af.prototype.request,t);return Y.extend(n,Af.prototype,t,{allOwnKeys:!0}),Y.extend(n,t,null,{allOwnKeys:!0}),n.create=function(t){return Ff(Qd(e,t))},n}var Z=Ff(Fd);Z.Axios=Af,Z.CanceledError=Rd,Z.CancelToken=jf,Z.isCancel=Ld,Z.VERSION=df,Z.toFormData=pd,Z.AxiosError=X,Z.Can
Line truncated
|
||||
|
After Width: | Height: | Size: 321 KiB |
@@ -6,8 +6,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Noctune - Music That Hits Different</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet">
|
||||
<script type="module" crossorigin src="/assets/index-C2ZrghzO.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-eqvJxEw1.css">
|
||||
<script type="module" crossorigin src="/assets/index-Ulrd01cQ.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-B-WaF5DI.css">
|
||||
</head>
|
||||
<body class="bg-noctune-cream">
|
||||
<div id="app"></div>
|
||||
|
||||
|
After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 321 KiB |
|
After Width: | Height: | Size: 161 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 156 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 321 KiB |
|
After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 321 KiB |
|
After Width: | Height: | Size: 161 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 156 KiB |
|
After Width: | Height: | Size: 34 KiB |
@@ -52,9 +52,7 @@ const authStore = useAuthStore();
|
||||
const uiStore = useUiStore();
|
||||
const playerStore = usePlayerStore();
|
||||
|
||||
const isAuthPage = computed(() => {
|
||||
return route.meta?.guest === true || route.path === '/register';
|
||||
});
|
||||
const isAuthPage = computed(() => route.meta?.guest === true)
|
||||
|
||||
const hasPlayer = computed(() => !!playerStore.currentTrack);
|
||||
|
||||
|
||||
@@ -41,14 +41,14 @@
|
||||
<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<router-link to="/profile" class="text-black hover:opacity-80">
|
||||
<button @click="goToProfile" class="text-black hover:opacity-80">
|
||||
<div class="w-8 h-8 rounded-full bg-noctune-dark overflow-hidden border-2 border-black">
|
||||
<img v-if="authStore.user?.avatarUrl" :src="formatUrl(authStore.user.avatarUrl)" class="w-full h-full object-cover" />
|
||||
<div v-else class="w-full h-full flex items-center justify-center">
|
||||
<svg class="w-5 h-5 text-white" fill="currentColor" viewBox="0 0 24 24"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
</router-link>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
@@ -61,11 +61,13 @@ import { usePlayerStore } from '../stores/playerStore.js'
|
||||
import { useQueueStore } from '../stores/queueStore.js'
|
||||
import api from '../lib/api.js'
|
||||
import { formatUrl } from '../lib/utils.js'
|
||||
import { useAuthGate } from '../composables/useAuthGate.js'
|
||||
|
||||
const router = useRouter()
|
||||
const authStore = useAuthStore()
|
||||
const playerStore = usePlayerStore()
|
||||
const queueStore = useQueueStore()
|
||||
const { requireAuth } = useAuthGate()
|
||||
|
||||
const query = ref('')
|
||||
const searchResults = ref(null)
|
||||
@@ -100,6 +102,16 @@ function playSearchTrack(track) {
|
||||
}
|
||||
|
||||
function toggleLikeRedirect() {
|
||||
router.push('/library')
|
||||
requireAuth({
|
||||
redirectTo: '/login',
|
||||
onAuthenticated: () => router.push('/library')
|
||||
})
|
||||
}
|
||||
|
||||
function goToProfile() {
|
||||
requireAuth({
|
||||
redirectTo: '/login',
|
||||
onAuthenticated: () => router.push('/profile')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -60,10 +60,12 @@ import { usePlayerStore } from '../stores/playerStore.js'
|
||||
import { useQueueStore } from '../stores/queueStore.js'
|
||||
import { useAuthStore } from '../stores/authStore.js'
|
||||
import { formatUrl } from '../lib/utils.js'
|
||||
import { useAuthGate } from '../composables/useAuthGate.js'
|
||||
|
||||
const playerStore = usePlayerStore()
|
||||
const queueStore = useQueueStore()
|
||||
const authStore = useAuthStore()
|
||||
const { requireAuth } = useAuthGate()
|
||||
|
||||
const isLiked = ref(false)
|
||||
|
||||
@@ -105,10 +107,13 @@ function playPrev() {
|
||||
}
|
||||
}
|
||||
|
||||
async function toggleLike() {
|
||||
function toggleLike() {
|
||||
if (!playerStore.currentTrack) return
|
||||
const id = playerStore.currentTrack._id || playerStore.currentTrack.id
|
||||
await authStore.toggleLike(id)
|
||||
requireAuth({
|
||||
redirectTo: '/login',
|
||||
onAuthenticated: () => authStore.toggleLike(id)
|
||||
})
|
||||
}
|
||||
|
||||
// Sync isLiked ref reactively from authStore
|
||||
|
||||
@@ -70,6 +70,7 @@ import { ref, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useAuthStore } from '../stores/authStore.js'
|
||||
import api from '../lib/api.js'
|
||||
import { useAuthGate } from '../composables/useAuthGate.js'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@@ -77,6 +78,8 @@ const authStore = useAuthStore()
|
||||
|
||||
const playlists = ref([])
|
||||
|
||||
const { requireAuth } = useAuthGate()
|
||||
|
||||
const isActive = (path) => route.path === path
|
||||
const isActivePrefix = (prefix) => route.path.startsWith(prefix)
|
||||
|
||||
@@ -88,7 +91,10 @@ async function fetchPlaylists() {
|
||||
} catch {}
|
||||
}
|
||||
|
||||
async function openCreatePlaylist() {
|
||||
function openCreatePlaylist() {
|
||||
requireAuth({
|
||||
redirectTo: '/login',
|
||||
onAuthenticated: async () => {
|
||||
const name = prompt('Playlist name:')
|
||||
if (!name?.trim()) return
|
||||
try {
|
||||
@@ -97,6 +103,8 @@ async function openCreatePlaylist() {
|
||||
playlists.value.push(data.data)
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(fetchPlaylists)
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { useAuthStore } from '../stores/authStore.js'
|
||||
import router from '../router/index.js'
|
||||
|
||||
let pendingAction = null
|
||||
|
||||
export function useAuthGate() {
|
||||
const authStore = useAuthStore()
|
||||
|
||||
async function requireAuth({ message, onAuthenticated }) {
|
||||
async function requireAuth({ message, onAuthenticated, redirectTo }) {
|
||||
if (authStore.isLoggedIn) {
|
||||
onAuthenticated()
|
||||
onAuthenticated?.()
|
||||
} else {
|
||||
pendingAction = onAuthenticated
|
||||
if (message) {
|
||||
pendingAction = onAuthenticated || null
|
||||
if (redirectTo) {
|
||||
router.push(redirectTo)
|
||||
} else if (message) {
|
||||
const { useUiStore } = await import('../stores/uiStore.js')
|
||||
const uiStore = useUiStore()
|
||||
uiStore.showToast(message, 'info')
|
||||
|
||||
@@ -10,14 +10,15 @@ import ProfilePage from '../views/ProfilePage.vue'
|
||||
import AdminPage from '../views/AdminPage.vue'
|
||||
|
||||
const routes = [
|
||||
{ path: '/', name: 'Login', component: LoginPage, meta: { guest: true } },
|
||||
{ path: '/', redirect: '/home' },
|
||||
{ path: '/login', name: 'Login', component: LoginPage, meta: { guest: true } },
|
||||
{ path: '/register', name: 'Register', component: RegisterPage, meta: { guest: true } },
|
||||
{ path: '/home', name: 'Home', component: LandingPage, meta: { auth: true } },
|
||||
{ path: '/library', name: 'Library', component: LibraryPage, meta: { auth: true } },
|
||||
{ path: '/playlist', name: 'Playlist', component: PlaylistPage, meta: { auth: true } },
|
||||
{ path: '/playlist/:id', name: 'PlaylistDetail', component: PlaylistPage, meta: { auth: true } },
|
||||
{ path: '/profile', name: 'Profile', component: ProfilePage, meta: { auth: true } },
|
||||
{ path: '/admin/tracks', name: 'AdminTracks', component: AdminPage, meta: { auth: true, admin: true } },
|
||||
{ path: '/home', name: 'Home', component: LandingPage },
|
||||
{ path: '/library', name: 'Library', component: LibraryPage },
|
||||
{ path: '/playlist', name: 'Playlist', component: PlaylistPage },
|
||||
{ path: '/playlist/:id', name: 'PlaylistDetail', component: PlaylistPage },
|
||||
{ path: '/profile', name: 'Profile', component: ProfilePage },
|
||||
{ path: '/admin/tracks', name: 'AdminTracks', component: AdminPage, meta: { admin: true } },
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
@@ -32,10 +33,6 @@ router.beforeEach((to, from, next) => {
|
||||
return next('/home')
|
||||
}
|
||||
|
||||
if (to.meta.auth && !authStore.isLoggedIn) {
|
||||
return next('/')
|
||||
}
|
||||
|
||||
if (to.meta.guest && authStore.isLoggedIn) {
|
||||
return next('/home')
|
||||
}
|
||||
|
||||
@@ -62,10 +62,12 @@ import { useQueueStore } from '../stores/queueStore.js'
|
||||
import { useAuthStore } from '../stores/authStore.js'
|
||||
import api from '../lib/api.js'
|
||||
import { formatUrl } from '../lib/utils.js'
|
||||
import { useAuthGate } from '../composables/useAuthGate.js'
|
||||
|
||||
const playerStore = usePlayerStore()
|
||||
const queueStore = useQueueStore()
|
||||
const authStore = useAuthStore()
|
||||
const { requireAuth } = useAuthGate()
|
||||
|
||||
const tracks = ref([])
|
||||
const loading = ref(true)
|
||||
@@ -93,8 +95,11 @@ function playFirstTrack() {
|
||||
if (tracks.value.length) playTrack(tracks.value[0])
|
||||
}
|
||||
|
||||
async function toggleLike(track) {
|
||||
await authStore.toggleLike(track._id)
|
||||
function toggleLike(track) {
|
||||
requireAuth({
|
||||
redirectTo: '/login',
|
||||
onAuthenticated: () => authStore.toggleLike(track._id)
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
<section class="mb-12">
|
||||
<h2 class="text-3xl font-black text-black mb-6">Liked Tracks</h2>
|
||||
<div v-if="loading" class="text-center py-12 text-gray-500">Loading...</div>
|
||||
<div v-else-if="!authStore.isLoggedIn" class="text-center py-12">
|
||||
<p class="text-gray-500 mb-4">Login to see your liked tracks</p>
|
||||
<router-link to="/login" class="bg-noctune-yellow border-2 border-black px-6 py-3 font-bold inline-block hover:bg-yellow-400 transition-colors rounded-lg">Login</router-link>
|
||||
</div>
|
||||
<div v-else-if="likedTracks.length === 0" class="text-center py-12">
|
||||
<p class="text-gray-500 mb-4">No liked tracks yet</p>
|
||||
<router-link to="/home" class="bg-noctune-yellow border-2 border-black px-6 py-3 font-bold inline-block hover:bg-yellow-400 transition-colors rounded-lg">Discover Music</router-link>
|
||||
@@ -75,10 +79,12 @@ import { useQueueStore } from '../stores/queueStore.js'
|
||||
import { useAuthStore } from '../stores/authStore.js'
|
||||
import api from '../lib/api.js'
|
||||
import { formatUrl } from '../lib/utils.js'
|
||||
import { useAuthGate } from '../composables/useAuthGate.js'
|
||||
|
||||
const playerStore = usePlayerStore()
|
||||
const queueStore = useQueueStore()
|
||||
const authStore = useAuthStore()
|
||||
const { requireAuth } = useAuthGate()
|
||||
|
||||
const likedTracks = ref([])
|
||||
const allTracks = ref([])
|
||||
@@ -105,15 +111,21 @@ function playTrack(track, fromLiked = false, idx) {
|
||||
playerStore.play()
|
||||
}
|
||||
|
||||
async function toggleLike(track) {
|
||||
function toggleLike(track) {
|
||||
const wasLiked = isLiked(track)
|
||||
requireAuth({
|
||||
redirectTo: '/login',
|
||||
onAuthenticated: async () => {
|
||||
await authStore.toggleLike(track._id)
|
||||
if (wasLiked) {
|
||||
likedTracks.value = likedTracks.value.filter((t) => t._id !== track._id)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (authStore.isLoggedIn) {
|
||||
try {
|
||||
const { data: liked } = await api.get('/tracks/liked')
|
||||
if (liked.success) {
|
||||
@@ -121,9 +133,9 @@ onMounted(async () => {
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
loading.value = false
|
||||
|
||||
try {
|
||||
const { data: all } = await api.get('/tracks')
|
||||
|
||||
@@ -77,6 +77,7 @@ import { useRouter } from 'vue-router'
|
||||
import { useAuthStore } from '../stores/authStore.js'
|
||||
import api from '../lib/api.js'
|
||||
import { formatUrl } from '../lib/utils.js'
|
||||
import { useAuthGate } from '../composables/useAuthGate.js'
|
||||
|
||||
const router = useRouter()
|
||||
const authStore = useAuthStore()
|
||||
@@ -138,10 +139,14 @@ async function handleUpdate() {
|
||||
|
||||
async function handleLogout() {
|
||||
await authStore.logout()
|
||||
router.push('/')
|
||||
router.push('/login')
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (!authStore.isLoggedIn) {
|
||||
router.push('/login')
|
||||
return
|
||||
}
|
||||
try {
|
||||
const { data } = await api.get('/tracks/liked')
|
||||
if (data.success) {
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</button>
|
||||
<p class="text-center mt-6 text-gray-600">
|
||||
Already have an account?
|
||||
<router-link to="/" class="text-noctune-orange font-bold hover:underline">Login</router-link>
|
||||
<router-link to="/login" class="text-noctune-orange font-bold hover:underline">Login</router-link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||