init
|
Before Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 701 KiB |
|
Before Width: | Height: | Size: 198 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 305 KiB |
|
Before Width: | Height: | Size: 728 KiB |
|
Before Width: | Height: | Size: 2.8 MiB |
|
Before Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 11 KiB |
48
public/logos/realm-black.svg
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 80 80">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: url(#linear-gradient);
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: none;
|
||||
stroke: #fff;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<linearGradient id="linear-gradient" x1="40" y1="2" x2="40" y2="82" gradientTransform="translate(0 82) scale(1 -1)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#fff" stop-opacity="0"/>
|
||||
<stop offset=".9" stop-color="#fff" stop-opacity=".1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<!-- Generator: Adobe Illustrator 28.6.0, SVG Export Plug-In . SVG Version: 1.2.0 Build 709) -->
|
||||
<g>
|
||||
<g id="Layer_1">
|
||||
<g id="c">
|
||||
<rect width="80" height="80" rx="18.2" ry="18.2"/>
|
||||
</g>
|
||||
<g id="d">
|
||||
<rect class="cls-1" width="80" height="80" rx="18.2" ry="18.2"/>
|
||||
</g>
|
||||
<g id="f" class="cls-4">
|
||||
<path class="cls-3" d="M63.4,57.7c0,3.2-2.7,5.8-6,5.8h-24.2c-.9,0-1.6-1-1.2-1.8h0c1.6-3.9,4.2-7.1,7.5-9.5.4-.3.9-.4,1.4-.4h16.6c3.3,0,5.9,2.7,5.9,6h0Z"/>
|
||||
<path class="cls-3" d="M46.7,16.6c.9,0,1.6,1,1.2,1.8h0c-1.6,3.9-4.2,7.1-7.5,9.5-.4.3-.9.4-1.4.4h-16.5c-3.2,0-5.9-2.5-6-5.8,0-3.3,2.6-6,5.9-6h24.2Z"/>
|
||||
<path class="cls-3" d="M22.4,63.4c-.7,0-1.5-.1-2.2-.4-3-1.2-4.4-4.7-3.2-7.7,1.9-4.6,4.6-8.7,8.1-12.3,3.6-3.7,7.9-6.5,12.6-8.5,6.6-2.7,11.7-7.8,14.4-14.4,1.2-3,4.7-4.4,7.7-3.2,3,1.2,4.4,4.7,3.2,7.7-1.9,4.6-4.6,8.7-8.1,12.3-3.6,3.7-7.9,6.5-12.6,8.5-6.6,2.7-11.7,7.8-14.4,14.4-.9,2.3-3.1,3.6-5.4,3.6Z"/>
|
||||
</g>
|
||||
<path class="cls-2" d="M22.6,57.4c-4.5-4.5-7.2-10.6-7.2-17.4,0-13.6,11-24.7,24.7-24.7s13,2.8,17.4,7.2M62.7,30.4c1.2,2.9,1.9,6.2,1.9,9.6,0,13.6-11,24.7-24.7,24.7s-6.6-.7-9.6-1.9"/>
|
||||
<path class="cls-2" d="M50.5,17.6c7.4-4.6,13.4-6.3,15.8-3.9,4.2,4.2-4.1,19.4-18.7,33.9-14.5,14.5-29.7,22.9-33.9,18.7-2.4-2.4-.7-8.3,3.8-15.7"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 515 KiB |
|
Before Width: | Height: | Size: 692 KiB |
|
Before Width: | Height: | Size: 351 KiB |
|
Before Width: | Height: | Size: 851 KiB |
|
Before Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 155 KiB |
|
Before Width: | Height: | Size: 150 KiB |
@@ -1,6 +0,0 @@
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
export default function WhyAreYouEvenHere() {
|
||||
redirect("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
|
||||
return null;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import Markdown from "react-markdown";
|
||||
import "../privacy-policy/markdown.css";
|
||||
|
||||
export default function PrivacyPolicy() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||
<div
|
||||
id="policy"
|
||||
className="py-42 mx-auto my-52 flex min-h-screen w-full flex-col p-10 lg:w-1/3 lg:p-0"
|
||||
>
|
||||
<Markdown>
|
||||
{`
|
||||
# Main Developer Team
|
||||
|
||||
* [**Mauro Baladés**](https://github.com/mauro-balades): Creator, Main Developer, and a funny guy.
|
||||
* **Oscar Gonzalez**: Site Reliability Engineer (SRE) and code signing.
|
||||
* [**Jafeth Garro**](https://iamjafeth.com/): Documentation writer.
|
||||
* [**Jan Heres**](https://janheres.eu/): Active contributor and helps with MacOS builds.
|
||||
* [**Bryan Galdámez**](https://josuegalre.netlify.app/): Huge contributor on theme functionalities
|
||||
* [**n7itro**](https://github.com/n7itro): Active contributor.
|
||||
* [**Canoa**](https://thatcanoa.org/) Active contributor, and very active in issue handling
|
||||
* [**BrhmDev**](https://github.com/BrhmDev): Active contributor with great ideas.
|
||||
* [**Larvey**](https://github.com/LarveyOfficial/): AUR maintainer.
|
||||
* [**Gunir**](https://github.com/gunir): Active contributor.
|
||||
|
||||
# Many more contributors
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||

|
||||
`}
|
||||
</Markdown>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { BrandingAssets } from "@/components/branding-assets";
|
||||
|
||||
export default function BrandingAssetsPage() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||
<BrandingAssets />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import CreateThemePage from "@/components/create-theme";
|
||||
|
||||
export default function BrandingAssetsPage() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||
<CreateThemePage />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import DownloadPage from "@/components/download";
|
||||
|
||||
export default function Download() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||
<DownloadPage />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
import { Feed } from "feed";
|
||||
import { releaseNotes } from "@/lib/release-notes";
|
||||
import type { ReleaseNote } from "@/lib/release-notes";
|
||||
|
||||
// Force feed.xml to be cached as static and remain constant for the lifetime of the current site build.
|
||||
// The supplied releaseNotes array is constant per build, so this will always be the latest release notes.
|
||||
export const dynamic = "force-static";
|
||||
|
||||
/** The default number of entries to include in the RSS feed. */
|
||||
const RSS_ENTRY_LIMIT = 20;
|
||||
|
||||
/**
|
||||
* Handles the GET request for the `feed.xml` endpoint.
|
||||
* @returns The RSS feed for the Zen Browser release notes.
|
||||
*/
|
||||
export async function GET() {
|
||||
// Just in case the release notes array is empty for whatever reason.
|
||||
const latestDate =
|
||||
releaseNotes.length > 0 ? formatRssDate(releaseNotes[0].date) : new Date();
|
||||
|
||||
const feed = new Feed({
|
||||
id: "https://www.zen-browser.app/release-notes",
|
||||
link: "https://www.zen-browser.app/release-notes",
|
||||
title: "Zen Browser Release Notes",
|
||||
description: "Release Notes for the Zen Browser",
|
||||
language: "en",
|
||||
favicon: "https://www.zen-browser.app/favicon.ico",
|
||||
copyright: `Zen Browser © ${new Date().getFullYear()} - Made with ❤️ by the Zen team.`,
|
||||
updated: latestDate,
|
||||
});
|
||||
|
||||
for (const releaseNote of releaseNotes.slice(0, RSS_ENTRY_LIMIT)) {
|
||||
feed.addItem({
|
||||
title: `Release notes for version ${releaseNote.version}`,
|
||||
id: `https://www.zen-browser.app/release-notes/${releaseNote.version}`,
|
||||
link: `https://www.zen-browser.app/release-notes/${releaseNote.version}`,
|
||||
date: formatRssDate(releaseNote.date),
|
||||
description: releaseNote.extra,
|
||||
content: formatReleaseNote(releaseNote),
|
||||
});
|
||||
}
|
||||
|
||||
return new Response(feed.rss2(), {
|
||||
headers: {
|
||||
"Content-Type": "application/xml; charset=utf-8",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a date string in the format day/month/year.
|
||||
*
|
||||
* Note: If release notes change to ISO format, this will need to be updated.
|
||||
* @param dateStr The date string to format.
|
||||
* @returns The passed in date string as a Date object.
|
||||
*/
|
||||
function formatRssDate(dateStr: string) {
|
||||
const splitDate = dateStr.split("/");
|
||||
if (splitDate.length !== 3) {
|
||||
throw new Error("Invalid date format");
|
||||
}
|
||||
|
||||
const day = Number(splitDate[0]);
|
||||
const month = Number(splitDate[1]) - 1;
|
||||
const year = Number(splitDate[2]);
|
||||
return new Date(year, month, day);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the release note entry for use as the content of the RSS feed.
|
||||
* @param releaseNote The release note to format.
|
||||
* @returns The formatted release note as a HTML string.
|
||||
*/
|
||||
function formatReleaseNote(releaseNote: ReleaseNote) {
|
||||
let content = `<p>
|
||||
If you encounter any issues, please report them on <a href="https://github.com/zen-browser/desktop/issues/">the issues page</a>.
|
||||
Thanks everyone for your feedback! ❤️
|
||||
</p>`;
|
||||
|
||||
if (releaseNote.image) {
|
||||
content += `<img src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/releases/${releaseNote.version}.png"
|
||||
alt="Release Image for version ${releaseNote.version}"
|
||||
style="max-width: 30em; width: 100%; border-radius: 0.5rem;"
|
||||
/>`;
|
||||
}
|
||||
|
||||
if (releaseNote.extra) {
|
||||
content += `<p>${releaseNote.extra.replace(/(\n)/g, "<br />")}</p>`;
|
||||
}
|
||||
|
||||
content += addReleaseNoteSection("⚠️ Breaking changes", releaseNote.breakingChanges);
|
||||
content += addReleaseNoteSection("✓ Fixes", releaseNote.fixes?.map(fixToReleaseNote));
|
||||
content += addReleaseNoteSection("🖌 Theme Changes", releaseNote.themeChanges)
|
||||
content += addReleaseNoteSection("⭐ Features", releaseNote.features);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
function addReleaseNoteSection(title: string, items?: string[]): string {
|
||||
if (!items) {
|
||||
return "";
|
||||
}
|
||||
|
||||
let content = `<h2>${title}</h2>`;
|
||||
content += `<ul>`;
|
||||
for (const item of items) {
|
||||
if (item && item.length > 0) {
|
||||
content += `<li>${item}</li>`;
|
||||
}
|
||||
}
|
||||
content += `</ul>`;
|
||||
return content;
|
||||
}
|
||||
|
||||
function fixToReleaseNote(fix?: Exclude<ReleaseNote['fixes'], undefined>[number]) {
|
||||
if (!fix || !fix.description || fix.description.length === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
let note = fix.description;
|
||||
if (fix.issue) {
|
||||
note += ` (<a href="https://github.com/zen-browser/desktop/issues/${fix.issue}" target="_blank">#${fix.issue}</a>)`;
|
||||
}
|
||||
return note;
|
||||
}
|
||||
@@ -9,9 +9,9 @@ import { Navigation } from "@/components/navigation";
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Zen Browser",
|
||||
description: "Download now and experience the Zen Browser",
|
||||
keywords: ["Zen", "Browser", "Zen Browser", "Web", "Internet", "Fast"],
|
||||
title: "Realm",
|
||||
description: "___ for the rest of us.",
|
||||
keywords: ["Realm", "Communication", "Realm Chat", "Communitity", "Internet", "Fast"],
|
||||
};
|
||||
|
||||
export default async function RootLayout({
|
||||
@@ -23,15 +23,6 @@ export default async function RootLayout({
|
||||
<html suppressHydrationWarning>
|
||||
<head>
|
||||
<link rel="me" href="https://fosstodon.org/@zenbrowser"></link>
|
||||
{/* Analitics */}
|
||||
<script
|
||||
defer
|
||||
src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/uma.js"
|
||||
data-host-url="https://uma.zen-browser.app"
|
||||
data-website-id="7148ef7c-5299-4ca1-9a18-9d6964e93b53"
|
||||
data-domains="zen-browser.app"
|
||||
></script>
|
||||
{/* End */}
|
||||
<link
|
||||
rel="alternate"
|
||||
type="application/rss+xml"
|
||||
@@ -44,8 +35,7 @@ export default async function RootLayout({
|
||||
<StyledComponentsRegistry>
|
||||
<div className="mt-5">
|
||||
{children}
|
||||
<Footer />
|
||||
<Navigation /> {/* At the bottom of the page */}
|
||||
<Navigation />
|
||||
</div>
|
||||
</StyledComponentsRegistry>
|
||||
</ThemeProvider>
|
||||
|
||||
@@ -7,7 +7,7 @@ export default function Home() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-start overflow-x-hidden">
|
||||
<Header />
|
||||
<Features />
|
||||
{/* <Features /> */}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#policy h1 {
|
||||
font-size: 2.5em;
|
||||
margin: 0.67em 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#policy {
|
||||
padding-top: 2.5em;
|
||||
margin-top: 4em;
|
||||
}
|
||||
|
||||
#policy h1:first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
#policy h2 {
|
||||
font-size: 2em;
|
||||
margin: 0.83em 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#policy h3 {
|
||||
font-size: 1.5em;
|
||||
margin: 1em 0;
|
||||
font-weight: semi-bold;
|
||||
}
|
||||
|
||||
#policy ul {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
#policy li {
|
||||
list-style: circle;
|
||||
margin-left: 1.1em;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
/* Link styles */
|
||||
#policy a {
|
||||
color: #007bff;
|
||||
transition: color 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
#policy a:hover {
|
||||
text-decoration: underline;
|
||||
color: #0056b3;
|
||||
}
|
||||
|
||||
#policy hr {
|
||||
margin: 2em 0;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
#policy p {
|
||||
margin: 1em 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
"use client";
|
||||
import Markdown from "react-markdown";
|
||||
import "./markdown.css";
|
||||
|
||||
export default function PrivacyPolicy() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||
<div
|
||||
id="policy"
|
||||
className="py-42 mx-auto my-52 flex min-h-screen w-full flex-col p-10 lg:w-1/3 lg:p-0"
|
||||
>
|
||||
<Markdown>
|
||||
{`
|
||||
# Privacy Policy
|
||||
* Last updated: 2024-08-12
|
||||
|
||||
## Introduction
|
||||
Welcome to Zen Browser! Your privacy is our priority. This Privacy Policy outlines the types of personal information we collect, how we use it, and the steps we take to protect your data when you use Zen Browser.
|
||||
|
||||
## 1. Information We Do Not Collect
|
||||
Zen Browser is designed with privacy in mind. We do not collect, store, or share any of your personal data. Here’s what that means:
|
||||
|
||||
* Crash reports can be sent to Mozilla Firefox. But, we do not collect any crash reports. Crash reports are sent securely to Mozilla Firefox to help improve the stability of the browser. They do not contain any personal information.
|
||||
|
||||
### **1.1. No Telemetry**
|
||||
We do not collect any telemetry data.
|
||||
|
||||
However, you can opt-in to share telemetry data to Mozilla for the improvement of FireFox (the base upon which the Zen Browser is built). It will be treated in accordance with their Privacy Policy which you can read about [here](https://www.mozilla.org/en-US/privacy/).
|
||||
|
||||
### **1.2. No Personal Data Collection**
|
||||
Zen Browser does not collect any personal information such as your IP address, browsing history, search queries, or form data.
|
||||
|
||||
### **1.3. No Third-Party Tracking**
|
||||
We do not allow third-party trackers or analytics tools to operate within Zen Browser. Your browsing activity remains entirely private and is not shared with any third party. Mozilla is not considered a third party as it is the base of Zen Browser.
|
||||
|
||||
## 2. Information Stored Locally on Your Device
|
||||
### **2.1. Browsing Data**
|
||||
Zen Browser stores certain data locally on your device to enhance your browsing experience. This includes:
|
||||
|
||||
* **Cookies**: Cookies are stored locally on your device and are not shared with Zen Browser or any third party. You have full control over the management of cookies through the browser’s settings.
|
||||
* **Cache and Temporary Files**: Zen Browser may store cache files and other temporary data locally to improve performance. These files can be cleared at any time through the browser’s settings.
|
||||
|
||||
### **2.2. Settings and Preferences**
|
||||
Any customizations, settings, and preferences you make within Zen Browser are stored locally on your device. We do not have access to or control over this data.
|
||||
|
||||
## 3. Sync Feature
|
||||
Zen Browser offers a "Sync" feature, this is implemented using Mozilla Firefox's Sync feature. This feature allows you to synchronize your bookmarks, history, passwords, and other data across multiple devices. For this feature to work, your data is encrypted and stored on Mozilla’s servers and is treated in accordance with their Privacy Policy. We, at Zen, cannot view any of this data.
|
||||
|
||||
* [Mozilla Firefox Sync](https://www.mozilla.org/en-US/privacy/mozilla-accounts/)
|
||||
* [This is how we store your passwords](https://support.mozilla.org/en-US/kb/how-firefox-securely-saves-passwords#:~:text=Firefox%20Desktop%20encrypts%20your%20passwords,cryptography%20to%20obscure%20your%20passwords.)
|
||||
|
||||
## 4. Data Security
|
||||
Although Zen Browser does not collect your data, we are committed to protecting the information that is stored locally on your device and, if you use the Sync feature, the encrypted data stored on Mozilla's servers. We recommend that you use secure passwords, enable device encryption, and regularly update your software to ensure your data remains safe.
|
||||
|
||||
* Note that most of the security measures are taken care by Mozilla Firefox.
|
||||
|
||||
## 5. Your Control
|
||||
### **5.1. Data Deletion**
|
||||
You have full control over all data stored locally on your device by Zen Browser. You can clear your browsing data, cookies, and cache at any time using the browser’s settings.
|
||||
|
||||
### **5.2. Do Not Track**
|
||||
Zen Browser automatically honors "Do Not Track" requests by default. We ensure that no tracking of your activity occurs, in compliance with this setting.
|
||||
|
||||
## 6. Our Website and Services
|
||||
|
||||
When you click on the "Download" button on our website, a number in the database is incremented to track the number of downloads. This is done to understand the popularity of the browser. No personal data is collected during the process.
|
||||
|
||||
### **6.1. External links**
|
||||
Zen Browser may contain links to external websites or services that are not owned or operated by us. We are not responsible for the content or privacy practices of these sites. We recommend that you review the privacy policies of these sites before providing them with any personal information.
|
||||
|
||||
## 7. Changes to This Privacy Policy
|
||||
We may update this Privacy Policy from time to time to reflect changes in our practices or legal requirements. We will notify you of any significant changes by updating the effective date at the top of this policy. Continued use of Zen Browser after such changes constitutes your acceptance of the new terms.
|
||||
|
||||
## 8. Other telemetry done by Mozilla Firefox
|
||||
|
||||
We try to disable all telemetry data collection in Zen Browser. But, we may have missed some. Check the below links for more information.
|
||||
|
||||
You can also optionally enable telemetry data collection and other Mozilla Research Studies in Zen Browser. This is disabled by default. You can enable it by going to the settings page.
|
||||
|
||||
* Please check [Firefox Privacy Notice](https://www.mozilla.org/en-US/privacy/) for more information.
|
||||
|
||||
## 9. Contact Us
|
||||
If you have any questions or concerns about this Privacy Policy or Zen Browser, please contact us at:
|
||||
|
||||
* Discord: [Zen Browser's Discord](https://discord.gg/zen-browser)
|
||||
* GitHub: [Organization](https://github.com/zen-browser)
|
||||
|
||||
---
|
||||
|
||||
By using Zen Browser, you agree to this Privacy Policy. Remember, with Zen, your privacy is in your hands.`}
|
||||
</Markdown>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import React from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { releaseNotes } from "@/lib/release-notes";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return [
|
||||
{ version: "latest" },
|
||||
...releaseNotes.map((note) => ({ version: note.version })),
|
||||
];
|
||||
}
|
||||
|
||||
export default function ReleaseNotePage({
|
||||
params,
|
||||
}: {
|
||||
params: { version: string };
|
||||
}) {
|
||||
const { version } = params;
|
||||
|
||||
if (version === "latest") {
|
||||
return redirect(`/release-notes/${releaseNotes[0].version}`);
|
||||
}
|
||||
|
||||
const currentIndex = releaseNotes.findIndex(
|
||||
(note) => note.version === version,
|
||||
);
|
||||
const releaseNote = releaseNotes[currentIndex];
|
||||
|
||||
if (!releaseNote) {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-center">
|
||||
<div className="flex h-screen flex-wrap items-center justify-center">
|
||||
<h1 className="mt-12 text-4xl font-bold">Release note not found</h1>
|
||||
<a href="/release-notes">
|
||||
<Button className="mt-4 items-center justify-center">
|
||||
Back to release notes
|
||||
</Button>
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
return redirect(`/release-notes#${version}`);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
import ReleaseNoteElement from "@/components/release-note";
|
||||
import { releaseNotes } from "@/lib/release-notes";
|
||||
import { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Release Notes",
|
||||
description: "Stay up to date with the latest changes to Zen Browser",
|
||||
keywords: [
|
||||
"Zen",
|
||||
"Browser",
|
||||
"Zen Browser",
|
||||
"Web",
|
||||
"Internet",
|
||||
"Fast",
|
||||
"Release",
|
||||
"Notes",
|
||||
],
|
||||
};
|
||||
|
||||
export default function ReleaseNotes() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||
<div className="py-42 flex min-h-screen flex-col justify-center px-10 lg:px-10 xl:px-10 2xl:w-3/5">
|
||||
<h1 className="mt-48 text-4xl font-bold">Release Notes</h1>
|
||||
<p className="mt-8 text-lg text-muted-foreground">
|
||||
Stay up to date with the latest changes to Zen Browser! Since the{" "}
|
||||
<a className="text-blue-500" href="#1.0.0-a.1">
|
||||
first release
|
||||
</a>{" "}
|
||||
till{" "}
|
||||
<a
|
||||
className="text-blue-500"
|
||||
href={`/release-notes/${releaseNotes[0].version}`}
|
||||
>
|
||||
{releaseNotes[0].version}
|
||||
</a>
|
||||
, we've been working hard to make Zen Browser the best it can be.
|
||||
<br />
|
||||
<br /> Thanks everyone for your feedback! ❤️
|
||||
</p>
|
||||
{releaseNotes.map((releaseNote) => (
|
||||
<ReleaseNoteElement key={releaseNote.version} data={releaseNote} />
|
||||
))}
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
import ThemePage from "@/components/theme-page";
|
||||
import { getAllThemes, getThemeFromId } from "@/lib/themes";
|
||||
import { Metadata, ResolvingMetadata } from "next";
|
||||
|
||||
export async function generateMetadata(
|
||||
{ params, searchParams }: any,
|
||||
parent: ResolvingMetadata,
|
||||
): Promise<Metadata> {
|
||||
const theme = params.theme;
|
||||
const themeData = await getThemeFromId(theme);
|
||||
if (!themeData) {
|
||||
return {
|
||||
title: "Theme not found",
|
||||
description: "Theme not found",
|
||||
};
|
||||
}
|
||||
return {
|
||||
title: themeData.name,
|
||||
description: themeData.description,
|
||||
keywords: [themeData.name, themeData.description],
|
||||
openGraph: {
|
||||
title: themeData.name,
|
||||
description: themeData.description,
|
||||
images: [
|
||||
{
|
||||
url: themeData.image,
|
||||
width: 500,
|
||||
height: 500,
|
||||
alt: themeData.name,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const themes = await getAllThemes();
|
||||
console.log(themes);
|
||||
return themes.map((theme) => ({
|
||||
theme: theme.id,
|
||||
}));
|
||||
}
|
||||
|
||||
export default async function ThemeInfoPage({
|
||||
params,
|
||||
}: {
|
||||
params: { theme: string };
|
||||
}) {
|
||||
const { theme } = params;
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||
<ThemePage themeID={theme} />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import MarketplacePage from "@/components/marketplace";
|
||||
import { getAllThemes } from "@/lib/themes";
|
||||
|
||||
export default async function ThemesMarketplace() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||
<MarketplacePage themes={await getAllThemes()} />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import WelcomePage from "@/components/welcome";
|
||||
|
||||
export default function Download() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||
<WelcomePage />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -27,12 +27,12 @@ export default function CoolHeaderText() {
|
||||
<>
|
||||
<div className="relative mb-3 mt-5 -translate-y-4 animate-fade-in text-balance bg-gradient-to-br from-30% to-black/40 bg-clip-text py-6 text-5xl font-extrabold font-semibold leading-none tracking-tighter text-transparent opacity-0 [--animation-delay:200ms] dark:from-white dark:to-white/40 sm:text-6xl md:text-7xl lg:text-8xl">
|
||||
<TextTitle>
|
||||
Stay focused, browse faster with Zen
|
||||
Chatting, for the rest of us.
|
||||
</TextTitle>
|
||||
</div>
|
||||
<div className="pointer-events-none absolute right-20 top-[-5px] mt-12 hidden h-fit w-fit !rotate-[15deg] transform animate-fade-in rounded-full bg-blue-500 px-3 py-1 text-white opacity-0 shadow [--animation-delay:400ms] md:block">
|
||||
{/* <div className="pointer-events-none absolute right-20 top-[-5px] mt-12 hidden h-fit w-fit !rotate-[15deg] transform animate-fade-in rounded-full bg-blue-500 px-3 py-1 text-white opacity-0 shadow [--animation-delay:400ms] md:block">
|
||||
Alpha Version
|
||||
</div>
|
||||
</div> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,8 +4,43 @@ import { ArrowRightIcon } from "@radix-ui/react-icons";
|
||||
import { useInView } from "framer-motion";
|
||||
import { useRef } from "react";
|
||||
import { Button } from "./ui/button";
|
||||
import { ChevronDown } from "lucide-react";
|
||||
import { AppWindow, AppWindowIcon, AppWindowMac, ChevronDown } from "lucide-react";
|
||||
import CoolHeaderText from "./cool-header-text";
|
||||
import Particles from "./ui/particles";
|
||||
import confetti from "canvas-confetti";
|
||||
|
||||
const download = () => {
|
||||
throwConfetti()
|
||||
window.location.replace(`https://realm.abunchofknowitalls.com/Realm.exe`)
|
||||
}
|
||||
|
||||
const throwConfetti = () => {
|
||||
const end = Date.now() + 3 * 1000; // 3 seconds
|
||||
const colors = ["#a786ff", "#fd8bbc", "#eca184", "#f8deb1"];
|
||||
const frame = () => {
|
||||
if (Date.now() > end) return;
|
||||
|
||||
confetti({
|
||||
particleCount: 2,
|
||||
angle: 60,
|
||||
spread: 55,
|
||||
startVelocity: 60,
|
||||
origin: { x: 0, y: 0.5 },
|
||||
colors,
|
||||
});
|
||||
confetti({
|
||||
particleCount: 2,
|
||||
angle: 120,
|
||||
spread: 55,
|
||||
startVelocity: 60,
|
||||
origin: { x: 1, y: 0.5 },
|
||||
colors,
|
||||
});
|
||||
requestAnimationFrame(frame);
|
||||
};
|
||||
frame();
|
||||
};
|
||||
|
||||
export default function Header() {
|
||||
const ref = useRef(null);
|
||||
const inView = useInView(ref, { once: true, margin: "-100px" });
|
||||
@@ -19,27 +54,34 @@ export default function Header() {
|
||||
<CoolHeaderText />
|
||||
</div>
|
||||
<p className="mb-12 -translate-y-4 animate-fade-in text-balance text-lg tracking-tight text-gray-400 opacity-0 [--animation-delay:400ms] md:text-xl">
|
||||
Beautifully designed, privacy-focused, and packed with features.
|
||||
<br className="hidden md:block" /> We care about your experience, not
|
||||
your data.
|
||||
Collaborate, Communicate, Connect
|
||||
<br className="hidden md:block" /> Because that's what you wanted and you deserve to own your content.
|
||||
</p>
|
||||
<div className="flex w-full flex-col justify-center md:flex-row">
|
||||
<a href="/download">
|
||||
<Button className="-translate-y-4 animate-fade-in gap-1 text-white opacity-0 ease-in-out [--animation-delay:600ms] dark:text-black">
|
||||
<span>Download Zen Now </span>
|
||||
<ArrowRightIcon className="ml-1 size-4 transition-transform duration-300 ease-in-out group-hover:translate-x-1" />
|
||||
</Button>
|
||||
</a>
|
||||
<a
|
||||
href="#features"
|
||||
className="-translate-y-4 animate-fade-up opacity-0 [--animation-delay:800ms]"
|
||||
>
|
||||
<Button variant="ghost" className="mt-4 md:ml-4 md:mt-0">
|
||||
Start Exploring <ChevronDown className="ml-1 size-4" />
|
||||
<a >
|
||||
<Button className="-translate-y-4 animate-fade-in gap-1 text-white opacity-0 ease-in-out [--animation-delay:600ms] dark:text-black" onClick={download}>
|
||||
<span>Download Realm for </span>
|
||||
<svg className="ml-1 size-4 transition-transform duration-300 ease-in-out group-hover:translate-x-1" xmlns="http://www.w3.org/2000/svg" width="64" height="64" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 640 640"><path d="M.2 298.669L0 90.615l256.007-34.76v242.814H.201zM298.658 49.654L639.905-.012v298.681H298.657V49.654zM640 341.331l-.071 298.681L298.669 592V341.332h341.33zM255.983 586.543L.189 551.463v-210.18h255.794v245.26z"/></svg>
|
||||
</Button>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
<Particles
|
||||
className="absolute inset-0 -z-10 hidden dark:block"
|
||||
quantity={50}
|
||||
ease={70}
|
||||
size={0.05}
|
||||
staticity={70}
|
||||
color="#ffffff"
|
||||
/>
|
||||
<Particles
|
||||
className="absolute inset-0 -z-10 block dark:hidden"
|
||||
quantity={30}
|
||||
ease={70}
|
||||
size={0.05}
|
||||
staticity={70}
|
||||
color="#000000"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
"use client";
|
||||
import { ny } from "@/lib/utils";
|
||||
import React from "react";
|
||||
import CachedImage from "./CachedImage";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function Logo({ withText, ...props }: any) {
|
||||
return (
|
||||
<div className="m-0 flex items-center" {...props}>
|
||||
<CachedImage
|
||||
src={`www/public/logos/zen-black.svg`}
|
||||
<Image
|
||||
src={`logos/realm-black.svg`}
|
||||
width={40}
|
||||
height={40}
|
||||
alt="Zen Logo"
|
||||
alt="Realm Logo"
|
||||
className={ny(
|
||||
"transition-all duration-300 hover:scale-110",
|
||||
withText && "mr-2",
|
||||
)}
|
||||
/>
|
||||
{withText && <span className="ml-2 text-2xl font-bold">zen</span>}
|
||||
{withText && <span className="ml-2 text-2xl font-bold">Realm</span>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -53,62 +53,11 @@ export function MobileNav() {
|
||||
variant="ghost"
|
||||
className="ml-auto mr-2 px-0 text-base hover:bg-transparent focus-visible:bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0"
|
||||
>
|
||||
<SidebarOpen className="size-6" />
|
||||
<span className="sr-only">Toggle Menu</span>
|
||||
<SidebarOpen className="size-6 opacity-0" />
|
||||
</Button>
|
||||
</div>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="left" className="pr-0">
|
||||
<MobileLink
|
||||
href="/"
|
||||
className="flex items-center"
|
||||
onOpenChange={setOpen}
|
||||
>
|
||||
<Logo withText />
|
||||
</MobileLink>
|
||||
<ScrollArea className="mt-4 h-[calc(100vh-8rem)] pl-6">
|
||||
<div className="flex flex-col space-y-3">
|
||||
<MobileLink href="/download" onOpenChange={setOpen}>
|
||||
<div>Download</div>
|
||||
<p className="text-xs opacity-60">
|
||||
Get the latest version of Zen Browser.
|
||||
</p>
|
||||
</MobileLink>
|
||||
<MobileLink href="/themes" onOpenChange={setOpen}>
|
||||
<div>Theme Store</div>
|
||||
<p className="text-xs opacity-60">
|
||||
Customize your browsing experience.
|
||||
</p>
|
||||
</MobileLink>
|
||||
<MobileLink href="/release-notes" onOpenChange={setOpen}>
|
||||
<div>Release Notes</div>
|
||||
<p className="text-xs opacity-60">
|
||||
Stay up to date with the latest changes.
|
||||
</p>
|
||||
</MobileLink>
|
||||
<MobileLink
|
||||
href="https://patreon.com/zen_browser?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink"
|
||||
rel="noopener noreferrer"
|
||||
onOpenChange={setOpen}
|
||||
target="_blank"
|
||||
>
|
||||
<div>Donate {"<"}3</div>
|
||||
<p className="text-xs opacity-60">Support the project</p>
|
||||
</MobileLink>
|
||||
{components.map(({ title, href, description, isTargetBlank, rel }) => (
|
||||
<MobileLink
|
||||
href={href}
|
||||
key={href}
|
||||
target={isTargetBlank ? "_blank" : "_self"}
|
||||
onOpenChange={setOpen}
|
||||
rel={rel}
|
||||
>
|
||||
<div>{title}</div>
|
||||
<p className="text-xs opacity-60">{description}</p>
|
||||
</MobileLink>
|
||||
))}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
<SheetContent side="left" className="pr-0">
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
);
|
||||
|
||||
@@ -126,88 +126,7 @@ export function Navigation() {
|
||||
<Logo withText />
|
||||
</NavigationMenuLink>
|
||||
</NavigationMenuItem>
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuTrigger>Getting Started</NavigationMenuTrigger>
|
||||
<NavigationMenuContent>
|
||||
<ul className="grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]">
|
||||
<li className="row-span-3">
|
||||
<NavigationMenuLink asChild>
|
||||
<a
|
||||
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md"
|
||||
href="/"
|
||||
>
|
||||
<Logo />
|
||||
<div className="mb-2 mt-4 text-lg font-medium">
|
||||
Zen Browser
|
||||
</div>
|
||||
<p className="text-sm leading-tight text-muted-foreground">
|
||||
Firefox based browser with a focus on privacy and
|
||||
customization.
|
||||
</p>
|
||||
</a>
|
||||
</NavigationMenuLink>
|
||||
</li>
|
||||
<ListItem href="/download" title="Download">
|
||||
Start using Zen Browser today with just a few clicks.
|
||||
</ListItem>
|
||||
<ListItem href="/themes" title="Mods Store">
|
||||
Customize your browser with a variety of Mods!
|
||||
</ListItem>
|
||||
<ListItem href="/release-notes" title="Release Notes">
|
||||
Stay up to date with the latest changes.
|
||||
</ListItem>
|
||||
</ul>
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuTrigger>
|
||||
<HeartFilledIcon className="text-red-500" />
|
||||
<span className="ml-2">Donate</span>
|
||||
</NavigationMenuTrigger>
|
||||
<NavigationMenuContent>
|
||||
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px]">
|
||||
<ListItem2
|
||||
title="Patreon"
|
||||
href="https://patreon.com/zen_browser?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Support us on Patreon and get exclusive rewards and keep the
|
||||
project alive.
|
||||
</ListItem2>
|
||||
<ListItem2
|
||||
title="Ko-Fi"
|
||||
href="https://ko-fi.com/zen_browser?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Ko-fi is a way to support us with a one-time donation and help
|
||||
us keep the project alive.
|
||||
</ListItem2>
|
||||
</ul>
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuTrigger>{"Useful Links"}</NavigationMenuTrigger>
|
||||
<NavigationMenuContent>
|
||||
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px]">
|
||||
{components.map(
|
||||
({ description, href, title, isTargetBlank, rel }) => (
|
||||
<ListItem
|
||||
key={title}
|
||||
title={title}
|
||||
href={href}
|
||||
target={isTargetBlank ? "_blank" : "_self"}
|
||||
rel={rel}
|
||||
>
|
||||
{description}
|
||||
</ListItem>
|
||||
),
|
||||
)}
|
||||
</ul>
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
<ModeToggle />
|
||||
{/* <ModeToggle /> */}
|
||||
</NavigationMenuList>
|
||||
</NavigationMenu>
|
||||
</div>
|
||||
|
||||