3.0 Beta 2

This commit is contained in:
2026-04-10 21:57:29 +02:00
parent 67918644e0
commit a01b5347d6
65 changed files with 1619 additions and 175 deletions

View File

@@ -0,0 +1,268 @@
@if (cookieConsentOpen) {
<div id="cookieConsent" tuiCardLarge>
<h1>
<tui-icon icon="@tui.cookie"></tui-icon>
{{'home.cookies'|translate}}
</h1>
<p>{{'home.cookiesDesc'|translate}}</p>
<button (click)="consent()" tuiButton iconStart="@tui.check">
{{'home.understood'|translate}}
</button>
</div>
}
<ng-template [(tuiDialog)]="androidBetaTestDialogOpen"
[tuiDialogOptions]="{label: translateService.instant('home.requestAlphaAccess'), size: 's'}">
<span>{{'home.joinGoogleGroupWhy'|translate}}</span>
<button (click)="enterGGroup()" style="width: 100%; margin-top: 10px" tuiButton iconStart="@tui.users">{{'home.joinGoogleGroup'|translate}}</button>
</ng-template>
<ng-template [(tuiDialog)]="appleBetaTestDialogOpen"
[tuiDialogOptions]="{label: translateService.instant('home.requestAlphaAccess'), size: 's'}">
<span>{{'home.testFlightDesc'|translate}}</span>
<button (click)="openTestFlight()" style="width: 100%; margin-top: 10px" tuiButton >
<i class="fa-brands fa-apple" style="font-size: 25px"></i>
{{'home.testFlight'|translate}}
</button>
</ng-template>
<ng-template [(tuiDialog)]="msBetaTestDialogOpen"
[tuiDialogOptions]="{label: translateService.instant('home.requestAlphaAccess'), size: 's'}">
<span>{{'home.microsoftStoreDesc'|translate}}</span>
<button (click)="openMsStore()" style="width: 100%; margin-top: 10px" tuiButton >
<i class="fa-brands fa-microsoft" style="font-size: 25px"></i>
{{'home.microsoftStore'|translate}}
</button>
</ng-template>
<main>
<section id="hero">
<div id="imgScroller" [style]="'opacity:'+scrollerOpacity">
<img [src]="'/images/homepage/new_customi_'+theme+'.png'" alt="ARYA_BLUE_IMAGES">
<img [src]="'/images/homepage/new_dm_'+theme+'.png'" alt="ARYA_BLUE_IMAGES">
<img [src]="'/images/homepage/new_network_'+theme+'.png'" alt="ARYA_BLUE_IMAGES">
<img [src]="'/images/homepage/new_network_discovery_'+theme+'.png'" alt="ARYA_BLUE_IMAGES">
<img [src]="'/images/homepage/new_picture_stats_'+theme+'.png'" alt="ARYA_BLUE_IMAGES">
<img [src]="'/images/homepage/new_pictures_'+theme+'.png'" alt="ARYA_BLUE_IMAGES">
</div>
<div id="introducer">
<svg viewBox="0 0 350 60" width="1000px" height="200px">
<text class="logo" x="50%" y="80%" text-anchor="middle">Chatenium</text>
</svg>
<div id="quickFeatures">
<h1>
{{ 'aChatProgram'|translate }}
</h1>
<p class="chtn_desc">
{{ 'whatIsChtn'|translate }}
</p>
<button style="width: 350px" routerLink="/chat" tuiButton iconStart="@tui.globe">
{{'home.enterChtnOnWeb'|translate}}
</button>
<button style="width: 350px" appearance="secondary" (click)="openRoadmap()" tuiButton iconStart="@tui.chart-no-axes-gantt">
Roadmap
</button>
<p style="display: flex; align-items: center; gap: 5px;">
<tui-icon icon="@tui.mouse"></tui-icon>
{{ 'scrollDownForMore'|translate }}
</p>
</div>
</div>
</section>
<section class="detailedFeature">
<div class="style">
<h1>{{ 'home.chtn'|translate }} <span style="color: var(--tui-status-negative)"><tui-icon icon="@tui.circle-gauge"></tui-icon>
{{ 'home.adaptsToYou'|translate }}</span></h1>
<p>{{ 'home.adaptsToYouDesc'|translate }}</p>
<div class="cardList">
<div tuiCardLarge>
<tui-icon icon="@tui.globe" style="font-size: 80px"></tui-icon>
<h2>{{ 'home.chtnOnWeb'|translate }}</h2>
<p>{{ 'home.chtnOnWebDesc'|translate }}</p>
</div>
<div tuiCardLarge>
<fa-icon [icon]="faAndroid"></fa-icon>
<h2>{{ 'home.chtnOnAndroid'|translate }}</h2>
<div tuiBadge>{{'home.openBeta'|translate}}</div>
<p>{{ 'home.chtnOnAndroidDesc'|translate }}</p>
</div>
<div tuiCardLarge>
<fa-icon [icon]="faApple"></fa-icon>
<h2>{{ 'home.chtnOnApple'|translate }}</h2>
<div tuiBadge>{{'home.openBeta'|translate}}</div>
<p>{{ 'home.chtnOnAppleDesc'|translate }}</p>
</div>
<div tuiCardLarge>
<fa-icon [icon]="faWindows"></fa-icon>
<h2>{{ 'home.chtnOnWindows'|translate }}</h2>
<div tuiBadge>{{'home.openBeta'|translate}}</div>
<p>{{ 'home.chtnOnWindowsDesc'|translate }}</p>
</div>
<div tuiCardLarge>
<fa-icon [icon]="faLinux"></fa-icon>
<h2>{{ 'home.chtnOnLinux'|translate }}</h2>
<div tuiBadge>{{'home.openBeta'|translate}}</div>
<p>{{ 'home.chtnOnLinuxDesc'|translate }}</p>
</div>
<div tuiCardLarge>
<fa-icon [icon]="faRecordVinyl"></fa-icon>
<h2>{{ 'home.chtnEcho'|translate }}</h2>
<div tuiBadge>{{'home.openBeta'|translate}}</div>
<p>{{ 'home.chtnEchoDesc'|translate }}</p>
</div>
<div tuiCardLarge>
<fa-icon [icon]="faDesktop"></fa-icon>
<h2>{{ 'home.chtnReson'|translate }}</h2>
<div tuiBadge>{{'home.openBeta'|translate}}</div>
<p>{{ 'home.chtnResonDesc'|translate }}</p>
</div>
</div>
</div>
</section>
<section class="detailedFeature">
<div class="style">
<h1>{{ 'home.chtnIs'|translate }} <span style="color: var(--tui-status-positive)"><tui-icon icon="@tui.lock"></tui-icon>
{{ 'home.secure'|translate }}</span></h1>
<p>{{ 'home.secureDesc'|translate }}</p>
<div class="cardList">
<div tuiCardLarge>
<tui-icon icon="@tui.file"></tui-icon>
<h2>{{ 'home.secureCdn'|translate }}</h2>
<p>{{ 'home.secureCdnDesc'|translate }}</p>
</div>
<div tuiCardLarge>
<tui-icon icon="@tui.message-circle"></tui-icon>
<h2>{{ 'home.encryptedText'|translate }}</h2>
<p>{{ 'home.encryptedTextDesc'|translate }}</p>
</div>
<div tuiCardLarge>
<tui-icon icon="@tui.shredder"></tui-icon>
<h2>{{ 'home.zeroDataCollection'|translate }}</h2>
<p>{{ 'home.zeroDataCollectionDesc'|translate }}</p>
</div>
<div tuiCardLarge>
<tui-icon icon="@tui.phone"></tui-icon>
<h2>{{ 'home.secureCalling'|translate }}</h2>
<p>{{ 'home.secureCallingDesc'|translate }}</p>
</div>
<div tuiCardLarge>
<tui-icon icon="@tui.footprints"></tui-icon>
<h2>{{ 'home.zeroDigitalFootprint'|translate }}</h2>
<p>{{ 'home.zeroDigitalFootprintDesc'|translate }}</p>
</div>
</div>
</div>
</section>
<section class="detailedFeature" style="margin-bottom: 5%;">
<div class="style">
<h1>{{ 'home.weAreExcitedFor'|translate }} <span style="color: var(--tui-status-negative)"><tui-icon icon="@tui.heart"></tui-icon>
{{ 'home.you'|translate }}</span></h1>
<p>{{ 'home.weAreExcitedForYouDesc'|translate }}</p>
<div class="cardList">
<div tuiCardLarge>
<tui-icon icon="@tui.globe" style="font-size: 80px"></tui-icon>
<h2><a routerLink="/chat">{{ 'home.enterChtnOnWeb'|translate }}</a></h2>
<p>{{ 'home.enterChtnOnWebDesc'|translate }}</p>
</div>
<div tuiCardLarge>
<fa-icon [icon]="faGooglePlay"></fa-icon>
<h2>{{ 'home.downloadChtnOnAndroid'|translate }}</h2>
<div tuiBadge>{{'home.openBeta'|translate}}</div>
<p>{{'home.openBetaDesc'|translate}}</p>
<button (click)="androidBetaTestDialogOpen = true" tuiButton iconStart="@tui.door-open">{{'home.requestAlphaAccess'|translate}}</button>
</div>
<div tuiCardLarge>
<fa-icon [icon]="faAppStoreIos"></fa-icon>
<h2>{{ 'home.downloadChtnOnApple'|translate }}</h2>
<div tuiBadge>{{'home.openBeta'|translate}}</div>
<p>{{'home.openBetaDesc'|translate}}</p>
<button (click)="appleBetaTestDialogOpen = true" tuiButton iconStart="@tui.door-open">{{'home.requestAlphaAccess'|translate}}</button>
</div>
<div tuiCardLarge>
<fa-icon [icon]="faMicrosoft"></fa-icon>
<h2>{{ 'home.downloadOnWindows'|translate }}</h2>
<div tuiBadge>{{'home.openBeta'|translate}}</div>
<p>{{'home.openBetaDesc'|translate}}</p>
<button (click)="msBetaTestDialogOpen = true" tuiButton iconStart="@tui.door-open">{{'home.requestAlphaAccess'|translate}}</button>
</div>
</div>
</div>
</section>
</main>
<footer>
<h1>Chatenium</h1>
<span>2026 &copy;</span>
<div style="display: flex; gap: 10px; margin-top: 10px;">
<button routerLink="/privacy" tuiButton iconStart="@tui.lock">
{{'home.privacyPolicy'|translate}}
</button>
<button routerLink="/tos" tuiButton iconStart="@tui.scroll">
{{'home.tos'|translate}}
</button>
<button (click)="openHelp()" tuiButton iconStart="@tui.badge-question-mark">
{{'home.help'|translate}}
</button>
<button (click)="openBlog()" tuiButton iconStart="@tui.scroll-text">
{{'home.blog'|translate}}
</button>
<button (click)="openAPISpecs()" tuiButton iconStart="@tui.braces">
{{'home.apiSpecs'|translate}}
</button>
</div>
</footer>

View File

@@ -0,0 +1,167 @@
* {
font-family: kinnBook, serif !important;
}
main {
#hero {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100vh;
#imgScroller {
position: fixed;
top: -500px;
left: 0;
transform: rotateX(35deg);
animation: scrollerAnim 30s infinite ease-in-out;
filter: blur(15px);
opacity: 0.5;
pointer-events: none;
img {
width: 100%;
}
}
#introducer {
z-index: 9999;
font-family: kinnBook, serif;
#quickFeatures {
display: flex;
align-items: center;
justify-content: center;
gap: 5px;
flex-direction: column;
h1 {
font-size: 25px;
}
p {
font-size: 18px;
}
.chtn_desc {
width: 500px;
}
}
}
@keyframes scrollerAnim {
0% {
transform: translateY(450px);
}
50% {
transform: translateY(-450px);
}
100% {
transform: translateY(450px);
}
}
}
.detailedFeature {
z-index: 9999;
padding: 50px 15% 50px 15%;
.style {
background: var(--tui-background-base-alt);
width: 100%;
padding: 20px 20px 20px 50px;
border-radius: 50px;
.cardList {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 10px;
div {
p {
font-size: 15px;
}
h2 {
display: flex;
align-items: center;
gap: 5px;
margin: 0;
}
i, fa-icon {
font-size: 75px;
}
a {
color: var(--tui-background-accent-1);
text-decoration: none;
}
}
}
}
h1 {
font-size: 50px;
font-weight: bolder;
}
tui-icon {
font-size: 50px;
}
p {
font-size: 20px;
}
}
}
.logo {
font-size: 55px;
stroke: var(--tui-background-accent-1);
fill: transparent;
font-family: kinnBook, serif !important;
font-weight: bold;
stroke-width: 2;
stroke-dasharray: 50 20; /* Dashes and gaps */
stroke-dashoffset: 0;
animation: moveStroke 2s linear infinite;
}
@keyframes moveStroke {
to {
stroke-dashoffset: -70; /* Negative offset moves the dashes endlessly */
}
}
footer {
height: 25svh;
width: 100vw;
background: var(--tui-background-base-alt);
padding: 50px;
p {
font-size: 25px;
font-family: kinnBook, serif;
font-weight: bold;
}
}
#cookieConsent {
position: fixed;
right: 25px;
bottom: 25px;
z-index: 9999;
width: 350px;
height: 300px;
h1 {
display: flex;
align-items: center;
gap: 10px;
margin: 0;
}
}

View File

@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Homepage } from './homepage';
describe('Homepage', () => {
let component: Homepage;
let fixture: ComponentFixture<Homepage>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [Homepage],
}).compileComponents();
fixture = TestBed.createComponent(Homepage);
component = fixture.componentInstance;
await fixture.whenStable();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,153 @@
import {Component, HostListener, inject} from '@angular/core';
import {Router, RouterLink} from '@angular/router';
import {TranslatePipe, TranslateService} from '@ngx-translate/core';
import {TUI_DARK_MODE, TuiAppearance, TuiButton, TuiDialog, TuiIcon} from '@taiga-ui/core';
import {TuiCardLarge} from '@taiga-ui/layout';
import {TuiBadge} from '@taiga-ui/kit';
import {FaIconComponent} from '@fortawesome/angular-fontawesome';
import {
faAndroid,
faApple,
faAppStoreIos,
faGooglePlay,
faLinux,
faMicrosoft,
faWindows
} from '@fortawesome/free-brands-svg-icons';
import {faDesktop, faRecordVinyl} from '@fortawesome/free-solid-svg-icons';
@Component({
selector: 'app-homepage',
imports: [
TranslatePipe,
TuiButton,
RouterLink,
TuiIcon,
TuiCardLarge,
TuiDialog,
TuiAppearance,
TuiBadge,
FaIconComponent
],
templateUrl: './homepage.html',
styleUrl: './homepage.scss',
})
export class Homepage {
public router = inject(Router);
translateService = inject(TranslateService)
darkMode = inject(TUI_DARK_MODE)
get theme(): string {
return this.darkMode() ? "dark" : "light"
}
androidBetaTestDialogOpen = false;
appleBetaTestDialogOpen = false;
msBetaTestDialogOpen = false;
cookieConsentOpen = false;
mainFeatureIndex = 0
features: { icon: string, title: string, color: string }[] = [
{
icon: "circle-gauge",
title: "fast",
color: "#ff3d32"
},
{
icon: "lock",
title: "secure",
color: "#22c55e"
},
{
icon: "speech",
title: "independent",
color: "#326fd1"
}
]
scrollerOpacity = 1;
@HostListener('window:scroll', ['$event'])
onScroll(event: Event) {
const scrollTop = window.scrollY;
const docHeight = document.getElementById("hero")?.clientHeight ?? 0;
let scrollPercent = scrollTop / docHeight;
if (scrollPercent > 1) scrollPercent = 1; // clamp at max
this.scrollerOpacity = 1 - scrollPercent; // invert
}
contact() {
const mail = 'mailto:personal@alms.hu';
const a = document.createElement('a');
a.href = mail;
a.click();
}
enterGGroup() {
window.open('https://groups.google.com/g/chatenium-closed-alpha-testing', '_blank');
}
openTestFlight() {
window.open('https://testflight.apple.com/join/ATGmZ8mx', '_blank')
}
openRoadmap() {
window.open('https://help.chatenium.hu/s/169154db-df3e-44cb-980d-2db1915ecdf8', '_blank')
}
openMsStore() {
window.open('https://apps.microsoft.com/detail/9p1xq5vb62b0?ocid=webpdpshare', '_blank')
}
openBlog() {
window.open('https://blog.chatenium.hu', '_blank')
}
openHelp() {
window.open('https://help.chatenium.hu/s/06a56637-0050-4332-b397-ea3ca8fa91a5', '_blank')
}
openAPISpecs() {
window.open('https://apispecs.chatenium.hu', '_blank')
}
gotoFunctions() {
location.href = "#functions"
}
stepFeature = () => {
console.log(this.features, this.mainFeatureIndex + 1, this.mainFeatureIndex);
if (this.features && this.features[this.mainFeatureIndex + 1] !== undefined) {
this.mainFeatureIndex++;
} else {
this.mainFeatureIndex = 0;
}
};
consent() {
localStorage.setItem("cookieConsentRead", "true")
this.cookieConsentOpen = false;
}
ngOnInit(): void {
const consentOk = localStorage.getItem("cookieConsentRead")
if (!consentOk) {
this.cookieConsentOpen = true
}
}
protected readonly window = window;
protected readonly scroll = scroll;
protected readonly localStorage = localStorage;
protected readonly faApple = faApple;
protected readonly faAndroid = faAndroid;
protected readonly faWindows = faWindows;
protected readonly faLinux = faLinux;
protected readonly faRecordVinyl = faRecordVinyl;
protected readonly faDesktop = faDesktop;
protected readonly faGooglePlay = faGooglePlay;
protected readonly faAppStoreIos = faAppStoreIos;
protected readonly faMicrosoft = faMicrosoft;
}