main sections, sessions, games in left menu
This commit is contained in:
parent
d8804c0030
commit
ac43777da9
14
package-lock.json
generated
14
package-lock.json
generated
@ -25,6 +25,7 @@
|
||||
"@tinkoff/ng-dompurify": "3.0.0",
|
||||
"dompurify": "2.2.9",
|
||||
"fast-average-color": "^9.1.1",
|
||||
"moment": "^2.29.4",
|
||||
"rxjs": "~7.5.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.11.4"
|
||||
@ -8044,6 +8045,14 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.29.4",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
@ -17786,6 +17795,11 @@
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.29.4",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
|
@ -27,6 +27,7 @@
|
||||
"@tinkoff/ng-dompurify": "3.0.0",
|
||||
"dompurify": "2.2.9",
|
||||
"fast-average-color": "^9.1.1",
|
||||
"moment": "^2.29.4",
|
||||
"rxjs": "~7.5.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.11.4"
|
||||
|
@ -9,5 +9,10 @@
|
||||
background-color: var(--sk-accent);
|
||||
border: none;
|
||||
border-radius: var(--sk-br-m);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
projects/ui/src/lib/game/game.component.html
Normal file
10
projects/ui/src/lib/game/game.component.html
Normal file
@ -0,0 +1,10 @@
|
||||
<div class="sk-game">
|
||||
<skirda-image-icon [src]="game.image"></skirda-image-icon>
|
||||
<div class="sk-game-info">
|
||||
<div class="info-game-line">
|
||||
<skirda-heading size="6">{{game.title}}</skirda-heading>
|
||||
</div>
|
||||
<skirda-text>description</skirda-text>
|
||||
</div>
|
||||
<skirda-icon name="play" size="16" (click)="run(game)" color="var(--sk-accent)"></skirda-icon>
|
||||
</div>
|
31
projects/ui/src/lib/game/game.component.scss
Normal file
31
projects/ui/src/lib/game/game.component.scss
Normal file
@ -0,0 +1,31 @@
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
.sk-game {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sk-gap-l);
|
||||
padding: var(--sk-gap-l);
|
||||
border-radius: var(--sk-br-m);
|
||||
transition: 0.1s ease;
|
||||
opacity: 0.5;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.sk-game-info {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
|
||||
.sk-game {
|
||||
opacity: 1;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
23
projects/ui/src/lib/game/game.component.spec.ts
Normal file
23
projects/ui/src/lib/game/game.component.spec.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { GameComponent } from './game.component';
|
||||
|
||||
describe('GameComponent', () => {
|
||||
let component: GameComponent;
|
||||
let fixture: ComponentFixture<GameComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ GameComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(GameComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
20
projects/ui/src/lib/game/game.component.ts
Normal file
20
projects/ui/src/lib/game/game.component.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Game } from 'src/app/interfaces/game.interface'
|
||||
|
||||
@Component({
|
||||
selector: 'skirda-game[game]',
|
||||
templateUrl: './game.component.html',
|
||||
styleUrls: ['./game.component.scss']
|
||||
})
|
||||
export class GameComponent implements OnInit {
|
||||
@Input() game!: Game
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
run(game: Game) {
|
||||
console.log('Game to run ' + game.title)
|
||||
}
|
||||
}
|
24
projects/ui/src/lib/game/game.module.ts
Normal file
24
projects/ui/src/lib/game/game.module.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { GameComponent } from './game.component';
|
||||
import { ImageIconModule } from '../image-icon/image-icon.module'
|
||||
import { TypographyModule } from '../typography/typography.module'
|
||||
import { TagModule } from '../tag/tag.module'
|
||||
import { IconModule } from '../icon/icon.module'
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
GameComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
ImageIconModule,
|
||||
TypographyModule,
|
||||
TagModule,
|
||||
IconModule
|
||||
],
|
||||
exports: [
|
||||
GameComponent
|
||||
]
|
||||
})
|
||||
export class GameModule { }
|
@ -1,7 +1,8 @@
|
||||
export interface Session {
|
||||
id: string;
|
||||
icon: string;
|
||||
title: string;
|
||||
status?: string;
|
||||
version: string;
|
||||
expires: string | Date;
|
||||
expires: Date;
|
||||
}
|
||||
|
8
projects/ui/src/lib/pipes/countdown.pipe.spec.ts
Normal file
8
projects/ui/src/lib/pipes/countdown.pipe.spec.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { CountdownPipe } from './countdown.pipe';
|
||||
|
||||
describe('CountdownPipe', () => {
|
||||
it('create an instance', () => {
|
||||
const pipe = new CountdownPipe();
|
||||
expect(pipe).toBeTruthy();
|
||||
});
|
||||
});
|
28
projects/ui/src/lib/pipes/countdown.pipe.ts
Normal file
28
projects/ui/src/lib/pipes/countdown.pipe.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import moment from 'moment'
|
||||
import { map, min, timer } from 'rxjs'
|
||||
|
||||
@Pipe({
|
||||
name: 'countdown'
|
||||
})
|
||||
export class CountdownPipe implements PipeTransform {
|
||||
|
||||
transform(value: Date) {
|
||||
return timer(0, 1000).pipe(map((_) => this.getCountDown(value)))
|
||||
}
|
||||
|
||||
getCountDown (value: Date) {
|
||||
let currentTime = new Date()
|
||||
let duration = moment.duration(value.getTime() - currentTime.getTime(), 'milliseconds')
|
||||
|
||||
let days = duration.days(), hours = duration.hours(), minutes = duration.minutes(), seconds = duration.seconds()
|
||||
if (days > 0)
|
||||
return `${days} ${days == 1 ? 'day' : 'days'}`
|
||||
else
|
||||
return `${this.pad(hours)}:${this.pad(minutes)}:${this.pad(seconds)}`
|
||||
}
|
||||
|
||||
private pad (value: number) {
|
||||
return value.toString().padStart(2, '0')
|
||||
}
|
||||
}
|
18
projects/ui/src/lib/pipes/pipes.module.ts
Normal file
18
projects/ui/src/lib/pipes/pipes.module.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CountdownPipe } from './countdown.pipe';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
CountdownPipe
|
||||
],
|
||||
imports: [
|
||||
CommonModule
|
||||
],
|
||||
exports: [
|
||||
CountdownPipe
|
||||
]
|
||||
})
|
||||
export class PipesModule { }
|
@ -9,32 +9,13 @@
|
||||
align-items: center;
|
||||
padding: var(--sk-gap-l);
|
||||
gap: var(--sk-gap-l);
|
||||
opacity: 0.75;
|
||||
mix-blend-mode: overlay;
|
||||
transition: 0.2s ease;
|
||||
opacity: 0.5;
|
||||
transition: 0.1s ease;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
|
||||
&:before {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
mix-blend-mode: overlay;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
transition: 0.2s ease;
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,11 +23,7 @@
|
||||
|
||||
.sk-section {
|
||||
opacity: 1;
|
||||
mix-blend-mode: normal;
|
||||
|
||||
&:before {
|
||||
opacity: 1;
|
||||
}
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,13 @@
|
||||
<div class="sk-session">
|
||||
<skirda-image-icon [src]="session.icon"></skirda-image-icon>
|
||||
<div class="sk-session-info">
|
||||
<skirda-heading size="6">{{session.title}}</skirda-heading>
|
||||
<skirda-text *ngIf="session.status">{{session.status}}</skirda-text>
|
||||
<div class="info-heading-line">
|
||||
<skirda-heading size="6">{{session.title}}</skirda-heading>
|
||||
<skirda-tag>{{session.expires | countdown | async}}</skirda-tag>
|
||||
</div>
|
||||
<div class="info-line">
|
||||
<skirda-tag class="filled">{{session.version}}</skirda-tag>
|
||||
<skirda-text *ngIf="session.status">{{session.status}}</skirda-text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,22 +1,55 @@
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
&.active {
|
||||
|
||||
.sk-session {
|
||||
background-color: var(--image-accent);
|
||||
}
|
||||
}
|
||||
|
||||
.sk-session {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sk-gap-l);
|
||||
padding: var(--sk-gap-l);
|
||||
border-radius: var(--sk-br-m);
|
||||
transition: 0.1s ease;
|
||||
opacity: 0.5;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.sk-session-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sk-gap-s);
|
||||
|
||||
.info-heading-line {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.info-line {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: var(--sk-gap-m);
|
||||
max-width: 248px;
|
||||
|
||||
skirda-text {
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
|
||||
.sk-session {
|
||||
opacity: 1;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,12 @@ import { CommonModule } from '@angular/common';
|
||||
import { SessionComponent } from './session.component';
|
||||
import { ImageIconModule } from '../image-icon/image-icon.module';
|
||||
import { TypographyModule } from '../typography/typography.module';
|
||||
import { TagModule } from '../tag/tag.module'
|
||||
import { PipesModule } from '../pipes/pipes.module'
|
||||
|
||||
@NgModule({
|
||||
declarations: [SessionComponent],
|
||||
imports: [CommonModule, ImageIconModule, TypographyModule],
|
||||
imports: [CommonModule, ImageIconModule, TypographyModule, TagModule, PipesModule],
|
||||
exports: [SessionComponent],
|
||||
})
|
||||
export class SessionModule {}
|
||||
|
5
projects/ui/src/lib/tag/tag.component.html
Normal file
5
projects/ui/src/lib/tag/tag.component.html
Normal file
@ -0,0 +1,5 @@
|
||||
<div class="sk-tag">
|
||||
<skirda-text>
|
||||
<ng-content></ng-content>
|
||||
</skirda-text>
|
||||
</div>
|
13
projects/ui/src/lib/tag/tag.component.scss
Normal file
13
projects/ui/src/lib/tag/tag.component.scss
Normal file
@ -0,0 +1,13 @@
|
||||
:host {
|
||||
|
||||
&.filled .sk-tag {
|
||||
background-color: var(--sk-accent);
|
||||
}
|
||||
|
||||
.sk-tag {
|
||||
display: inline-block;
|
||||
padding: 0px var(--sk-gap-m);
|
||||
border-radius: var(--sk-br-s);
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
}
|
23
projects/ui/src/lib/tag/tag.component.spec.ts
Normal file
23
projects/ui/src/lib/tag/tag.component.spec.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TagComponent } from './tag.component';
|
||||
|
||||
describe('TagComponent', () => {
|
||||
let component: TagComponent;
|
||||
let fixture: ComponentFixture<TagComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ TagComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(TagComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
15
projects/ui/src/lib/tag/tag.component.ts
Normal file
15
projects/ui/src/lib/tag/tag.component.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'skirda-tag',
|
||||
templateUrl: './tag.component.html',
|
||||
styleUrls: ['./tag.component.scss']
|
||||
})
|
||||
export class TagComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
20
projects/ui/src/lib/tag/tag.module.ts
Normal file
20
projects/ui/src/lib/tag/tag.module.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { TagComponent } from './tag.component';
|
||||
import { TypographyModule } from '../typography/typography.module'
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
TagComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
TypographyModule
|
||||
],
|
||||
exports: [
|
||||
TagComponent
|
||||
]
|
||||
})
|
||||
export class TagModule { }
|
@ -7,6 +7,9 @@ import { TypographyModule } from './typography/typography.module';
|
||||
import { SectionLabelModule } from './section-label/section-label.module';
|
||||
import { ImageIconModule } from './image-icon/image-icon.module';
|
||||
import { ButtonModule } from './button/button.module';
|
||||
import { TagModule } from './tag/tag.module';
|
||||
import { PipesModule } from './pipes/pipes.module';
|
||||
import { GameModule } from './game/game.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
@ -19,6 +22,9 @@ import { ButtonModule } from './button/button.module';
|
||||
SectionLabelModule,
|
||||
ImageIconModule,
|
||||
ButtonModule,
|
||||
TagModule,
|
||||
PipesModule,
|
||||
GameModule,
|
||||
],
|
||||
exports: [
|
||||
IconModule,
|
||||
@ -28,6 +34,9 @@ import { ButtonModule } from './button/button.module';
|
||||
TypographyModule,
|
||||
SectionLabelModule,
|
||||
ImageIconModule,
|
||||
TagModule,
|
||||
PipesModule,
|
||||
GameModule
|
||||
],
|
||||
})
|
||||
export class UiModule {}
|
||||
|
@ -10,3 +10,6 @@ export * from './lib/section/section.module';
|
||||
export * from './lib/typography/typography.module';
|
||||
export * from './lib/section-label/section-label.module';
|
||||
export * from './lib/image-icon/image-icon.module';
|
||||
export * from './lib/tag/tag.module';
|
||||
export * from './lib/pipes/pipes.module';
|
||||
export * from './lib/game/game.module';
|
||||
|
@ -8,18 +8,21 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="sk-sections">
|
||||
<skirda-section class="active">
|
||||
<!-- Здесь class="active" для подсвечивания активного раздела прописывается автоматически,
|
||||
если URL после перехода соддержит routerLink (класс прописывается в routerLinkActive) -->
|
||||
<skirda-section [routerLink]="['servers']" routerLinkActive="active">
|
||||
<skirda-icon name="server"></skirda-icon>
|
||||
<skirda-heading size="6">Servers</skirda-heading>
|
||||
</skirda-section>
|
||||
<skirda-section>
|
||||
<skirda-section [routerLink]="['games']" routerLinkActive="active">
|
||||
<skirda-icon name="game"></skirda-icon>
|
||||
<skirda-heading size="6">Games</skirda-heading>
|
||||
</skirda-section>
|
||||
<skirda-section>
|
||||
<skirda-section [routerLink]="['friends']" routerLinkActive="active">
|
||||
<skirda-icon name="friends"></skirda-icon>
|
||||
<skirda-heading size="6">Friends</skirda-heading>
|
||||
</skirda-section>
|
||||
</div>
|
||||
<app-menu-sessions></app-menu-sessions>
|
||||
<app-menu-games></app-menu-games>
|
||||
</menu>
|
||||
|
@ -0,0 +1,10 @@
|
||||
<skirda-section-label>
|
||||
Pinned games <div class="count">{{games.length}}</div>
|
||||
</skirda-section-label>
|
||||
<div class="games">
|
||||
<skirda-game
|
||||
[routerLink]="['/game/' + game.gameId]" routerLinkActive="active"
|
||||
*ngFor="let game of games; index as i"
|
||||
[game]="game"
|
||||
></skirda-game>
|
||||
</div>
|
@ -0,0 +1,9 @@
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
.games {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MenuGamesComponent } from './menu-games.component';
|
||||
|
||||
describe('MenuGamesComponent', () => {
|
||||
let component: MenuGamesComponent;
|
||||
let fixture: ComponentFixture<MenuGamesComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ MenuGamesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(MenuGamesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,29 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Game } from 'src/app/interfaces/game.interface'
|
||||
|
||||
@Component({
|
||||
selector: 'app-menu-games',
|
||||
templateUrl: './menu-games.component.html',
|
||||
styleUrls: ['./menu-games.component.scss']
|
||||
})
|
||||
export class MenuGamesComponent implements OnInit {
|
||||
games: Game[] = [{
|
||||
gameId: 'id:minecraft',
|
||||
title: 'Minecraft',
|
||||
image: '/assets/games/minecraft/icon.png',
|
||||
}, {
|
||||
gameId: 'id:garrysmod',
|
||||
title: 'Garry\'s mod',
|
||||
image: '/assets/games/garrysmod/icon.png',
|
||||
}, {
|
||||
gameId: 'id:openarena',
|
||||
title: 'OpenArena',
|
||||
image: '/assets/games/openarena/icon.png',
|
||||
}]
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,10 @@
|
||||
<skirda-section-label>
|
||||
Active sessions <div class="count">3</div>
|
||||
Active sessions <div class="count">{{sessions.length}}</div>
|
||||
</skirda-section-label>
|
||||
<div class="sessions">
|
||||
<skirda-session [ngClass]="{'active': i == 1}" *ngFor="let session of sessions; index as i" [session]="session"></skirda-session>
|
||||
<skirda-session
|
||||
[routerLink]="['/session/' + session.id]" routerLinkActive="active"
|
||||
*ngFor="let session of sessions; index as i"
|
||||
[session]="session"
|
||||
></skirda-session>
|
||||
</div>
|
||||
|
@ -9,23 +9,26 @@ import { Session } from 'projects/ui/src/lib/interfaces/session';
|
||||
export class MenuSessionsComponent implements OnInit {
|
||||
sessions: Session[] = [
|
||||
{
|
||||
id: 'minecraft-001',
|
||||
icon: '/assets/games/minecraft/icon.png',
|
||||
title: 'Minecraft',
|
||||
version: '000',
|
||||
status: 'text',
|
||||
expires: new Date(),
|
||||
version: '1.19.2',
|
||||
status: 'Before returning the same line, console log the same logic',
|
||||
expires: new Date('2022-10-30'),
|
||||
},
|
||||
{
|
||||
id: 'minecraft-002',
|
||||
icon: '/assets/games/garrysmod/icon.png',
|
||||
title: 'Minecraft 2',
|
||||
version: '000',
|
||||
expires: new Date(),
|
||||
version: '1.12-dev',
|
||||
expires: new Date('2022-10-22T20:00:00'),
|
||||
},
|
||||
{
|
||||
id: 'minecraft-003',
|
||||
icon: '/assets/games/minecraft/icon.png',
|
||||
title: 'Minecraft 3',
|
||||
version: '000',
|
||||
expires: new Date(),
|
||||
version: '1.7.10',
|
||||
expires: new Date('2022-10-30T20:00:00'),
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
<div class="main-wrapper" [style]="'--image-accent:' + color?.rgba">
|
||||
<img [src]="image" id="image">
|
||||
<div class="main-wrapper" [style.background-image]="'url(' + image + ')'">
|
||||
<app-main-menu></app-main-menu>
|
||||
<div class="content">
|
||||
content will be here
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -25,8 +25,6 @@
|
||||
flex: 1;
|
||||
background-color: rgba(0,0,0,0.05);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
backdrop-filter: blur(1rem);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FastAverageColor, FastAverageColorResult } from 'fast-average-color';
|
||||
|
||||
@Component({
|
||||
selector: 'app-main-root',
|
||||
@ -8,29 +7,8 @@ import { FastAverageColor, FastAverageColorResult } from 'fast-average-color';
|
||||
})
|
||||
export class MainRootComponent implements OnInit {
|
||||
image: string = 'assets/games/minecraft/backgrounds/5.webp';
|
||||
color?: FastAverageColorResult;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
//Called after ngAfterContentInit when the component's view has been initialized. Applies to components only.
|
||||
//Add 'implements AfterViewInit' to the class.
|
||||
window.addEventListener('load', () => {
|
||||
this.setColors();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
setColors() {
|
||||
// extractColors(this.image).then((value) => {
|
||||
// console.log(value);
|
||||
// });
|
||||
let fac = new FastAverageColor();
|
||||
this.color = fac.getColor(
|
||||
document.getElementById('image') as HTMLImageElement
|
||||
);
|
||||
|
||||
console.log(this.color);
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,52 @@ import { CommonModule } from '@angular/common';
|
||||
import { MainRootComponent } from './main-root/main-root.component';
|
||||
import { MainMenuComponent } from './main-menu/main-menu.component';
|
||||
import { UiModule } from 'projects/ui/src/lib/ui.module';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { FormsModule,
|
||||
ReactiveFormsModule } from '@angular/forms';
|
||||
import { MenuSessionsComponent } from './main-menu/menu-sessions/menu-sessions.component';
|
||||
import { MenuGamesComponent } from './main-menu/menu-games/menu-games.component';
|
||||
import { ServersPageComponent } from './sections/servers-page/servers-page.component';
|
||||
import { FriendsPageComponent } from './sections/friends-page/friends-page.component';
|
||||
import { GamesPageComponent } from './sections/games-page/games-page.component';
|
||||
import { SessionPageComponent } from './sections/session-page/session-page.component';
|
||||
import { GamePageComponent } from './sections/game-page/game-page.component';
|
||||
import { MainRoutingModule } from './routing.module'
|
||||
import { ButtonModule } from 'projects/ui/src/lib/button/button.module'
|
||||
import { TypographyModule } from 'projects/ui/src/lib/typography/typography.module'
|
||||
import { IconModule } from 'projects/ui/src/lib/icon/icon.module'
|
||||
|
||||
@NgModule({
|
||||
declarations: [MainRootComponent, MainMenuComponent, MenuSessionsComponent],
|
||||
imports: [CommonModule, UiModule, ReactiveFormsModule, FormsModule],
|
||||
exports: [MainRootComponent, MainMenuComponent, MenuSessionsComponent],
|
||||
declarations: [
|
||||
MainRootComponent,
|
||||
MainMenuComponent,
|
||||
MenuSessionsComponent,
|
||||
MenuGamesComponent,
|
||||
ServersPageComponent,
|
||||
FriendsPageComponent,
|
||||
GamesPageComponent,
|
||||
SessionPageComponent,
|
||||
GamePageComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
UiModule,
|
||||
ReactiveFormsModule,
|
||||
FormsModule,
|
||||
MainRoutingModule,
|
||||
TypographyModule,
|
||||
ButtonModule,
|
||||
IconModule
|
||||
],
|
||||
exports: [
|
||||
MainRootComponent,
|
||||
MainMenuComponent,
|
||||
MenuSessionsComponent,
|
||||
MenuGamesComponent,
|
||||
ServersPageComponent,
|
||||
FriendsPageComponent,
|
||||
GamesPageComponent,
|
||||
SessionPageComponent,
|
||||
GamePageComponent
|
||||
]
|
||||
})
|
||||
export class MainModule {}
|
||||
|
35
src/app/components/main/routing.module.ts
Normal file
35
src/app/components/main/routing.module.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { MainRootComponent } from './main-root/main-root.component'
|
||||
import { FriendsPageComponent } from './sections/friends-page/friends-page.component'
|
||||
import { GamePageComponent } from './sections/game-page/game-page.component'
|
||||
import { GamesPageComponent } from './sections/games-page/games-page.component'
|
||||
import { ServersPageComponent } from './sections/servers-page/servers-page.component'
|
||||
import { SessionPageComponent } from './sections/session-page/session-page.component'
|
||||
|
||||
const routes: Routes = [{
|
||||
path: '',
|
||||
component: MainRootComponent,
|
||||
children: [{
|
||||
path: 'servers',
|
||||
component: ServersPageComponent
|
||||
}, {
|
||||
path: 'friends',
|
||||
component: FriendsPageComponent
|
||||
}, {
|
||||
path: 'games',
|
||||
component: GamesPageComponent
|
||||
}, {
|
||||
path: 'session/:id',
|
||||
component: SessionPageComponent
|
||||
}, {
|
||||
path: 'game/:id',
|
||||
component: GamePageComponent
|
||||
}]
|
||||
}]
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class MainRoutingModule { }
|
17
src/app/components/main/sections/_global.scss
Normal file
17
src/app/components/main/sections/_global.scss
Normal file
@ -0,0 +1,17 @@
|
||||
@mixin page {
|
||||
|
||||
.section {
|
||||
padding: 3rem;
|
||||
|
||||
.section-head {
|
||||
|
||||
.head-title {
|
||||
padding-bottom: var(--sk-gap-xl);
|
||||
}
|
||||
}
|
||||
|
||||
.section-content {
|
||||
padding: var(--sk-gap-xl) 0rem;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<div class="section">
|
||||
<div class="section-head">
|
||||
<div class="head-title">
|
||||
<skirda-heading size="1">Friends</skirda-heading>
|
||||
</div>
|
||||
<div class="head-subtitle">Friends page will be here</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,7 @@
|
||||
@use '../global';
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
@include global.page();
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FriendsPageComponent } from './friends-page.component';
|
||||
|
||||
describe('FriendsPageComponent', () => {
|
||||
let component: FriendsPageComponent;
|
||||
let fixture: ComponentFixture<FriendsPageComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ FriendsPageComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(FriendsPageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-friends-page',
|
||||
templateUrl: './friends-page.component.html',
|
||||
styleUrls: ['./friends-page.component.scss']
|
||||
})
|
||||
export class FriendsPageComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<div class="section">
|
||||
<div class="section-head">
|
||||
<div class="head-title">
|
||||
<skirda-heading size="1">Game</skirda-heading>
|
||||
</div>
|
||||
<div class="head-subtitle">Game page will be here</div>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<skirda-button>
|
||||
<skirda-icon name="play" size="16"></skirda-icon>
|
||||
Run game
|
||||
</skirda-button>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,7 @@
|
||||
@use '../global';
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
@include global.page();
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { GamePageComponent } from './game-page.component';
|
||||
|
||||
describe('GamePageComponent', () => {
|
||||
let component: GamePageComponent;
|
||||
let fixture: ComponentFixture<GamePageComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ GamePageComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(GamePageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-game-page',
|
||||
templateUrl: './game-page.component.html',
|
||||
styleUrls: ['./game-page.component.scss']
|
||||
})
|
||||
export class GamePageComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<div class="section">
|
||||
<div class="section-head">
|
||||
<div class="head-title">
|
||||
<skirda-heading size="1">Games</skirda-heading>
|
||||
</div>
|
||||
<div class="head-subtitle">Games page will be here</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,7 @@
|
||||
@use '../global';
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
@include global.page();
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { GamesPageComponent } from './games-page.component';
|
||||
|
||||
describe('GamesPageComponent', () => {
|
||||
let component: GamesPageComponent;
|
||||
let fixture: ComponentFixture<GamesPageComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ GamesPageComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(GamesPageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-games-page',
|
||||
templateUrl: './games-page.component.html',
|
||||
styleUrls: ['./games-page.component.scss']
|
||||
})
|
||||
export class GamesPageComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<div class="section">
|
||||
<div class="section-head">
|
||||
<div class="head-title">
|
||||
<skirda-heading size="1">Servers</skirda-heading>
|
||||
</div>
|
||||
<div class="head-subtitle">Servers page will be here</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,7 @@
|
||||
@use '../global';
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
@include global.page();
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ServersPageComponent } from './servers-page.component';
|
||||
|
||||
describe('ServersPageComponent', () => {
|
||||
let component: ServersPageComponent;
|
||||
let fixture: ComponentFixture<ServersPageComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ServersPageComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ServersPageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-servers-page',
|
||||
templateUrl: './servers-page.component.html',
|
||||
styleUrls: ['./servers-page.component.scss']
|
||||
})
|
||||
export class ServersPageComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<div class="section">
|
||||
<div class="section-head">
|
||||
<div class="head-title">
|
||||
<skirda-heading size="1">Session</skirda-heading>
|
||||
</div>
|
||||
<div class="head-subtitle">Session page will be here</div>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<skirda-button>
|
||||
<skirda-icon name="play" size="16"></skirda-icon>
|
||||
Run session
|
||||
</skirda-button>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,7 @@
|
||||
@use '../global';
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
|
||||
@include global.page();
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SessionPageComponent } from './session-page.component';
|
||||
|
||||
describe('SessionPageComponent', () => {
|
||||
let component: SessionPageComponent;
|
||||
let fixture: ComponentFixture<SessionPageComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SessionPageComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SessionPageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-session-page',
|
||||
templateUrl: './session-page.component.html',
|
||||
styleUrls: ['./session-page.component.scss']
|
||||
})
|
||||
export class SessionPageComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
@ -3,5 +3,5 @@ export interface Game {
|
||||
gameId: string
|
||||
title: string;
|
||||
image: string;
|
||||
description: string;
|
||||
description?: string;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { MainRootComponent } from '../components/main/main-root/main-root.component';
|
||||
import { MainRoutingModule } from '../components/main/routing.module'
|
||||
import { PlaygroundComponent } from '../components/playground/playground.component';
|
||||
import { SandboxComponent } from '../components/sandbox/sandbox.component';
|
||||
import { SignInComponent } from '../components/sign-in/sign-in.component';
|
||||
@ -12,7 +13,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'main',
|
||||
component: MainRootComponent,
|
||||
loadChildren: () => MainRoutingModule
|
||||
},
|
||||
{
|
||||
path: 'sandbox',
|
||||
|
3
src/assets/icons/Name=play.svg
Normal file
3
src/assets/icons/Name=play.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2 4.82985V19.1721C2 22.1095 5.1779 23.9529 7.71426 22.4842L13.906 18.9023L20.0977 15.3055C22.6341 13.8368 22.6341 10.1651 20.0977 8.6964L13.906 5.0996L7.71426 1.5178C5.1779 0.0491071 2 1.87747 2 4.82985Z" stroke="#292D32" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 403 B |
@ -5,6 +5,7 @@ html, body {
|
||||
}
|
||||
|
||||
:root {
|
||||
--sk-gap-xs: 0.125rem;
|
||||
--sk-gap-s: 0.25rem;
|
||||
--sk-gap-m: 0.5rem;
|
||||
--sk-gap-l: 0.75rem;
|
||||
@ -17,5 +18,6 @@ html, body {
|
||||
--sk-accent-dark: #2A3B39;
|
||||
|
||||
// border-radius
|
||||
--sk-br-s: 0.25rem;
|
||||
--sk-br-m: 0.5rem;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user