refactor: move navbar and footer to layout.tsx

This commit is contained in:
Konstantin Zhigaylo 2025-07-01 15:40:10 +03:00
parent c52e971b36
commit 66b780eaad
No known key found for this signature in database
GPG Key ID: DD1C2780F0E05B5C
8 changed files with 394 additions and 449 deletions

2
.gitignore vendored
View File

@ -39,3 +39,5 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
/.idea

View File

@ -1,6 +1,8 @@
import type { Metadata } from "next";
import { Geist, Rokkitt } from "next/font/google";
import "./globals.css";
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
const geistSans = Geist({
variable: "--font-geist",
@ -25,9 +27,11 @@ export default function RootLayout({
return (
<html lang="en">
<body
className={`${geistSans.variable} ${rokkitt.variable} bg-stone-900 font-geist antialiased`}
className={`${geistSans.variable} ${rokkitt.variable} flex flex-col gap-4 bg-stone-900 font-geist antialiased max-w-[700px] mx-auto p-4 pt-15`}
>
<NavBar />
{children}
<Footer />
</body>
</html>
);

View File

@ -1,25 +1,17 @@
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
import Text from "@/components/blocks/Text";
export default function Home() {
return (
<div className={"bg-stone-900 min-h-screen font-geist"}>
<main
className={"max-w-[700px] pt-15 flex flex-col gap-4 mx-auto w-full p-4"}
>
<NavBar />
<main className={"flex flex-col gap-4 mx-auto w-full"}>
<Text>
Welcome to an unofficial webpage about the Real Address Chat protocol.
Here you can find clients, servers, and documentation on how to use
RAC and its successor, WRAC.
Here you can find clients, servers, and documentation on how to use RAC
and its successor, WRAC.
</Text>
<Text>
Want to add your project to Racinfo? Make a pull request on our
official GitHub repository, and well review it.
Want to add your project to Racinfo? Make a pull request on our official
GitHub repository, and well review it.
</Text>
<Footer />
</main>
</div>
);
}

View File

@ -43,13 +43,6 @@ export default function Projects() {
description: "Coming Soon™",
tags: ["Unreleased", "WRAC", "RAC", "v2"],
},
{
name: "oWRAC",
authorId: "pansangg",
projectGit: "https://github.com/pansangg/oWRAC",
description: "An online WRAC client (works in web)",
tags: ["Unreleased", "WRAC", "v2"],
},
{
name: "clRAC",
externalDownload: true,
@ -116,17 +109,13 @@ export default function Projects() {
];
return (
<div className={"bg-stone-900 min-h-screen font-geist"}>
<main
className={"max-w-[700px] pt-15 flex flex-col gap-4 mx-auto w-full p-4"}
>
<NavBar />
<main className={"flex flex-col gap-4 w-full"}>
<PageTitle id={"projects"}>Projects</PageTitle>
<Text>
This is a curated list of projects that is related to RAC protocol.
There is a client and server implementations of RAC. Note that some
projects are not available on Git services and should be downloaded
from external sources. They are marked with
projects are not available on Git services and should be downloaded from
external sources. They are marked with
<InlineCode>external@</InlineCode> text at the beginning of the author
ID. If you want to add your project to this list, please make an issue
on our GitHub repository.
@ -169,8 +158,6 @@ export default function Projects() {
/>
))}
</div>
<Footer />
</main>
</div>
);
}

View File

@ -1,24 +1,18 @@
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
import Link from "next/link";
import Link from "next/link";
import Text from "@/components/blocks/Text";
import PageTitle from "@/components/blocks/PageTitle";
import Title from "@/components/blocks/Title";
export default function Protocol() {
return (
<div className={"bg-stone-900 min-h-screen font-geist"}>
<main
className={"max-w-[700px] pt-15 flex flex-col gap-4 mx-auto w-full p-4"}
>
<NavBar />
<main className={"flex flex-col gap-4 w-full"}>
<PageTitle id={"protocol"}>Protocol</PageTitle>
<Text>
Real Address Chat is a protocol based on TCP intended for chatting,
like IRC. It was supposed to be an IRC killer, but in reality, its
Real Address Chat is a protocol based on TCP intended for chatting, like
IRC. It was supposed to be an IRC killer, but in reality, its
implementation is poor. Theres also a community-made successor called
WRAC. Its basically the same as RAC, but it uses WebSockets instead
of TCP for connections.
WRAC. Its basically the same as RAC, but it uses WebSockets instead of
TCP for connections.
</Text>
<Text>
If you want to experiment with or implement RAC in your client or
@ -68,14 +62,12 @@ export default function Protocol() {
User Agents
</h1>
<p className={"text-stone-500"}>
A community-made solution to identify clients by a unique symbol
in front of their username.
A community-made solution to identify clients by a unique symbol in
front of their username.
</p>
<small className={"text-stone-600"}>Curated by @kostya-zero</small>
</Link>
</div>
<Footer />
</main>
</div>
);
}

View File

@ -1,6 +1,4 @@
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
import { ArrowLeft } from "lucide-react";
import { ArrowLeft } from "lucide-react";
import Link from "next/link";
import {
Table,
@ -18,11 +16,7 @@ import Code from "@/components/blocks/Code";
export default function Rac() {
return (
<div className={"bg-stone-900 min-h-screen font-geist"}>
<main
className={"max-w-[700px] pt-15 flex flex-col gap-4 mx-auto w-full p-4"}
>
<NavBar />
<main className={"flex flex-col gap-4 w-full"}>
<Link
href={"/protocol"}
className={
@ -40,8 +34,8 @@ export default function Rac() {
implementation is pretty simple, so dont worry.
</Text>
<Text>
All RAC servers use port <InlineCode>42666</InlineCode> by default,
but servers that implement RACS (Real Address Chat Secure) use port{" "}
All RAC servers use port <InlineCode>42666</InlineCode> by default, but
servers that implement RACS (Real Address Chat Secure) use port{" "}
<InlineCode>42667</InlineCode>.
</Text>
<Text>
@ -56,8 +50,8 @@ export default function Rac() {
</Text>
<Text>
But before you try to receive new messages, you need to get the total
size of all messages. The messages are stored on the server in a
single file, and to get new messages, you should send an offset.
size of all messages. The messages are stored on the server in a single
file, and to get new messages, you should send an offset.
</Text>
<Text>
To receive the current size of the messages on the server, you need to
@ -67,38 +61,37 @@ export default function Rac() {
</Text>
<Text>
The first way is to receive all messages stored on the server. The
client should send a <InlineCode>0x00</InlineCode> byte and then, in
the same stream, send a <InlineCode>0x01</InlineCode> byte to the
server. The server will respond with all messages, separated by{" "}
client should send a <InlineCode>0x00</InlineCode> byte and then, in the
same stream, send a <InlineCode>0x01</InlineCode> byte to the server.
The server will respond with all messages, separated by{" "}
<InlineCode>\n</InlineCode>.
</Text>
<Text>
The second way is to get messages in chunks. Again, the client sends a{" "}
<InlineCode>0x00</InlineCode> byte and then sends a{" "}
<InlineCode>0x02</InlineCode> byte, along with the size of the
messages it wants to receive. The number of messages to receive is
calculated using this formula:
<InlineCode>0x02</InlineCode> byte, along with the size of the messages
it wants to receive. The number of messages to receive is calculated
using this formula:
</Text>
<Code>new_received_size - last_known_size</Code>
<Text>
The server will send messages matching the requested size, separated
by <InlineCode>\n</InlineCode>.
The server will send messages matching the requested size, separated by{" "}
<InlineCode>\n</InlineCode>.
</Text>
<Title id={"sending-messages"}>Sending messages</Title>
<Text>
Sending messages in RAC is implemented simply, but with some
interesting details. The server doesnt identify clients or users, so
clients have to handle that themselves. This means the client must
send the user agent, username, and message all in one packet. For
example:
Sending messages in RAC is implemented simply, but with some interesting
details. The server doesnt identify clients or users, so clients have
to handle that themselves. This means the client must send the user
agent, username, and message all in one packet. For example:
</Text>
<Code>{"▲<zero> Hello, world!"}</Code>
<Text>
Did you notice the <InlineCode></InlineCode> symbol? This is called a
User Agent. In this example, the message was sent by the Tower client,
because <InlineCode></InlineCode> is its respective user agent. As
mentioned earlier, the server itself cannot identify clients, so
clients have to identify each other using these user agents.
mentioned earlier, the server itself cannot identify clients, so clients
have to identify each other using these user agents.
</Text>
<Text>
Also, note that <InlineCode>zero</InlineCode> is wrapped inside{" "}
@ -107,18 +100,18 @@ export default function Rac() {
own in the user agents article.
</Text>
<Text>
Note that the server should store the IP address with each sent
message. However, messages sent by clients in authorized mode should
be ignored for this. This idea, introduced by Sugoma, means that
clients shouldnt be anonymous unless theyre authorized. Still, most
clients ignore the IP address and dont display it.
Note that the server should store the IP address with each sent message.
However, messages sent by clients in authorized mode should be ignored
for this. This idea, introduced by Sugoma, means that clients shouldnt
be anonymous unless theyre authorized. Still, most clients ignore the
IP address and dont display it.
</Text>
<Text>
Back to sending messages: To send a message to the server, the client
should send a <InlineCode>0x01</InlineCode> byte, followed by the
message in the same packetnot separately. After that, you wont
receive anything from the server, even if theres an error. So your
final message should look like this:
message in the same packetnot separately. After that, you wont receive
anything from the server, even if theres an error. So your final
message should look like this:
</Text>
<Code>{"<user> Hello, everyone!"}</Code>
<Text>
@ -126,30 +119,28 @@ export default function Rac() {
authorized mode. To send message in authorized mode, you need to send{" "}
<InlineCode>0x02</InlineCode> and after that, separating by{" "}
<InlineCode>\n</InlineCode>, send user&apos;s user name, password and
message (<b>do not</b> include <InlineCode>\n</InlineCode> in the
end).
message (<b>do not</b> include <InlineCode>\n</InlineCode> in the end).
</Text>
<Text>
If the message was sent successfully, the server wont send any
response. If not, the server will send a <InlineCode>0x01</InlineCode>{" "}
byte if the user doesnt exist, and a <InlineCode>0x02</InlineCode>{" "}
byte if the password is incorrect.
byte if the user doesnt exist, and a <InlineCode>0x02</InlineCode> byte
if the password is incorrect.
</Text>
<Title id={"authorization"}>Authorization</Title>
<Text>
Authorization is only available on servers that implement the RAC v2
protocol, which adds an authorization system. This feature was added
by Sugoma for people who dont want to expose their IP address to
everyone.
protocol, which adds an authorization system. This feature was added by
Sugoma for people who dont want to expose their IP address to everyone.
</Text>
<Text>
Before sending messages in authorized mode, you need to register a
user on the server. To do this, the client should send a{" "}
<InlineCode>0x03</InlineCode> byte and, just like when sending
messages, include the username and password separated by{" "}
Before sending messages in authorized mode, you need to register a user
on the server. To do this, the client should send a{" "}
<InlineCode>0x03</InlineCode> byte and, just like when sending messages,
include the username and password separated by{" "}
<InlineCode>\n</InlineCode>. If the user is created, the client will
receive nothing in response. If the user already exists, the server
will respond with a <InlineCode>0x01</InlineCode> byte.
receive nothing in response. If the user already exists, the server will
respond with a <InlineCode>0x01</InlineCode> byte.
</Text>
<Title id={"tls-connection"}>TLS Connection</Title>
<Text>
@ -162,10 +153,9 @@ export default function Rac() {
dont add much functionality.
</Text>
<Text>
One of them is the <InlineCode>0x69</InlineCode> byte. You can send
this byte to the server to get technical information about it. For
example, after sending this byte, you might receive these bytes in
response:
One of them is the <InlineCode>0x69</InlineCode> byte. You can send this
byte to the server to get technical information about it. For example,
after sending this byte, you might receive these bytes in response:
</Text>
<Table>
<TableHeader>
@ -199,8 +189,6 @@ export default function Rac() {
Also, right after this byte, the server will send information about
itself, such as the server software name and its version.
</Text>
<Footer />
</main>
</div>
);
}

View File

@ -1,6 +1,4 @@
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
import { ArrowLeft } from "lucide-react";
import { ArrowLeft } from "lucide-react";
import Link from "next/link";
import {
Table,
@ -60,11 +58,7 @@ export default function Wrac() {
},
];
return (
<div className={"bg-stone-900 min-h-screen font-geist"}>
<main
className={"max-w-[700px] pt-15 flex flex-col gap-4 mx-auto w-full p-4"}
>
<NavBar />
<main className={"flex flex-col gap-4 w-full"}>
<Link
href={"/protocol"}
className={
@ -75,21 +69,21 @@ export default function Wrac() {
</Link>
<PageTitle id={"user-agents"}>User Agents</PageTitle>
<Text>
The RAC protocol doesnt have any functionality to identify clients,
so the community decided to use their own solution called{" "}
The RAC protocol doesnt have any functionality to identify clients, so
the community decided to use their own solution called{" "}
<b>User Agents</b>.
</Text>
<Text>
User Agents in RAC are implemented by adding an extra Unicode symbol
as a prefix to usernames. For example, a message sent with the Tower
User Agents in RAC are implemented by adding an extra Unicode symbol as
a prefix to usernames. For example, a message sent with the Tower
client:
</Text>
<Code>{"▲<zero> Hello, world!"}</Code>
<Text>
The <InlineCode></InlineCode> symbol in front of the username
indicates that this message was sent using the Tower client. The
client should use regex to parse these messages and determine the
client, username, and message.
The <InlineCode></InlineCode> symbol in front of the username indicates
that this message was sent using the Tower client. The client should use
regex to parse these messages and determine the client, username, and
message.
</Text>
<h3 className={"text-3xl text-stone-300 font-semibold font-rokkitt"}>
Known Agents
@ -110,9 +104,7 @@ export default function Wrac() {
<TableBody>
{userAgents.map((agent) => (
<TableRow key={agent.client}>
<TableCell className={"font-semibold"}>
{agent.client}
</TableCell>
<TableCell className={"font-semibold"}>{agent.client}</TableCell>
<TableCell>
<code>{agent.regex}</code>
</TableCell>
@ -121,8 +113,6 @@ export default function Wrac() {
))}
</TableBody>
</Table>
<Footer />
</main>
</div>
);
}

View File

@ -1,6 +1,4 @@
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
import { ArrowLeft } from "lucide-react";
import { ArrowLeft } from "lucide-react";
import Link from "next/link";
import Text from "@/components/blocks/Text";
import PageTitle from "@/components/blocks/PageTitle";
@ -9,11 +7,7 @@ import InlineCode from "@/components/blocks/InlineCode";
export default function Wrac() {
return (
<div className={"bg-stone-900 min-h-screen font-geist"}>
<main
className={"max-w-[700px] pt-15 flex flex-col gap-4 mx-auto w-full p-4"}
>
<NavBar />
<main className={"flex flex-col gap-4 w-full"}>
<Link
href={"/protocol"}
className={
@ -26,12 +20,11 @@ export default function Wrac() {
WebSocket Real Address Chat Protocol
</PageTitle>
<Text>
WRAC (WebSocket Real Address Chat) is a community-made successor to
RAC that uses WebSockets instead of TCP. It uses the same requests as
RAC, but you should send data in binary format. Unlike regular RAC,
you can use the same connection multiple timesin RAC, you had to
reconnect to the server for every request. This changes how message
receiving works.
WRAC (WebSocket Real Address Chat) is a community-made successor to RAC
that uses WebSockets instead of TCP. It uses the same requests as RAC,
but you should send data in binary format. Unlike regular RAC, you can
use the same connection multiple timesin RAC, you had to reconnect to
the server for every request. This changes how message receiving works.
</Text>
<Title id={"receiving-messages"}>Receiving messages</Title>
<Text>
@ -40,14 +33,11 @@ export default function Wrac() {
</Text>
<Text>
Receiving messages in WRAC is done by sending a single packet to the
server with two bytes. The first byte is <InlineCode>0x00</InlineCode>
, which indicates that you want to receive messages, and the second
byte is either <InlineCode>0x01</InlineCode> or{" "}
<InlineCode>0x02</InlineCode>. These two bytes work the same way as in
RAC.
server with two bytes. The first byte is <InlineCode>0x00</InlineCode>,
which indicates that you want to receive messages, and the second byte
is either <InlineCode>0x01</InlineCode> or <InlineCode>0x02</InlineCode>
. These two bytes work the same way as in RAC.
</Text>
<Footer />
</main>
</div>
);
}