mirror of
https://github.com/hpware/news-analyze.git
synced 2025-06-23 15:51:01 +08:00
feat: enhance typography with new font sources, update footer layout, and improve navigation structure
This commit is contained in:
parent
7c7601a38b
commit
d773473eb0
2
app.vue
2
app.vue
@ -1,6 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import "bootstrap-icons/font/bootstrap-icons.css";
|
||||
import "animate.css";
|
||||
import "@fontsource/fira-sans";
|
||||
import '@fontsource-variable/noto-sans-tc';
|
||||
const { t } = useI18n();
|
||||
</script>
|
||||
<template>
|
||||
|
9
bun.lock
9
bun.lock
@ -4,6 +4,9 @@
|
||||
"": {
|
||||
"name": "nuxt-app",
|
||||
"dependencies": {
|
||||
"@fontsource-variable/noto-sans-tc": "^5.2.5",
|
||||
"@fontsource/fira-code": "^5.2.6",
|
||||
"@fontsource/fira-sans": "^5.2.5",
|
||||
"@heroicons/vue": "^2.2.0",
|
||||
"@nuxt/image": "1.10.0",
|
||||
"@nuxtjs/i18n": "9.5.4",
|
||||
@ -176,6 +179,12 @@
|
||||
|
||||
"@fastify/busboy": ["@fastify/busboy@3.1.1", "", {}, "sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw=="],
|
||||
|
||||
"@fontsource-variable/noto-sans-tc": ["@fontsource-variable/noto-sans-tc@5.2.5", "", {}, "sha512-oaAn5hkLxraNBOWuiqyJ6+t1SmQ9Sszmcs+wJpmAmUO/1dsaHjDU5HXEjutvPpucqVeqdvVNr/kHRx+ghdiPeA=="],
|
||||
|
||||
"@fontsource/fira-code": ["@fontsource/fira-code@5.2.6", "", {}, "sha512-wCkIpPm0BqlkCPLYeY4Vui96ODmVUV0/GpEe3OfJ4v8EJn/BF2SlyxvarFsTs1CKiGjrO2cXlIZbBrKi9F+hUQ=="],
|
||||
|
||||
"@fontsource/fira-sans": ["@fontsource/fira-sans@5.2.5", "", {}, "sha512-N+GrTGOTIeYE/Wi5tY0RAnc1Tl3ddCdwfZQncvA1zH/lOpKerj9ZS5nfniSXDZ9wrXFRdWTH7anyrRDc+cMpCg=="],
|
||||
|
||||
"@heroicons/vue": ["@heroicons/vue@2.2.0", "", { "peerDependencies": { "vue": ">= 3" } }, "sha512-G3dbSxoeEKqbi/DFalhRxJU4mTXJn7GwZ7ae8NuEQzd1bqdd0jAbdaBZlHPcvPD2xI1iGzNVB4k20Un2AguYPw=="],
|
||||
|
||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||
|
@ -1,9 +1,12 @@
|
||||
<template>
|
||||
<div
|
||||
class="flex flex-row justify-center align-center text-center absolute inset-x-0"
|
||||
class="flex flex-col justify-center align-center text-center absolute inset-x-0"
|
||||
>
|
||||
<span class="text-xs m-4"
|
||||
>{{ new Date().getFullYear() }} © 吳元皓</span
|
||||
<span class="text-sm m-4 mb-0 text-center align-center justify-center"
|
||||
>{{ new Date().getFullYear() }} © yh</span
|
||||
>
|
||||
<span class="text-xs mt-0 m-2 text-center align-center justify-center">
|
||||
Inspired by Ground.News
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -1,9 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { gsap } from "gsap";
|
||||
import { ScrambleTextPlugin } from "gsap/dist/ScrambleTextPlugin";
|
||||
gsap.registerPlugin(ScrambleTextPlugin);
|
||||
|
||||
const { t, locale, locales } = useI18n();
|
||||
const localePath = useLocalePath();
|
||||
const switchLocalePath = useSwitchLocalePath();
|
||||
|
||||
const dropdownOpen = ref(false);
|
||||
@ -17,39 +14,32 @@ const toggleDropdown = () => {
|
||||
dropdownOpen.value = !dropdownOpen.value;
|
||||
};
|
||||
|
||||
const runAnimation = () => {
|
||||
gsap.to(title.value, {
|
||||
duration: 1,
|
||||
scrambleText: "BlindSpec",
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<!--Spent too much time trying to set a Navbar....-->
|
||||
<div
|
||||
class="fixed top-0 inset-x-0 bg-[#81611a]/70 backdrop-blur-sm h-[55px] flex align-center flex-row text-white pl-4 pt-2 gap-x-5 justify-between z-50 rounded-3xl m-2"
|
||||
class="fixed top-0 inset-x-0 bg-[#81611a]/70 backdrop-blur-sm h-[55px] flex align-center items-center flex-row text-white pl-4 gap-x-5 justify-between z-50 rounded-3xl m-2"
|
||||
>
|
||||
<div class="text-3xl text-bold">
|
||||
<!--Use mouseenter instead of hover-->
|
||||
<a href="/" @mouseenter="runAnimation" ref="title"> BlindSpec </a>
|
||||
<NuxtLink :to="localePath('home')" ref="title">BlindSpec</NuxtLink>
|
||||
</div>
|
||||
<div class="text-[0.9em] text-center align-center">
|
||||
<a
|
||||
href="/"
|
||||
<div class="text-[0.9em] left-1/2 absolute transform -translate-x-1/2 space-x-4 items-center">
|
||||
<NuxtLink
|
||||
:to="localePath('home')"
|
||||
class="hover:text-blue-500 cursor-pointer transiton-all duration-100"
|
||||
>{{ t("nav.home") }}</a
|
||||
>{{ t("nav.home") }}</NuxtLink
|
||||
>
|
||||
|
||||
<a
|
||||
href="/dailybriefing"
|
||||
<NuxtLink
|
||||
:to="localePath('dailybriefing')"
|
||||
class="hover:text-blue-500 cursor-pointer transiton-all duration-100"
|
||||
>{{ t("nav.dailybriefing") }}</a
|
||||
>{{ t("nav.dailybriefing") }}</NuxtLink
|
||||
>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<button
|
||||
@click="toggleDropdown"
|
||||
class="flex items-center space-x-2 px-4 py-2 rounded hover:bg-gray-900 transition-all duration-100"
|
||||
class="flex items-center space-x-1 px-4 py-2 rounded hover:bg-gray-900 transition-all duration-100 mr-5"
|
||||
>
|
||||
<span>{{ locale }}</span>
|
||||
<svg
|
||||
@ -68,8 +58,8 @@ const runAnimation = () => {
|
||||
</button>
|
||||
|
||||
<Transition
|
||||
enter-active-class="animate__animated animate__fadeInDown animate__faster"
|
||||
leave-active-class="animate__animated animate__fadeOutUp animate__faster"
|
||||
enter-active-class="animate__animated animate__fadeInDown animate_fastest"
|
||||
leave-active-class="animate__animated animate__fadeOutUp animate_fastest"
|
||||
>
|
||||
<div
|
||||
v-if="dropdownOpen"
|
||||
@ -89,3 +79,8 @@ const runAnimation = () => {
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.animate_fastest {
|
||||
--animate-duration: 0.2s;
|
||||
}
|
||||
</style>
|
@ -6,6 +6,15 @@
|
||||
"home": "Home",
|
||||
"dailybriefing": "Daily Briefing"
|
||||
},
|
||||
"home": {
|
||||
"nonMoving": "Hi! This is your ",
|
||||
"moving": {
|
||||
"newsPlatform": "News Platform",
|
||||
"miniWikipedia": "Mini Wikipedia",
|
||||
"newsComparePlatform": "news comparison platform"
|
||||
},
|
||||
"startusing": "Let's Start!"
|
||||
},
|
||||
"dailybriefing": "Daily Briefing",
|
||||
"Welcome": "Welcome",
|
||||
"loading": "Loading..."
|
||||
|
@ -6,6 +6,15 @@
|
||||
"home": "首頁",
|
||||
"dailybriefing": "今日報導"
|
||||
},
|
||||
"home": {
|
||||
"nonMoving": "嗨!這是你的",
|
||||
"moving": {
|
||||
"newsPlatform": "新聞平台",
|
||||
"miniWikipedia": "米你維基百科",
|
||||
"newsComparePlatform": "新聞觀點比對平台"
|
||||
},
|
||||
"startusing": "開始使用!"
|
||||
},
|
||||
"dailybriefing": "今日報導",
|
||||
"Welcome": "歡迎",
|
||||
"loading": "載入中..."
|
||||
|
@ -11,6 +11,9 @@
|
||||
"prettier": "prettier --write ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource-variable/noto-sans-tc": "^5.2.5",
|
||||
"@fontsource/fira-code": "^5.2.6",
|
||||
"@fontsource/fira-sans": "^5.2.5",
|
||||
"@heroicons/vue": "^2.2.0",
|
||||
"@nuxt/image": "1.10.0",
|
||||
"@nuxtjs/i18n": "9.5.4",
|
||||
|
3
pages/dailybriefing.vue
Normal file
3
pages/dailybriefing.vue
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
|
||||
</template>
|
@ -1,5 +1,48 @@
|
||||
<script setup lang="ts">
|
||||
import { gsap } from 'gsap'
|
||||
import { TextPlugin } from 'gsap/TextPlugin'
|
||||
gsap.registerPlugin(TextPlugin)
|
||||
const { t } = useI18n();
|
||||
|
||||
const popMessage = ref(null);
|
||||
const messages = [t("home.moving.newsPlatform"), t("home.moving.miniWikipedia"), t("home.moving.newsComparePlatform"), "BlindSpec"];
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
const tl = gsap.timeline({ repeat: -1 })
|
||||
messages.forEach((message) => {
|
||||
tl.to(popMessage.value, {
|
||||
duration:0.5,
|
||||
text:message,
|
||||
ease: "none."
|
||||
}).to(popMessage.value, {
|
||||
duration:2,
|
||||
text:message,
|
||||
ease: "none."
|
||||
})
|
||||
|
||||
for (let i = message.length; i >=0; i--) {
|
||||
tl.to(popMessage.value, {
|
||||
duration:0.06,
|
||||
text:message.substring(0, i),
|
||||
ease: "none"
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold text-center">嗨!</h1>
|
||||
<div class="flex flex-col justify-center align-center text-center absolute w-full h-screen inset-x-0 inset-y-0">
|
||||
<span class="text-3xl">
|
||||
<span class="bg-gradient-to-b from-[#eee] to-[#333] bg-clip-text text-transparent">{{ t("home.nonMoving") }}</span>
|
||||
<span ref="popMessage" class="bg-gradient-to-r from-[#2a7b9b] then-[#8d57c7] to-[#ed4242] bg-clip-text text-transparent"></span></span>
|
||||
<NuxtLink>
|
||||
<button class="m-4 bg-[#8C9393] text-white p-3 rounded-full bg-gradient-to-l from-sky-500 to-purple-600 transition-all duration-100">
|
||||
<span>{{ t("home.startusing") }}</span>
|
||||
</button>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div class="h-screen"></div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
@ -26,6 +26,20 @@ const {
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
data: fetchOtherData,
|
||||
pending: fetchOtherDataPending,
|
||||
error: fetchOtherDataError,
|
||||
} = useFetch("/api/getData/fetchSidebarData", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: {
|
||||
lang: locale,
|
||||
}
|
||||
})
|
||||
|
||||
watchEffect(() => {
|
||||
loading.value = pending.value;
|
||||
});
|
||||
@ -46,10 +60,10 @@ onMounted(() => {
|
||||
import { GlobeAltIcon } from "@heroicons/vue/24/outline";
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div class="text-center align-center justify-center">
|
||||
<div class="flex flex-row flex-wrap w-full mt-2">
|
||||
<div class="text-center align-center justify-center w-[70%]">
|
||||
<div
|
||||
class="flex flex-row bg-[#AAACAAFF] rounded-3xl p-3 gap-3 m-3 scale-5"
|
||||
class="flex flex-row bg-[#AAACAA61] rounded-3xl p-3 gap-3 m-3 scale-5"
|
||||
>
|
||||
<NuxtImg
|
||||
:src="fetchNewsOrgInfo?.logoUrl"
|
||||
@ -76,5 +90,28 @@ import { GlobeAltIcon } from "@heroicons/vue/24/outline";
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-3 text-left justify-right align-right bg-[#AAACAA61] w-[28%] rounded-3xl p-3 mt-3 h-screen">
|
||||
<h3 class="text-2xl mt-2s">其他媒體</h3>
|
||||
<hr/>
|
||||
<div v-for="data in fetchOtherData" :key="data.id" class="flex flex-col">
|
||||
<NuxtImg :src="data.image"></NuxtImg>
|
||||
<div class="flex flex-row">
|
||||
<h1 class="text-xl text-bold">{{ data.title }}</h1>
|
||||
<span class="text-ms ml-2 align-center justify-center text-center">
|
||||
(
|
||||
<span>{{ data.lean }}</span>
|
||||
-
|
||||
<span>文章分數:
|
||||
<span>{{ data.score }}</span>
|
||||
</span> )
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<NuxtLink class="justify-center align-center text-center">
|
||||
<button class="bg-red-500 text-black p-2 rounded-full justify-center align-center">
|
||||
<span>查看更多</span>
|
||||
</button>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
3
pages/newsOrgs.vue
Normal file
3
pages/newsOrgs.vue
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
|
||||
</template>
|
13
server/api/getData/fetchSidebarData.ts
Normal file
13
server/api/getData/fetchSidebarData.ts
Normal file
@ -0,0 +1,13 @@
|
||||
export default defineEventHandler(async (event) => {
|
||||
const body = await readBody(event);
|
||||
return {
|
||||
0: {
|
||||
id: "1",
|
||||
image: "whatever",
|
||||
tags: [],
|
||||
title: "三立新聞",
|
||||
lean: "left",
|
||||
score: "40"
|
||||
}
|
||||
};
|
||||
});
|
@ -9,4 +9,16 @@
|
||||
body {
|
||||
@apply bg-black m-0 p-0 min-h-screen text-white;
|
||||
}
|
||||
html,body {
|
||||
font-family: 'Noto Sans TC Variable', "Fira Sans", sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
/* noto-sans-tc-chinese-traditional-wght-normal */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans TC Variable';
|
||||
font-style: normal;
|
||||
font-display: auto;
|
||||
font-weight: 100 900;
|
||||
src: url(@fontsource-variable/noto-sans-tc/files/noto-sans-tc-chinese-traditional-wght-normal.woff2) format('woff2-variations');
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user