🌐 Localize solar network intro

This commit is contained in:
LittleSheep 2025-02-06 17:53:28 +08:00
parent 35cb92b322
commit 5973c7f25e
19 changed files with 219 additions and 31 deletions

8
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

12
.idea/Capital.iml generated Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

61
.idea/codeStyles/Project.xml generated Normal file
View File

@ -0,0 +1,61 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<HTMLCodeStyleSettings>
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
</HTMLCodeStyleSettings>
<JSCodeStyleSettings version="0">
<option name="USE_SEMICOLON_AFTER_STATEMENT" value="false" />
<option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="USE_DOUBLE_QUOTES" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" />
<option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
<option name="SPACES_WITHIN_IMPORTS" value="true" />
</JSCodeStyleSettings>
<TypeScriptCodeStyleSettings version="0">
<option name="USE_SEMICOLON_AFTER_STATEMENT" value="false" />
<option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="USE_DOUBLE_QUOTES" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" />
<option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
<option name="SPACES_WITHIN_IMPORTS" value="true" />
</TypeScriptCodeStyleSettings>
<VueCodeStyleSettings>
<option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
<option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
</VueCodeStyleSettings>
<codeStyleSettings language="HTML">
<option name="SOFT_MARGINS" value="120" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="SOFT_MARGINS" value="120" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="TypeScript">
<option name="SOFT_MARGINS" value="120" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="Vue">
<option name="SOFT_MARGINS" value="120" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

10
.idea/material_theme_project_new.xml generated Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MaterialThemeProjectNewConfig">
<option name="metadata">
<MTProjectMetadataState>
<option name="userId" value="14beee28:194cb09ea37:-7ffd" />
</MTProjectMetadataState>
</option>
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Capital.iml" filepath="$PROJECT_DIR$/.idea/Capital.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

5
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"cSpell.words": [
"Testflight"
]
}

BIN
bun.lockb

Binary file not shown.

7
next-i18next.config.js Normal file
View File

@ -0,0 +1,7 @@
/** @type {import('next-i18next').UserConfig} */
module.exports = {
i18n: {
defaultLocale: 'en-US',
locales: ['en-US', 'zh-CN'],
},
}

View File

@ -1,7 +1,10 @@
import type { NextConfig } from 'next' import type { NextConfig } from 'next'
import { i18n } from './next-i18next.config'
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
/* config options here */ /* config options here */
i18n,
reactStrictMode: true, reactStrictMode: true,
output: 'standalone', output: 'standalone',
generateBuildId: async () => { generateBuildId: async () => {

View File

@ -27,11 +27,14 @@
"axios-case-converter": "^1.1.1", "axios-case-converter": "^1.1.1",
"cookies-next": "^5.0.2", "cookies-next": "^5.0.2",
"feed": "^4.2.2", "feed": "^4.2.2",
"i18next": "^24.2.2",
"next": "^15.1.5", "next": "^15.1.5",
"next-i18next": "^15.4.2",
"next-nprogress-bar": "^2.4.3", "next-nprogress-bar": "^2.4.3",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-hook-form": "^7.54.2", "react-hook-form": "^7.54.2",
"react-i18next": "^15.4.0",
"rehype-sanitize": "^6.0.0", "rehype-sanitize": "^6.0.0",
"rehype-stringify": "^10.0.1", "rehype-stringify": "^10.0.1",
"remark-breaks": "^4.0.0", "remark-breaks": "^4.0.0",
@ -57,6 +60,7 @@
}, },
"trustedDependencies": [ "trustedDependencies": [
"@vercel/speed-insights", "@vercel/speed-insights",
"core-js",
"esbuild", "esbuild",
"sharp" "sharp"
] ]

View File

@ -0,0 +1,13 @@
{
"actionDownload": "Download",
"downloadPlatform": "Platform",
"downloadDistribution": "Distribution",
"downloadAppleStore": "iOS / macOS (App Store)",
"downloadAppleTestflight": "iOS / macOS (TestFlight)",
"downloadAndroid": "Android",
"downloadWindows": "Windows",
"downloadWeb": "Web",
"downloadSourceCode": "Source Code",
"actionOpen": "Open",
"faq": "Frequently Asked Questions"
}

View File

@ -0,0 +1,13 @@
{
"appName": "Solar Network",
"appDescription": "The next generation Social Network platform.",
"appSlogan": "Social Network, Redefined.",
"faq1": "What's the relationship between Solar Network and Solian?",
"faq1a": "Solian is the official app made for Solar Network. And the Solar Network is the official HyperNet instance hosted by Solsynth LLC. For simple, Solian is the app, and the Solar Network is the platform.",
"faq2": "What's the relationship between Solar Network and HyperNet?",
"faq2a": "HyperNet is the entire project including frontend app (also knowns as Solian for public) and the backend server. And the Solar Network is the official HyperNet instance which hosted and managed by Solsynth LLC who developed the HyperNet Project.",
"faq3": "Which rules do I need to follow while using Solar Network?",
"faq3a": "Check out our Terms & Conditions for a detailed explanation of what you can do and cannot do on Solar Network. If you violate any of these rules, we have the right to suspend or terminate your account., you can see them in the drawer.",
"faq4": "If I have any question about Solar Network, where can I get help?",
"faq4a": "Feel free to email as at lily@solsynth.dev"
}

View File

@ -0,0 +1,13 @@
{
"actionDownload": "下载",
"downloadPlatform": "平台",
"downloadDistribution": "分发",
"downloadAppleStore": "iOS / macOS (App Store)",
"downloadAppleTestflight": "iOS / macOS (TestFlight)",
"downloadAndroid": "安卓",
"downloadWindows": "Windows",
"downloadWeb": "网页版",
"downloadSourceCode": "源代码",
"actionOpen": "打开",
"faq": "常见问题"
}

View File

@ -0,0 +1,13 @@
{
"appName": "Solar Network",
"appDescription": "下一代社交网络平台",
"appSlogan": "重新定义社交网络",
"faq1": "Solar Network 和 Solian 之间有什么关系?",
"faq1a": "Solian 是为 Solar Network 制作的官方应用程序。而 Solar Network 是由 Solsynth LLC 托管的官方 HyperNet 实例。简单来说Solian 是应用程序,而 Solar Network 是平台。",
"faq2": "Solar Network 和 HyperNet 之间有什么关系?",
"faq2a": "HyperNet 是整个项目,包括前端应用程序(公众也称 Solian和后端服务器。而 Solar Network 是由开发 HyperNet 项目的 Solsynth LLC 托管和管理的官方 HyperNet 实例。",
"faq3": "使用 Solar Network 时我需要遵守哪些规则?",
"faq3a": "查看我们的条款和条件,详细了解您在 Solar Network 上可以做什么和不能做什么。如果您违反任何这些规则,我们有权暂停或终止您的帐户。您可以在抽屉中看到它们。",
"faq4": "如果我对 Solar Network 有任何疑问,我可以在哪里获得帮助?",
"faq4a": "你可以发邮件给我们的客户服务获取支持lily@solsynth.dev"
}

View File

@ -1,4 +1,5 @@
import '@/styles/globals.css' import '@/styles/globals.css'
import type { AppProps } from 'next/app' import type { AppProps } from 'next/app'
import { Box, createTheme, CssBaseline, ThemeProvider } from '@mui/material' import { Box, createTheme, CssBaseline, ThemeProvider } from '@mui/material'
import { Roboto } from 'next/font/google' import { Roboto } from 'next/font/google'
@ -7,6 +8,7 @@ import { PagesProgressBar as ProgressBar } from 'next-nprogress-bar'
import { AppProvider } from '@toolpad/core/nextjs' import { AppProvider } from '@toolpad/core/nextjs'
import { useUserStore } from 'solar-js-sdk' import { useUserStore } from 'solar-js-sdk'
import { useEffect } from 'react' import { useEffect } from 'react'
import { appWithTranslation } from 'next-i18next'
import Head from 'next/head' import Head from 'next/head'
const fontRoboto = Roboto({ const fontRoboto = Roboto({
@ -31,7 +33,7 @@ const siteTheme = createTheme({
}, },
}) })
export default function App({ Component, pageProps }: AppProps) { function App({ Component, pageProps }: AppProps) {
const userStore = useUserStore() const userStore = useUserStore()
useEffect(() => { useEffect(() => {
@ -80,3 +82,5 @@ export default function App({ Component, pageProps }: AppProps) {
</> </>
) )
} }
export default appWithTranslation(App)

View File

@ -15,6 +15,7 @@ import {
} from '@mui/material' } from '@mui/material'
import { JSX } from 'react' import { JSX } from 'react'
import { Roboto_Serif } from 'next/font/google' import { Roboto_Serif } from 'next/font/google'
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
import Image from 'next/image' import Image from 'next/image'
import NextLink from 'next/link' import NextLink from 'next/link'
@ -31,6 +32,7 @@ import ImgSolarNetworkIcon from '@/assets/products/solar-network/icon.png'
import ImgSolarNetworkAlpha from '@/assets/products/solar-network/alpha.webp' import ImgSolarNetworkAlpha from '@/assets/products/solar-network/alpha.webp'
import 'animate.css' import 'animate.css'
import { useTranslation } from 'next-i18next'
interface DownloadableAsset { interface DownloadableAsset {
icon: JSX.Element icon: JSX.Element
@ -51,68 +53,69 @@ const fontSerif = Roboto_Serif({
style: 'italic', style: 'italic',
}) })
export async function getStaticProps() { export async function getStaticProps({ locale }: { locale: string }) {
return { return {
props: { props: {
title: 'Solar Network', title: 'Solar Network',
...(await serverSideTranslations(locale, ['common', 'product-solar-network'])),
}, },
} }
} }
export default function ProductSolarNetwork() { export default function ProductSolarNetwork() {
const { t: ct } = useTranslation('common')
const { t } = useTranslation('product-solar-network')
const downloadableAssets: DownloadableAsset[] = [ const downloadableAssets: DownloadableAsset[] = [
{ {
icon: <AppleIcon />, icon: <AppleIcon />,
title: 'iOS / macOS (App Store)', title: ct('downloadAppleStore'),
href: 'https://apps.apple.com/us/app/solian/id6499032345?itscg=30200&itsct=apps_box_link&mttnsubad=6499032345', href: 'https://apps.apple.com/us/app/solian/id6499032345?itscg=30200&itsct=apps_box_link&mttnsubad=6499032345',
}, },
{ {
icon: <AppleIcon />, icon: <AppleIcon />,
title: 'iOS / macOS (TestFlight)', title: ct('downloadAppleTestflight'),
href: 'https://testflight.apple.com/join/YJ0lmN6O', href: 'https://testflight.apple.com/join/YJ0lmN6O',
}, },
{ {
icon: <AndroidIcon />, icon: <AndroidIcon />,
title: 'Android', title: ct('downloadAndroid'),
href: 'https://files.solsynth.dev/production01/solian/app-arm64-v8a-release.apk', href: 'https://files.solsynth.dev/production01/solian/app-arm64-v8a-release.apk',
}, },
{ {
icon: <WindowIcon />, icon: <WindowIcon />,
title: 'Windows', title: ct('downloadWindows'),
href: 'https://files.solsynth.dev/production01/solian/windows-x86_64-release.zip', href: 'https://files.solsynth.dev/production01/solian/windows-x86_64-release.zip',
}, },
{ {
icon: <WebIcon />, icon: <WebIcon />,
title: 'Web', title: ct('downloadWeb'),
href: 'https://sn.solsynth.dev', href: 'https://sn.solsynth.dev',
open: true, open: true,
}, },
{ {
icon: <CodeIcon />, icon: <CodeIcon />,
title: 'Source Code', title: ct('downloadSourceCode'),
href: 'https://github.com/Solsynth/HyperNet.Surface', href: 'https://github.com/Solsynth/HyperNet.Surface',
}, },
] ]
const askableQuestions: AskableQuestion[] = [ const askableQuestions: AskableQuestion[] = [
{ {
question: "What's the relationship between Solar Network and Solian?", question: t('faq1'),
answer: answer: t('faq1a'),
'Solian is the official app made for Solar Network. And the Solar Network is the official HyperNet instance hosted by Solsynth LLC. For simple, Solian is the app, and the Solar Network is the platform.',
}, },
{ {
question: "What's the relationship between Solar Network and HyperNet?", question: t('faq2'),
answer: answer: t('faq2a'),
'HyperNet is the entire project including frontend app (also knowns as Solian for public) and the backend server. And the Solar Network is the official HyperNet instance which hosted and managed by Solsynth LLC who developed the HyperNet Project.',
}, },
{ {
question: 'Which rules do I need to follow while using Solar Network?', question: t('faq3'),
answer: answer: t('faq3a'),
'Check out our Terms & Conditions for a detailed explanation of what you can do and cannot do on Solar Network. If you violate any of these rules, we have the right to suspend or terminate your account., you can see them in the drawer.',
}, },
{ {
question: 'If I have any question about Solar Network, where can I get help?', question: t('faq4'),
answer: 'Feel free to email as at lily@solsynth.dev', answer: t('faq4a'),
}, },
] ]
@ -129,7 +132,7 @@ export default function ProductSolarNetwork() {
/> />
<Box position="relative" width="fit-content" className="animate__animated animate__fadeInUp"> <Box position="relative" width="fit-content" className="animate__animated animate__fadeInUp">
<Typography variant="h4" component="h1"> <Typography variant="h4" component="h1">
Solar Network {t('appName')}
</Typography> </Typography>
<Box <Box
position="absolute" position="absolute"
@ -139,14 +142,14 @@ export default function ProductSolarNetwork() {
className="animate__animated animate__pulse animate__infinite" className="animate__animated animate__pulse animate__infinite"
> >
<Chip <Chip
label="2.0" label="2.2"
variant="outlined" variant="outlined"
sx={{ fontFamily: 'monospace', backgroundColor: 'background.default', fontSize: 12 }} sx={{ fontFamily: 'monospace', backgroundColor: 'background.default', fontSize: 12 }}
/> />
</Box> </Box>
</Box> </Box>
<Typography variant="subtitle1" component="h1" className="animate__animated animate__fadeInUp"> <Typography variant="subtitle1" component="h1" className="animate__animated animate__fadeInUp">
The next generation Social Network platform. {t('appDescription')}
</Typography> </Typography>
<Typography <Typography
@ -156,11 +159,11 @@ export default function ProductSolarNetwork() {
sx={{ mt: 2.5, width: 'fit-content', fontStyle: 'italic' }} sx={{ mt: 2.5, width: 'fit-content', fontStyle: 'italic' }}
className="textmarker-effect animate__animated animate__fadeInUp" className="textmarker-effect animate__animated animate__fadeInUp"
> >
Social Network, Redefined. {t('appSlogan')}
</Typography> </Typography>
<Link href="#download" sx={{ my: 2.5 }}> <Link href="#download" sx={{ my: 2.5 }}>
Download <DownloadIcon sx={{ fontSize: 15, marginLeft: 0.5 }} /> {ct('actionDownload')} <DownloadIcon sx={{ fontSize: 15, marginLeft: 0.5 }} />
</Link> </Link>
<Box position="relative" width="100%" sx={{ aspectRatio: 16 / 10, mt: 5 }}> <Box position="relative" width="100%" sx={{ aspectRatio: 16 / 10, mt: 5 }}>
@ -170,15 +173,15 @@ export default function ProductSolarNetwork() {
<Box id="download"> <Box id="download">
<Typography variant="h5" component="h2" textAlign="center" sx={{ mb: 5 }}> <Typography variant="h5" component="h2" textAlign="center" sx={{ mb: 5 }}>
Download {ct('actionDownload')}
</Typography> </Typography>
<Table sx={{ maxWidth: '800px', marginX: 'auto' }} aria-label="download table"> <Table sx={{ maxWidth: '800px', marginX: 'auto' }} aria-label="download table">
<TableHead> <TableHead>
<TableRow> <TableRow>
<TableCell /> <TableCell />
<TableCell>Platform</TableCell> <TableCell>{ct('downloadPlatform')}</TableCell>
<TableCell align="right">Distribution</TableCell> <TableCell align="right">{ct('downloadDistribution')}</TableCell>
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
@ -190,12 +193,12 @@ export default function ProductSolarNetwork() {
<NextLink passHref href={a.href} target="_blank"> <NextLink passHref href={a.href} target="_blank">
{a.open ? ( {a.open ? (
<Link component="span"> <Link component="span">
Open now {ct('actionOpen')}
<LaunchIcon sx={{ fontSize: 15, marginLeft: 0.5 }} /> <LaunchIcon sx={{ fontSize: 15, marginLeft: 0.5 }} />
</Link> </Link>
) : ( ) : (
<Link component="span"> <Link component="span">
Download now {ct('actionDownload')}
<DownloadIcon sx={{ fontSize: 15, marginLeft: 0.5 }} /> <DownloadIcon sx={{ fontSize: 15, marginLeft: 0.5 }} />
</Link> </Link>
)} )}
@ -209,7 +212,7 @@ export default function ProductSolarNetwork() {
<Box id="faq"> <Box id="faq">
<Typography variant="h5" component="h2" textAlign="center" sx={{ mb: 5 }}> <Typography variant="h5" component="h2" textAlign="center" sx={{ mb: 5 }}>
Frequently Asked Questions {ct('faq')}
</Typography> </Typography>
<Box sx={{ maxWidth: '800px', marginX: 'auto' }}> <Box sx={{ maxWidth: '800px', marginX: 'auto' }}>

View File

@ -17,6 +17,6 @@
"@/*": ["./src/*"] "@/*": ["./src/*"]
} }
}, },
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "next-i18next.config.js"],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }