Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/scripts/minify.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ const cssTargets = [
const jsTargets = [
'sw.js',
'js/main.js',
'js/region-navigation.js',
'js/language-suggestion.js',
'js/calendar-reminder.js',
'js/pwa-install.js',
'js/widget-referral.js',
'js/service-worker-registration.js',
'js/main-calculator-ui.js',
'js/calculator.js',
'js/ui.js',
Expand Down
2 changes: 1 addition & 1 deletion en/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ <h3>Q. Is my weekly reward diary data saved?</h3>
<div id="toast" class="toast"></div>
</main>

<script type="module" src="../js/main.js?v=fbe8708023"></script>
<script type="module" src="../js/main.js?v=416109bf12"></script>
<script src="../js/third-party.js?v=30f1e46c0b" defer></script>

</body>
Expand Down
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ <h3>Q. ほくほくリワード日記のデータは保存されますか?</h3
<div id="toast" class="toast"></div>
</main>

<script type="module" src="js/main.js?v=fbe8708023"></script>
<script type="module" src="js/main.js?v=416109bf12"></script>
<script src="js/third-party.js?v=30f1e46c0b" defer></script>

</body>
Expand Down
58 changes: 58 additions & 0 deletions js/calendar-reminder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use strict';

import { CONFIGS, STATE, ANALYTICS, getNextFridayCalendarWindow } from './config.js';

export function bindCalendarReminderEvents() {
if (STATE.dom.downloadIcalBtn) {
STATE.dom.downloadIcalBtn.addEventListener('click', () => downloadICS());
}
if (STATE.dom.registerGoogleCalBtn) {
STATE.dom.registerGoogleCalBtn.addEventListener('click', () => {
ANALYTICS.track('calendar_reminder_added', {
region: STATE.currentRegion,
calendar_type: 'google'
});
});
}
}

// ICSファイルのダウンロードロジック
export function downloadICS() {
const config = CONFIGS[STATE.currentRegion];
const texts = config.uiText;
const summary = texts.calSubject;
const description = texts.calDetails.replace(/\n/g, '\\n');

const calendarWindow = getNextFridayCalendarWindow(STATE.currentRegion === 'US');

const icsLines = [
'BEGIN:VCALENDAR',
'VERSION:2.0',
'PRODID:-//PlayPoint//NONSGML Calendar//EN',
'BEGIN:VEVENT',
`SUMMARY:${summary}`,
`DESCRIPTION:${description}`,
`DTSTART:${calendarWindow.start}`,
`DTEND:${calendarWindow.end}`,
'RRULE:FREQ=WEEKLY;BYDAY=FR',
'SEQUENCE:0',
'STATUS:CONFIRMED',
'TRANSP:TRANSPARENT',
'END:VEVENT',
'END:VCALENDAR'
];
const icsString = icsLines.join('\r\n');
const blob = new Blob([icsString], { type: 'text/calendar;charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = texts.icsFilename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
ANALYTICS.track('calendar_reminder_added', {
region: STATE.currentRegion,
calendar_type: 'ical'
});
}
88 changes: 88 additions & 0 deletions js/language-suggestion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
'use strict';

import { STATE, CONSTANTS } from './config.js';
import {
isEnglishPath,
isKoreanPath,
isTaiwanPath,
switchRegion
} from './region-navigation.js';

export function bindLanguageSuggestionDismiss() {
if (!STATE.dom.closeLangBannerBtn) return;

STATE.dom.closeLangBannerBtn.addEventListener('click', () => {
if (STATE.dom.languageSuggestionBanner) {
STATE.dom.languageSuggestionBanner.classList.add(CONSTANTS.CLASS_HIDDEN);
}
try {
sessionStorage.setItem('playpointLangBannerClosed', 'true');
} catch (e) {
console.error("セッションストレージの書き込みに失敗しました:", e);
}
});
}

// 言語提案バナーの表示ロジック
export function checkLanguageSuggestion() {
if (!STATE.dom.languageSuggestionBanner) return;

let isClosed = false;
try {
isClosed = sessionStorage.getItem('playpointLangBannerClosed') === 'true';
} catch (e) {
console.error("セッションストレージの読み込みに失敗しました:", e);
}
if (isClosed) return;

let preferredRegion = null;
try {
preferredRegion = localStorage.getItem(CONSTANTS.STORAGE_REGION_KEY);
} catch (e) {
console.error("ローカルストレージの読み込みに失敗しました:", e);
}

if (preferredRegion) return;

const browserLang = (navigator.language || navigator.userLanguage || '').toLowerCase();

let targetRegion = null;
let messageText = '';
let buttonText = '';
let isCurrentMatch = false;

if (browserLang.startsWith('ko')) {
targetRegion = 'KR';
messageText = '한국어 버전이 있습니다!';
buttonText = '한국어로 전환';
isCurrentMatch = isKoreanPath();
} else if (browserLang.startsWith('zh-tw') || browserLang.startsWith('zh-hk')) {
targetRegion = 'TW';
messageText = '提供繁體中文版本!';
buttonText = '切換至繁體中文';
isCurrentMatch = isTaiwanPath();
} else if (browserLang.startsWith('en')) {
targetRegion = 'US';
messageText = 'English version is available!';
buttonText = 'Switch to English';
isCurrentMatch = isEnglishPath();
}

if (targetRegion && !isCurrentMatch) {
const spanEl = STATE.dom.languageSuggestionBanner.querySelector('span');
const btnEl = STATE.dom.switchToEnBtn;
if (spanEl && btnEl) {
spanEl.textContent = messageText;
btnEl.textContent = buttonText;

const newBtn = btnEl.cloneNode(true);
btnEl.parentNode.replaceChild(newBtn, btnEl);
STATE.dom.switchToEnBtn = newBtn;

newBtn.addEventListener('click', () => {
switchRegion(targetRegion);
});
}
STATE.dom.languageSuggestionBanner.classList.remove(CONSTANTS.CLASS_HIDDEN);
}
}
Loading