Skip to content

Commit bb4ed00

Browse files
Adding twitch bot pages
1 parent 51e10ba commit bb4ed00

File tree

13 files changed

+103
-32
lines changed

13 files changed

+103
-32
lines changed

src/src/app/app.routes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const routes: Routes = [
1616
{path: 'home', component: HomeComponent},
1717
{path: 'vm-admin', component: VmManagerComponent, canActivate: [authGuard]},
1818
{path: 'twitch-bot/index', component: TwitchBotIndexComponent},
19-
{path: 'twitch-bot/config', component: TwitchBotConfigComponent, canActivate: [authGuard]},
19+
{path: 'twitch-bot/config', component: TwitchBotConfigComponent},
2020
{path: 'imdb-search', component: ImdbSearchComponent},
2121
{path: '**', component: NotFoundComponent},
2222
];

src/src/app/common/components/loading-icon/loading-icon.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<svg attr.width="{{width}}" attr.height="{{height}}" viewBox="0 0 135 135" style="margin-right: 10px"
1+
<svg attr.width="{{width}}" attr.height="{{height}}" viewBox="0 0 135 135" class="icon"
22
xmlns="http://www.w3.org/2000/svg" attr.fill="{{fill}}">
33
<path
44
d="M67.447 58c5.523 0 10-4.477 10-10s-4.477-10-10-10-10 4.477-10 10 4.477 10 10 10zm9.448 9.447c0 5.523 4.477 10 10 10 5.522 0 10-4.477 10-10s-4.478-10-10-10c-5.523 0-10 4.477-10 10zm-9.448 9.448c-5.523 0-10 4.477-10 10 0 5.522 4.477 10 10 10s10-4.478 10-10c0-5.523-4.477-10-10-10zM58 67.447c0-5.523-4.477-10-10-10s-10 4.477-10 10 4.477 10 10 10 10-4.477 10-10z">

src/src/app/common/components/loading-icon/loading-icon.component.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,8 @@
33
vertical-align: middle;
44
font-weight: 500;
55
}
6+
7+
.icon {
8+
margin-right: 10px;
9+
vertical-align: middle;
10+
}

src/src/app/common/components/twitch-login/twitch-login.component.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,16 @@ export class TwitchLoginComponent {
1717
* 1 = Twitch Bot Login
1818
*/
1919
@Input() twitchScopeIndex: number = 0;
20+
@Input() redirectUrl: string | null = null;
2021

2122
twitchLogin(): void {
22-
const redirectUrl = `${environment.apiUrl}/user/twitch-login`;
23+
let redirectUrl = null;
24+
if (!this.redirectUrl) {
25+
redirectUrl = `${environment.apiUrl}/user/twitch-login`;
26+
} else {
27+
redirectUrl = `${environment.apiUrl}/${this.redirectUrl}`;
28+
}
29+
2330
window.location.href = `https://id.twitch.tv/oauth2/authorize?` +
2431
encodeURI(`client_id=${environment.twitchClientId}&` +
2532
`redirect_uri=${redirectUrl}&` +
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface FeatureToggleResponse {
2+
feature: string;
3+
isEnabled: boolean;
4+
}

src/src/app/service/nullinside.service.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Observable } from "rxjs";
44
import { environment } from "../../environments/environment";
55
import { UserRolesResponse } from "../common/interface/user-roles-response";
66
import { DockerResource } from '../common/interface/docker-resource';
7+
import { FeatureToggleResponse } from "../common/interface/feature-toggle-response";
78

89
@Injectable({
910
providedIn: 'root'
@@ -28,4 +29,8 @@ export class NullinsideService {
2829
setVirtualMachinePowerState(id: number, turnOn: boolean): Observable<boolean> {
2930
return this.httpClient.post<boolean>(`${environment.apiUrl}/docker/${id}`, {turnOn: turnOn});
3031
}
32+
33+
getFeatureToggles(): Observable<FeatureToggleResponse[]> {
34+
return this.httpClient.get<FeatureToggleResponse[]>(`${environment.apiUrl}/featureToggle`);
35+
}
3136
}
Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
11
<app-standard-banner />
22

3-
@if (apps.length > 0) {
4-
<div class="layout-content flex-container">
5-
@for (app of apps; track app.displayName) {
6-
<div class="app hover-border-blink" (click)="onAppClicked(app.displayName)"
7-
(keyup.enter)="onAppClicked(app.displayName)" tabindex="0">
8-
<h1>{{ app.displayName }}</h1>
9-
<p>{{ app.description }}</p>
3+
@if (!loading) {
4+
@if (!error) {
5+
@if (apps.length > 0) {
6+
<div class="layout-content flex-container">
7+
@for (app of apps; track app.displayName) {
8+
<div class="app hover-border-blink" (click)="onAppClicked(app.displayName)"
9+
(keyup.enter)="onAppClicked(app.displayName)" tabindex="0">
10+
<h1>{{ app.displayName }}</h1>
11+
<p>{{ app.description }}</p>
12+
</div>
13+
}
14+
</div>
15+
} @else {
16+
<div class="layout-content bye">
17+
<div class="info-banner">
18+
Sorry, there are no applications available to you at this time.
19+
</div>
1020
</div>
1121
}
12-
</div>
13-
} @else {
14-
<div class="layout-content bye">
15-
<div class="info-banner">
16-
Sorry, there are no applications available to you at this time.
22+
} @else {
23+
<div class="error-banner">
24+
{{ error }}
1725
</div>
18-
</div>
26+
}
27+
} @else {
28+
<app-loading-icon class="center" fontSize="32px" height="45px" width="45px">Getting Available Apps</app-loading-icon>
1929
}

src/src/app/view/home/home.component.ts

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import { WebsiteApp } from "../../common/interface/website-app";
66
import { Router } from '@angular/router';
77
import { MatAnchor, MatButton } from '@angular/material/button';
88
import { StandardBannerComponent } from '../../common/components/standard-banner/standard-banner.component';
9+
import { LoadingIconComponent } from "../../common/components/loading-icon/loading-icon.component";
10+
import { catchError, forkJoin, Observable, of } from "rxjs";
11+
import { UserRolesResponse } from "../../common/interface/user-roles-response";
912

1013
@Component({
1114
selector: 'app-home',
@@ -14,7 +17,8 @@ import { StandardBannerComponent } from '../../common/components/standard-banner
1417
LogoComponent,
1518
MatButton,
1619
MatAnchor,
17-
StandardBannerComponent
20+
StandardBannerComponent,
21+
LoadingIconComponent
1822
],
1923
templateUrl: './home.component.html',
2024
styleUrl: './home.component.scss'
@@ -23,20 +27,21 @@ export class HomeComponent implements OnInit {
2327
public roles: string[] | null = null;
2428
public error: string | null = null;
2529
public userIsLoggedIn: boolean = false;
30+
public loading: boolean = true;
2631

2732
public apps: WebsiteApp[] = [
2833
{
2934
displayName: 'IMDB Search',
3035
description: 'Search the public IMDB database using various search techniques',
3136
url: 'imdb-search',
3237
params: undefined
38+
},
39+
{
40+
displayName: 'Twitch Bot',
41+
description: 'The nullinside anti-bot Twitch bot.',
42+
url: 'twitch-bot/index',
43+
params: undefined
3344
}
34-
/* {
35-
displayName: 'Twitch Bot',
36-
description: 'The nullinside anti-bot Twitch bot.',
37-
url: 'twitch-bot/index',
38-
params: undefined
39-
},*/
4045
];
4146

4247
constructor(private api: NullinsideService,
@@ -46,10 +51,14 @@ export class HomeComponent implements OnInit {
4651
ngOnInit(): void {
4752
this.userIsLoggedIn = null !== localStorage.getItem('auth-token');
4853

49-
this.api.getUserRoles()
54+
forkJoin({
55+
// We don't care if the roles don't exist. This is only for authed users. So catch the error if there is one.
56+
user: this.api.getUserRoles().pipe(catchError(_ => of({roles: []}))) as Observable<UserRolesResponse>,
57+
featureToggles: this.api.getFeatureToggles()
58+
})
5059
.subscribe({
5160
next: response => {
52-
this.roles = response.roles;
61+
this.roles = response.user.roles;
5362
if (-1 !== this.roles?.indexOf(VM_ADMIN)) {
5463
this.apps = [...this.apps, {
5564
displayName: 'VM Admin',
@@ -58,11 +67,19 @@ export class HomeComponent implements OnInit {
5867
params: null
5968
}];
6069
}
70+
71+
const twitchBotFeatureToggle = response.featureToggles.find(f => 'Twitch Bot' === f.feature);
72+
if (!twitchBotFeatureToggle || !twitchBotFeatureToggle.isEnabled) {
73+
this.apps = [...this.apps.filter(f => 'Twitch Bot' !== f.displayName)]
74+
}
75+
76+
this.loading = false;
6177
},
62-
error: error => {
63-
this.error = error;
78+
error: _ => {
79+
this.error = 'Failed to get list of apps from the server, please refresh to try again...';
80+
this.loading = false;
6481
}
65-
})
82+
});
6683
}
6784

6885
onAppClicked(displayName: string) {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export enum Errors {
2+
TwitchErrorWithToken,
3+
TwitchAccountHasNoEmail,
4+
InternalError
5+
}

src/src/app/view/login-landing/login-landing.component.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { LoadingIconComponent } from "../../common/components/loading-icon/loadi
55
import { ActivatedRoute, ParamMap, Router } from "@angular/router";
66
import { environment } from "../../../environments/environment";
77
import { HttpErrorResponse } from "@angular/common/http";
8+
import { Errors } from "./errors";
89

910
@Component({
1011
selector: 'app-login-landing',
@@ -34,7 +35,15 @@ export class LoginLandingComponent implements OnInit, OnDestroy {
3435
next: (params: ParamMap) => {
3536
const error = params.get('error');
3637
if (null !== error) {
37-
'4' === error ? this.onLoginFailed(':( Your Twitch account must have a valid e-mail address, please add one and try again', false) : this.onLoginFailed();
38+
const errorNum = +error;
39+
if (Errors.TwitchAccountHasNoEmail === errorNum) {
40+
this.onLoginFailed('Your Twitch account must have a valid e-mail address, please add one and try again', false)
41+
} else if (Errors.TwitchErrorWithToken === errorNum) {
42+
this.onLoginFailed('Twitch failed to give us a valid token, please add one and try again', false)
43+
} else {
44+
this.onLoginFailed('Sorry we did something wrong trying to log you in, please add one and try again', false)
45+
}
46+
3847
return;
3948
}
4049

0 commit comments

Comments
 (0)