commit 79a99bf91b5824729bc9010bda109385b826527d
parent 0601f946c8e4c66270fee8d997fa312de6816b93
Author: Sunny <122193933+Sunny-JP@users.noreply.github.com>
Date: Fri, 21 Mar 2025 21:24:40 +0900
Dev 8 (#20)
* adjust loop icon
* add i18n
Diffstat:
11 files changed, 230 insertions(+), 17 deletions(-)
diff --git a/package-lock.json b/package-lock.json
@@ -13,8 +13,10 @@
"@vue-youtube/component": "^0.0.6",
"@vue-youtube/core": "^0.0.6",
"vue": "3.5.13",
+ "vue-i18n": "^11.1.2",
"vue-router": "^4.5.0",
- "vue3-cookies": "^1.0.6"
+ "vue3-cookies": "^1.0.6",
+ "vue3-flag-icons": "^0.0.3"
},
"devDependencies": {
"@vitejs/plugin-vue": "5.2.1",
@@ -495,6 +497,50 @@
"node": ">=18"
}
},
+ "node_modules/@intlify/core-base": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.1.2.tgz",
+ "integrity": "sha512-nmG512G8QOABsserleechwHGZxzKSAlggGf9hQX0nltvSwyKNVuB/4o6iFeG2OnjXK253r8p8eSDOZf8PgFdWw==",
+ "license": "MIT",
+ "dependencies": {
+ "@intlify/message-compiler": "11.1.2",
+ "@intlify/shared": "11.1.2"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ }
+ },
+ "node_modules/@intlify/message-compiler": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-11.1.2.tgz",
+ "integrity": "sha512-T/xbNDzi+Yv0Qn2Dfz2CWCAJiwNgU5d95EhhAEf4YmOgjCKktpfpiUSmLcBvK1CtLpPQ85AMMQk/2NCcXnNj1g==",
+ "license": "MIT",
+ "dependencies": {
+ "@intlify/shared": "11.1.2",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ }
+ },
+ "node_modules/@intlify/shared": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-11.1.2.tgz",
+ "integrity": "sha512-dF2iMMy8P9uKVHV/20LA1ulFLL+MKSbfMiixSmn6fpwqzvix38OIc7ebgnFbBqElvghZCW9ACtzKTGKsTGTWGA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ }
+ },
"node_modules/@jamescoyle/vue-icon": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@jamescoyle/vue-icon/-/vue-icon-0.1.2.tgz",
@@ -1143,6 +1189,12 @@
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"license": "MIT"
},
+ "node_modules/flag-icons": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/flag-icons/-/flag-icons-7.3.2.tgz",
+ "integrity": "sha512-QkaZ6Zvai8LIjx+UNAHUJ5Dhz9OLZpBDwCRWxF6YErxIcR16jTkIFm3bFu54EkvKQy4+wicW+Gm7/0631wVQyQ==",
+ "license": "MIT"
+ },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -1447,6 +1499,26 @@
}
}
},
+ "node_modules/vue-i18n": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.1.2.tgz",
+ "integrity": "sha512-MfdkdKGUHN+jkkaMT5Zbl4FpRmN7kfelJIwKoUpJ32ONIxdFhzxZiLTVaAXkAwvH3y9GmWpoiwjDqbPIkPIMFA==",
+ "license": "MIT",
+ "dependencies": {
+ "@intlify/core-base": "11.1.2",
+ "@intlify/shared": "11.1.2",
+ "@vue/devtools-api": "^6.5.0"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/kazupon"
+ },
+ "peerDependencies": {
+ "vue": "^3.0.0"
+ }
+ },
"node_modules/vue-router": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.0.tgz",
@@ -1487,6 +1559,17 @@
"dependencies": {
"vue": "^3.0.0"
}
+ },
+ "node_modules/vue3-flag-icons": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/vue3-flag-icons/-/vue3-flag-icons-0.0.3.tgz",
+ "integrity": "sha512-DtRMzdn6iFTwdOazJLMIZNMcJmNzgTOfZY88y9kfPJ6o3gJFkIJJKsBaUmynv0/rkOIX8sHnmwx3f4GgtKjy5A==",
+ "dependencies": {
+ "flag-icons": "^7.2.3"
+ },
+ "peerDependencies": {
+ "vue": "^3.3.4"
+ }
}
}
}
diff --git a/package.json b/package.json
@@ -14,8 +14,10 @@
"@vue-youtube/component": "^0.0.6",
"@vue-youtube/core": "^0.0.6",
"vue": "3.5.13",
+ "vue-i18n": "^11.1.2",
"vue-router": "^4.5.0",
- "vue3-cookies": "^1.0.6"
+ "vue3-cookies": "^1.0.6",
+ "vue3-flag-icons": "^0.0.3"
},
"devDependencies": {
"@vitejs/plugin-vue": "5.2.1",
diff --git a/src/App.vue b/src/App.vue
@@ -1,10 +1,11 @@
<script setup lang="ts">
-import { ref, onMounted, onBeforeUnmount } from "vue";
+import { ref, onMounted, onBeforeUnmount, watch } from "vue";
import Player from "./components/Player.vue";
+import FlagIcon from 'vue3-flag-icons'
+import { useI18n } from 'vue-i18n';
import { screenSaver } from "./screen-saver";
const MenuButton = ref(false);
-
const closeMenu = (event: Event) => {
const target = event.target as HTMLElement;
if (!target.closest(".menu") && !target.closest(".hamburger_btn")) {
@@ -12,7 +13,24 @@ const closeMenu = (event: Event) => {
}
};
+const { locale } = useI18n();
+const changeLanguage = (lang: string) => {
+ locale.value = lang;
+ localStorage.setItem("selectedLanguage", lang);
+};
+
+const updateBodyClass = () => {
+ document.body.className = `locale-${locale.value}`;
+};
+
+watch(locale, updateBodyClass);
+
onMounted(() => {
+ const savedLanguage = localStorage.getItem("selectedLanguage");
+ if (savedLanguage) {
+ locale.value = savedLanguage;
+ }
+ updateBodyClass();
window.addEventListener("click", closeMenu);
screenSaver();
});
@@ -35,14 +53,20 @@ onBeforeUnmount(() => {
</div>
<div class="menu" :class="{ open: MenuButton }">
<ul>
- <!-- 将来的には多言語対応する.中,韓ではそれぞれNoto sans C,Kを用いる -->
- <li><router-link to="/" @click="MenuButton = false">Top</router-link></li>
- <li><router-link to="/about" @click="MenuButton = false">About</router-link></li>
- <li><router-link to="/terms" @click="MenuButton = false">利用規約</router-link></li>
- <li><router-link to="/policy" @click="MenuButton = false">プライバシーポリシー</router-link></li>
- <li><router-link to="/enquiries" @click="MenuButton = false">お問い合わせ</router-link></li>
- <li><router-link to="/info" @click="MenuButton = false">運営者情報</router-link></li>
+ <li><router-link to="/" @click="MenuButton = false">{{ $t('menu.top') }}</router-link></li>
+ <li><router-link to="/about" @click="MenuButton = false">{{ $t('menu.about') }}</router-link></li>
+ <li><router-link to="/terms" @click="MenuButton = false">{{ $t('menu.terms') }}</router-link></li>
+ <li><router-link to="/policy" @click="MenuButton = false">{{ $t('menu.policy') }}</router-link></li>
+ <li><router-link to="/enquiries" @click="MenuButton = false">{{ $t('menu.enquiries') }}</router-link></li>
+ <li><router-link to="/info" @click="MenuButton = false">{{ $t('menu.info') }}</router-link></li>
</ul>
+ <div class="language-switcher">
+ <button class="language_btn" @click="changeLanguage('ja')"><FlagIcon code="jp" size="20" /></button>
+ <button class="language_btn" @click="changeLanguage('en')"><FlagIcon code="us" size="20" /></button>
+ <button class="language_btn" @click="changeLanguage('zh')"><FlagIcon code="cn" size="20" /></button>
+ <button class="language_btn" @click="changeLanguage('ko')"><FlagIcon code="kr" size="20" /></button>
+ </div>
+
</div>
</nav>
</header>
diff --git a/src/locales/en.json b/src/locales/en.json
@@ -0,0 +1,10 @@
+{
+ "menu": {
+ "top": "Top",
+ "about": "About",
+ "terms": "Terms of Use",
+ "policy": "Privacy Policy",
+ "enquiries": "Enquiries",
+ "info": "Operator Info"
+ }
+}+
\ No newline at end of file
diff --git a/src/locales/ja.json b/src/locales/ja.json
@@ -0,0 +1,10 @@
+{
+ "menu": {
+ "top": "Top",
+ "about": "About",
+ "terms": "利用規約",
+ "policy": "プライバシーポリシー",
+ "enquiries": "お問い合わせ",
+ "info": "運営者情報"
+ }
+}+
\ No newline at end of file
diff --git a/src/locales/ko.json b/src/locales/ko.json
@@ -0,0 +1,10 @@
+{
+ "menu": {
+ "top": "홈화면",
+ "about": "소개",
+ "terms": "이용 약관",
+ "policy": "개인정보 보호정책",
+ "enquiries": "문의",
+ "info": "운영자 정보"
+ }
+}+
\ No newline at end of file
diff --git a/src/locales/zh.json b/src/locales/zh.json
@@ -0,0 +1,10 @@
+{
+ "menu": {
+ "top": "首页",
+ "about": "关于",
+ "terms": "使用条款",
+ "policy": "隐私政策",
+ "enquiries": "查询",
+ "info": "运营者信息"
+ }
+}+
\ No newline at end of file
diff --git a/src/main.ts b/src/main.ts
@@ -1,12 +1,30 @@
import { createApp } from 'vue'
-import { createManager } from '@vue-youtube/core';
-import './style.css'
import App from './App.vue'
import router from './router'
+import { createManager } from '@vue-youtube/core';
import VueCookies from 'vue3-cookies';
+import { createI18n } from 'vue-i18n'
+import ja from './locales/ja.json';
+import en from './locales/en.json';
+import zh from './locales/zh.json';
+import ko from './locales/ko.json';
+import './style.css'
+import 'vue3-flag-icons/styles'
+
+const i18n = createI18n({
+ locale: 'ja',
+ fallbackLocale: 'en',
+ messages: {
+ ja,
+ en,
+ zh,
+ ko,
+ },
+});
const app = createApp(App)
app.use(createManager())
+app.use(i18n)
app.use(router)
app.use(VueCookies)
app.mount('#app')
\ No newline at end of file
diff --git a/src/player-style.css b/src/player-style.css
@@ -134,7 +134,7 @@
.fs_loop,
.fs_fav {
cursor: pointer;
- padding-left: clamp(2px, calc(2vw), 12px);
+ padding-left: clamp(2px, calc(3vw), 16px);
margin-top: 4px;
}
diff --git a/src/style.css b/src/style.css
@@ -1,12 +1,12 @@
@import './reset-style.css';
-@import url('https://fonts.googleapis.com/css2?family=Lekton:wght@700&family=Noto+Sans+JP:wght@100..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
+@import url('https://fonts.googleapis.com/css2?family=Lekton:wght@700&family=Noto+Sans+JP:wght@100..900&family=Noto+Sans+KR:wght@100..900&family=Noto+Sans+SC:wght@100..900&family=Noto+Sans:wght@100..900&family=Poppins&display=swap');
/* general */
body {
margin: 0px;
padding: 0px;
color: #ffffff;
- font-family: "Poppins", "Noto Sans JP", "Helvetica Neue", "Helvetica", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Meiryo", sans-serif;
+ font-family: sans-serif;
font-size: 14px;
font-weight: 400;
background: #000000;
@@ -16,6 +16,20 @@ body {
-webkit-tap-highlight-color: transparent;
}
+/* font for language */
+.locale-ja,
+.locale-en {
+ font-family: "Poppins", "Noto Sans JP", "Noto Sans", sans-serif;
+}
+
+.locale-zh {
+ font-family: "Poppins", "Noto Sans SC", "Noto Sans", sans-serif;
+}
+
+.locale-ko {
+ font-family: "Poppins", "Noto Sans KR", "Noto Sans", sans-serif;
+}
+
/* pages */
.page {
@@ -52,6 +66,28 @@ body {
/* hamburger button */
+.language-switcher {
+ width: 150px;
+ z-index: -20;
+ text-align: center;
+}
+
+.language_btn {
+ background: none;
+ width: 30px;
+ margin: 5px;
+ border: none;
+ cursor: pointer;
+ opacity: 0.7;
+ transition: 0.4s ease;
+}
+
+.language_btn:hover {
+ opacity: 1;
+}
+
+
+/* hamburger button */
.hamburger_btn {
position: fixed;
top: 0;
@@ -106,7 +142,7 @@ body {
z-index: 30;
padding: 50px 5px 5px 5px;
position: fixed;
- width: 10rem;
+ width: 160px;
height: 100vh;
top: 0;
right: 0;
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
@@ -1,2 +1,7 @@
/// <reference types="vite/client" />
declare module '@jamescoyle/vue-icon';
+declare module 'vue3-flag-icons/styles';
+declare module '*.json' {
+ const value: any;
+ export default value;
+}+
\ No newline at end of file