Skip to content

#315 🎇 Happy Chinese New Year!#316

Merged
thekingofcity merged 6 commits intomainfrom
copilot/add-cny-notification-banner
Feb 10, 2026
Merged

#315 🎇 Happy Chinese New Year!#316
thekingofcity merged 6 commits intomainfrom
copilot/add-cny-notification-banner

Conversation

Copy link
Contributor

Copilot AI commented Feb 10, 2026

During CNY 2026 (Feb 15-23 UTC+8), show a festival notification and temporarily unlock RMP_CLOUD for all logged-in users.

Changes

  • src/util/cny-2026.ts — Network time-based period checker using external time servers (worldtimeapi.org, timeapi.io). Returns epoch on failure to prevent local clock manipulation from granting free access.
  • src/components/app-root.tsx — Two new effects:
    • Show translated CNY notification once per session (only during promotional period)
    • Enable RMP_CLOUD subscription for logged-in users, re-checked every 15 minutes
  • Translation files (en, zh-Hans, zh-Hant, ja, ko) — Added happyChineseNewYear key with localized messages
  • src/util/cny-2026.test.ts — Period boundary tests, time server response parsing, fallback behavior

Subscription unlock approach

// Sets RMP_CLOUD expiry to match the CNY period end
dispatch(setActiveSubscriptions({
    ...activeSubscriptions,
    RMP_CLOUD: '2026-02-23T15:59:59Z',
}));

ActiveSubscriptions.RMP_CLOUD uses DateTimeString (not boolean as in the reference project), so the promotion sets it to the period end timestamp.

Original prompt

This section details on the original issue you should resolve

<issue_title>Happy Chinese New Year 🎇</issue_title>
<issue_description>今年,在过年的特殊期间,我希望一部分原先需要订阅的功能限时免费开放给所有登录用户

需要在首页添加活动通知,别忘了添加各语言欢度春节的翻译

参考以下代码实现逻辑,注意这是另一个项目的修改,不能直接套用,但是关键的alert使用和翻译可以参考

diff --git a/src/components/app-root.tsx b/src/components/app-root.tsx
index b996e168..995b0b20 100644
--- a/src/components/app-root.tsx
+++ b/src/components/app-root.tsx
@@ -5,9 +5,7 @@ import React from 'react';
 import { useTranslation } from 'react-i18next';
 import { LocalStorageKey } from '../constants/constants';
 import { useRootDispatch, useRootSelector } from '../redux';
-import { setActiveSubscriptions } from '../redux/account/account-slice';
-import { closePaletteAppClip, onPaletteAppClipEmit, setGlobalAlert } from '../redux/runtime/runtime-slice';
-import { checkCNY2026Period, CNY_CHECK_INTERVAL } from '../util/cny-2026';
+import { closePaletteAppClip, onPaletteAppClipEmit } from '../redux/runtime/runtime-slice';
 
 const PageHeader = React.lazy(() => import('./page-header/page-header'));
 const ToolsPanel = React.lazy(() => import('./panels/tools/tools'));
@@ -20,12 +18,7 @@ export default function AppRoot() {
     const {
         paletteAppClip: { input },
     } = useRootSelector(state => state.runtime);
-    const accountState = useRootSelector(state => state.account.state);
-    const activeSubscriptions = useRootSelector(state => state.account.activeSubscriptions);
-    const {
-        t,
-        i18n: { language: lang },
-    } = useTranslation();
+    const { t } = useTranslation();
 
     const [isShowRMTMessage, setIsShowRMTMessage] = React.useState(false);
 
@@ -35,61 +28,6 @@ export default function AppRoot() {
         }
     }, []);
 
-    // CNY 2026 promotion: Check if we're in the promotional period and unlock RMP_CLOUD
-    const [cnyNotificationShown, setCnyNotificationShown] = React.useState(false);
-
-    // Show CNY notification once per session (always, regardless of login or period)
-    React.useEffect(() => {
-        if (!cnyNotificationShown) {
-            const timeoutId = setTimeout(() => {
-                dispatch(
-                    setGlobalAlert({
-                        status: 'warning',
-                        message: t('happyChineseNewYear'),
-                        url: `https://railmapgen.org/rmt-blog/${lang}/rmg-7th-newyear`,
-                    })
-                );
-                setCnyNotificationShown(true);
-            }, 1000);
-            return () => clearTimeout(timeoutId);
-        }
-    }, [cnyNotificationShown, dispatch, t]);
-
-    // Check CNY period and enable RMP_CLOUD for logged-in users
-    React.useEffect(() => {
-        let isActive = true;
-
-        const checkAndApplyCNYPromotion = async () => {
-            // Check login status inside to handle users logging in during use
-            const isLoggedIn = accountState === 'free' || accountState === 'subscriber';
-            if (!isLoggedIn || !isActive) return;
-
-            const isInPeriod = await checkCNY2026Period();
-            if (isInPeriod && isActive) {
-                // Enable RMP_CLOUD for all logged-in users during CNY period
-                if (!activeSubscriptions.RMP_CLOUD) {
-                    dispatch(
-                        setActiveSubscriptions({
-                            ...activeSubscriptions,
-                            RMP_CLOUD: true,
-                        })
-                    );
-                }
-            }
-        };
-
-        // Check immediately on mount
-        checkAndApplyCNYPromotion();
-
-        // Check every 15 minutes
-        const intervalId = setInterval(checkAndApplyCNYPromotion, CNY_CHECK_INTERVAL);
-
-        return () => {
-            isActive = false;
-            clearInterval(intervalId);
-        };
-    }, [accountState, activeSubscriptions, dispatch]);
-
     return (
         <RmgThemeProvider>
             <RmgWindow>
diff --git a/src/i18n/translations/en.json b/src/i18n/translations/en.json
index e0a1a62c..3e06fd79 100644
--- a/src/i18n/translations/en.json
+++ b/src/i18n/translations/en.json
@@ -950,7 +950,5 @@
         "flipDiagonal135": "Flip across 135° line"
     },
 
-    "localStorageQuotaExceeded": "Local storage limit reached. Unable to save new changes.",
-
-    "happyChineseNewYear": "🎇 Happy Chinese New Year 2026! Cloud features are free for all users during the festival period (Feb 15-23)."
+    "localStorageQuotaExceeded": "Local storage limit reached. Unable to save new changes."
 }
diff --git a/src/i18n/translations/ja.json b/src/i18n/translations/ja.json
index 78acedbb..3f45fc9e 100644
--- a/src/i18n/translations/ja.json
+++ b/src/i18n/translations/ja.json
@@ -951,7 +951,5 @@
         "flipDiagonal135": "135° 線で反転"
     },
 
-    "localStorageQuotaExceeded": "ローカルストレージの上限に達しました。新しい変更は保存できません。",
-
-    "happyChineseNewYear": "🎇 旧正月おめでとうございます!2026年春節期間中(2月15日~23日)、クラウド機能が全ユーザーに無料で開放されます。"
+    "loc...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes railmapgen/railmapgen.github.io#315

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for you](https://github.com/railmapgen/railmapgen.github.io/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits February 10, 2026 12:43
…ations

Co-authored-by: thekingofcity <3353040+thekingofcity@users.noreply.github.com>
Co-authored-by: thekingofcity <3353040+thekingofcity@users.noreply.github.com>
Copilot AI changed the title [WIP] Add Chinese New Year notification for logged-in users Add Chinese New Year 2026 promotional period: notification + RMP_CLOUD unlock Feb 10, 2026
Copilot AI requested a review from thekingofcity February 10, 2026 12:46
@thekingofcity thekingofcity marked this pull request as ready for review February 10, 2026 13:15
Copy link
Member

@thekingofcity thekingofcity left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@thekingofcity thekingofcity changed the title Add Chinese New Year 2026 promotional period: notification + RMP_CLOUD unlock #315 🎇 Happy Chinese New Year! Feb 10, 2026
@thekingofcity thekingofcity linked an issue Feb 10, 2026 that may be closed by this pull request
@thekingofcity thekingofcity merged commit 59e790b into main Feb 10, 2026
1 check passed
@thekingofcity thekingofcity deleted the copilot/add-cny-notification-banner branch February 10, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🎇 Happy Chinese New Year!

2 participants

Comments