Compare commits

...

2 Commits

Author SHA1 Message Date
1f2c4f33cb 📝 Add before you start section 2025-03-18 23:54:17 +08:00
e9e182ea48 Basic Solar Network product page 2025-03-18 23:15:37 +08:00
22 changed files with 447 additions and 54 deletions

View File

@ -0,0 +1,46 @@
<svg id="livetype" xmlns="http://www.w3.org/2000/svg" width="119.66407" height="40" viewBox="0 0 119.66407 40">
<title>Download_on_the_App_Store_Badge_US-UK_RGB_wht_092917</title>
<g>
<g>
<g>
<path d="M110.13477,0H9.53468c-.3667,0-.729,0-1.09473.002-.30615.002-.60986.00781-.91895.0127A13.21476,13.21476,0,0,0,5.5171.19141a6.66509,6.66509,0,0,0-1.90088.627A6.43779,6.43779,0,0,0,1.99757,1.99707,6.25844,6.25844,0,0,0,.81935,3.61816a6.60119,6.60119,0,0,0-.625,1.90332,12.993,12.993,0,0,0-.1792,2.002C.00587,7.83008.00489,8.1377,0,8.44434V31.5586c.00489.3105.00587.6113.01515.9219a12.99232,12.99232,0,0,0,.1792,2.0019,6.58756,6.58756,0,0,0,.625,1.9043A6.20778,6.20778,0,0,0,1.99757,38.001a6.27445,6.27445,0,0,0,1.61865,1.1787,6.70082,6.70082,0,0,0,1.90088.6308,13.45514,13.45514,0,0,0,2.0039.1768c.30909.0068.6128.0107.91895.0107C8.80567,40,9.168,40,9.53468,40H110.13477c.3594,0,.7246,0,1.084-.002.3047,0,.6172-.0039.9219-.0107a13.279,13.279,0,0,0,2-.1768,6.80432,6.80432,0,0,0,1.9082-.6308,6.27742,6.27742,0,0,0,1.6172-1.1787,6.39482,6.39482,0,0,0,1.1816-1.6143,6.60413,6.60413,0,0,0,.6191-1.9043,13.50643,13.50643,0,0,0,.1856-2.0019c.0039-.3106.0039-.6114.0039-.9219.0078-.3633.0078-.7246.0078-1.0938V9.53613c0-.36621,0-.72949-.0078-1.09179,0-.30664,0-.61426-.0039-.9209a13.5071,13.5071,0,0,0-.1856-2.002,6.6177,6.6177,0,0,0-.6191-1.90332,6.46619,6.46619,0,0,0-2.7988-2.7998,6.76754,6.76754,0,0,0-1.9082-.627,13.04394,13.04394,0,0,0-2-.17676c-.3047-.00488-.6172-.01074-.9219-.01269-.3594-.002-.7246-.002-1.084-.002Z"/>
<path d="M8.44483,39.125c-.30468,0-.602-.0039-.90429-.0107a12.68714,12.68714,0,0,1-1.86914-.1631,5.88381,5.88381,0,0,1-1.65674-.5479,5.40573,5.40573,0,0,1-1.397-1.0166,5.32082,5.32082,0,0,1-1.02051-1.3965,5.72186,5.72186,0,0,1-.543-1.6572,12.41351,12.41351,0,0,1-.1665-1.875c-.00634-.2109-.01464-.9131-.01464-.9131V8.44434S.88185,7.75293.8877,7.5498a12.37039,12.37039,0,0,1,.16553-1.87207,5.7555,5.7555,0,0,1,.54346-1.6621A5.37349,5.37349,0,0,1,2.61183,2.61768,5.56543,5.56543,0,0,1,4.01417,1.59521a5.82309,5.82309,0,0,1,1.65332-.54394A12.58589,12.58589,0,0,1,7.543.88721L8.44532.875H111.21387l.9131.0127a12.38493,12.38493,0,0,1,1.8584.16259,5.93833,5.93833,0,0,1,1.6709.54785,5.59374,5.59374,0,0,1,2.415,2.41993,5.76267,5.76267,0,0,1,.5352,1.64892,12.995,12.995,0,0,1,.1738,1.88721c.0029.2832.0029.5874.0029.89014.0079.375.0079.73193.0079,1.09179V30.4648c0,.3633,0,.7178-.0079,1.0752,0,.3252,0,.6231-.0039.9297a12.73126,12.73126,0,0,1-.1709,1.8535,5.739,5.739,0,0,1-.54,1.67,5.48029,5.48029,0,0,1-1.0156,1.3857,5.4129,5.4129,0,0,1-1.3994,1.0225,5.86168,5.86168,0,0,1-1.668.5498,12.54218,12.54218,0,0,1-1.8692.1631c-.2929.0068-.5996.0107-.8974.0107l-1.084.002Z" style="fill: #fff"/>
</g>
<g id="_Group_" data-name="&lt;Group&gt;">
<g id="_Group_2" data-name="&lt;Group&gt;">
<g id="_Group_3" data-name="&lt;Group&gt;">
<path id="_Path_" data-name="&lt;Path&gt;" d="M24.99671,19.88935a5.14625,5.14625,0,0,1,2.45058-4.31771,5.26776,5.26776,0,0,0-4.15039-2.24376c-1.74624-.1833-3.43913,1.04492-4.329,1.04492-.90707,0-2.27713-1.02672-3.75247-.99637a5.52735,5.52735,0,0,0-4.65137,2.8367c-2.01111,3.482-.511,8.59939,1.41551,11.414.96388,1.37823,2.09037,2.91774,3.56438,2.86315,1.4424-.05983,1.98111-.91977,3.7222-.91977,1.72494,0,2.23035.91977,3.73427.88506,1.54777-.02512,2.52292-1.38435,3.453-2.77563a11.39931,11.39931,0,0,0,1.579-3.21589A4.97284,4.97284,0,0,1,24.99671,19.88935Z"/>
<path id="_Path_2" data-name="&lt;Path&gt;" d="M22.15611,11.47681a5.06687,5.06687,0,0,0,1.159-3.62989,5.15524,5.15524,0,0,0-3.33555,1.72582,4.82131,4.82131,0,0,0-1.18934,3.4955A4.26259,4.26259,0,0,0,22.15611,11.47681Z"/>
</g>
</g>
<g>
<path d="M42.30178,27.13965h-4.7334l-1.13672,3.35645H34.42678l4.4834-12.418h2.083l4.4834,12.418H43.43752Zm-4.24316-1.54883h3.752L39.961,20.14355H39.9092Z"/>
<path d="M55.1592,25.96973c0,2.81348-1.50586,4.62109-3.77832,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238h1.79883v1.50586h.03418a3.21162,3.21162,0,0,1,2.88281-1.60059C53.64455,21.34766,55.1592,23.16406,55.1592,25.96973Zm-1.91016,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C52.30178,29.01563,53.249,27.81934,53.249,25.96973Z"/>
<path d="M65.12453,25.96973c0,2.81348-1.50635,4.62109-3.77881,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238h1.79883v1.50586h.03418a3.21162,3.21162,0,0,1,2.88281-1.60059C63.6094,21.34766,65.12453,23.16406,65.12453,25.96973Zm-1.91064,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C62.26662,29.01563,63.21389,27.81934,63.21389,25.96973Z"/>
<path d="M71.70949,27.03613c.1377,1.23145,1.334,2.04,2.96875,2.04,1.56641,0,2.69336-.80859,2.69336-1.91895,0-.96387-.67969-1.541-2.28906-1.93652l-1.60937-.3877c-2.28027-.55078-3.33887-1.61719-3.33887-3.34766,0-2.14258,1.86719-3.61426,4.51758-3.61426,2.625,0,4.42383,1.47168,4.48438,3.61426h-1.876c-.1123-1.23926-1.13672-1.9873-2.63379-1.9873s-2.52148.75684-2.52148,1.8584c0,.87793.6543,1.39453,2.25488,1.79l1.36816.33594c2.54785.60254,3.60547,1.626,3.60547,3.44238,0,2.32324-1.84961,3.77832-4.793,3.77832-2.75391,0-4.61328-1.4209-4.7334-3.667Z"/>
<path d="M83.34621,19.2998v2.14258h1.72168v1.47168H83.34621v4.99121c0,.77539.34473,1.13672,1.10156,1.13672a5.80752,5.80752,0,0,0,.61133-.043v1.46289a5.10351,5.10351,0,0,1-1.03223.08594c-1.833,0-2.54785-.68848-2.54785-2.44434V22.91406H80.16262V21.44238H81.479V19.2998Z"/>
<path d="M86.064,25.96973c0-2.84863,1.67773-4.63867,4.29395-4.63867,2.625,0,4.29492,1.79,4.29492,4.63867,0,2.85645-1.66113,4.63867-4.29492,4.63867C87.72512,30.6084,86.064,28.82617,86.064,25.96973Zm6.69531,0c0-1.9541-.89551-3.10742-2.40137-3.10742s-2.40137,1.16211-2.40137,3.10742c0,1.96191.89551,3.10645,2.40137,3.10645S92.7593,27.93164,92.7593,25.96973Z"/>
<path d="M96.18508,21.44238h1.77246v1.541h.043a2.1594,2.1594,0,0,1,2.17773-1.63574,2.86616,2.86616,0,0,1,.63672.06934v1.73828a2.59794,2.59794,0,0,0-.835-.1123,1.87264,1.87264,0,0,0-1.93652,2.083v5.37012h-1.8584Z"/>
<path d="M109.38332,27.83691c-.25,1.64355-1.85059,2.77148-3.89844,2.77148-2.63379,0-4.26855-1.76465-4.26855-4.5957,0-2.83984,1.64355-4.68164,4.19043-4.68164,2.50488,0,4.08008,1.7207,4.08008,4.46582v.63672h-6.39453v.1123a2.358,2.358,0,0,0,2.43555,2.56445,2.04834,2.04834,0,0,0,2.09082-1.27344Zm-6.28223-2.70215h4.52637a2.1773,2.1773,0,0,0-2.2207-2.29785A2.292,2.292,0,0,0,103.10109,25.13477Z"/>
</g>
</g>
</g>
<g id="_Group_4" data-name="&lt;Group&gt;">
<g>
<path d="M37.82619,8.731a2.63964,2.63964,0,0,1,2.80762,2.96484c0,1.90625-1.03027,3.002-2.80762,3.002H35.67092V8.731Zm-1.22852,5.123h1.125a1.87588,1.87588,0,0,0,1.96777-2.146,1.881,1.881,0,0,0-1.96777-2.13379h-1.125Z"/>
<path d="M41.68068,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C44.57522,13.99463,45.01369,13.42432,45.01369,12.44434Z"/>
<path d="M51.57326,14.69775h-.92187l-.93066-3.31641h-.07031l-.92676,3.31641h-.91309l-1.24121-4.50293h.90137l.80664,3.436h.06641l.92578-3.436h.85254l.92578,3.436h.07031l.80273-3.436h.88867Z"/>
<path d="M53.85354,10.19482H54.709v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915h-.88867V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z"/>
<path d="M59.09377,8.437h.88867v6.26074h-.88867Z"/>
<path d="M61.21779,12.44434a2.13346,2.13346,0,1,1,4.24756,0,2.1338,2.1338,0,1,1-4.24756,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C64.11232,13.99463,64.5508,13.42432,64.5508,12.44434Z"/>
<path d="M66.4009,13.42432c0-.81055.60352-1.27783,1.6748-1.34424l1.21973-.07031v-.38867c0-.47559-.31445-.74414-.92187-.74414-.49609,0-.83984.18213-.93848.50049h-.86035c.09082-.77344.81836-1.26953,1.83984-1.26953,1.12891,0,1.76563.562,1.76563,1.51318v3.07666h-.85547v-.63281h-.07031a1.515,1.515,0,0,1-1.35254.707A1.36026,1.36026,0,0,1,66.4009,13.42432Zm2.89453-.38477v-.37646l-1.09961.07031c-.62012.0415-.90137.25244-.90137.64941,0,.40527.35156.64111.835.64111A1.0615,1.0615,0,0,0,69.29543,13.03955Z"/>
<path d="M71.34816,12.44434c0-1.42285.73145-2.32422,1.86914-2.32422a1.484,1.484,0,0,1,1.38086.79h.06641V8.437h.88867v6.26074h-.85156v-.71143h-.07031a1.56284,1.56284,0,0,1-1.41406.78564C72.0718,14.772,71.34816,13.87061,71.34816,12.44434Zm.918,0c0,.95508.4502,1.52979,1.20313,1.52979.749,0,1.21191-.583,1.21191-1.52588,0-.93848-.46777-1.52979-1.21191-1.52979C72.72121,10.91846,72.26613,11.49707,72.26613,12.44434Z"/>
<path d="M79.23,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C82.12453,13.99463,82.563,13.42432,82.563,12.44434Z"/>
<path d="M84.66945,10.19482h.85547v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915H87.605V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z"/>
<path d="M93.51516,9.07373v1.1416h.97559v.74854h-.97559V13.2793c0,.47168.19434.67822.63672.67822a2.96657,2.96657,0,0,0,.33887-.02051v.74023a2.9155,2.9155,0,0,1-.4834.04541c-.98828,0-1.38184-.34766-1.38184-1.21582v-2.543h-.71484v-.74854h.71484V9.07373Z"/>
<path d="M95.70461,8.437h.88086v2.48145h.07031a1.3856,1.3856,0,0,1,1.373-.80664,1.48339,1.48339,0,0,1,1.55078,1.67871v2.90723H98.69v-2.688c0-.71924-.335-1.0835-.96289-1.0835a1.05194,1.05194,0,0,0-1.13379,1.1416v2.62988h-.88867Z"/>
<path d="M104.76125,13.48193a1.828,1.828,0,0,1-1.95117,1.30273A2.04531,2.04531,0,0,1,100.73,12.46045a2.07685,2.07685,0,0,1,2.07617-2.35254c1.25293,0,2.00879.856,2.00879,2.27V12.688h-3.17969v.0498a1.1902,1.1902,0,0,0,1.19922,1.29,1.07934,1.07934,0,0,0,1.07129-.5459Zm-3.126-1.45117h2.27441a1.08647,1.08647,0,0,0-1.1084-1.1665A1.15162,1.15162,0,0,0,101.63527,12.03076Z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 770 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

@ -19,8 +19,8 @@ async function loadPost({ done }: any) {
offset: posts.value.length.toString(),
})
if (props.publisher) {
searchQueries.set("author", props.publisher)
if (props.author) {
searchQueries.set("author", props.author)
}
if (props.realm) {
searchQueries.set("realm", props.realm)

View File

@ -69,6 +69,16 @@
"continueReading": "Continue Reading",
"download": "Download",
"downloadDescription": "Pick the right version for you",
"downloadSwitchPrerelease": "Switch to pre-release",
"downloadSwitchRelease": "Switch to regular release",
"downloadForApple": "Looking for iOS / macOS version?",
"downloadTestFlight": "TestFlight",
"downloadTestFlightDescription": "For pre-release version",
"downloadForDesktop": "Looking for desktop version?",
"downloadForDesktopDescription": "If the release does not contain the desktop version, you can still download the latest build from GitHub Action",
"downloadWithoutDownload": "Want have a try without downloading?",
"downloadWeb": "Web",
"downloadWebChina": "with China Mainland Optimized",
"attachmentUpload": "Upload new",
"attachmentCreate": "Create Attachment",
"attachmentCreateCaption": "Use Solar Network host your files",
@ -76,5 +86,18 @@
"attachmentUploadCompleted": "Uploaded",
"upload": "Upload",
"cancel": "Cancel",
"seeMore": "See more"
"seeMore": "See more",
"solarNetworkDescription": "A open, free, and friendly social network.",
"solarNetworkBeforeYouStart": "Before you start",
"solarNetworkBeforeYouStartDescription": "Learn some culture and basics of Solar Network",
"solarNetworkFreedomOfSpeech": "Freedom of Speech",
"solarNetworkFreedomOfSpeechDescription": "While Solar Network protects your freedom of speech and does not manually delete posts, this does not mean you are not responsible for your words. Additionally, when the 'flag the post' feature is activated, your posts will be hidden from other users. We still encourage users to prioritize harmony and minimize conflicts.",
"solarNetworkConfirmAccount": "Confirm Account",
"solarNetworkConfirmAccountDescription": "After registering, please check your bound email for the account confirmation email. Otherwise, your account will be reclaimed within 24 hours, and during this period, no permissions will be assigned, affecting most functionalities.",
"solarNetworkNoImpersonation": "No Impersonation",
"solarNetworkNoImpersonationDescription": "Do not impersonate individuals either within or outside the platform, especially those with a certain level of recognition. Regardless of intent, if it causes misunderstanding among users, we reserve the right to take action on the relevant account and content.",
"solarNetworkReadDialog": "Read Error Messages",
"solarNetworkReadDialogDescription": "When encountering an error message, do not immediately take a screenshot and complain. Try to understand why the issue occurred. Then, seek help in the development channel or on GitHub instead of making complaint posts.",
"solarNetworkToS": "And, if you continue registering, means you accept our Terms & Conditions",
"solarNetworkToSCheck": "Check them out"
}

View File

@ -69,6 +69,16 @@
"continueReading": "继续阅读",
"download": "下载",
"downloadDescription": "选择适合你的版本下载",
"downloadSwitchPrerelease": "切换至预发行版本",
"downloadSwitchRelease": "切换至稳定版本",
"downloadForApple": "使用 iOS / macOS 的设备?",
"downloadTestFlight": "测试飞机 (TestFlight)",
"downloadTestFlightDescription": "提供预发行版本",
"downloadForDesktop": "使用桌面设备?",
"downloadForDesktopDescription": "通常如果发行未包含桌面版本,你仍然可以从 GitHub Action 处下载最新的构建",
"downloadWithoutDownload": "想不下载尝试一下?",
"downloadWeb": "网页版",
"downloadWebChina": "中国大陆特供版本 (优化过的内容分发网络)",
"attachmentUpload": "新传附件",
"attachmentCreate": "新建附件",
"attachmentCreateCaption": "使用 Solar Network 来托管你的文件",
@ -76,5 +86,18 @@
"attachmentUploadCompleted": "上传完成",
"upload": "上传",
"cancel": "取消",
"seeMore": "查看更多"
"seeMore": "查看更多",
"solarNetworkDescription": "开放、包容、和谐",
"solarNetworkBeforeYouStart": "桥豆麻袋",
"solarNetworkBeforeYouStartDescription": "在你开始之前,了解一些关于 Solar Network 文化和常识",
"solarNetworkFreedomOfSpeech": "言论自由",
"solarNetworkFreedomOfSpeechDescription": "尽管 Solar Network 保护你的言论自由,不会手动对帖子进行删除。但是这不代表你可以对你的言论不负责。同时 Solar Network 上的「吹哨」功能生效时会对其他用户隐藏你的帖子。我们还是希望用户能以和为贵,少发生争吵。",
"solarNetworkConfirmAccount": "确认账户",
"solarNetworkConfirmAccountDescription": "在注册之后记得前往您绑定的邮件获取确认帐号的邮件,否则您的帐号会在 24 小时内被回收,并且期间不会分配权限,影响绝大部分功能使用。",
"solarNetworkNoImpersonation": "不要冒充他人",
"solarNetworkNoImpersonationDescription": "不要冒充在站内 / 站外的人物,对方有一定知名度的甚是。无论出发点如何,对用户造成了误解时我们保留权利处理相关帐号和内容。",
"solarNetworkReadDialog": "阅读错误提示",
"solarNetworkReadDialogDescription": "遇到报错提示不要第一时间截图抱怨,尝试理解为什么这件事情发生。其次在开发频道或 GitHub 寻求帮助,不要发帖抱怨。",
"solarNetworkToS": "还有,如果你继续注册 Solarpass 帐号,这意味着你同意我们的各项条款",
"solarNetworkToSCheck": "阅读这些条款"
}

View File

@ -38,7 +38,7 @@
</template>
<script setup lang="ts">
import Logo from "../assets/logo-w-shadow.png"
import Logo from "~/assets/logo-w-shadow.png"
const { t } = useI18n()
const openDrawer = ref(false)

View File

@ -16,6 +16,7 @@
"@nuxt/kit": "^3.16.0",
"@nuxtjs/i18n": "^8.5.6",
"@nuxtjs/sitemap": "^6.1.5",
"@octokit/rest": "^21.1.1",
"@pinia/nuxt": "^0.5.5",
"@vueuse/motion": "^3.0.3",
"feed": "^4.2.2",

View File

@ -44,13 +44,19 @@
<div class="text-xs text-grey flex flex-col mx-[2.5ch]">
<span>Solar Network Attachment Web Preview</span>
<span>Powered by <a class="underline" target="_blank" href="https://git.solsynth.dev/Hydrogen/Paperclip">Hydrogen.Paperclip</a></span>
<span
>Powered by
<a class="underline" target="_blank" href="https://git.solsynth.dev/Hydrogen/Paperclip"
>Hydrogen.Paperclip</a
></span
>
</div>
</v-col>
</v-row>
</template>
<script setup lang="ts">
import { formatBytes } from "~/utils/format"
import { useDisplay } from "vuetify"
const route = useRoute()
@ -61,7 +67,9 @@ const firstVideo = ref<string | null>()
const isMediumScreen = useDisplay().mdAndUp
const { data: attachment } = await useFetch<any>(`${config.public.solarNetworkApi}/cgi/uc/attachments/${route.params.id}/meta`)
const { data: attachment } = await useFetch<any>(
`${config.public.solarNetworkApi}/cgi/uc/attachments/${route.params.id}/meta`,
)
definePageMeta({
layout: "minimal",
@ -76,7 +84,9 @@ if (!attachment.value) {
const title = computed(() => `Attachment ${attachment.value?.id}`)
watch(attachment, (value) => {
watch(
attachment,
(value) => {
if (value.mimetype.split("/")[0] == "image") {
firstImage.value = `${config.public.solarNetworkApi}/cgi/uc/attachments/${value.id}`
}
@ -84,7 +94,9 @@ watch(attachment, (value) => {
if (value.mimetype.split("/")[0] == "video") {
firstVideo.value = `${config.public.solarNetworkApi}/cgi/uc/attachments/${value.id}`
}
}, { immediate: true, deep: true })
},
{ immediate: true, deep: true },
)
useHead({
title: title.value,
@ -106,16 +118,4 @@ useSeoMeta({
publisher: "Solar Network",
ogSiteName: "Solsynth Capital",
})
function formatBytes(bytes: number, decimals = 2) {
if (!+bytes) return "0 Bytes"
const k = 1024
const dm = decimals < 0 ? 0 : decimals
const sizes = ["Bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]
const i = Math.floor(Math.log(bytes) / Math.log(k))
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`
}
</script>

View File

@ -93,7 +93,7 @@ onMounted(() => {
const poolOptions = [
{ label: "Interactive", description: "Public indexable, no lifecycle.", value: "interactive" },
{ label: "Messaging", description: "Has lifecycle, will delete after 14 days.", value: "messaging" },
{ label: "Messaging", description: "Has lifecycle, will be deleted after 14 days.", value: "messaging" },
{ label: "Sticker", description: "Public indexable, privilege required.", value: "sticker", disabled: true },
{ label: "Dedicated Pool", description: "Your own configuration, coming soon.", value: "dedicated", disabled: true },
]
@ -201,12 +201,12 @@ async function uploadSingleMultipart(chunkId: string) {
const chunkIdx: number = multipartInfo.value["file_chunks"][chunkId]
const chunk = content.value.slice(chunkIdx * multipartSize.value, (chunkIdx + 1) * multipartSize.value)
const data = new FormData()
data.set("file", chunk)
const resp = await solarFetch(`/cgi/uc/attachments/multipart/${multipartInfo.value.rid}/${chunkId}`, {
method: "POST",
body: data,
body: chunk,
headers: {
"Content-Type": "application/octet-stream",
},
signal: AbortSignal.timeout(3 * 60 * 1000),
})
if (resp.status != 200) throw new Error(await resp.text())

View File

@ -1,4 +1,6 @@
<template>
<canvas ref="canvasRef" class="fixed top-0 left-0 w-screen h-screen opacity-50"></canvas>
<v-container class="flex flex-col my-2 px-12 gap-[4rem]">
<section class="content-section flex flex-col items-center justify-center text-center px-4">
<img
@ -10,6 +12,7 @@
enter: {
y: 0,
opacity: 1,
transition: { duration: 0.8 }
},
}"
:src="Logo"
@ -74,7 +77,7 @@
</template>
<script setup lang="ts">
import Logo from "../assets/logo-w-shadow.png"
import Logo from "~/assets/logo-w-shadow.png"
import { getLocale } from "~/utils/locale"
@ -100,6 +103,88 @@ const { data: products } = await useAsyncData("products", () => {
.limit(5)
.find()
})
const canvasRef = ref(null)
onMounted(() => {
const canvas: HTMLCanvasElement = canvasRef.value!
const ctx = canvas.getContext("2d")!
const dpr = window.devicePixelRatio || 1;
canvas.width = window.innerWidth * dpr;
canvas.height = window.innerHeight * dpr;
let particles: Particle[] = []
const numParticles = 100
class Particle {
x: number
y: number
vx: number
vy: number
size: number
constructor() {
this.x = Math.random() * canvas.width
this.y = Math.random() * canvas.height
this.vx = (Math.random() - 0.5) * 1.5
this.vy = (Math.random() - 0.5) * 1.5
this.size = Math.random() * 3 + 1
}
move() {
this.x += this.vx
this.y += this.vy
if (this.x <= 0 || this.x >= canvas.width) this.vx *= -1
if (this.y <= 0 || this.y >= canvas.height) this.vy *= -1
}
draw() {
ctx.beginPath();
ctx.arc(this.x * dpr, this.y * dpr, this.size * dpr, 0, Math.PI * 2);
ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
ctx.fill();
}
}
function init() {
particles = []
for (let i = 0; i < numParticles; i++) {
particles.push(new Particle())
}
}
function drawLines() {
for (let i = 0; i < particles.length; i++) {
for (let j = i + 1; j < particles.length; j++) {
let dx = particles[i].x - particles[j].x;
let dy = particles[i].y - particles[j].y;
let distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
ctx.beginPath();
ctx.moveTo(particles[i].x * dpr, particles[i].y * dpr);
ctx.lineTo(particles[j].x * dpr, particles[j].y * dpr);
ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
ctx.lineWidth = 0.5 * dpr;
ctx.stroke();
}
}
}
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height)
particles.forEach((p) => {
p.move()
p.draw()
})
drawLines()
requestAnimationFrame(animate)
}
init()
animate()
})
</script>
<style scoped>

View File

@ -0,0 +1,219 @@
<template>
<v-container class="flex flex-col my-2 px-12 gap-[4rem]">
<section class="content-section flex flex-col items-center justify-center text-center px-4" id="intro">
<div class="pt-1/3 mb-4 w-full relative">
<img :src="AlphaScreenshot" class="absolute bottom-2 left-0 right-0" />
<img
v-motion="{
initial: {
y: 100,
opacity: 0,
},
enter: {
y: 0,
opacity: 1,
transition: { duration: 0.8 },
},
}"
:src="Icon"
alt="Solar Network Logo"
class="w-32 h-32 p-2 z-10 mx-auto icon-glow bg-white dark:bg-black shadow-2xl rounded-xl"
/>
</div>
<div>
<h1 class="text-4xl font-bold">Solar Network</h1>
<p class="mt-2 text-lg">{{ t("solarNetworkDescription") }}</p>
<v-btn class="mt-4" color="primary" prepend-icon="mdi-arrow-down" href="#products">{{ t("learnMore") }}</v-btn>
</div>
</section>
<section class="content-section flex flex-col items-center justify-center text-center px-4" id="reminders">
<h1 class="text-3xl font-bold">{{ t("solarNetworkBeforeYouStart") }}</h1>
<p class="text-lg">{{ t("solarNetworkBeforeYouStartDescription") }}</p>
<div class="max-h-[500px] w-full mt-4 text-left">
<v-row dense>
<v-col cols="12" md="4">
<v-card :title="t('solarNetworkFreedomOfSpeech')" prepend-icon="mdi-account-voice" density="comfortable">
<v-card-text>{{ t("solarNetworkFreedomOfSpeechDescription") }}</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="4">
<v-card :title="t('solarNetworkConfirmAccount')" prepend-icon="mdi-account-check" density="comfortable">
<v-card-text>{{ t("solarNetworkConfirmAccountDescription") }}</v-card-text>
</v-card>
<v-card
:title="t('solarNetworkNoImpersonation')"
prepend-icon="mdi-account-cancel"
density="comfortable"
class="mt-2"
>
<v-card-text>{{ t("solarNetworkNoImpersonationDescription") }}</v-card-text>
</v-card>
</v-col>
<v-col cols="12" md="4">
<v-card :title="t('solarNetworkReadDialog')" prepend-icon="mdi-alert-circle" density="comfortable">
<v-card-text>{{ t("solarNetworkReadDialogDescription") }}</v-card-text>
</v-card>
</v-col>
</v-row>
</div>
<p class="text-sm mt-4">{{ t("solarNetworkToS") }}</p>
<nuxt-link class="underline text-sm" to="/terms">{{ t("solarNetworkToSCheck") }}</nuxt-link>
</section>
<section class="content-section flex flex-col items-center justify-center text-center px-4" id="downloads">
<h1 class="text-3xl font-bold">{{ t("download") }}</h1>
<p class="text-lg">
File-hosting & versioning by
<nuxt-link class="underline" to="https://github.com/Solsynth/HyperNet.Surface" target="_blank">GitHub</nuxt-link
><sup>®</sup>
</p>
<v-btn
v-if="hasPrerelease"
slim
density="compact"
prepend-icon="mdi-beta"
variant="text"
style="text-transform: none"
color="white"
@click="showPrerelease = !showPrerelease"
>
{{ showPrerelease ? t("downloadSwitchRelease") : t("downloadSwitchPrerelease") }}
</v-btn>
<div class="max-h-[500px] w-full mt-4 text-left">
<v-row dense>
<v-col cols="12" md="6">
<v-card
prepend-icon="mdi-alert-decagram"
:title="showPrerelease ? 'Latest pre-release' : 'Latest release'"
density="comfortable"
>
<v-card-text v-if="currentRelease.status.value === 'success'">
<p class="text-xs">
<code>{{ currentRelease.data.value?.tag_name }}</code>
</p>
<p class="font-bold text-lg">{{ latestRelease.data.value?.name }}</p>
<article class="prose prose-sm max-h-[360px] overflow-y-auto" style="max-width: unset">
<m-d-c :value="currentRelease.data.value!.body!" />
</article>
</v-card-text>
<div v-else>
<v-progress-circular class="px-5 my-3" indeterminate />
</div>
</v-card>
</v-col>
<v-col cols="12" md="6">
<v-card prepend-icon="mdi-download" title="Distributions" density="comfortable">
<div v-if="currentRelease.status.value === 'success'">
<v-list density="comfortable" slim>
<v-list-item
v-for="asset in currentRelease.data.value!.assets"
:key="asset.id"
:title="asset.label ?? asset.name"
:subtitle="formatBytes(asset.size)"
:href="asset.browser_download_url"
target="_blank"
/>
</v-list>
</div>
<div v-else>
<v-progress-circular class="px-5 my-3" indeterminate />
</div>
<v-card-text>
<p class="text-sm opacity-50 mb-2">{{ t("downloadForApple") }}</p>
<div class="flex align-center gap-2.5">
<nuxt-link
to="https://apps.apple.com/us/app/solian/id6499032345?itscg=30200&itsct=apps_box_link&mttnsubad=6499032345"
target="_blank"
>
<img :src="AppStoreDownload" />
</nuxt-link>
<div>
<nuxt-link to="https://testflight.apple.com/join/YJ0lmN6O" target="_blank" class="underline">
{{ t("downloadTestFlight") }}
</nuxt-link>
<p class="text-xs opacity-40">{{ t("downloadTestFlightDescription") }}</p>
</div>
</div>
<p class="text-sm opacity-50 mt-4">{{ t("downloadForDesktop") }}</p>
<p class="text-sm">{{ t("downloadForDesktopDescription") }}</p>
<p class="text-sm opacity-50 mt-4">{{ t("downloadWithoutDownload") }}</p>
<div class="text-sm flex gap-2 underline">
<nuxt-link to="https://sn.solsynth.dev" target="_blank">{{ t("downloadWeb") }}</nuxt-link>
<nuxt-link to="https://sn.solsynth.dev?cdn=cn" target="_blank">{{ t("downloadWebChina") }}</nuxt-link>
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</div>
</section>
</v-container>
</template>
<script lang="ts" setup>
import Icon from "~/assets/products/solar-network/icon.png"
import AlphaScreenshot from "~/assets/products/solar-network/alpha.webp"
import AppStoreDownload from "~/assets/products/app-store-download.svg"
import { formatBytes } from "~/utils/format"
import { Octokit } from "@octokit/rest"
const { t } = useI18n()
const latestRelease = useAsyncData("sn-latest-release", async () => {
const octo = new Octokit({})
const resp = await octo.repos.getLatestRelease({
owner: "Solsynth",
repo: "HyperNet.Surface",
})
return resp.data
})
const latestPrerelease = useAsyncData("sn-latest-prerelease", async () => {
const octo = new Octokit({})
const resp = await octo.repos.listReleases({
owner: "Solsynth",
repo: "HyperNet.Surface",
per_page: 1,
})
return resp.data[0]
})
const showPrerelease = ref(false)
const currentRelease = computed(() => (showPrerelease.value ? latestPrerelease : latestRelease))
const hasPrerelease = computed<boolean>(
() => latestPrerelease.data?.value?.tag_name != latestRelease.data?.value?.tag_name,
)
</script>
<style scoped>
.content-section {
min-height: calc(100vh - 80px);
display: flex;
place-items: center;
}
.icon-glow {
-webkit-filter: drop-shadow(0 0 7px rgba(0, 0, 0, 0.5));
filter: drop-shadow(0 0 7px rgba(0, 0, 0, 0.5));
}
@media (prefers-color-scheme: dark) {
.icon-glow {
-webkit-filter: invert() drop-shadow(0 0 7px rgba(255, 255, 255, 0.5));
filter: invert() drop-shadow(0 0 7px rgba(255, 255, 255, 0.5));
}
}
</style>
<style>
body,
html {
scroll-behavior: smooth;
}
</style>

View File

@ -27,7 +27,7 @@
</v-col>
<v-col row="12" lg="4" order="first" order-lg="last">
<div class="sticky top-0 h-fit">
<v-card prepend-icon="mdi-identifier" title="About">
<v-card prepend-icon="mdi-information-outline" title="About">
<v-card-text>
<p><b>Description</b></p>
<p>{{ account.description }}</p>
@ -53,7 +53,7 @@ const config = useRuntimeConfig()
const tab = ref(1)
const { data: account } = await useFetch<any>(`${config.public.solarNetworkApi}/cgi/co/publisher/${route.params.name}`)
const { data: account } = await useFetch<any>(`${config.public.solarNetworkApi}/cgi/co/publishers/${route.params.name}`)
if (account.value == null) {
throw createError({

View File

@ -12,16 +12,7 @@
</div>
<div class="mb-7">
<v-card rounded="xl" class="mx-[-5px]">
<v-tabs
v-model="tab"
align-tabs="start"
color="primary"
hide-slider
>
<v-tab :value="1">{{ t("userActivity") }}</v-tab>
</v-tabs>
</v-card>
</div>
<v-row>
@ -46,10 +37,6 @@
</template>
<script setup lang="ts">
definePageMeta({
alias: ["/@:name(.*)*"],
})
const { t } = useI18n()
const route = useRoute()
const config = useRuntimeConfig()
@ -67,6 +54,4 @@ if (account.value == null) {
const urlOfAvatar = computed(() => account.value?.avatar ? `${config.public.solarNetworkApi}/cgi/uc/attachments/${account.value.avatar}` : void 0)
const urlOfBanner = computed(() => account.value?.banner ? `${config.public.solarNetworkApi}/cgi/uc/attachments/${account.value.banner}` : void 0)
const externalOpenLink = computed(() => `${config.public.solianUrl}/accounts/view/${route.params.name}`)
</script>

11
utils/format.ts Normal file
View File

@ -0,0 +1,11 @@
export function formatBytes(bytes: number, decimals = 2) {
if (!+bytes) return "0 Bytes"
const k = 1024
const dm = decimals < 0 ? 0 : decimals
const sizes = ["Bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]
const i = Math.floor(Math.log(bytes) / Math.log(k))
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`
}