Skip to content

Commit

Permalink
tweak: cfx-ui: placeholder mods page
Browse files Browse the repository at this point in the history
Yes, this should be on a separate branch, but I don't trust my ability in keeping infinite WIP branches clean enough.
  • Loading branch information
blattersturm committed May 5, 2020
1 parent 4c2ea59 commit 99850db
Show file tree
Hide file tree
Showing 23 changed files with 484 additions and 5 deletions.
3 changes: 2 additions & 1 deletion ext/cfx-ui/package.json
Expand Up @@ -58,6 +58,7 @@
"int64-buffer": "^0.99.1007",
"js-md5": "0.7.3",
"mini-css-extract-plugin": "^0.8.0",
"ngx-filesize": "^2.0.15",
"ngx-linky": "^2.1.0",
"ngx-virtual-scroller": "^4.0.3",
"node-forge": "^0.8.5",
Expand Down Expand Up @@ -89,4 +90,4 @@
"typescript": "3.8.3",
"webpack-cli": "^3.3.5"
}
}
}
11 changes: 11 additions & 0 deletions ext/cfx-ui/src/app/app-nav.component.html
Expand Up @@ -77,6 +77,17 @@
</span>
</a>

<a
class="nav-item"
[routerLink]="['/mods']"
routerLinkActive="active"
style="display: none"
>
<span l10nTranslate>
#BottomNav_Mods
</span>
</a>

<a
class="nav-item"
[routerLink]="['/settings']"
Expand Down
17 changes: 17 additions & 0 deletions ext/cfx-ui/src/app/app-routing.module.ts
Expand Up @@ -11,6 +11,9 @@ import {DirectConnectComponent} from './servers/direct/direct-connect.component'

import { environment } from '../environments/environment';
import { MetaGuard } from '@ngx-meta/core';
import { ModsComponent } from './mods/mods/mods.component';
import { ModListComponent } from './mods/mod-list/mod-list.component';
import { ModDetailComponent } from './mods/mod-detail/mod-detail.component';

const routes: Routes = [
{
Expand Down Expand Up @@ -57,6 +60,20 @@ const routes: Routes = [
}
]
},
{
path: 'mods',
component: ModsComponent,
children: [
{
path: '',
component: ModListComponent
},
{
path: 'detail/:id',
component: ModDetailComponent
}
]
},
{
path: 'settings',
component: SettingsComponent
Expand Down
6 changes: 4 additions & 2 deletions ext/cfx-ui/src/app/app.component.ts
Expand Up @@ -62,8 +62,10 @@ export class AppComponent implements OnInit {
(<HTMLDivElement>document.querySelector('app-root')).style.opacity = '1';
};

if (environment.web) {
settle();
if (environment.web || !environment.production) {
setTimeout(() => {
settle();
}, 100);
return;
}

Expand Down
16 changes: 15 additions & 1 deletion ext/cfx-ui/src/app/app.module.ts
Expand Up @@ -12,6 +12,7 @@ import {MomentModule} from 'angular2-moment';
import {Angulartics2Module} from 'angulartics2';
import {Angulartics2Piwik} from 'angulartics2/piwik';
import {LinkyModule} from 'ngx-linky';
import {NgxFilesizeModule} from 'ngx-filesize';
import {MetaModule, MetaLoader, MetaStaticLoader, PageTitlePositioning} from '@ngx-meta/core';

import {AppRoutingModule} from './app-routing.module';
Expand Down Expand Up @@ -58,6 +59,12 @@ import { Observable } from 'rxjs';
import { take } from 'rxjs/operators';

import { MatTabsModule } from '@angular/material/tabs';
import { ModsComponent } from './mods/mods/mods.component';
import { ModListComponent } from './mods/mod-list/mod-list.component';
import { ModDetailComponent } from './mods/mod-detail/mod-detail.component';
import { ModsService } from './mods/mods.service';
import { ModsListComponent } from './mods/mods-list/mods-list.component';
import { ModItemComponent } from './mods/mod-item/mod-item.component';

const localePrefix = (environment.web) ? '/' : './';

Expand Down Expand Up @@ -164,7 +171,12 @@ export function metaFactory(): MetaLoader {
PlayerAvatarComponent,
MinModeComponent,
ColorizePipe,
EscapePipe
EscapePipe,
ModsComponent,
ModListComponent,
ModDetailComponent,
ModsListComponent,
ModItemComponent
],
imports: [
BrowserModule.withServerTransition({ appId: 'cfx-ui' }),
Expand All @@ -186,6 +198,7 @@ export function metaFactory(): MetaLoader {
}),
BrowserAnimationsModule,
MatTabsModule,
NgxFilesizeModule,
],
providers: [
ServersService,
Expand All @@ -211,6 +224,7 @@ export function metaFactory(): MetaLoader {
deps: [L10nLoader],
multi: true
},
ModsService,
],
bootstrap: [
AppComponent
Expand Down
@@ -0,0 +1 @@
<p>mod-detail works!</p>
Empty file.
25 changes: 25 additions & 0 deletions ext/cfx-ui/src/app/mods/mod-detail/mod-detail.component.spec.ts
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { ModDetailComponent } from './mod-detail.component';

describe('ModDetailComponent', () => {
let component: ModDetailComponent;
let fixture: ComponentFixture<ModDetailComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ModDetailComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(ModDetailComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
15 changes: 15 additions & 0 deletions ext/cfx-ui/src/app/mods/mod-detail/mod-detail.component.ts
@@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-mod-detail',
templateUrl: './mod-detail.component.html',
styleUrls: ['./mod-detail.component.scss']
})
export class ModDetailComponent implements OnInit {

constructor() { }

ngOnInit(): void {
}

}
30 changes: 30 additions & 0 deletions ext/cfx-ui/src/app/mods/mod-item/mod-item.component.html
@@ -0,0 +1,30 @@
<div class="mod-item"
[class.enabled]="mod.enabled || mod.downloadState == 'available'"
[class.downloading]="mod.downloadState == 'downloading'"
[class.installed]="mod.downloadState == 'installed'">
<figure><img [src]="mod.iconUri"></figure>

<div>
<h1>{{mod.displayName}}</h1>
<h2>by {{mod.authorName}}</h2>
</div>

<span class="icons">
<span aria-label="Available" data-balloon-pos="left" *ngIf="mod.downloadState == 'available'">
<i class="fas fa-download"></i>
</span>
<span *ngIf="mod.downloadState == 'downloading'" aria-label="Downloading (42%)" data-balloon-pos="left">
<i class="fas fa-sync"></i>
</span>
<span *ngIf="mod.downloadState == 'installed' && mod.enabled" aria-label="Installed" data-balloon-pos="left">
<i class="fas fa-check"></i>
</span>
<span *ngIf="mod.downloadState == 'installed' && !mod.enabled" aria-label="Disabled" data-balloon-pos="left">
<i class="fas fa-times"></i>
</span>
</span>

<span class="size">{{ mod.sizeBytes | filesize }}</span>

<progress [value]="mod.progress"></progress>
</div>
100 changes: 100 additions & 0 deletions ext/cfx-ui/src/app/mods/mod-item/mod-item.component.scss
@@ -0,0 +1,100 @@
@import "variables";

$modItemHeight: 9vh;

.mod-item {
overflow: hidden;
height: $modItemHeight;
position: relative;

transition: background-color 0.2s;

@include theme() using ($theme) {
background-color: rgba(gtv($theme, bgColour), .5);
};

&:hover {
@include theme() using ($theme) {
background-color: rgba(gtv($theme, bgColour), 1);
};
}

margin-top: $padding / 3;
display: flex;

figure {
display: flex;
flex-direction: column;
justify-content: center;

img {
width: $modItemHeight;
}
}

&:not(.enabled) figure img {
opacity: .6;
}

&>div {
padding: $padding;
display: flex;
flex-direction: column;
justify-content: space-between;

h1 {
font-weight: normal;
font-size: $fontSize * 1.4;
}

h2 {
font-weight: normal;
font-size: $fontSize * 1.1;
}
}

span.size {
position: absolute;
bottom: $padding;
right: $padding;

font-size: $fontSize * 0.6;
}

span.icons {
position: absolute;
top: $padding;
right: $padding;

font-size: $fontSize * 0.6;

span {
padding-left: $padding;
}
}

progress {
display: none;
appearance: none;

z-index: 999;

position: absolute;
bottom: 0px;
width: 100%;
height: 3px;

&::-webkit-progress-value {
@include theme() using ($theme) {
background-color: rgba(gtv($theme, greenyColour), 1);
box-shadow: rgba(gtv($theme, greenyColour), .8) 0px 0px 8px;
};
}
}

&.downloading {
progress {
display: block;
}
}
}
18 changes: 18 additions & 0 deletions ext/cfx-ui/src/app/mods/mod-item/mod-item.component.ts
@@ -0,0 +1,18 @@
import { Component, OnInit, Input } from '@angular/core';
import { ModInfo } from '../mods.service';

@Component({
selector: 'app-mod-item',
templateUrl: './mod-item.component.html',
styleUrls: ['./mod-item.component.scss']
})
export class ModItemComponent implements OnInit {
@Input()
mod: ModInfo;

constructor() { }

ngOnInit(): void {
}

}
2 changes: 2 additions & 0 deletions ext/cfx-ui/src/app/mods/mod-list/mod-list.component.html
@@ -0,0 +1,2 @@
<app-mods-list [source]="installedMods" [searchPlaceholder]="'Search installed mods...'"></app-mods-list>
<app-mods-list [source]="availableMods" [searchPlaceholder]="'Search available mods...'"></app-mods-list>
14 changes: 14 additions & 0 deletions ext/cfx-ui/src/app/mods/mod-list/mod-list.component.scss
@@ -0,0 +1,14 @@
@import "variables";

:host {
display: flex;

justify-content: space-between;

@include appContent;
}

app-mods-list {
width: 50%;
padding: $padding;
}

0 comments on commit 99850db

Please sign in to comment.