@ -0,0 +1,53 @@
|
||||
{
|
||||
"extends": [
|
||||
"next/core-web-vitals",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:prettier/recommended",
|
||||
"eslint-config-prettier"
|
||||
],
|
||||
"plugins": ["prettier"],
|
||||
"rules": {
|
||||
"@typescript-eslint/no-explicit-any": ["off"], // 允许使用any
|
||||
"@typescript-eslint/ban-ts-comment": "off", // 允许使用@ts-ignore
|
||||
"@typescript-eslint/no-non-null-assertion": "off", // 允许使用非空断言
|
||||
"@typescript-eslint/no-var-requires": "off", // 允许使用CommonJS的写法
|
||||
"no-console": ["warn", { "allow": ["warn", "error"] }], // 提交时不允许有console.log
|
||||
"no-debugger": "warn",
|
||||
"import/order": [
|
||||
"error",
|
||||
{
|
||||
"groups": ["builtin", "external", "parent", "sibling", "index", "internal", "object", "type"], // 按照分组顺序进行排序
|
||||
// 通过路径自定义分组
|
||||
"pathGroups": [
|
||||
{
|
||||
"pattern": "react*",
|
||||
"group": "builtin",
|
||||
"position": "before"
|
||||
},
|
||||
{
|
||||
"pattern": "@/components/**",
|
||||
"group": "parent",
|
||||
"position": "before"
|
||||
},
|
||||
{
|
||||
"pattern": "@/utils/**",
|
||||
"group": "parent",
|
||||
"position": "after"
|
||||
},
|
||||
{
|
||||
"pattern": "@/apis/**",
|
||||
"group": "parent",
|
||||
"position": "after"
|
||||
}
|
||||
],
|
||||
"pathGroupsExcludedImportTypes": ["react"],
|
||||
"newlines-between": "always", // 每个分组之间换行
|
||||
// 根据字母顺序对每个组内的顺序进行排序
|
||||
"alphabetize": {
|
||||
"order": "asc",
|
||||
"caseInsensitive": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
.yarn/install-state.gz
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
@ -0,0 +1,3 @@
|
||||
/.next/
|
||||
/node_modules
|
||||
.env*.local
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"endOfLine": "auto",
|
||||
"printWidth": 120,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "all",
|
||||
"bracketSpacing": true
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3001](http://localhost:3001) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
extends: ['@commitlint/config-conventional'],
|
||||
};
|
@ -0,0 +1,6 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
output: 'export',
|
||||
};
|
||||
|
||||
export default nextConfig;
|
@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "queyue-h5",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev -p 3001",
|
||||
"build": "next build",
|
||||
"start": "next start -p 3001",
|
||||
"lint": "eslint src --fix --ext .ts,.tsx,.js,.jsx --max-warnings 0"
|
||||
},
|
||||
"dependencies": {
|
||||
"lib-flexible": "^0.3.2",
|
||||
"next": "14.1.3",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^19.1.0",
|
||||
"@commitlint/config-conventional": "^19.1.0",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.1.3",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"husky": "^9.0.11",
|
||||
"lint-staged": "^15.2.2",
|
||||
"postcss": "^8",
|
||||
"postcss-flexbugs-fixes": "^5.0.2",
|
||||
"postcss-preset-env": "^9.5.1",
|
||||
"postcss-pxtorem": "^6.1.0",
|
||||
"prettier": "^3.2.5",
|
||||
"tailwindcss": "^3.3.0",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.{js,jsx,ts,tsx,json}": [
|
||||
"npm run lint",
|
||||
"prettier --write"
|
||||
]
|
||||
},
|
||||
"browserslist": [
|
||||
"iOS >= 7",
|
||||
"Android >= 4"
|
||||
]
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
'postcss-flexbugs-fixes': {},
|
||||
'postcss-preset-env': {
|
||||
autoprefixer: {
|
||||
flexbox: 'no-2009',
|
||||
},
|
||||
stage: 3,
|
||||
features: {
|
||||
'custom-properties': false,
|
||||
},
|
||||
},
|
||||
'postcss-pxtorem': {
|
||||
rootValue: 37.5,
|
||||
unitPrecision: 5,
|
||||
propList: ['*'],
|
||||
selectorBlackList: [],
|
||||
replace: true,
|
||||
mediaQuery: false,
|
||||
minPixelValue: 0,
|
||||
exclude: '',
|
||||
},
|
||||
},
|
||||
};
|
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 167 KiB |
After Width: | Height: | Size: 199 KiB |
After Width: | Height: | Size: 160 KiB |
After Width: | Height: | Size: 248 KiB |
After Width: | Height: | Size: 151 KiB |
After Width: | Height: | Size: 199 KiB |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 258 KiB |
After Width: | Height: | Size: 253 KiB |
After Width: | Height: | Size: 237 KiB |
After Width: | Height: | Size: 208 KiB |
After Width: | Height: | Size: 286 KiB |
After Width: | Height: | Size: 253 KiB |
After Width: | Height: | Size: 237 KiB |
After Width: | Height: | Size: 243 KiB |
After Width: | Height: | Size: 898 B |
After Width: | Height: | Size: 276 B |
After Width: | Height: | Size: 276 B |
After Width: | Height: | Size: 506 B |
After Width: | Height: | Size: 514 B |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 507 KiB |
After Width: | Height: | Size: 11 MiB |
After Width: | Height: | Size: 7.8 MiB |
After Width: | Height: | Size: 104 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 716 B |
After Width: | Height: | Size: 233 KiB |
After Width: | Height: | Size: 5.0 MiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 405 B |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 5.0 MiB |
After Width: | Height: | Size: 3.7 MiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 211 B |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 792 B |
After Width: | Height: | Size: 921 B |
After Width: | Height: | Size: 391 B |
After Width: | Height: | Size: 355 B |
After Width: | Height: | Size: 276 B |
After Width: | Height: | Size: 438 B |
After Width: | Height: | Size: 619 B |
After Width: | Height: | Size: 312 B |
After Width: | Height: | Size: 236 B |
After Width: | Height: | Size: 312 B |
After Width: | Height: | Size: 747 B |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 411 B |
After Width: | Height: | Size: 211 B |
After Width: | Height: | Size: 771 B |
@ -0,0 +1,54 @@
|
||||
'use client';
|
||||
|
||||
import Image from 'next/image';
|
||||
|
||||
import { download } from '@/utils/download';
|
||||
|
||||
import useUA from '@/hooks/useUA';
|
||||
|
||||
export default function Download() {
|
||||
const { inWX } = useUA();
|
||||
|
||||
const handleDownload = () => {
|
||||
download();
|
||||
};
|
||||
|
||||
return (
|
||||
<main className="relative max-w-screen-sm min-h-screen mx-auto flex flex-col items-center text-white font-normal bg-gradient-to-b from-[#030303] to-[#1f1f20]">
|
||||
{inWX && (
|
||||
<div className="absolute top-[4px] left-1/2 translate-x-[-50%] w-[339px] h-[87px] flex justify-between bg-gradient-to-r from-[#1c1c1c] to-[#1e1e1e] rounded-[6px] px-[18px] py-[19px] box-border">
|
||||
<div>
|
||||
<h5 className="font-medium text-[17px] leading-[23.8px] mb-[5px]">下载【雀乐】APP</h5>
|
||||
<p className="text-[14px] leading-[19.6px] text-[#ffffffb2] flex items-center">
|
||||
点击右上角
|
||||
<Image
|
||||
unoptimized
|
||||
className="w-[24px] h-[24px]"
|
||||
width={24}
|
||||
height={24}
|
||||
src="/img/icon_dot.png"
|
||||
alt="dot"
|
||||
/>
|
||||
选择在浏览器中打开
|
||||
</p>
|
||||
</div>
|
||||
<Image className="w-[37px] h-[35px] mr-[3px]" width={37} height={35} src="/img/vector-2.svg" alt="arrow" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-col items-center mt-[151px]">
|
||||
<Image className="w-[90px] h-[90px]" width={90} height={90} src="/img/app_icon_white_bg.svg" alt="queyue" />
|
||||
<p className="text-[20px] leading-[24px] font-['Fontquan-XinYiJiXiangSong-Regular'] mt-[20px] tracking-[3px]">
|
||||
独立 不独于世
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<button
|
||||
className="w-[283px] h-[48px] flex items-center justify-center bg-[#B44343] font-medium text-[17px] rounded-full mt-[44px]"
|
||||
onClick={handleDownload}
|
||||
>
|
||||
下载【雀乐】APP
|
||||
</button>
|
||||
</main>
|
||||
);
|
||||
}
|
After Width: | Height: | Size: 25 KiB |
@ -0,0 +1,51 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@font-face {
|
||||
font-family: 'PingFang SC-Regular';
|
||||
src: url('/fonts/ping-fang-hei-ti-zhun-jian.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'PingFang SC-Medium';
|
||||
src: url('/fonts/pingfang-sc-medium.otf') format('opentype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'PingFang SC-Semibold';
|
||||
src: url('/fonts/pingfangsc-semibold.otf') format('opentype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Abhaya Libre SemiBold-Regular';
|
||||
src: url('/fonts/ping-fang-hei-ti-zhun-jian.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Fontquan-XinYiJiXiangSong-Regular';
|
||||
src: url('/fonts/Fontquan-XinYiJiXiangSong.ttf') format('truetype');
|
||||
}
|
||||
|
||||
:root {
|
||||
--body-bg-color: #1a1a1a;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--body-bg-color);
|
||||
font-family: 'PingFang SC-Regular', Helvetica;
|
||||
|
||||
/* padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom); */
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.text-balance {
|
||||
text-wrap: balance;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
import './globals.css';
|
||||
|
||||
export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
|
||||
const setRem = async () => {
|
||||
await import('lib-flexible');
|
||||
setLoaded(true);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setRem();
|
||||
window.addEventListener('resize', setRem);
|
||||
return () => {
|
||||
window.removeEventListener('resize', setRem);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<html lang="zn-ch">
|
||||
<head>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,viewport-fit=cover"
|
||||
/>
|
||||
<meta httpEquiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>雀乐</title>
|
||||
<meta name="description" content="独立 不独于世" />
|
||||
</head>
|
||||
<body>{loaded ? children : null}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
@ -0,0 +1,176 @@
|
||||
'use client';
|
||||
|
||||
import { useRef } from 'react';
|
||||
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
|
||||
import { download } from '@/utils/download';
|
||||
|
||||
import useUA from '@/hooks/useUA';
|
||||
|
||||
export default function Home() {
|
||||
const firstScreenRef = useRef<HTMLDivElement>(null);
|
||||
const { inWX } = useUA();
|
||||
|
||||
const handleShare = () => {
|
||||
alert('正在开发中,敬请期待');
|
||||
};
|
||||
|
||||
const handleDownload = () => {
|
||||
download();
|
||||
};
|
||||
|
||||
const handleSlideDown = () => {
|
||||
window.scrollTo({ top: firstScreenRef?.current?.offsetHeight, behavior: 'smooth' });
|
||||
};
|
||||
|
||||
return (
|
||||
<main className="max-w-screen-sm min-h-screen mx-auto flex flex-col items-center text-white font-normal">
|
||||
{/* 首屏 */}
|
||||
<div
|
||||
ref={firstScreenRef}
|
||||
className="relative w-full min-h-screen flex flex-col items-center bg-[url('/img/index_background.svg')] bg-center bg-cover"
|
||||
>
|
||||
{/* title */}
|
||||
{!inWX && <h1 className="text-center text-[17px] h-[44px] leading-[44px]">雀乐</h1>}
|
||||
|
||||
{/* App logo */}
|
||||
<div className="flex flex-col items-center absolute top-[25%]">
|
||||
<Image className="w-[90px] h-[90px]" width={90} height={90} src="/img/app_icon_white_bg.svg" alt="queyue" />
|
||||
<p className="text-[20px] font-['Fontquan-XinYiJiXiangSong-Regular'] mt-3 tracking-[3px]">独立 不独于世</p>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col items-center absolute bottom-0">
|
||||
<button
|
||||
className="w-[283px] h-[48px] flex items-center justify-center bg-[#000000f2] font-medium text-[17px] rounded-full mb-[16px]"
|
||||
onClick={handleShare}
|
||||
>
|
||||
<Image
|
||||
className="w-[24px] h-[24px] mr-[6px]"
|
||||
width={24}
|
||||
height={24}
|
||||
src="/img/index_weChatIcon.svg"
|
||||
alt="wx-share"
|
||||
/>
|
||||
<span>分享给好友</span>
|
||||
</button>
|
||||
<button
|
||||
className="w-[283px] h-[48px] flex items-center justify-center bg-[#B44343] font-medium text-[17px] rounded-full mb-[16px]"
|
||||
onClick={handleDownload}
|
||||
>
|
||||
下载【雀乐】APP
|
||||
</button>
|
||||
<button className="w-[283px] h-[48px] flex justify-center" onClick={handleSlideDown}>
|
||||
<Image
|
||||
className="w-[36px] h-[36px] animate-bounce"
|
||||
width={36}
|
||||
height={36}
|
||||
src="/img/index_Dropdown.svg"
|
||||
alt="download"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 第二屏 */}
|
||||
<div className="relative w-full min-h-screen flex flex-col items-center bg-black">
|
||||
<div className="w-[75.5%]">
|
||||
<Image
|
||||
className="w-[165.24px] h-[46.44px] mt-[51.58px]"
|
||||
width={165.24}
|
||||
height={46.44}
|
||||
src="/img/handwritten_white.svg"
|
||||
alt="we are back"
|
||||
/>
|
||||
|
||||
<p className="text-[#ffffffb2] text-[14px] leading-[26px] mt-[19.98px]">
|
||||
音乐是一种态度
|
||||
<br />
|
||||
不论是创作者还是聆听者
|
||||
<br />
|
||||
它流经心灵
|
||||
<br />
|
||||
纵然期待影响现实的力量是种奢望
|
||||
<br />
|
||||
如果刚巧有些声音
|
||||
<br />
|
||||
会叫你记得一段往事
|
||||
<br />
|
||||
伤痛或是甜蜜
|
||||
<br />
|
||||
那记忆便有了厚厚的壳
|
||||
<br />
|
||||
恒久的 温暖有如初生
|
||||
</p>
|
||||
|
||||
<Image
|
||||
className="w-[299px] h-[451.61px] mt-[26px] ml-auto mr-auto"
|
||||
width={299}
|
||||
height={451.61}
|
||||
src="/img/index_mockup.svg"
|
||||
alt="app preview"
|
||||
/>
|
||||
|
||||
<h5 className="text-[#ffffffb2] text-center text-[15px] leading-[21px] mt-[100px] mb-[4px]">合作联系</h5>
|
||||
<p className="text-center text-[20px] font-medium leading-[33.6px]">rock@indie.cn</p>
|
||||
|
||||
<h5 className="text-[#ffffffb2] text-center text-[15px] leading-[21px] mt-[47px] mb-[4px]">Weibo</h5>
|
||||
<p className="text-center text-[20px] font-medium leading-[33.6px] flex items-center justify-center">
|
||||
<Link
|
||||
className="relative"
|
||||
href="https://weibo.com/1886232237?refer_flag=1001030103_"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
官方微博
|
||||
<Image
|
||||
className="w-[24px] h-[24px] absolute top-[50%] right-[-24px] translate-y-[-50%]"
|
||||
width={24}
|
||||
height={24}
|
||||
src="/img/icon.svg"
|
||||
alt="arrow-right"
|
||||
/>
|
||||
</Link>
|
||||
</p>
|
||||
|
||||
{/* <h5 className="text-[#ffffffb2] text-center text-[15px] leading-[21px] mt-[47px] mb-[4px]">贡献者</h5>
|
||||
<p className="text-center text-[20px] font-medium leading-[33.6px] flex items-center justify-center">
|
||||
<span className="relative">
|
||||
加入我们
|
||||
<Image
|
||||
className="w-[24px] h-[24px] absolute top-[50%] right-[-24px] translate-y-[-50%]"
|
||||
width={24}
|
||||
height={24}
|
||||
src="/img/icon.svg"
|
||||
alt="arrow-right"
|
||||
/>
|
||||
</span>
|
||||
</p> */}
|
||||
|
||||
<Link
|
||||
className="block w-[fit-content] mt-[68px] ml-auto mr-auto"
|
||||
href="http://weixin.qq.com/r/thLfx-3EHaBirbmk90ek"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
className="w-[97.5px] h-[97.5px] mb-[10.5px] rounded-sm"
|
||||
width={97.5}
|
||||
height={97.5}
|
||||
src="/img/index_QRCode.svg"
|
||||
alt="arrow-right"
|
||||
/>
|
||||
<h5 className="text-[#ffffffb2] text-center text-[12px] leading-[18.8px]">雀乐公众号</h5>
|
||||
</Link>
|
||||
|
||||
<p className="text-[#ffffff33] text-center text-[9px] leading-[12.6px] mt-[53px] mb-[52px]">
|
||||
粤ICP备2024190175号-1 深圳雀乐文化科技有限责任公司
|
||||
<br />
|
||||
Shenzhen QueYue Culture Technology Co., Ltd.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
import { Hosting } from '@/utils/ua';
|
||||
|
||||
export default function useUA() {
|
||||
const [inWX, setInWX] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
setInWX(Hosting.isWX(window?.navigator?.userAgent?.toLowerCase()));
|
||||
}, []);
|
||||
|
||||
return { inWX };
|
||||
}
|
@ -0,0 +1 @@
|
||||
declare module 'lib-flexible';
|
@ -0,0 +1,9 @@
|
||||
import { Hosting } from '@/utils/ua';
|
||||
|
||||
// 下载
|
||||
export const download = () => {
|
||||
const ua = window?.navigator?.userAgent?.toLowerCase();
|
||||
if (!Hosting.isWX(ua)) {
|
||||
window.open('//cdn.indie.cn/release/queyue.apk', '__blank');
|
||||
}
|
||||
};
|
@ -0,0 +1,8 @@
|
||||
// 判断 H5 宿主环境
|
||||
export const Hosting = {
|
||||
isAndroid: (ua: any) => ua.indexOf('android') > -1 || ua.indexOf('linux') > -1,
|
||||
isIPhone: (ua: any) => ua.indexOf('iphone') > -1,
|
||||
isIPad: (ua: any) => ua.indexOf('ipad') > -1,
|
||||
isIPod: (ua: any) => ua.indexOf('ipod') > -1,
|
||||
isWX: (ua: any) => ua.indexOf('micromessenger') > -1,
|
||||
};
|
@ -0,0 +1,20 @@
|
||||
import type { Config } from 'tailwindcss';
|
||||
|
||||
const config: Config = {
|
||||
content: [
|
||||
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./src/modules/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||
'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
export default config;
|
@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|