From b3d92b5f6e40ce0453b7fbcd72ae51942a5772d6 Mon Sep 17 00:00:00 2001 From: mileswa1q22 Date: Sun, 29 Mar 2026 17:22:14 -0500 Subject: [PATCH] put it on live --- LICENSE | 18 +++++++ README.md | 3 ++ app.js | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++ data.txt | 50 ++++++++++++++++++ index.html | 32 ++++++++++++ lists.html | 44 ++++++++++++++++ players.html | 33 ++++++++++++ styles.css | 34 ++++++++++++ 8 files changed, 357 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 app.js create mode 100644 data.txt create mode 100644 index.html create mode 100644 lists.html create mode 100644 players.html create mode 100644 styles.css diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..cc2fa06 --- /dev/null +++ b/LICENSE @@ -0,0 +1,18 @@ +MIT License + +Copyright (c) 2026 miles + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee0c49a --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# gd-list + +my gd list \ No newline at end of file diff --git a/app.js b/app.js new file mode 100644 index 0000000..2ef653f --- /dev/null +++ b/app.js @@ -0,0 +1,143 @@ +// Lightweight multi-page handler for GD Demand List +(function(){ + function qs(id){return document.getElementById(id)} + + const page = document.body.dataset.page; + + // Storage helpers + function read(key, fallback){ + try{const v = localStorage.getItem(key); return v?JSON.parse(v):fallback} + catch(e){return fallback} + } + function write(key, val){localStorage.setItem(key,JSON.stringify(val))} + + // Players page + if(page==='players'){ + const form = qs('player-form'); const nameIn = qs('player-name'); const list = qs('players'); + let players = read('gd_players',[]); + function render(){list.innerHTML=''; players.forEach((p,idx)=>{ + const li=document.createElement('li'); li.innerHTML=`${escapeHtml(p.name)} (${p.id})`; + const actions=document.createElement('div'); actions.className='actions'; + const edit=document.createElement('button'); edit.textContent='Edit'; edit.onclick=()=>{const nv=prompt('Edit name',p.name); if(nv){players[idx].name=nv; write('gd_players',players); render()}}; + const del=document.createElement('button'); del.textContent='Delete'; del.onclick=()=>{if(confirm('Delete player?')){players.splice(idx,1); write('gd_players',players); render()}}; + actions.appendChild(edit); actions.appendChild(del); li.appendChild(actions); list.appendChild(li); + })} + form.addEventListener('submit',e=>{e.preventDefault(); const name=nameIn.value.trim(); if(!name) return; players.push({id:Date.now().toString(36),name}); write('gd_players',players); nameIn.value=''; render()}); + render(); + } + + // Lists page + if(page==='lists'){ + const levelsEl = qs('levels'); const listArea = qs('list-area'); const titleEl = qs('list-title'); + // Load hard-coded data file data.txt (category|position|title|url per line) + function loadData(){ + fetch('data.txt').then(r=>r.text()).then(txt=>{ + const lines = txt.split(/\r?\n/).map(l=>l.trim()).filter(Boolean); + const items = lines.map(l=>{ + const parts = l.split('|').map(p=>p.trim()); + return {level:parts[0]||'Unknown',position:parts[1]||'',title:parts[2]||'Untitled',url:parts[3]||''}; + }); + setupLevels(items); + }).catch(err=>{listArea.innerHTML='

Failed to load data.txt — run via a local server.

'; console.error(err)}); + } + + function computeCategories(items){ + const max = items.reduce((m,it)=>Math.max(m, Number(it.position)||0), 0); + const cats = ['Full List']; + for(let i=1;i<=max;i+=10){ + const start = i; const end = Math.min(i+9, max); + cats.push(`Top ${start}-${end}`); + } + return cats; + } + + function setupLevels(items){ + const categories = computeCategories(items); + levelsEl.innerHTML=''; + const filterSelect = qs('level-filter'); + filterSelect.innerHTML = ''; + categories.forEach(cat=>{ + const li = document.createElement('li'); + const btn = document.createElement('button'); + btn.type = 'button'; + btn.textContent = cat; + btn.className = 'level-link'; + btn.addEventListener('click', ()=> { + selectLevel(cat, items, btn); + filterSelect.value = cat; + }); + li.appendChild(btn); + levelsEl.appendChild(li); + + const opt = document.createElement('option'); opt.value = cat; opt.textContent = cat; filterSelect.appendChild(opt); + }); + // search and filter handlers + qs('search').addEventListener('input', ()=> renderTable(items)); + filterSelect.addEventListener('change', ()=> renderTable(items)); + // default select Full List + selectLevel('Full List', items, levelsEl.querySelector('.level-link')); + } + + function selectLevel(level, items, linkEl){ + levelsEl.querySelectorAll('.level-link').forEach(a=>a.classList.remove('active')); + if(linkEl) linkEl.classList.add('active'); + qs('level-filter').value = level; + renderTable(items); + } + + function renderTable(items){ + const q = (qs('search') && qs('search').value || '').toLowerCase(); + const levelFilter = (qs('level-filter') && qs('level-filter').value) || 'all'; + const filtered = items.filter(it=>{ + // apply level / category filter (support range categories like "Top 1-10") + if(levelFilter && levelFilter!=='all' && levelFilter!=='Full List'){ + const m = levelFilter.match(/Top\s*(\d+)-(\d+)/i); + if(m){ + const s = Number(m[1]); const e = Number(m[2]); const pos = Number(it.position)||0; + if(pos < s || pos > e) return false; + } + } + if(!q) return true; + return (it.title||'').toLowerCase().includes(q) || (it.level||'').toLowerCase().includes(q); + }).sort((a,b)=> (Number(a.position)||0)-(Number(b.position)||0)); + + const tbody = qs('list-area'); tbody.innerHTML=''; + filtered.forEach(it=>{ + const tr = document.createElement('tr'); + const tdNum = document.createElement('td'); tdNum.textContent = it.position; + const tdTitle = document.createElement('td'); tdTitle.textContent = it.title; + const tdAct = document.createElement('td'); + const a = document.createElement('a'); a.textContent='Open'; a.href='#'; a.className='btn'; + a.addEventListener('click', (e)=>{e.preventDefault(); openVideo(it.url)}); + tdAct.appendChild(a); + tr.appendChild(tdNum); tr.appendChild(tdTitle); tr.appendChild(tdAct); + tbody.appendChild(tr); + }); + } + + function openVideo(url){ + if(!url) return; const id = extractYouTubeID(url); + if(!id){ window.open(url,'_blank'); return } + let modal = document.querySelector('.video-modal'); + if(!modal){ + modal = document.createElement('div'); modal.className='video-modal'; + const inner = document.createElement('div'); inner.className='inner'; + const close = document.createElement('button'); close.textContent='Close'; close.className='btn'; close.style.float='right'; close.onclick=()=>modal.remove(); + inner.appendChild(close); + const iframe = document.createElement('iframe'); iframe.allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture'; iframe.allowFullscreen=true; + inner.appendChild(iframe); modal.appendChild(inner); document.body.appendChild(modal); + } + modal.querySelector('iframe').src = `https://www.youtube.com/embed/${id}`; + modal.style.display = 'flex'; + } + + function extractYouTubeID(url){ + const m = url.match(/(?:v=|\/embed\/|youtu\.be\/)([A-Za-z0-9_-]{6,})/); return m?m[1]:''; + } + + loadData(); + } + + // Utility + function escapeHtml(s){return String(s).replace(/[&<>"']/g, c=>({"&":"&","<":"<",">":">","\"":""","'":"'"})[c])} +})(); diff --git a/data.txt b/data.txt new file mode 100644 index 0000000..e1ec169 --- /dev/null +++ b/data.txt @@ -0,0 +1,50 @@ +new|1|Flamewall|https://youtu.be/x4Io4zkWVRw?si=tf0DBaWahOPPEWxO +new|2|Thinking Space II|https://youtu.be/CELNmHwln_c?si=soP6SzRn92G1vKbl +new|4|Amethyst|https://youtu.be/4lfkzz1VCbA?si=6NNeWiH-nnwu21Cb +new|3|Tidal Wave|https://youtu.be/9fsZ014qB3s?si=oj4E4ceyNtRVcDvd +new|5|Orbit|https://youtu.be/QKcv8DkNPd0?si=cKBFqp7GRqmfupgJ +new|6|BOOBAWAMBA|https://youtu.be/20fYiqLAo_E?si=QSSixz31rWeeQ_8B +new|7|Nullscapes|https://youtu.be/EztneTPp5CU?si=ljn-S_bnGYwOoUyV +new|8|Quantuese Processing|https://youtu.be/j5NC0u1Q91Q?si=FvUEY2kdDtNMqWSD +new|9|Subsuming Vortex|https://youtu.be/0eYG1ogJpIQ?si=7XRxfDsmMVb0G9Si +new|10|Andromeda|https://youtu.be/mk3TDemdkC0?si=va13_RKAJUyFvhcv +new|11|Every End|https://youtu.be/AO--mVVFtKI?si=gIT5vxyc1FZ4_8Jj +new|12|Silent Clubstep|https://youtu.be/GR4OMkS3SN8?si=CMNz8bPBaUU94wiy +new|13|Anathema|https://youtu.be/_uKwmjHmySI?si=PgXwX7Z--wCay34b +new|14|Acheron|https://youtu.be/sBKR6aUorzA?si=0A9S2_W8gi1awZ81 +new|15|Ashley Wave Trials|https://youtu.be/aTxt76U3e2Q?si=RVcEcOTOfs7NGWRi +new|16|Avernus|https://youtu.be/16Zh8jssanc?si=0o6d2dH4p_J7UjKB +new|17|Menace|https://youtu.be/nnkgghxxsEE?si=OuUQfD7WbXVooYyX +new|18|Spectre|https://youtu.be/MzsSLKJrLSI?si=-bXtr_jG96kTCzy4 +new|19|Abyss Of Darkness|https://youtu.be/ejJkpqcMMCY?si=Rpp4HEi1kOMh-p0h +new|20|Defeated Circles|https://youtu.be/nU5AQPzd2YA?si=6eKDMPh-2QjDBBOF +new|21|Tunnel Of Despair|https://youtu.be/LpS4JREhW98?si=Z6_DRV5YZTEA0TeQ +new|22|Subterminal Point|https://youtu.be/h2wmRMgACH4?si=nDD0-bmLqPgcdVJP +new|23|KOCMOC|https://youtu.be/2CxE-UWCIG4?si=9xz4hBjtNKe8Rcbs +new|24|Slaughterhouse|https://youtu.be/kpcF1-QAHQc?si=7ybF9EbcjqHzloLM +new|25|Kyouki|https://youtu.be/KDa5c0CJTHs?si=WU0sPusFLB7Jtkam +new|26|The Lightning Rod|https://youtu.be/nQDTi077O6M?si=Kqp2Od3lJx1YWTDB +new|27|Based After Based|https://youtu.be/yQBFyUvB3lY?si=Cmxbc5jrTrNlcmG5 +new|28|CHIL|https://youtu.be/DROMiCc2ZRM?si=_bR8CCnqJGVCex9F +new|29|Sakupen Circles|https://youtu.be/ofG2mJi9kEA?si=3yv78_jxidKPhtL5 +new|30|Deimos (ItsHybrid)|https://youtu.be/b2yHaIk5zio?si=AMIuVFR-EW4CK8_P +new|31|Eyes In The Water|https://youtu.be/yvLwiOy3KEA?si=1991xs25WTEoTbE0 +new|32|Voltage|https://youtu.be/wBRvBN9tmlc?si=GU2md9I7ZnUV7Rfr +new|33|Firework|https://youtu.be/QBe5x2o9v2w?si=dhPg9YcCRjwngxU9 +new|34|Silentlocked|https://youtu.be/O-IQeUdEGvI?si=KeSHH6kwZoSVGINT +new|35|poocubed|https://youtu.be/fzL31vai1ms?si=9Gwk7RDtbEFxOJ6t +new|36|KOSETSU|https://youtu.be/hZ8vFX8z_BU?si=P6fFal0yazJbje2O +new|37|Through The Gates|https://youtu.be/4yHA6jux5UI?si=nstk3A6FDN3QR-qm +new|38|Saul Goodman|https://youtu.be/hjs5PjUaw9k?si=qJpGrru21d50gO5R +new|39|The Salt Factory|https://youtu.be/lQ7M-Sgov24?si=nXYVL0XGy5NOJLXn +new|40|Snowbound|https://youtu.be/cjHwgbtAkXU?si=ghJbRJCkN-m0zu60 +new|41|CONVOLSION|https://youtu.be/qeRKuyU3eGI?si=UPaem0b3V8fX0L1r +new|42|The Apocalyptic Trilogy|https://youtu.be/RUBbpsTR5eU?si=mEsPtyMLrQgP5fWl +new|43|MINUSdry|https://youtu.be/YvA8ehhzz0Q?si=DT6DfrXOQ41swSIR +new|44|Sevvend Clubstep|https://youtu.be/TvA8EJTJFCc?si=Rm9HyExGYpeGn4qs +new|45|Edge Of Destiny|https://youtu.be/rUphe3H59yU?si=dZ8LgDyqif1ET_k1 +new|46|The Halucination|https://youtu.be/tYbXsNkO9HE?si=b8hmXS98BAjDlPzF +new|47|CONVULSION|https://youtu.be/qeRKuyU3eGI?si=qJN026t6RcGjU3iW +new|48|Solar Flare|https://youtu.be/eHQNgty8ypY?si=ZdUIODdeDYLAXeHI +new|49|LIMBO|https://youtu.be/kXYMbaMVOZg?si=fWm4ngeSxBhFZadA +new|50|The Catacombs|https://youtu.be/T9-75lfKVQg?si=zEH6vP1617n5666I \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..0212b33 --- /dev/null +++ b/index.html @@ -0,0 +1,32 @@ + + + + + + GD Demand List + + + +
+

GD Demand List

+ +
+
+
+

Welcome

+

Use the top navigation to view players or demand lists. This UI follows a compact table-first layout for quick browsing.

+
+
+
+

Quick Links

+ View Lists + Players +
+
+
+ + + diff --git a/lists.html b/lists.html new file mode 100644 index 0000000..7c56a34 --- /dev/null +++ b/lists.html @@ -0,0 +1,44 @@ + + + + + + Lists — GD Demand List + + + +
+

Demand Lists

+ +
+
+ + +
+
+

All Videos

+ + +
+ +
+ + + + + +
#TitleAction
+
+
+
+ + + diff --git a/players.html b/players.html new file mode 100644 index 0000000..d0d17b4 --- /dev/null +++ b/players.html @@ -0,0 +1,33 @@ + + + + + + Players — GD Demand List + + + +
+

Players

+ +
+
+
+

Add Player

+
+ + +
+
+ +
+

Players

+
    +
    +
    + + + diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..aff94bc --- /dev/null +++ b/styles.css @@ -0,0 +1,34 @@ +:root{--bg:#0f1724;--panel:#071326;--accent:#5cc5ff;--muted:#9fb3c8;--text:#e6eef8;--card:#081220} +*{box-sizing:border-box} +html,body{height:100%;margin:0;font-family:Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,"Helvetica Neue",Arial;color:var(--text);background:linear-gradient(180deg,#061021 0%,#071426 100%)} +header{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;background:linear-gradient(90deg,rgba(255,255,255,0.02),transparent);backdrop-filter:blur(4px)} +header h1{margin:0;font-size:1.1rem} +nav a{color:var(--muted);margin-left:14px;text-decoration:none} +main{padding:18px 20px} +.layout{display:flex;gap:16px;align-items:flex-start} +.sidebar{width:220px} +.sidebar .panel{padding:12px;height:calc(100vh - 120px);overflow:auto} +.sidebar h2{margin:0 0 8px 0;font-size:0.95rem} +.sidebar ul{list-style:none;padding:0;margin:0} +.sidebar li{margin:6px 0} +.level-link{display:block;width:100%;text-align:left;padding:8px;border-radius:6px;border:0;background:transparent;color:var(--muted);cursor:pointer;font-weight:600} +.level-link.active{background:rgba(92,197,255,0.06);color:var(--accent)} +.content{flex:1} +.panel{background:var(--panel);padding:14px;border-radius:10px;margin-bottom:12px;box-shadow:0 3px 12px rgba(2,6,23,0.6)} +.search-row{display:flex;gap:8px;align-items:center;margin-bottom:12px} +.search-row input[type=text]{flex:1;padding:10px 12px;border-radius:8px;border:1px solid rgba(255,255,255,0.04);background:transparent;color:var(--text)} +.search-row select{padding:8px;border-radius:8px;border:1px solid rgba(255,255,255,0.04);background:transparent;color:var(--text)} +.table-wrap{overflow:auto;border-radius:8px} +table.levels-table{width:100%;border-collapse:collapse;background:linear-gradient(180deg,rgba(255,255,255,0.012),transparent)} +table.levels-table th,table.levels-table td{padding:12px 14px;border-bottom:1px solid rgba(255,255,255,0.02);text-align:left} +table.levels-table th{color:var(--muted);font-size:0.85rem;font-weight:600} +table.levels-table tr:hover td{background:rgba(255,255,255,0.01)} +.btn{display:inline-block;padding:8px 10px;border-radius:8px;background:var(--accent);color:#042;cursor:pointer;border:none} +.muted{color:var(--muted);font-size:0.9rem} +.video-modal{position:fixed;inset:0;background:rgba(0,0,0,0.7);display:flex;align-items:center;justify-content:center;z-index:1200} +.video-modal .inner{width:90%;max-width:960px;background:var(--card);padding:12px;border-radius:8px} +.video-modal iframe{width:100%;height:540px;border:0;border-radius:6px} +@media(max-width:900px){.layout{flex-direction:column}.sidebar{width:100%}.video-modal iframe{height:320px}} + +/* small helpers reused */ +.small{font-size:0.9rem}