Lashtw commited on
Commit
adc7e5a
·
verified ·
1 Parent(s): b4dce81

Upload 3 files

Browse files
.gitattributes CHANGED
@@ -36,3 +36,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
36
  m1.GIF filter=lfs diff=lfs merge=lfs -text
37
  m4.GIF filter=lfs diff=lfs merge=lfs -text
38
  pigod.png filter=lfs diff=lfs merge=lfs -text
 
 
 
36
  m1.GIF filter=lfs diff=lfs merge=lfs -text
37
  m4.GIF filter=lfs diff=lfs merge=lfs -text
38
  pigod.png filter=lfs diff=lfs merge=lfs -text
39
+ Sacred[[:space:]]Dawn[[:space:]]Ascending.mp3 filter=lfs diff=lfs merge=lfs -text
40
+ Singularity[[:space:]]Drift.mp3 filter=lfs diff=lfs merge=lfs -text
Sacred Dawn Ascending.mp3 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:550d42b62277e1e12b680279fefec3a34802345dafd532776a68c7c230505344
3
+ size 4947564
Singularity Drift.mp3 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e5a59f965320ff9286c27200d899e4e6a6a96c72cf6a036f861d58b239012721
3
+ size 9653300
index.html CHANGED
@@ -274,7 +274,9 @@
274
  <!-- Excel 匯入面板 -->
275
  <div class="glass-panel" style="margin-bottom: 2rem; background: rgba(0,0,0,0.4); border: 1px dashed var(--primary);">
276
  <h2 style="color: var(--accent); margin-top: 0; font-size: 1.8rem; text-shadow: 0 2px 4px rgba(0,0,0,0.5);">📁 賜下預先名冊 (Excel 匯入)</h2>
277
- <p style="color: #d1d5db; margin-bottom: 1rem;">可先從 Excel 匯入檔案自動尋找第一名。檔案需至少兩欄:第一欄姓名、第二欄數字(不含標頭第一行)。</p>
 
 
278
  <input type="file" id="excelFile" accept=".xlsx, .xls" style="color: white; margin-bottom: 1rem; width: 100%; padding: 0.5rem; border: 1px solid rgba(255,255,255,0.2); border-radius: 0.5rem; background: rgba(0,0,0,0.3);"/>
279
  <div style="display: flex; gap: 1rem; align-items: center; flex-wrap: wrap;">
280
  <button class="btn" id="importBtn" style="width: auto; padding: 0.75rem 1.5rem; font-size: 1.2rem;">匯入並預先請求神諭</button>
@@ -288,14 +290,19 @@
288
  </div>
289
 
290
  <div class="glass-panel" style="margin-bottom: 2rem;">
291
- <div style="display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 1.5rem; border-bottom: 1px solid rgba(255,255,255,0.1); padding-bottom: 1rem;">
292
  <div>
293
  <h2 style="margin: 0; font-size: 1.8rem; text-shadow: 0 2px 4px rgba(0,0,0,0.5);">👨‍🎓 信徒等待區</h2>
294
  <p style="margin: 0.5rem 0 0 0; color: #d1d5db;">目前已收到 <strong id="studentCount" style="color: white; font-size: 1.2rem;">0</strong> 份幸運數字</p>
295
  </div>
296
- <button class="btn" id="searchApiBtn" style="width: auto; padding: 1rem 3rem; font-size: 1.5rem;">
297
- 祈求眷顧!開始搜尋
298
- </button>
 
 
 
 
 
299
  </div>
300
  <!-- 卡片列表動態產生於此 -->
301
  <div class="students-grid" id="studentsGrid"></div>
@@ -329,6 +336,73 @@
329
  <script type="module">
330
  import { initializeApp } from "https://www.gstatic.com/firebasejs/10.8.1/firebase-app.js";
331
  import { getFirestore, doc, collection, onSnapshot, query, orderBy, getDocs, limit, setDoc, deleteDoc, updateDoc, where } from "https://www.gstatic.com/firebasejs/10.8.1/firebase-firestore.js";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
 
333
  const firebaseConfig = {
334
  apiKey: "AIzaSyA2fxxaGAdWSR_QOH2Hm92kttGZmLDH8-w",
@@ -408,6 +482,7 @@
408
  // --- 0. 開場動畫點擊 ---
409
  const introScreen = document.getElementById('introScreen');
410
  introScreen.addEventListener('click', () => {
 
411
  introScreen.style.opacity = '0';
412
  setTimeout(() => {
413
  introScreen.style.display = 'none';
@@ -512,8 +587,13 @@
512
  text: studentUrl, width: 300, height: 300, colorDark : "#000000", colorLight : "#ffffff", correctLevel : QRCode.CorrectLevel.L
513
  });
514
 
515
- document.getElementById('qrcodeArea').onclick = () => document.getElementById('qrModal').style.display = 'flex';
 
 
 
516
  document.getElementById('qrModal').onclick = () => document.getElementById('qrModal').style.display = 'none';
 
 
517
 
518
  // 啟動資料庫監聽
519
  if(isTestMode) {
@@ -900,6 +980,25 @@
900
  // 按數字大小從大排到小 (越深的人排名越高)
901
  finalPool.sort((a, b) => b.resultVal - a.resultVal);
902
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
903
  drawPodium(finalPool);
904
 
905
  if(finalPool.length > 0) {
@@ -939,6 +1038,7 @@
939
  }
940
 
941
  function drawPodium(validData) {
 
942
  const podiumArea = document.getElementById('podiumArea');
943
  podiumArea.innerHTML = "";
944
 
 
274
  <!-- Excel 匯入面板 -->
275
  <div class="glass-panel" style="margin-bottom: 2rem; background: rgba(0,0,0,0.4); border: 1px dashed var(--primary);">
276
  <h2 style="color: var(--accent); margin-top: 0; font-size: 1.8rem; text-shadow: 0 2px 4px rgba(0,0,0,0.5);">📁 賜下預先名冊 (Excel 匯入)</h2>
277
+ <p style="color: #d1d5db; margin-bottom: 1rem;">可先從 Excel 匯入檔案自動尋找第一名。檔案需至少兩欄:第一欄姓名、第二欄數字(不含標頭第一行)。
278
+ <a href="https://docs.google.com/spreadsheets/d/11hXMTLU7rPeu9h6B-BNGF6esFWEXJSGo/edit?usp=drive_link&ouid=115947803934724851078&rtpof=true&sd=true" target="_blank" style="color: var(--accent); text-decoration: underline; margin-left: 0.5rem; white-space: nowrap;">📥 下載範例檔案</a>
279
+ </p>
280
  <input type="file" id="excelFile" accept=".xlsx, .xls" style="color: white; margin-bottom: 1rem; width: 100%; padding: 0.5rem; border: 1px solid rgba(255,255,255,0.2); border-radius: 0.5rem; background: rgba(0,0,0,0.3);"/>
281
  <div style="display: flex; gap: 1rem; align-items: center; flex-wrap: wrap;">
282
  <button class="btn" id="importBtn" style="width: auto; padding: 0.75rem 1.5rem; font-size: 1.2rem;">匯入並預先請求神諭</button>
 
290
  </div>
291
 
292
  <div class="glass-panel" style="margin-bottom: 2rem;">
293
+ <div style="display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 1.5rem; border-bottom: 1px solid rgba(255,255,255,0.1); padding-bottom: 1rem; flex-wrap: wrap; gap: 1rem;">
294
  <div>
295
  <h2 style="margin: 0; font-size: 1.8rem; text-shadow: 0 2px 4px rgba(0,0,0,0.5);">👨‍🎓 信徒等待區</h2>
296
  <p style="margin: 0.5rem 0 0 0; color: #d1d5db;">目前已收到 <strong id="studentCount" style="color: white; font-size: 1.2rem;">0</strong> 份幸運數字</p>
297
  </div>
298
+ <div style="display: flex; gap: 1rem;">
299
+ <button class="btn" id="restartMusicBtn" style="width: auto; padding: 1rem 1.5rem; font-size: 1.2rem; background: rgba(59, 130, 246, 0.8); border-color: rgba(96, 165, 250, 0.5); color: white;" title="返回等候階段,重新播放背景音樂">
300
+ 🎵 重啟等候音樂
301
+ </button>
302
+ <button class="btn" id="searchApiBtn" style="width: auto; padding: 1rem 3rem; font-size: 1.5rem;">
303
+ ✨ 祈求眷顧!開始搜尋
304
+ </button>
305
+ </div>
306
  </div>
307
  <!-- 卡片列表動態產生於此 -->
308
  <div class="students-grid" id="studentsGrid"></div>
 
336
  <script type="module">
337
  import { initializeApp } from "https://www.gstatic.com/firebasejs/10.8.1/firebase-app.js";
338
  import { getFirestore, doc, collection, onSnapshot, query, orderBy, getDocs, limit, setDoc, deleteDoc, updateDoc, where } from "https://www.gstatic.com/firebasejs/10.8.1/firebase-firestore.js";
339
+
340
+ // --- 音樂資源設定 ---
341
+ const audioDrift = new Audio('Singularity Drift.mp3');
342
+ audioDrift.loop = true;
343
+ audioDrift.volume = 0;
344
+
345
+ const audioDawn = new Audio('Sacred Dawn Ascending.mp3');
346
+ audioDawn.loop = true;
347
+ audioDawn.volume = 0;
348
+
349
+ let fadeInterval = null;
350
+
351
+ function playDrift() {
352
+ clearInterval(fadeInterval);
353
+ audioDrift.play().catch(e => console.warn("Audio play error:", e));
354
+
355
+ fadeInterval = setInterval(() => {
356
+ let driftVol = audioDrift.volume;
357
+ let dawnVol = audioDawn.volume;
358
+ let done = true;
359
+
360
+ if (dawnVol > 0.05) {
361
+ audioDawn.volume = Math.max(0, dawnVol - 0.05);
362
+ done = false;
363
+ } else {
364
+ audioDawn.volume = 0;
365
+ if(!audioDawn.paused) audioDawn.pause();
366
+ }
367
+
368
+ if (driftVol < 0.95) {
369
+ audioDrift.volume = Math.min(1, driftVol + 0.05);
370
+ done = false;
371
+ } else {
372
+ audioDrift.volume = 1;
373
+ }
374
+
375
+ if (done) clearInterval(fadeInterval);
376
+ }, 100);
377
+ }
378
+
379
+ function playDawn() {
380
+ clearInterval(fadeInterval);
381
+ audioDawn.play().catch(e => console.warn("Audio play error:", e));
382
+
383
+ fadeInterval = setInterval(() => {
384
+ let driftVol = audioDrift.volume;
385
+ let dawnVol = audioDawn.volume;
386
+ let done = true;
387
+
388
+ if (driftVol > 0.05) {
389
+ audioDrift.volume = Math.max(0, driftVol - 0.05);
390
+ done = false;
391
+ } else {
392
+ audioDrift.volume = 0;
393
+ if(!audioDrift.paused) audioDrift.pause();
394
+ }
395
+
396
+ if (dawnVol < 0.95) {
397
+ audioDawn.volume = Math.min(1, dawnVol + 0.05);
398
+ done = false;
399
+ } else {
400
+ audioDawn.volume = 1;
401
+ }
402
+
403
+ if (done) clearInterval(fadeInterval);
404
+ }, 100);
405
+ }
406
 
407
  const firebaseConfig = {
408
  apiKey: "AIzaSyA2fxxaGAdWSR_QOH2Hm92kttGZmLDH8-w",
 
482
  // --- 0. 開場動畫點擊 ---
483
  const introScreen = document.getElementById('introScreen');
484
  introScreen.addEventListener('click', () => {
485
+ playDrift(); // 🎵 開始播放背景音樂
486
  introScreen.style.opacity = '0';
487
  setTimeout(() => {
488
  introScreen.style.display = 'none';
 
587
  text: studentUrl, width: 300, height: 300, colorDark : "#000000", colorLight : "#ffffff", correctLevel : QRCode.CorrectLevel.L
588
  });
589
 
590
+ document.getElementById('qrcodeArea').onclick = () => {
591
+ document.getElementById('qrModal').style.display = 'flex';
592
+ playDrift(); // 自動重新播放等候音樂 (第二階段掃碼時)
593
+ };
594
  document.getElementById('qrModal').onclick = () => document.getElementById('qrModal').style.display = 'none';
595
+ // 手動按鈕重新播放音樂
596
+ document.getElementById('restartMusicBtn').onclick = () => playDrift();
597
 
598
  // 啟動資料庫監聽
599
  if(isTestMode) {
 
980
  // 按數字大小從大排到小 (越深的人排名越高)
981
  finalPool.sort((a, b) => b.resultVal - a.resultVal);
982
 
983
+ // 排列名次並將最終總排名推播至 Firebase 讓學生端更新
984
+ let currentRank = 1;
985
+ for (let i = 0; i < finalPool.length; i++) {
986
+ // 若分數與前一名不同,名次改為目前人數順序 (並列名次處理)
987
+ if (i > 0 && finalPool[i].resultVal < finalPool[i-1].resultVal) {
988
+ currentRank = i + 1;
989
+ }
990
+ finalPool[i].rank = currentRank;
991
+
992
+ // 若非 Excel 資料 (即現場真實手機連線資料),回寫 Firebase
993
+ if (!finalPool[i].id.startsWith('excel_') && !isTestMode) {
994
+ try {
995
+ updateDoc(doc(db, "rooms", currentRoom, "students", finalPool[i].id), {
996
+ rank: currentRank
997
+ });
998
+ } catch(e) {}
999
+ }
1000
+ }
1001
+
1002
  drawPodium(finalPool);
1003
 
1004
  if(finalPool.length > 0) {
 
1038
  }
1039
 
1040
  function drawPodium(validData) {
1041
+ playDawn(); // 🎵 結果出爐,切換為 Sacred Dawn Ascending.mp3 音樂
1042
  const podiumArea = document.getElementById('podiumArea');
1043
  podiumArea.innerHTML = "";
1044