1import{j as t,B as S,r as d,y as O,K as ge,ac as xe,h as ve,ab as z,s as be}from"./index-BvsqCpEz.js";import{I as M}from"./input-BedoGODD.js";import{o as ee,T as je,u as we,v as ye,L as Ne,A as ke,a as Ae,b as Ce,c as De,d as Te,e as Fe,f as Re,g as Ue}from"./MemberDashboard-Cs5Sf23a.js";import{f as B,p as Se}from"./ReplayPlayer-CImKQLks.js";import{L as Me}from"./list-ordered-BY2yW7CF.js";import{C as Le}from"./ChapterMarkPlayer-D2NLBJgO.js";import{U as V}from"./upload-B6sNIh33.js";import{C as Ee}from"./circle-alert-DQWk7aEq.js";import"./use-auth-4OwtEfAA.js";import"./index-5yHiP4fM.js";import"./wind-DW6YfAyS.js";import"./arrow-left-DasGo8Zs.js";import"./calendar-BX6XEece.js";import"./user-DLmK3dAG.js";import"./format-Dogvratb.js";import"./check-B97Uezjq.js";import"./download-0HDG1NIG.js";import"./dropdown-menu-DO9fT12w.js";import"./chevron-right-CPI6eVSm.js";import"./pause-BSClxgvH.js";const Pe=({chapters:l,onChange:u,duration:m=0})=>{const x=(p,i)=>{u(l.map((c,L)=>L===p?{...c,...i}:c))},w=(p,i)=>{m>0&&Se(i)>m&&x(p,{time:B(m)})},T=p=>u(l.filter((i,c)=>c!==p)),y=()=>u([...l,{time:"0:00",title:""}]);return t.jsx("div",{className:"pl-7 mt-2",children:t.jsxs("div",{className:"rounded-lg border border-border bg-muted/20 p-3 space-y-2",children:[t.jsxs("div",{className:"flex items-center justify-between",children:[t.jsxs("span",{className:"text-[11px] font-bold uppercase tracking-wider text-muted-foreground inline-flex items-center gap-1.5",children:[t.jsx(Me,{className:"h-3 w-3"})," Chapters",l.length>0&&t.jsxs("span",{className:"text-muted-foreground/70",children:["(",l.length,")"]})]}),t.jsxs(S,{type:"button",variant:"ghost",size:"sm",onClick:y,className:"h-7 text-xs px-2",children:[t.jsx(ee,{className:"h-3 w-3 mr-1"})," Add chapter"]})]}),l.length===0?t.jsxs("p",{className:"text-[11px] text-muted-foreground",children:["Add chapter markers to let listeners jump to specific moments. Use formats like ",t.jsx("code",{children:"1:23"})," or ",t.jsx("code",{children:"1:02:30"}),m>0&&t.jsxs(t.Fragment,{children:[" â this track runs to ",t.jsx("code",{children:B(m)})]}),"."]}):t.jsx("ul",{className:"space-y-1.5",children:l.map((p,i)=>t.jsxs("li",{className:"flex items-center gap-2",children:[t.jsx(M,{value:p.time,onChange:c=>x(i,{time:c.target.value}),onBlur:c=>w(i,c.target.value),placeholder:"0:00",className:"h-8 text-xs font-mono w-20 shrink-0"}),t.jsx(M,{value:p.title,onChange:c=>x(i,{title:c.target.value}),placeholder:"Chapter title",className:"h-8 text-xs flex-1 min-w-0"}),t.jsx(S,{type:"button",variant:"ghost",size:"icon",className:"h-8 w-8 shrink-0 text-destructive hover:text-destructive",onClick:()=>T(i),title:"Remove chapter",children:t.jsx(je,{className:"h-3.5 w-3.5"})})]},i))})]})})},$e=/^[A-Za-z0-9.-]+\.mp3$/,Oe=500*1024*1024,ze=()=>{const l=new Date,u=m=>String(m).padStart(2,"0");return`${l.getFullYear()}${u(l.getMonth()+1)}${u(l.getDate())}-${u(l.getHours())}${u(l.getMinutes())}${u(l.getSeconds())}`},Be=l=>{const u=l.split(/[\\/]/).pop()??l,m=u.toLowerCase().endsWith(".mp3")?".mp3":"";return(u.replace(/\.mp3$/i,"").replace(/\s+/g,"-").replace(/[^A-Za-z0-9.-]/g,"").replace(/-+/g,"-").replace(/^-+|-+$/g,"")||"podcast")+(m||".mp3")},Ie=l=>(l.split(/[\\/]/).pop()??l).replace(/\.mp3$/i,"").replace(/[-_]+/g," ").replace(/\s+/g," ").trim(),it=({value:l,onChange:u,defaultPrefix:m})=>{const[x,w]=d.useState(null),[T,y]=d.useState(0),[p,i]=d.useState(null),c=d.useRef(null),[L,I]=d.useState(null),[te,X]=d.useState(new Set),[se,N]=d.useState(null),[re,F]=d.useState(!1),[_,ae]=d.useState(null),W=d.useRef(null),[Y,ne]=d.useState(!1),[G,R]=d.useState(null),[le,oe]=d.useState({}),h=d.useRef(l);d.useEffect(()=>{h.current=l},[l]);const b=e=>{h.current=e,u(e)},E=()=>{const e=W.current;e&&(e.onended=null,e.onerror=null,e.pause(),e.removeAttribute("src"),e.load()),W.current=null,ae(null)};d.useEffect(()=>E,[]);const U=(e,s)=>{const r=h.current.map((n,f)=>f!==e?n:{...n,...s});b(r)},ie=(e,s)=>{var n;const r=((n=h.current[e])==null?void 0:n.chapters)??[];U(e,{chapters:[...r,{time:B(s),title:""}]})},ce=e=>{_!==null&&E(),b(h.current.filter((s,r)=>r!==e)),X(s=>{const r=new Set;
1return s.forEach(n=>{n<e?r.add(n):n>e&&r.add(n-1)}),r})},H=(e,s)=>{const r=e+s;if(r<0||r>=h.current.length)return;_!==null&&E();const n=[...h.current];[n[e],n[r]]=[n[r],n[e]],b(n)},de=()=>{b([...h.current,{title:"",url:""}])},q=e=>{X(s=>{const r=new Set(s);return r.has(e)?r.delete(e):r.add(e),r}),i(null)},ue=e=>{var s;i(null),I(e),(s=c.current)==null||s.click()},Z=async(e,s)=>{var f,v;if(!e.name.toLowerCase().endsWith(".mp3")){i({index:s,message:"Only MP3 files are allowed."});return}if(e.size>Oe){i({index:s,message:"File is larger than 500 MB."});return}let r=Be(e.name);m&&!r.toLowerCase().startsWith(m.toLowerCase()+"-")&&(r=`${m}-${r}`);const n=`${ze()}-${r}`;if(!$e.test(n)){i({index:s,message:"Filename contains invalid characters after cleaning."});return}w(s),y(0);try{const{data:o,error:a}=await be.functions.invoke("sign-podcast-upload",{body:{filename:n,contentType:"audio/mpeg"}});if(a||!(o!=null&&o.url))throw new Error((a==null?void 0:a.message)||(o==null?void 0:o.error)||"Failed to get upload URL");const A=new FormData;Object.entries(o.fields).forEach(([D,j])=>{A.append(D,j)}),A.append("file",e),await new Promise((D,j)=>{const g=new XMLHttpRequest;g.open("POST",o.url,!0),g.upload.onprogress=$=>{$.lengthComputable&&y(Math.round($.loaded/$.total*100))},g.onload=()=>{g.status>=200&&g.status<300?D():j(new Error(`S3 upload failed (${g.status}): ${g.responseText.slice(0,200)}`))},g.onerror=()=>j(new Error("Network error during upload. Check the bucket CORS configuration.")),g.send(A)});const pe=URL.createObjectURL(e),C=h.current,he=((v=(f=C[s])==null?void 0:f.title)==null?void 0:v.trim())??"",Q={...C[s]??{title:"",url:""},title:he||Ie(e.name),url:o.publicUrl,previewUrl:pe},fe=s<C.length?C.map((D,j)=>j===s?Q:D):[...C,Q];b(fe),z.success("Audio uploaded!")}catch(o){const a=o instanceof Error?o.message:"Upload failed";i({index:s,message:a}),z.error("Upload failed",{description:a})}finally{w(null),y(0),c.current&&(c.current.value="")}},me=async e=>{const s=L;if(I(null),s!==null){if(!Y){R({files:[e],startIndex:s}),c.current&&(c.current.value="");return}await Z(e,s)}},K=async(e,s)=>{var v;const r=Array.from(e).filter(o=>o.name.toLowerCase().endsWith(".mp3"));if(r.length===0){z.error("Only MP3 files are supported");return}const n=[...h.current],f=[];for(let o=0;o<r.length;o++){let a;o===0&&s!==null&&!((v=n[s])!=null&&v.url)?a=s:(n.push({title:"",url:""}),a=n.length-1),f.push(a)}b(n);for(let o=0;o<r.length;o++)await Z(r[o],f[o])},J=async(e,s)=>{if(!Y){R({files:Array.from(e),startIndex:s});return}await K(e,s)},k=l,P=k.length>0;return t.jsxs("div",{className:O("bg-card border rounded-2xl p-4 sm:p-5 transition-colors",re?"border-primary bg-primary/5":"border-border"),onDragEnter:e=>{Array.from(e.dataTransfer.types).includes("Files")&&(e.preventDefault(),F(!0))},onDragOver:e=>{Array.from(e.dataTransfer.types).includes("Files")&&e.preventDefault()},onDragLeave:e=>{const s=e.currentTarget.getBoundingClientRect();(e.clientX<=s.left||e.clientX>=s.right||e.clientY<=s.top||e.clientY>=s.bottom)&&(F(!1),N(null))},onDrop:e=>{Array.from(e.dataTransfer.types).includes("Files")&&(e.preventDefault(),F(!1),N(null),e.dataTransfer.files.length>0&&J(e.dataTransfer.files,null))},children:[t.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[t.jsx(ge,{className:"h-4 w-4 text-primary"}),t.jsx("h3",{className:"font-display text-sm font-bold text-foreground",children:"Audio attachments"}),P&&t.jsxs("span",{className:"ml-auto text-xs text-muted-foreground",children:[k.length," ",k.length===1?"track":"tracks"]})]}),t.jsxs("div",{className:"space-y-3",children:[k.map((e,s)=>{const r=x===s,n=(p==null?void 0:p.index)===s,f=!!e.url,v=te.has(s),o=se===s;return t.jsxs("div",{className:O("rounded-xl transition-colors",o&&"ring-2 ring-primary bg-primary/5"),children:[t.jsxs("div",{className:"flex items-center gap-1.5",children:[t.jsxs("div",{className:"flex flex-col gap-0.5",children:[t.jsx("button",{type:"button",onClick:()=>H(s,-1),disabled:s===0||r,className:"text-muted-foreground hover:text-foreground disabled:opacity-30 disabled:cursor-not-allowed transition-colors",title:"Move up",children:t.jsx(we,{className:"h-3.5 w-3.5"})}),t.jsx("button",{type:"button",onClick:()=>H(s,1),disabled:s===k.length-1||r,className:"text-muted-foreground hover:text-foreground disabled:opacity-30 disabled:cursor-not-allowed transition-colors",title:"Move down",children:t.jsx(ye,{className:"h-3.5 w-3.5"})})]}),t.jsxs("span",{className:"text-xs font-mono text-muted-foreground w-5 text-right shrink-0",children:[s+1,"."]}),t.jsx(M,{value:e.title,onChange:a=>U(s,{title:a.target.value}),placeholder:"Track title (required)",className:"h-9 text-sm flex-1 min-w-0",disabled:r}),t.jsx(S,{variant:"ghost",size:"icon",className:"h-9 w-9 shrink-0 text-destructive hover:text-destructive",onClick:()=>ce(s),disabled:r,title:"Remove track",children:t.jsx(xe,{className:"h-4 w-4"})})]}),!f&&t.jsxs("div",{className:"pl-7 mt-2",children:[r?t.jsxs("div",{className:"rounded-lg border border-dashed border-primary/30 bg-primary/5 py-3 px-3 flex items-center gap-3",children:[t.jsx(ve,{className:"h-4 w-4 animate-spin text-primary shrink-0"}),t.jsxs("div",{className:"flex-1 min-w-0",children:[t.jsxs("div",{className:"flex justify-between text-[11px] text-muted-foreground mb-1",children:[t.jsx("span",{children:"Uploadingâ¦"}),t.jsxs("span",{children:[T,"%"]})]}),t.jsx("div",{className:"h-1.5 bg-muted rounded-full overflow-hidden",children:t.jsx("div",{className:"h-full bg-primary transition-all",style:{width:`${T}%`}})})]})]}):v?t.jsxs("div",{className:"space-y-1",children:[t.jsx(M,{value:e.url,onChange:a=>U(s,{url:a.target.value.trim()}),placeholder:"https://example.com/audio.mp3",className:"h-9 text-sm",type:"url"}),t.jsxs("button",{type:"button",onClick:()=>q(s),className:"text-[11px] text-muted-foreground hover:text-foreground inline-flex items-center gap-1 transition-colors",children:[t.jsx(V,{className:"h-3 w-3"}),"Switch to file upload"]})]}):t.jsxs("div",{onDragOver:a=>{Array.from(a.dataTransfer.types).includes("Files")&&(a.preventDefault(),a.stopPropagation(),N(s),F(!1))},onDragLeave:()=>N(null),onDrop:a=>{Array.from(a.dataTransfer.types).includes("Files")&&(a.preventDefault(),a.stopPropagation(),N(null),a.dataTransfer.files.length>0&&J(a.dataTransfer.files,s))},className:"space-y-1",children:[t.jsxs("button",{type:"button",onClick:()=>ue(s),className:O("w-full rounded-lg border border-dashed py-2.5 px-3 flex items-center justify-center gap-2 transition-colors text-xs",n?"border-destructive/40 bg-destructive/5 hover:bg-destructive/10 text-destructive":"border-border hover:border-primary/40 hover:bg-muted/30 text-muted-foreground"),children:[t.jsx(V,{className:"h-3.5 w-3.5"}),t.jsx("span",{className:"font-medium",children:"Click or drag to upload MP3"})]}),t.jsxs("button",{type:"button",onClick:()=>q(s),className:"text-[11px] text-muted-foreground hover:text-foreground inline-flex items-center gap-1 transition-colors",children:[t.jsx(Ne,{className:"h-3 w-3"}),"Use a manual URL instead"]})]}),n&&t.jsxs("div",{className:"flex items-start gap-2 text-xs text-destructive bg-destructive/10 rounded-lg p-2 mt-2",children:[t.jsx(Ee,{className:"h-3.5 w-3.5 flex-shrink-0 mt-0.5"}),t.jsx("span",{children:p.message})]})]}),f&&t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"pl-7 mt-2",children:t.jsx(Le,{src:e.previewUrl||e.url,onMarkChapter:a=>ie(s,a),onDurationChange:a=>oe(A=>({...A,[s]:a}))},e.previewUrl||e.url)}),t.jsx(Pe,{chapters:e.chapters??[],onChange:a=>U(s,{chapters:a.length>0?a:void 0}
1),duration:le[s]??0})]})]},s)}),!P&&t.jsx("p",{className:"text-sm text-muted-foreground text-center py-2",children:"No audio attached yet. Drag an MP3 here or click below."}),t.jsxs(S,{type:"button",variant:"ghost",size:"sm",onClick:de,disabled:x!==null,className:"w-full bg-muted/40 hover:bg-muted",children:[t.jsx(ee,{className:"h-3.5 w-3.5 mr-1.5"}),P?"Add another audio file":"Add audio file"]}),t.jsx("input",{ref:c,type:"file",accept:"audio/mpeg,.mp3",className:"hidden",onChange:e=>{var r;const s=(r=e.target.files)==null?void 0:r[0];s&&me(s)}})]}),t.jsx(ke,{open:!!G,onOpenChange:e=>{e||R(null)},children:t.jsxs(Ae,{children:[t.jsxs(Ce,{children:[t.jsx(De,{children:"Audio upload guidelines"}),t.jsxs(Te,{className:"whitespace-pre-line text-foreground/90",children:["Only audio that has previously been broadcast on the station may be submitted.",` 2 3`,"Audio files should begin at the start of the relevant content. Any preceding material, including NRN News, or other unrelated content, must be edited out.",` 4 5`,"Please ensure your file is named clearly and logically using a consistent format.",` 6 7`,"For example: mondaybreakfast-johninterview-ddmmyy.mp3",` 8 9`,"File names should accurately describe the program, content, and broadcast date where applicable."]})]}),t.jsxs(Fe,{children:[t.jsx(Re,{children:"Cancel"}),t.jsx(Ue,{onClick:async()=>{ne(!0);const e=G;R(null),e&&await K(e.files,e.startIndex)},children:"I acknowledge & accept"})]})]})})]})};export{it as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.