working download and blog
This commit is contained in:
+243
@@ -0,0 +1,243 @@
|
|||||||
|
---
|
||||||
|
authors: Kleo dev, John Doe
|
||||||
|
title: Testing
|
||||||
|
description: Test
|
||||||
|
image: /background.png
|
||||||
|
date: 2025-04-16
|
||||||
|
tags: test, testing
|
||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Advertisement :)**
|
||||||
|
|
||||||
|
- **[pica](https://nodeca.github.io/pica/demo/)** - high quality and fast image
|
||||||
|
resize in browser.
|
||||||
|
- **[babelfish](https://github.com/nodeca/babelfish/)** - developer friendly
|
||||||
|
i18n with plurals support and easy syntax.
|
||||||
|
|
||||||
|
You will like those projects!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# h1 Heading 8-)
|
||||||
|
|
||||||
|
## h2 Heading
|
||||||
|
|
||||||
|
### h3 Heading
|
||||||
|
|
||||||
|
#### h4 Heading
|
||||||
|
|
||||||
|
##### h5 Heading
|
||||||
|
|
||||||
|
###### h6 Heading
|
||||||
|
|
||||||
|
## Horizontal Rules
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Typographic replacements
|
||||||
|
|
||||||
|
Enable typographer option to see result.
|
||||||
|
|
||||||
|
(c) (C) (r) (R) (tm) (TM) (p) (P) +-
|
||||||
|
|
||||||
|
test.. test... test..... test?..... test!....
|
||||||
|
|
||||||
|
!!!!!! ???? ,, -- ---
|
||||||
|
|
||||||
|
"Smartypants, double quotes" and 'single quotes'
|
||||||
|
|
||||||
|
## Emphasis
|
||||||
|
|
||||||
|
**This is bold text**
|
||||||
|
|
||||||
|
**This is bold text**
|
||||||
|
|
||||||
|
_This is italic text_
|
||||||
|
|
||||||
|
_This is italic text_
|
||||||
|
|
||||||
|
~~Strikethrough~~
|
||||||
|
|
||||||
|
## Blockquotes
|
||||||
|
|
||||||
|
> Blockquotes can also be nested...
|
||||||
|
>
|
||||||
|
> > ...by using additional greater-than signs right next to each other...
|
||||||
|
> >
|
||||||
|
> > > ...or with spaces between arrows.
|
||||||
|
|
||||||
|
## Lists
|
||||||
|
|
||||||
|
Unordered
|
||||||
|
|
||||||
|
- Create a list by starting a line with `+`, `-`, or `*`
|
||||||
|
- Sub-lists are made by indenting 2 spaces:
|
||||||
|
- Marker character change forces new list start:
|
||||||
|
- Ac tristique libero volutpat at
|
||||||
|
* Facilisis in pretium nisl aliquet
|
||||||
|
- Nulla volutpat aliquam velit
|
||||||
|
- Very easy!
|
||||||
|
|
||||||
|
Ordered
|
||||||
|
|
||||||
|
1. Lorem ipsum dolor sit amet
|
||||||
|
2. Consectetur adipiscing elit
|
||||||
|
3. Integer molestie lorem at massa
|
||||||
|
|
||||||
|
4. You can use sequential numbers...
|
||||||
|
5. ...or keep all the numbers as `1.`
|
||||||
|
|
||||||
|
Start numbering with offset:
|
||||||
|
|
||||||
|
57. foo
|
||||||
|
1. bar
|
||||||
|
|
||||||
|
## Code
|
||||||
|
|
||||||
|
Inline `code`
|
||||||
|
|
||||||
|
Indented code
|
||||||
|
|
||||||
|
// Some comments
|
||||||
|
line 1 of code
|
||||||
|
line 2 of code
|
||||||
|
line 3 of code
|
||||||
|
|
||||||
|
Block code "fences"
|
||||||
|
|
||||||
|
```
|
||||||
|
Sample text here...
|
||||||
|
```
|
||||||
|
|
||||||
|
Syntax highlighting
|
||||||
|
|
||||||
|
```js
|
||||||
|
var foo = function (bar) {
|
||||||
|
return bar++;
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(foo(5));
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tables
|
||||||
|
|
||||||
|
| Option | Description |
|
||||||
|
| ------ | ------------------------------------------------------------------------- |
|
||||||
|
| data | path to data files to supply the data that will be passed into templates. |
|
||||||
|
| engine | engine to be used for processing templates. Handlebars is the default. |
|
||||||
|
| ext | extension to be used for dest files. |
|
||||||
|
|
||||||
|
Right aligned columns
|
||||||
|
|
||||||
|
| Option | Description |
|
||||||
|
| -----: | ------------------------------------------------------------------------: |
|
||||||
|
| data | path to data files to supply the data that will be passed into templates. |
|
||||||
|
| engine | engine to be used for processing templates. Handlebars is the default. |
|
||||||
|
| ext | extension to be used for dest files. |
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
[link text](http://dev.nodeca.com)
|
||||||
|
|
||||||
|
[link with title](http://nodeca.github.io/pica/demo/ "title text!")
|
||||||
|
|
||||||
|
Autoconverted link https://github.com/nodeca/pica (enable linkify to see)
|
||||||
|
|
||||||
|
## Images
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
Like links, Images also have a footnote style syntax
|
||||||
|
|
||||||
|
![Alt text][id]
|
||||||
|
|
||||||
|
With a reference later in the document defining the URL location:
|
||||||
|
|
||||||
|
[id]: https://octodex.github.com/images/dojocat.jpg "The Dojocat"
|
||||||
|
|
||||||
|
## Plugins
|
||||||
|
|
||||||
|
The killer feature of `markdown-it` is very effective support of
|
||||||
|
[syntax plugins](https://www.npmjs.org/browse/keyword/markdown-it-plugin).
|
||||||
|
|
||||||
|
### [Emojies](https://github.com/markdown-it/markdown-it-emoji)
|
||||||
|
|
||||||
|
> Classic markup: :wink: :cry: :laughing: :yum:
|
||||||
|
>
|
||||||
|
> Shortcuts (emoticons): :-) :-( 8-) ;)
|
||||||
|
|
||||||
|
see [how to change output](https://github.com/markdown-it/markdown-it-emoji#change-output) with twemoji.
|
||||||
|
|
||||||
|
### [Subscript](https://github.com/markdown-it/markdown-it-sub) / [Superscript](https://github.com/markdown-it/markdown-it-sup)
|
||||||
|
|
||||||
|
- 19^th^
|
||||||
|
- H~2~O
|
||||||
|
|
||||||
|
### [\<ins>](https://github.com/markdown-it/markdown-it-ins)
|
||||||
|
|
||||||
|
++Inserted text++
|
||||||
|
|
||||||
|
### [\<mark>](https://github.com/markdown-it/markdown-it-mark)
|
||||||
|
|
||||||
|
==Marked text==
|
||||||
|
|
||||||
|
### [Footnotes](https://github.com/markdown-it/markdown-it-footnote)
|
||||||
|
|
||||||
|
Footnote 1 link[^first].
|
||||||
|
|
||||||
|
Footnote 2 link[^second].
|
||||||
|
|
||||||
|
Inline footnote^[Text of inline footnote] definition.
|
||||||
|
|
||||||
|
Duplicated footnote reference[^second].
|
||||||
|
|
||||||
|
[^first]: Footnote **can have markup**
|
||||||
|
|
||||||
|
and multiple paragraphs.
|
||||||
|
|
||||||
|
[^second]: Footnote text.
|
||||||
|
|
||||||
|
### [Definition lists](https://github.com/markdown-it/markdown-it-deflist)
|
||||||
|
|
||||||
|
Term 1
|
||||||
|
|
||||||
|
: Definition 1
|
||||||
|
with lazy continuation.
|
||||||
|
|
||||||
|
Term 2 with _inline markup_
|
||||||
|
|
||||||
|
: Definition 2
|
||||||
|
|
||||||
|
{ some code, part of Definition 2 }
|
||||||
|
|
||||||
|
Third paragraph of definition 2.
|
||||||
|
|
||||||
|
_Compact style:_
|
||||||
|
|
||||||
|
Term 1
|
||||||
|
~ Definition 1
|
||||||
|
|
||||||
|
Term 2
|
||||||
|
~ Definition 2a
|
||||||
|
~ Definition 2b
|
||||||
|
|
||||||
|
### [Abbreviations](https://github.com/markdown-it/markdown-it-abbr)
|
||||||
|
|
||||||
|
This is HTML abbreviation example.
|
||||||
|
|
||||||
|
It converts "HTML", but keep intact partial entries like "xxxHTMLyyy" and so on.
|
||||||
|
|
||||||
|
\*[HTML]: Hyper Text Markup Language
|
||||||
|
|
||||||
|
### [Custom containers](https://github.com/markdown-it/markdown-it-container)
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
_here be dragons_
|
||||||
|
:::
|
||||||
Generated
+1205
-3
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -12,7 +12,8 @@
|
|||||||
"lucide-react": "^0.488.0",
|
"lucide-react": "^0.488.0",
|
||||||
"next": "15.3.0",
|
"next": "15.3.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0"
|
"react-dom": "^19.0.0",
|
||||||
|
"react-markdown": "^10.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4",
|
"@tailwindcss/postcss": "^4",
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import Footer from "@/components/Footer";
|
||||||
|
import Header from "@/components/Header";
|
||||||
|
import listNews from "@/lib/news";
|
||||||
|
import Image from "next/image";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
export default function Download() {
|
||||||
|
return (
|
||||||
|
<div className="flex-1 flex flex-col h-screen">
|
||||||
|
<div className="flex flex-col bg-[url('/background.png')] bg-center bg-no-repeat h-52">
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<h1 className="text-5xl font-black m-auto w-max font-['Panton']">
|
||||||
|
DOWNLOAD
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-full h-full flex flex-col items-center pt-6">
|
||||||
|
Release downloads aren't available yet :(
|
||||||
|
<Link
|
||||||
|
href="https://github.com/saturnclientmc/saturnclient/releases/"
|
||||||
|
target="_blank"
|
||||||
|
className="hover:cursor-pointer mt-10 relative bg-red border text-white py-4 px-6 rounded-xl backdrop-blur-xs w-max group transition-colors duration-300 hover:text-[#e2bf7d] animate-fadeIn"
|
||||||
|
>
|
||||||
|
Download on GitHub
|
||||||
|
</Link>
|
||||||
|
<div className="flex flex-col items-center mt-4 gap-2">
|
||||||
|
<p>Step 1: Download the latest release from GitHub</p>
|
||||||
|
<p>Step 2: Locate your Minecraft mods folder (fabric required)</p>
|
||||||
|
<p>Step 3: Place the downloaded release into the mods folder</p>
|
||||||
|
<p>
|
||||||
|
Step 4: Launch the game on the official minecraft launcher (fabric)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
h1 {
|
||||||
|
font-size: xx-large;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: x-large;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: large;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: disc;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
list-style-type: decimal;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import Markdown from "react-markdown";
|
||||||
|
import "./Markdown.css";
|
||||||
|
|
||||||
|
export default function Md({ children }: { children: string }) {
|
||||||
|
return <Markdown>{children}</Markdown>;
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { readFileSync } from "fs";
|
||||||
|
import smartSplit from "@/lib/smartSplit";
|
||||||
|
import { parseNews } from "@/lib/news";
|
||||||
|
import Header from "@/components/Header";
|
||||||
|
import Footer from "@/components/Footer";
|
||||||
|
import Md from "./Markdown";
|
||||||
|
|
||||||
|
export default async function News({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ id: string }>;
|
||||||
|
}) {
|
||||||
|
const contents = readFileSync(`news/${(await params).id}.md`, "utf-8");
|
||||||
|
|
||||||
|
const { authors, title, description, image, date } = parseNews(
|
||||||
|
contents,
|
||||||
|
(await params).id
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
className="bg-[url('/background.png')] bg-center bg-no-repeat h-96"
|
||||||
|
style={{ backgroundImage: `url(${image})` }}
|
||||||
|
>
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<h1 className="font-black m-auto w-max font-['Panton'] !text-5xl mt-14">
|
||||||
|
{title}
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="m-auto w-max font-['Panton'] !text-2xl mt-5">
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
|
<p className="m-auto w-max font-['Panton'] !text-xl">
|
||||||
|
written by {authors.join(", ")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="w-[54rem] mx-auto mt-10">
|
||||||
|
<div className="rounded-2xl bg-[#111] p-5 markdown">
|
||||||
|
<Md>{smartSplit(contents, "---", 3)[2]}</Md>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
+11
-8
@@ -1,5 +1,6 @@
|
|||||||
import Footer from "@/components/Footer";
|
import Footer from "@/components/Footer";
|
||||||
import Header from "@/components/Header";
|
import Header from "@/components/Header";
|
||||||
|
import listNews from "@/lib/news";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
@@ -14,14 +15,16 @@ import Link from "next/link";
|
|||||||
// },
|
// },
|
||||||
// ];
|
// ];
|
||||||
|
|
||||||
const newsList = Array(3 * 6).fill({
|
// const newsList = Array(3 * 6).fill({
|
||||||
authors: [],
|
// authors: [],
|
||||||
title: "Hello World",
|
// title: "Hello World",
|
||||||
description: "lorem ipsum ipsum lorem",
|
// description: "lorem ipsum ipsum lorem",
|
||||||
image: "/background.png",
|
// image: "/background.png",
|
||||||
date: "2025-04-16",
|
// date: "2025-04-16",
|
||||||
id: "",
|
// id: "",
|
||||||
});
|
// });
|
||||||
|
|
||||||
|
const newsList = listNews();
|
||||||
|
|
||||||
export default function News() {
|
export default function News() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { readdirSync, readFileSync } from "fs";
|
||||||
|
|
||||||
|
export interface News {
|
||||||
|
authors: string[];
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
image: string;
|
||||||
|
date: string;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseNews(news: string, id: string): News {
|
||||||
|
const content = news.split("---", 2)[1];
|
||||||
|
|
||||||
|
const params: News = {
|
||||||
|
authors: [],
|
||||||
|
title: "Undefined title",
|
||||||
|
description: "",
|
||||||
|
image: "/background.png",
|
||||||
|
date: "Undefined date",
|
||||||
|
id,
|
||||||
|
};
|
||||||
|
|
||||||
|
content.split("\n").forEach((v) => {
|
||||||
|
const [key, value] = v.split(":").map((v) => v.trim());
|
||||||
|
if (key === "authors") {
|
||||||
|
params.authors = value.split(",").map((v) => v.trim());
|
||||||
|
} else if (
|
||||||
|
key === "title" ||
|
||||||
|
key === "description" ||
|
||||||
|
key === "image" ||
|
||||||
|
key === "date"
|
||||||
|
) {
|
||||||
|
params[key] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function listNews(): News[] {
|
||||||
|
const newsIdList = readdirSync("news");
|
||||||
|
|
||||||
|
if (newsIdList === null) return [];
|
||||||
|
|
||||||
|
return newsIdList.map((v) => {
|
||||||
|
return parseNews(
|
||||||
|
readFileSync(`news/${v}`, "utf-8"),
|
||||||
|
v.replaceAll(".md", "")
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
export default function smartSplit(
|
||||||
|
str: string,
|
||||||
|
separator: string,
|
||||||
|
limit: number
|
||||||
|
) {
|
||||||
|
const parts = str.split(separator);
|
||||||
|
if (parts.length <= limit) return parts;
|
||||||
|
|
||||||
|
const head = parts.slice(0, limit - 1);
|
||||||
|
const tail = parts.slice(limit - 1).join(separator);
|
||||||
|
return [...head, tail];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user