Lashtw commited on
Commit
98c4e5f
·
verified ·
1 Parent(s): 66cf72a

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +53 -5
index.html CHANGED
@@ -8,6 +8,8 @@
8
  <script src="https://cdn.tailwindcss.com"></script>
9
  <!-- 載入彩帶效果庫 -->
10
  <script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.2/dist/confetti.browser.min.js"></script>
 
 
11
  <style>
12
  /* 定義閃卡的翻轉效果 */
13
  .flip-container {
@@ -79,6 +81,12 @@
79
  opacity: 0;
80
  transform: translateX(100%);
81
  }
 
 
 
 
 
 
82
  </style>
83
  </head>
84
  <body class="bg-gray-50 min-h-screen flex flex-col items-center p-4 sm:p-8 font-sans">
@@ -343,7 +351,7 @@
343
  </label>
344
  </div>
345
 
346
- <button id="generate-link-btn" class="w-full mb-4 bg-indigo-600 text-white font-bold py-3 rounded-lg hover:bg-indigo-700 transition-colors">
347
  產生分享連結
348
  </button>
349
 
@@ -354,6 +362,7 @@
354
  <button id="copy-link-btn" class="px-6 py-3 bg-violet-600 text-white rounded-lg hover:bg-violet-700 shrink-0">複製</button>
355
  </div>
356
  <p id="copy-feedback" class="text-green-600 text-sm h-5 mt-2 text-center font-semibold"></p>
 
357
  </div>
358
 
359
  <div class="flex justify-end mt-4">
@@ -487,6 +496,7 @@
487
  const copyLinkBtn = document.getElementById('copy-link-btn');
488
  const copyFeedback = document.getElementById('copy-feedback');
489
  const closeShareModalBtn = document.getElementById('close-share-modal-btn');
 
490
  const confirmClearModal = document.getElementById('confirm-clear-modal');
491
  const cancelClearBtn = document.getElementById('cancel-clear-btn');
492
  const confirmClearBtn = document.getElementById('confirm-clear-btn');
@@ -1020,6 +1030,21 @@
1020
  });
1021
  };
1022
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1023
  // --- 事件監聽 ---
1024
  document.querySelectorAll('.mode-btn[data-mode]').forEach(btn => {
1025
  btn.addEventListener('click', () => setupLearningView(btn.dataset.mode));
@@ -1041,7 +1066,7 @@
1041
  nextBtn.addEventListener('click', () => { if (currentCardIndex < wordsForCurrentMode.length - 1) { currentCardIndex++; displayCard(); }});
1042
  quizForm.addEventListener('submit', (e) => { e.preventDefault(); checkAnswer(); });
1043
  speakBtn.addEventListener('click', (e) => { e.stopPropagation(); const word = getCurrentWordToSpeak(); if(word) speakWord(word, 0.75); });
1044
- speakSlowBtn.addEventListener('click', (e) => { e.stopPropagation(); const word = getCurrentWordToSpeak(); if(word) speakWord(word, 0.2); });
1045
  hintBtn.addEventListener('click', () => {
1046
  const card = currentMode === 'speed' ? currentSpeedCard : quizQueue[0];
1047
  if (!card) return;
@@ -1099,10 +1124,16 @@
1099
  shareResultContainer.classList.add('hidden');
1100
  shareLinkInput.value = '';
1101
  copyFeedback.textContent = '';
 
 
 
1102
  shareModal.classList.remove('hidden');
1103
  });
1104
 
1105
- generateLinkBtn.addEventListener('click', () => {
 
 
 
1106
  try {
1107
  const wordsString = JSON.stringify(words);
1108
  const base64Words = btoa(unescape(encodeURIComponent(wordsString)));
@@ -1124,12 +1155,29 @@
1124
  }
1125
  }
1126
 
1127
- shareLinkInput.value = url.toString();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1128
  shareResultContainer.classList.remove('hidden');
1129
 
1130
  } catch (error) {
1131
  console.error("產生分享連結時發生錯誤:", error);
1132
- alert("產生分享連結時發生錯誤,可能是單字列表過大。");
 
 
 
1133
  }
1134
  });
1135
 
 
8
  <script src="https://cdn.tailwindcss.com"></script>
9
  <!-- 載入彩帶效果庫 -->
10
  <script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.2/dist/confetti.browser.min.js"></script>
11
+ <!-- 載入 QR Code 產生器 -->
12
+ <script src="https://cdn.jsdelivr.net/npm/qrcode-generator/qrcode.js"></script>
13
  <style>
14
  /* 定義閃卡的翻轉效果 */
15
  .flip-container {
 
81
  opacity: 0;
82
  transform: translateX(100%);
83
  }
84
+ #qrcode-container img {
85
+ margin: auto;
86
+ border: 6px solid white;
87
+ border-radius: 10px;
88
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
89
+ }
90
  </style>
91
  </head>
92
  <body class="bg-gray-50 min-h-screen flex flex-col items-center p-4 sm:p-8 font-sans">
 
351
  </label>
352
  </div>
353
 
354
+ <button id="generate-link-btn" class="w-full mb-4 bg-indigo-600 text-white font-bold py-3 rounded-lg hover:bg-indigo-700 transition-colors disabled:bg-indigo-400">
355
  產生分享連結
356
  </button>
357
 
 
362
  <button id="copy-link-btn" class="px-6 py-3 bg-violet-600 text-white rounded-lg hover:bg-violet-700 shrink-0">複製</button>
363
  </div>
364
  <p id="copy-feedback" class="text-green-600 text-sm h-5 mt-2 text-center font-semibold"></p>
365
+ <div id="qrcode-container" class="mt-4 flex justify-center"></div>
366
  </div>
367
 
368
  <div class="flex justify-end mt-4">
 
496
  const copyLinkBtn = document.getElementById('copy-link-btn');
497
  const copyFeedback = document.getElementById('copy-feedback');
498
  const closeShareModalBtn = document.getElementById('close-share-modal-btn');
499
+ const qrcodeContainer = document.getElementById('qrcode-container');
500
  const confirmClearModal = document.getElementById('confirm-clear-modal');
501
  const cancelClearBtn = document.getElementById('cancel-clear-btn');
502
  const confirmClearBtn = document.getElementById('confirm-clear-btn');
 
1030
  });
1031
  };
1032
 
1033
+ const generateQRCode = (text) => {
1034
+ qrcodeContainer.innerHTML = '';
1035
+ try {
1036
+ const typeNumber = 4;
1037
+ const errorCorrectionLevel = 'L';
1038
+ const qr = qrcode(typeNumber, errorCorrectionLevel);
1039
+ qr.addData(text);
1040
+ qr.make();
1041
+ qrcodeContainer.innerHTML = qr.createImgTag(6, 12);
1042
+ } catch(e) {
1043
+ console.error("QR Code generation failed:", e);
1044
+ qrcodeContainer.textContent = 'QR碼產生失敗,網址可能過長。';
1045
+ }
1046
+ };
1047
+
1048
  // --- 事件監聽 ---
1049
  document.querySelectorAll('.mode-btn[data-mode]').forEach(btn => {
1050
  btn.addEventListener('click', () => setupLearningView(btn.dataset.mode));
 
1066
  nextBtn.addEventListener('click', () => { if (currentCardIndex < wordsForCurrentMode.length - 1) { currentCardIndex++; displayCard(); }});
1067
  quizForm.addEventListener('submit', (e) => { e.preventDefault(); checkAnswer(); });
1068
  speakBtn.addEventListener('click', (e) => { e.stopPropagation(); const word = getCurrentWordToSpeak(); if(word) speakWord(word, 0.75); });
1069
+ speakSlowBtn.addEventListener('click', (e) => { e.stopPropagation(); const word = getCurrentWordToSpeak(); if(word) speakWord(word, 0.35); });
1070
  hintBtn.addEventListener('click', () => {
1071
  const card = currentMode === 'speed' ? currentSpeedCard : quizQueue[0];
1072
  if (!card) return;
 
1124
  shareResultContainer.classList.add('hidden');
1125
  shareLinkInput.value = '';
1126
  copyFeedback.textContent = '';
1127
+ qrcodeContainer.innerHTML = '';
1128
+ generateLinkBtn.textContent = '產生分享連結';
1129
+ generateLinkBtn.disabled = false;
1130
  shareModal.classList.remove('hidden');
1131
  });
1132
 
1133
+ generateLinkBtn.addEventListener('click', async () => {
1134
+ generateLinkBtn.textContent = '產生中...';
1135
+ generateLinkBtn.disabled = true;
1136
+
1137
  try {
1138
  const wordsString = JSON.stringify(words);
1139
  const base64Words = btoa(unescape(encodeURIComponent(wordsString)));
 
1155
  }
1156
  }
1157
 
1158
+ const longUrl = url.toString();
1159
+
1160
+ // 使用TinyURL API縮短網址
1161
+ const response = await fetch(`https://tinyurl.com/api-create.php?url=${encodeURIComponent(longUrl)}`);
1162
+ if (response.ok) {
1163
+ const shortUrl = await response.text();
1164
+ shareLinkInput.value = shortUrl;
1165
+ generateQRCode(shortUrl);
1166
+ } else {
1167
+ // 如果API失敗,則退回使用長網址
1168
+ shareLinkInput.value = longUrl;
1169
+ generateQRCode(longUrl);
1170
+ copyFeedback.textContent = '縮短網址失敗,已產生原始連結。';
1171
+ }
1172
+
1173
  shareResultContainer.classList.remove('hidden');
1174
 
1175
  } catch (error) {
1176
  console.error("產生分享連結時發生錯誤:", error);
1177
+ alert("產生分享連結時發生錯誤,可能是網路問題或單字列表過大。");
1178
+ } finally {
1179
+ generateLinkBtn.textContent = '重新產生';
1180
+ generateLinkBtn.disabled = false;
1181
  }
1182
  });
1183