initial commit
This commit is contained in:
commit
dc797d78ed
16
.browserslistrc
Normal file
16
.browserslistrc
Normal file
@ -0,0 +1,16 @@
|
||||
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
|
||||
# For additional information regarding the format and rule options, please see:
|
||||
# https://github.com/browserslist/browserslist#queries
|
||||
|
||||
# For the full list of supported browsers by the Angular framework, please see:
|
||||
# https://angular.io/guide/browser-support
|
||||
|
||||
# You can see what browsers were selected by your queries by running:
|
||||
# npx browserslist
|
||||
|
||||
last 1 Chrome version
|
||||
last 1 Firefox version
|
||||
last 2 Edge major versions
|
||||
last 2 Safari major versions
|
||||
last 2 iOS major versions
|
||||
Firefox ESR
|
16
.editorconfig
Normal file
16
.editorconfig
Normal file
@ -0,0 +1,16 @@
|
||||
# Editor configuration, see https://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.ts]
|
||||
quote_type = single
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
43
.gitignore
vendored
Normal file
43
.gitignore
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# Compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
/bazel-out
|
||||
|
||||
# Node
|
||||
/node_modules
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# IDEs and editors
|
||||
.vscode/
|
||||
.idea/
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history/*
|
||||
|
||||
# Miscellaneous
|
||||
/.angular/cache
|
||||
.sass-cache/
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# System files
|
||||
.DS_Store
|
||||
Thumbs.db
|
27
README.md
Normal file
27
README.md
Normal file
@ -0,0 +1,27 @@
|
||||
# ProximaTVFrontend
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 13.1.4.
|
||||
|
||||
## Development server
|
||||
|
||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Running end-to-end tests
|
||||
|
||||
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
|
115
angular.json
Normal file
115
angular.json
Normal file
@ -0,0 +1,115 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"Proxima-TV-Frontend": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:application": {
|
||||
"strict": true
|
||||
}
|
||||
},
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"allowedCommonJsDependencies": [
|
||||
"crypto-js"
|
||||
],
|
||||
"outputPath": "dist/proxima-tv-frontend",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.css",
|
||||
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||
"node_modules/plyr/dist/plyr.css"
|
||||
],
|
||||
"scripts": [
|
||||
"./node_modules/bootstrap/dist/js/bootstrap.min.js",
|
||||
"./node_modules/chart.js/dist/chart.min.js",
|
||||
"./node_modules/crypto-js/crypto-js.js"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kb",
|
||||
"maximumError": "1mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
],
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"buildOptimizer": true,
|
||||
"optimization": true,
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": true,
|
||||
"sourceMap": true,
|
||||
"namedChunks": true
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "Proxima-TV-Frontend:build:production"
|
||||
},
|
||||
"development": {
|
||||
"browserTarget": "Proxima-TV-Frontend:build:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "Proxima-TV-Frontend:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"scripts": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "Proxima-TV-Frontend"
|
||||
}
|
44
karma.conf.js
Normal file
44
karma.conf.js
Normal file
@ -0,0 +1,44 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client: {
|
||||
jasmine: {
|
||||
// you can add configuration options for Jasmine here
|
||||
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||
// for example, you can disable the random execution with `random: false`
|
||||
// or set a specific seed with `seed: 4321`
|
||||
},
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
jasmineHtmlReporter: {
|
||||
suppressAll: true // removes the duplicated traces
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: require('path').join(__dirname, './coverage/proxima-tv-frontend'),
|
||||
subdir: '.',
|
||||
reporters: [
|
||||
{ type: 'html' },
|
||||
{ type: 'text-summary' }
|
||||
]
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false,
|
||||
restartOnFileChange: true
|
||||
});
|
||||
};
|
19544
package-lock.json
generated
Normal file
19544
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
47
package.json
Normal file
47
package.json
Normal file
@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "proxima-tv-frontend",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "ng test"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~13.1.0",
|
||||
"@angular/common": "~13.1.0",
|
||||
"@angular/compiler": "~13.1.0",
|
||||
"@angular/core": "~13.1.0",
|
||||
"@angular/forms": "~13.1.0",
|
||||
"@angular/platform-browser": "~13.1.0",
|
||||
"@angular/platform-browser-dynamic": "~13.1.0",
|
||||
"@angular/router": "~13.1.0",
|
||||
"@tinymce/tinymce-angular": "^5.0.1",
|
||||
"@types/crypto-js": "^4.1.0",
|
||||
"bootstrap": "^5.1.3",
|
||||
"chart.js": "^3.7.0",
|
||||
"crypto-js": "^4.1.1",
|
||||
"ngx-cookie-service": "^13.1.2",
|
||||
"ngx-plyr": "^4.0.1",
|
||||
"plyr": "^3.7.2",
|
||||
"rxjs": "~7.4.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^13.1.4",
|
||||
"@angular/cli": "~13.1.4",
|
||||
"@angular/compiler-cli": "~13.1.0",
|
||||
"@types/jasmine": "~3.10.0",
|
||||
"@types/node": "^17.0.12",
|
||||
"jasmine-core": "~3.10.0",
|
||||
"karma": "~6.3.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.1.0",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"typescript": "~4.5.2"
|
||||
}
|
||||
}
|
10
src/app/app-routing.module.ts
Normal file
10
src/app/app-routing.module.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
const routes: Routes = [];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule { }
|
0
src/app/app.component.css
Normal file
0
src/app/app.component.css
Normal file
3
src/app/app.component.html
Normal file
3
src/app/app.component.html
Normal file
@ -0,0 +1,3 @@
|
||||
<app-navbar></app-navbar>
|
||||
<router-outlet></router-outlet>
|
||||
<app-footer></app-footer>
|
35
src/app/app.component.spec.ts
Normal file
35
src/app/app.component.spec.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [
|
||||
RouterTestingModule
|
||||
],
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should create the app', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should have as title 'Proxima-TV-Frontend'`, () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app.title).toEqual('Proxima-TV-Frontend');
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('.content span')?.textContent).toContain('Proxima-TV-Frontend app is running!');
|
||||
});
|
||||
});
|
12
src/app/app.component.ts
Normal file
12
src/app/app.component.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'Proxima-TV-Frontend';
|
||||
|
||||
|
||||
}
|
72
src/app/app.module.ts
Normal file
72
src/app/app.module.ts
Normal file
@ -0,0 +1,72 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { StatsComponent } from './stats/stats.component';
|
||||
import { CommentsComponent } from './comments/comments.component';
|
||||
import { HistoryComponent } from './history/history.component';
|
||||
import { NavbarComponent } from './navbar/navbar.component';
|
||||
import { FormsComponent } from './forms/forms.component';
|
||||
import { QuestionsComponent } from './questions/questions.component';
|
||||
import { ServicePreviewComponent } from './service-preview/service-preview.component';
|
||||
import { SettingsComponent } from './settings/settings.component';
|
||||
import { WatchComponent } from './watch/watch.component';
|
||||
import { FooterComponent } from './footer/footer.component';
|
||||
import { LoginComponent } from './login/login.component';
|
||||
import { RegisterComponent } from './register/register.component';
|
||||
import { LoginModule } from './login/login.module';
|
||||
import { RegisterModule } from './register/register.module';
|
||||
import { HomeComponent } from './home/home.component';
|
||||
import { SearchModule } from './search/search.module';
|
||||
import { ErrorComponent } from './error/error.component';
|
||||
import { WatchModule } from './watch/watch.module';
|
||||
import { AuthGuard } from './auth.guard';
|
||||
import { SearchPageComponent } from './search-page/search-page.component';
|
||||
import { UploadsComponent } from './uploads/uploads.component';
|
||||
import { UploadsModule } from './uploads/uploads.module';
|
||||
import { ChannelComponent } from './channel/channel.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: HomeComponent},
|
||||
{ path: 'profile', component: StatsComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'watch/:watch', component: WatchComponent},
|
||||
{ path: 'settings', component: SettingsComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'login', component: LoginComponent },
|
||||
{ path: 'register', component: RegisterComponent },
|
||||
{ path: 'register/:email', component: RegisterComponent },
|
||||
{ path: 'search/:query', component: SearchPageComponent },
|
||||
{ path: 'upload', component: UploadsComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'channel/:id', component: ChannelComponent },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
StatsComponent,
|
||||
CommentsComponent,
|
||||
HistoryComponent,
|
||||
NavbarComponent,
|
||||
FormsComponent,
|
||||
QuestionsComponent,
|
||||
ServicePreviewComponent,
|
||||
SettingsComponent,
|
||||
FooterComponent,
|
||||
HomeComponent,
|
||||
ErrorComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
AppRoutingModule,
|
||||
LoginModule,
|
||||
UploadsModule,
|
||||
RegisterModule,
|
||||
WatchModule,
|
||||
RouterModule.forRoot(routes),
|
||||
SearchModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
16
src/app/auth.guard.spec.ts
Normal file
16
src/app/auth.guard.spec.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AuthGuard } from './auth.guard';
|
||||
|
||||
describe('AuthGuard', () => {
|
||||
let guard: AuthGuard;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
guard = TestBed.inject(AuthGuard);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(guard).toBeTruthy();
|
||||
});
|
||||
});
|
21
src/app/auth.guard.ts
Normal file
21
src/app/auth.guard.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AuthService } from './auth.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthGuard implements CanActivate {
|
||||
constructor( private authService: AuthService, private router: Router){}
|
||||
canActivate(){
|
||||
if(this.authService.loggedIn()){
|
||||
console.log("guard")
|
||||
return true;
|
||||
} else {
|
||||
this.router.navigate(['/login']);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
16
src/app/auth.service.spec.ts
Normal file
16
src/app/auth.service.spec.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AuthService } from './auth.service';
|
||||
|
||||
describe('AuthService', () => {
|
||||
let service: AuthService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(AuthService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
25
src/app/auth.service.ts
Normal file
25
src/app/auth.service.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {HttpClient, HttpHeaders} from '@angular/common/http';
|
||||
import {map} from'rxjs/operators';
|
||||
import { CryptoService } from './crypto.service';
|
||||
import { CookiesService } from './cookies.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthService {
|
||||
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
private cookies:CookiesService
|
||||
) { }
|
||||
|
||||
register(data:object){
|
||||
this.http.post('http://localhost:3000/users/register',data, {})
|
||||
}
|
||||
loggedIn(): boolean{
|
||||
// TODO: verify data against data on the server
|
||||
let loggin = this.cookies.getCookie("proxima-login-cookie").split(',')
|
||||
return loggin[0] != null && loggin[1] != null;
|
||||
}
|
||||
}
|
BIN
src/app/channel/channe_darf.png
Normal file
BIN
src/app/channel/channe_darf.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
12
src/app/channel/channel.component.css
Normal file
12
src/app/channel/channel.component.css
Normal file
@ -0,0 +1,12 @@
|
||||
.channel-header {
|
||||
position: static;
|
||||
padding: 10px;
|
||||
height: 200px;
|
||||
background-color: #ecf0f1;
|
||||
}
|
||||
.channel-pic {
|
||||
border-radius: 50%;
|
||||
height: 180px;
|
||||
width: 180px;
|
||||
border: 1px solid black;
|
||||
}
|
22
src/app/channel/channel.component.html
Normal file
22
src/app/channel/channel.component.html
Normal file
@ -0,0 +1,22 @@
|
||||
<div class="channel-header">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-2">
|
||||
<img class="channel-pic" src="https://cdn.slpnetwork.de/img/sys/users/Thesteev.png" alt="">
|
||||
</div>
|
||||
<div class="col-10" style="padding-top: 3%;">
|
||||
<h3 style="font-weight: bold; color:#7f8c8d;">{{username}}<br>{{subscribers}} Subscribers</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row" style="padding: 0;">
|
||||
<div class="col-1"></div>
|
||||
<div class="col-10" style="padding:0">
|
||||
<div class="row" #searchList>
|
||||
|
||||
</div>
|
||||
<div class="col-1"></div>
|
||||
</div>
|
||||
</div>
|
25
src/app/channel/channel.component.spec.ts
Normal file
25
src/app/channel/channel.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ChannelComponent } from './channel.component';
|
||||
|
||||
describe('ChannelComponent', () => {
|
||||
let component: ChannelComponent;
|
||||
let fixture: ComponentFixture<ChannelComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ChannelComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ChannelComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
75
src/app/channel/channel.component.ts
Normal file
75
src/app/channel/channel.component.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { Component, ElementRef, OnInit, Renderer2, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ConfigService } from '../config.service';
|
||||
import { CookiesService } from '../cookies.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-channel',
|
||||
templateUrl: './channel.component.html',
|
||||
styleUrls: ['./channel.component.css']
|
||||
})
|
||||
export class ChannelComponent implements OnInit {
|
||||
@ViewChild('searchList')cl: ElementRef;
|
||||
searchAmnt: number;
|
||||
username: string;
|
||||
subscribers: number;
|
||||
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
private rednerer: Renderer2,
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private config: ConfigService,
|
||||
private cookies: CookiesService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
const query = {
|
||||
query: this.activatedRoute.snapshot.params['id']
|
||||
};
|
||||
|
||||
this.username = this.cookies.getCookie('proxima-login-cookie').split(',')[0];
|
||||
this.subscribers = 0;
|
||||
|
||||
let params = new HttpParams()
|
||||
.set('creator',JSON.stringify(query));
|
||||
|
||||
this.http.get<any>(this.config.hostname + '/videos/channel', {
|
||||
params: params
|
||||
}).subscribe(data => {
|
||||
console.log("data arrive")
|
||||
console.log(data.videos.length);
|
||||
this.searchAmnt = data.length;
|
||||
for(let i = 0; i < data.videos.length; i++) {
|
||||
console.log(i);
|
||||
// TODO: construct html for the page to load
|
||||
// ALSO TODO: determing what data is needed on this exact page
|
||||
const topDiv: HTMLDivElement = this.rednerer.createElement("div");
|
||||
const Anchor: HTMLAnchorElement = this.rednerer.createElement("a");
|
||||
const div: HTMLDivElement = this.rednerer.createElement("div");
|
||||
const Img: HTMLImageElement = this.rednerer.createElement("img");
|
||||
const bottomdiv: HTMLDivElement = this.rednerer.createElement("div")
|
||||
const title: HTMLTitleElement = this.rednerer.createElement("h2");
|
||||
const titleText = this.rednerer.createText(data.videos[i]["title"])
|
||||
|
||||
topDiv.appendChild(Anchor);
|
||||
topDiv.classList.add("col-4");
|
||||
topDiv.style.marginTop = "20px";
|
||||
Anchor.appendChild(div);
|
||||
Anchor.href = "/watch/" + data.videos[i]["vid_id"];
|
||||
div.appendChild(Img);
|
||||
div.classList.add("card");
|
||||
div.classList.add("bg-dark");
|
||||
div.appendChild(bottomdiv);
|
||||
bottomdiv.appendChild(title);
|
||||
bottomdiv.classList.add("card-img-overlay");
|
||||
bottomdiv.style.backgroundColor = "rgba(0, 0, 0, 0.432)";
|
||||
title.appendChild(titleText);
|
||||
title.classList.add("card-title");
|
||||
title.style.color = "white";
|
||||
Img.classList.add("card-img");
|
||||
Img.src = "https://proxima-tv.github.io/poster.jpg";
|
||||
this.cl.nativeElement.prepend(topDiv);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
15
src/app/channel/channel.module.ts
Normal file
15
src/app/channel/channel.module.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ChannelComponent } from './channel.component';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
ChannelComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule
|
||||
]
|
||||
})
|
||||
export class ChannelModule { }
|
0
src/app/comments/comments.component.css
Normal file
0
src/app/comments/comments.component.css
Normal file
22
src/app/comments/comments.component.html
Normal file
22
src/app/comments/comments.component.html
Normal file
@ -0,0 +1,22 @@
|
||||
<br>
|
||||
<h1>Last Written Comments: </h1>
|
||||
<div class="list-group">
|
||||
<a href="#" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">Video 1</h5>
|
||||
</div>
|
||||
<p class="mb-1">Some kind of Comment.</p>
|
||||
</a>
|
||||
<a href="#" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">Video 2</h5>
|
||||
</div>
|
||||
<p class="mb-1">Some kind of Comment.</p>
|
||||
</a>
|
||||
<a href="#" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">Video 3</h5>
|
||||
</div>
|
||||
<p class="mb-1">Some kind of Comment.</p>
|
||||
</a>
|
||||
</div>
|
25
src/app/comments/comments.component.spec.ts
Normal file
25
src/app/comments/comments.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CommentsComponent } from './comments.component';
|
||||
|
||||
describe('CommentsComponent', () => {
|
||||
let component: CommentsComponent;
|
||||
let fixture: ComponentFixture<CommentsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ CommentsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CommentsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
15
src/app/comments/comments.component.ts
Normal file
15
src/app/comments/comments.component.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-comments',
|
||||
templateUrl: './comments.component.html',
|
||||
styleUrls: ['./comments.component.css']
|
||||
})
|
||||
export class CommentsComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
16
src/app/config.service.spec.ts
Normal file
16
src/app/config.service.spec.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ConfigService } from './config.service';
|
||||
|
||||
describe('ConfigService', () => {
|
||||
let service: ConfigService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(ConfigService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
9
src/app/config.service.ts
Normal file
9
src/app/config.service.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ConfigService {
|
||||
public hostname = "http://localhost:3000"
|
||||
constructor() { }
|
||||
}
|
16
src/app/cookies.service.spec.ts
Normal file
16
src/app/cookies.service.spec.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CookiesService } from './cookies.service';
|
||||
|
||||
describe('CookiesService', () => {
|
||||
let service: CookiesService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(CookiesService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
44
src/app/cookies.service.ts
Normal file
44
src/app/cookies.service.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {CookieService} from 'ngx-cookie-service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class CookiesService {
|
||||
constructor(private service:CookieService) { }
|
||||
|
||||
/**
|
||||
* gets given cookie name
|
||||
* @param cookie the cookie to receive name
|
||||
* @returns value of cookie
|
||||
*/
|
||||
getCookie(cookie:string){
|
||||
return this.service.get(cookie);
|
||||
}
|
||||
|
||||
/**
|
||||
* get all cookies from browser
|
||||
* @returns all cookies
|
||||
*/
|
||||
getAllCookies() {
|
||||
return this.service.getAll();
|
||||
}
|
||||
|
||||
deleteCookie(name:string){
|
||||
try {
|
||||
this.service.delete(name);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sets specified cookies
|
||||
* @param cookieName the name of the cookie to store
|
||||
* @param values the value to store inside the cookie
|
||||
*/
|
||||
setCookie(cookieName:string, values:string):void{
|
||||
// TODO: rework to fit new proper structuer
|
||||
this.service.set(cookieName, values)
|
||||
}
|
||||
}
|
16
src/app/crypto.service.spec.ts
Normal file
16
src/app/crypto.service.spec.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CryptoService } from './crypto.service';
|
||||
|
||||
describe('CryptoService', () => {
|
||||
let service: CryptoService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(CryptoService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
62
src/app/crypto.service.ts
Normal file
62
src/app/crypto.service.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import * as CryptoJS from 'crypto-js';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
/**
|
||||
* @deprecated in its current state the cryptoservice in nonfunctional
|
||||
*/
|
||||
export class CryptoService {
|
||||
|
||||
private static secretKey = "";
|
||||
|
||||
static makeid(length:number):string {
|
||||
var result = '';
|
||||
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
var charactersLength = characters.length;
|
||||
for ( var i = 0; i < length; i++ ) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); }
|
||||
return result;
|
||||
}
|
||||
|
||||
static setKey(k:string) { this.secretKey = k; }
|
||||
|
||||
//The set method is use for encrypt the value.
|
||||
static encrypt(data:string){
|
||||
var key = CryptoJS.enc.Utf8.parse(this.secretKey);
|
||||
var iv = CryptoJS.enc.Utf8.parse(this.makeid(16)); // TODO: Randomize IV to reenhance security
|
||||
|
||||
// console.log("Key: " + key);
|
||||
console.log("Initial Vector: " + iv);
|
||||
|
||||
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(data.toString()), key,
|
||||
{
|
||||
keySize: 128 / 8,
|
||||
iv: iv,
|
||||
mode: CryptoJS.mode.CBC,
|
||||
padding: CryptoJS.pad.Pkcs7
|
||||
});
|
||||
|
||||
let out = {
|
||||
"content": encrypted.toString(),
|
||||
"iv": iv
|
||||
};
|
||||
|
||||
// Instead of sending only the encrypted string, send an object with iv and encrypted data
|
||||
return out;
|
||||
}
|
||||
|
||||
//The get method is use for decrypt the value.
|
||||
static decrypt(data:any){
|
||||
console.log("Initial Vector: " + data['iv']);
|
||||
|
||||
var key = CryptoJS.enc.Utf8.parse(this.secretKey);
|
||||
|
||||
var decrypted = CryptoJS.AES.decrypt(data['content'], key, {
|
||||
keySize: 128 / 8,
|
||||
iv: data['iv'],
|
||||
mode: CryptoJS.mode.CBC,
|
||||
padding: CryptoJS.pad.Pkcs7
|
||||
});
|
||||
|
||||
return decrypted.toString(CryptoJS.enc.Utf8);
|
||||
}
|
||||
}
|
41
src/app/error/error.component.css
Normal file
41
src/app/error/error.component.css
Normal file
@ -0,0 +1,41 @@
|
||||
span {
|
||||
margin-left: 600px;
|
||||
margin-right:600px;
|
||||
text-decoration: underline;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: large;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content:center;
|
||||
border-style: dashed;
|
||||
background-color: rgb(255,0,0) ;
|
||||
align-items: center;
|
||||
|
||||
|
||||
}
|
||||
a{
|
||||
margin-left: 600px;
|
||||
margin-right:600px;
|
||||
text-decoration: underline;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: large;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content:center;
|
||||
border-style: hidden;
|
||||
background-color: rgb(255,0,0) ;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
h3{
|
||||
margin-left: 600px;
|
||||
margin-right:600px;
|
||||
text-decoration: underline;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: large;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content:center;
|
||||
align-items: center;
|
||||
|
||||
}
|
22
src/app/error/error.component.html
Normal file
22
src/app/error/error.component.html
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-12 col-sm-12">
|
||||
<div class="card shadow-lg border-0 rounded-lg mt-5 mx-auto" >
|
||||
<h3 class="card-header display-1 text-muted text-center">
|
||||
404
|
||||
</h3>
|
||||
|
||||
<span class="card-subtitle mb-2 text-muted text-center">
|
||||
Page Could Not Be Found
|
||||
</span>
|
||||
|
||||
<div class="card-body mx-auto">
|
||||
<a type="button" href="http://localhost:4200/"
|
||||
class="btn btn-sm btn-info text-white"> Back To Home </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
25
src/app/error/error.component.spec.ts
Normal file
25
src/app/error/error.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ErrorComponent } from './error.component';
|
||||
|
||||
describe('ErrorComponent', () => {
|
||||
let component: ErrorComponent;
|
||||
let fixture: ComponentFixture<ErrorComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ErrorComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ErrorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
15
src/app/error/error.component.ts
Normal file
15
src/app/error/error.component.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-error',
|
||||
templateUrl: './error.component.html',
|
||||
styleUrls: ['./error.component.css']
|
||||
})
|
||||
export class ErrorComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
0
src/app/footer/footer.component.css
Normal file
0
src/app/footer/footer.component.css
Normal file
16
src/app/footer/footer.component.html
Normal file
16
src/app/footer/footer.component.html
Normal file
@ -0,0 +1,16 @@
|
||||
<div class="container">
|
||||
<footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
|
||||
<div class="col-md-4 d-flex align-items-center">
|
||||
<a href="/" class="mb-3 me-2 mb-md-0 text-muted text-decoration-none lh-1">
|
||||
<img src="assets/logo.png" alt="Company icon" width="30" height="30">
|
||||
</a>
|
||||
<span class="text-muted">© 2022 Proxima Studios</span>
|
||||
</div>
|
||||
|
||||
<ul class="nav col-md-4 justify-content-end list-unstyled d-flex">
|
||||
<li class="ms-3"><a class="text-muted" href="#"><i style="font-size: 32px;" class="fab fa-twitter"></i></a></li>
|
||||
<li class="ms-3"><a class="text-muted" href="#"><i style="font-size: 32px;" class="fab fa-instagram"></i></a></li>
|
||||
<li class="ms-3"><a class="text-muted" href="#"><i style="font-size: 32px;" class="fab fa-github"></i></a></li>
|
||||
</ul>
|
||||
</footer>
|
||||
</div>
|
25
src/app/footer/footer.component.spec.ts
Normal file
25
src/app/footer/footer.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FooterComponent } from './footer.component';
|
||||
|
||||
describe('FooterComponent', () => {
|
||||
let component: FooterComponent;
|
||||
let fixture: ComponentFixture<FooterComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ FooterComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FooterComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
15
src/app/footer/footer.component.ts
Normal file
15
src/app/footer/footer.component.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-footer',
|
||||
templateUrl: './footer.component.html',
|
||||
styleUrls: ['./footer.component.css']
|
||||
})
|
||||
export class FooterComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
0
src/app/forms/forms.component.css
Normal file
0
src/app/forms/forms.component.css
Normal file
22
src/app/forms/forms.component.html
Normal file
22
src/app/forms/forms.component.html
Normal file
@ -0,0 +1,22 @@
|
||||
<div style="background-image:url(https://i.pinimg.com/originals/21/5c/7f/215c7fdca6033092baa04b35c17466bd.gif); background-size: cover; height: 450px;">
|
||||
<div style="background-image: url('Proxima');">
|
||||
<div class="container" style="padding-top: 200px;">
|
||||
<div class="row">
|
||||
<div class="col-3"></div>
|
||||
<div class="col-6">
|
||||
<h1 style="color:white;">Register to get started</h1>
|
||||
<form (submit)="redirect()">
|
||||
<div class="row">
|
||||
<div class="col-9">
|
||||
<input type="email" class="form-control" id="frontPageEmailInput" placeholder="name@example.com" name="email">
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<button class="btn btn-success" type="submit" onclick="window.location.href = '/register/'+document.getElementById('frontPageEmailInput').value">Register</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-3"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
25
src/app/forms/forms.component.spec.ts
Normal file
25
src/app/forms/forms.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FormsComponent } from './forms.component';
|
||||
|
||||
describe('FormsComponent', () => {
|
||||
let component: FormsComponent;
|
||||
let fixture: ComponentFixture<FormsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ FormsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FormsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
20
src/app/forms/forms.component.ts
Normal file
20
src/app/forms/forms.component.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { AppModule } from '../app.module';
|
||||
|
||||
@Component({
|
||||
selector: 'app-forms',
|
||||
templateUrl: './forms.component.html',
|
||||
styleUrls: ['./forms.component.css']
|
||||
})
|
||||
export class FormsComponent implements OnInit {
|
||||
|
||||
email:any;
|
||||
constructor(private router:Router) { }
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
redirect(){
|
||||
this.router.navigate(['/register/' + this.email]);
|
||||
}
|
||||
}
|
16
src/app/forms/forms.module.ts
Normal file
16
src/app/forms/forms.module.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsComponent } from './forms.component';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [FormsComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule
|
||||
]
|
||||
})
|
||||
export class FormModule { }
|
0
src/app/history/history.component.css
Normal file
0
src/app/history/history.component.css
Normal file
22
src/app/history/history.component.html
Normal file
22
src/app/history/history.component.html
Normal file
@ -0,0 +1,22 @@
|
||||
<br>
|
||||
<h1>Your Watch History: </h1>
|
||||
<div class="list-group">
|
||||
<a href="#" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">Video 1</h5>
|
||||
</div>
|
||||
<p class="mb-1">a video description.</p>
|
||||
</a>
|
||||
<a href="#" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">Video 2</h5>
|
||||
</div>
|
||||
<p class="mb-1">a video description.</p>
|
||||
</a>
|
||||
<a href="#" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">Video 3</h5>
|
||||
</div>
|
||||
<p class="mb-1">a video description.</p>
|
||||
</a>
|
||||
</div>
|
25
src/app/history/history.component.spec.ts
Normal file
25
src/app/history/history.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HistoryComponent } from './history.component';
|
||||
|
||||
describe('HistoryComponent', () => {
|
||||
let component: HistoryComponent;
|
||||
let fixture: ComponentFixture<HistoryComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ HistoryComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(HistoryComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
15
src/app/history/history.component.ts
Normal file
15
src/app/history/history.component.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-history',
|
||||
templateUrl: './history.component.html',
|
||||
styleUrls: ['./history.component.css']
|
||||
})
|
||||
export class HistoryComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
6
src/app/home/home.component.css
Normal file
6
src/app/home/home.component.css
Normal file
@ -0,0 +1,6 @@
|
||||
.flex-center {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
10
src/app/home/home.component.html
Normal file
10
src/app/home/home.component.html
Normal file
@ -0,0 +1,10 @@
|
||||
<div class="container">
|
||||
<div class="row" style="padding: 0;">
|
||||
<div class="col-1"></div>
|
||||
<div class="col-10" style="padding:0">
|
||||
<div class="row" #searchList>
|
||||
|
||||
</div>
|
||||
<div class="col-1"></div>
|
||||
</div>
|
||||
</div>
|
25
src/app/home/home.component.spec.ts
Normal file
25
src/app/home/home.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HomeComponent } from './home.component';
|
||||
|
||||
describe('HomeComponent', () => {
|
||||
let component: HomeComponent;
|
||||
let fixture: ComponentFixture<HomeComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ HomeComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(HomeComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
68
src/app/home/home.component.ts
Normal file
68
src/app/home/home.component.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { Component, ElementRef, OnInit, Renderer2, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ConfigService } from '../config.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-home',
|
||||
templateUrl: './home.component.html',
|
||||
styleUrls: ['./home.component.css']
|
||||
})
|
||||
export class HomeComponent implements OnInit {
|
||||
@ViewChild('searchList')cl:ElementRef;
|
||||
searchAmnt:number;
|
||||
constructor(
|
||||
private http:HttpClient,
|
||||
private rednerer:Renderer2,
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private config: ConfigService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
const query = {
|
||||
query: this.activatedRoute.snapshot.params['query']
|
||||
};
|
||||
|
||||
let params = new HttpParams()
|
||||
.set('query',JSON.stringify(query));
|
||||
|
||||
this.http.get<any>(this.config.hostname + '/videos/videos', {
|
||||
params: params
|
||||
}).subscribe(data => {
|
||||
console.log("data arrive")
|
||||
console.log(data.videos.length);
|
||||
this.searchAmnt = data.length;
|
||||
for(let i = 0; i < data.videos.length; i++) {
|
||||
console.log(i);
|
||||
// TODO: construct html for the page to load
|
||||
// ALSO TODO: determing what data is needed on this exact page
|
||||
const topDiv:HTMLDivElement = this.rednerer.createElement("div");
|
||||
const Anchor:HTMLAnchorElement = this.rednerer.createElement("a");
|
||||
const div:HTMLDivElement = this.rednerer.createElement("div");
|
||||
const Img:HTMLImageElement = this.rednerer.createElement("img");
|
||||
const bottomdiv:HTMLDivElement = this.rednerer.createElement("div")
|
||||
const title: HTMLTitleElement = this.rednerer.createElement("h2");
|
||||
const titleText = this.rednerer.createText(data.videos[i]["title"])
|
||||
|
||||
topDiv.appendChild(Anchor);
|
||||
topDiv.classList.add("col-4");
|
||||
topDiv.style.marginTop = "20px";
|
||||
Anchor.appendChild(div);
|
||||
Anchor.href = "/watch/" + data.videos[i]["vid_id"];
|
||||
div.appendChild(Img);
|
||||
div.classList.add("card");
|
||||
div.classList.add("bg-dark");
|
||||
div.appendChild(bottomdiv);
|
||||
bottomdiv.appendChild(title);
|
||||
bottomdiv.classList.add("card-img-overlay");
|
||||
bottomdiv.style.backgroundColor = "rgba(0, 0, 0, 0.432)";
|
||||
title.appendChild(titleText);
|
||||
title.classList.add("card-title");
|
||||
title.style.color = "white";
|
||||
Img.classList.add("card-img");
|
||||
Img.src = "https://proxima-tv.github.io/poster.jpg";
|
||||
this.cl.nativeElement.prepend(topDiv);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
26
src/app/login/login.component.css
Normal file
26
src/app/login/login.component.css
Normal file
@ -0,0 +1,26 @@
|
||||
.form-signin {
|
||||
width: 100%;
|
||||
max-width: 330px;
|
||||
padding: 15px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.form-signin .checkbox {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.form-signin .form-floating:focus-within {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.form-signin input[type="email"] {
|
||||
margin-bottom: -1px;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.form-signin input[type="password"] {
|
||||
margin-bottom: 10px;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
22
src/app/login/login.component.html
Normal file
22
src/app/login/login.component.html
Normal file
@ -0,0 +1,22 @@
|
||||
<div class="form-signin">
|
||||
<form (ngSubmit)="onSubmit()" style="margin-top: 20%;">
|
||||
<h1 class="h3 mb-3 fw-normal" style="text-align: center;">Please sign in</h1>
|
||||
|
||||
<div class="form-floating">
|
||||
<input type="email" class="form-control" id="floatingInput" placeholder="name@example.com" [(ngModel)]="logEmail" name="logEmail">
|
||||
<label for="floatingInput">Email address</label>
|
||||
</div>
|
||||
<div class="form-floating">
|
||||
<input type="password" class="form-control" id="floatingPassword" placeholder="Password" [(ngModel)]="logPassword" name="logPassword">
|
||||
<label for="floatingPassword">Password</label>
|
||||
</div>
|
||||
|
||||
<div class="checkbox mb-3">
|
||||
<label>
|
||||
<input type="checkbox" [(ngModel)]="remember" value="remember-me"> Remember me
|
||||
</label>
|
||||
</div>
|
||||
<button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button>
|
||||
<a href="/register">no account yet?</a>
|
||||
</form>
|
||||
</div>
|
25
src/app/login/login.component.spec.ts
Normal file
25
src/app/login/login.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LoginComponent } from './login.component';
|
||||
|
||||
describe('LoginComponent', () => {
|
||||
let component: LoginComponent;
|
||||
let fixture: ComponentFixture<LoginComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ LoginComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LoginComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
57
src/app/login/login.component.ts
Normal file
57
src/app/login/login.component.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { ConfigService } from '../config.service';
|
||||
import { CookiesService } from '../cookies.service';
|
||||
import { NavbarComponent } from '../navbar/navbar.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
templateUrl: './login.component.html',
|
||||
styleUrls: ['./login.component.css']
|
||||
})
|
||||
export class LoginComponent implements OnInit {
|
||||
public logEmail: any;
|
||||
public logPassword: any;
|
||||
public remember: any;
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
private cookies: CookiesService,
|
||||
private router: Router,
|
||||
private config: ConfigService
|
||||
) { }
|
||||
|
||||
ngOnInit(): void { }
|
||||
|
||||
onSubmit(): void {
|
||||
const user = {
|
||||
email: this.logEmail,
|
||||
password: encodeURIComponent(this.logPassword.toString())
|
||||
};
|
||||
|
||||
console.log(user);
|
||||
console.log(this.remember);
|
||||
|
||||
let params = new HttpParams().set('user', JSON.stringify(user));
|
||||
|
||||
console.log(params);
|
||||
|
||||
// this should use the body but has to revert back to using query strings
|
||||
this.http.get<any>(this.config.hostname + '/user/login', {
|
||||
params: params
|
||||
}).subscribe(async data => {
|
||||
console.log(JSON.stringify(data));
|
||||
if(this.remember){
|
||||
var d = new Date();
|
||||
d.setTime(d.getTime() + (7*24*60*60*1000));
|
||||
var expires = "expires="+ d.toUTCString();
|
||||
document.cookie = `proxima-login-cookie=${data['payload']['username']},${data['payload']['email']},${data['payload']['id']}; ${expires}; SameSite:none; Secure`;
|
||||
document.cookie = `proxima-login-reload=1`;
|
||||
} else {
|
||||
this.cookies.setCookie('proxima-login-cookie', `${data['payload']['username']},${data['payload']['email']},${data['payload']['id']},`);
|
||||
}
|
||||
NavbarComponent.isLoggedIn = true;
|
||||
this.router.navigate(['/profile']);
|
||||
});
|
||||
}
|
||||
}
|
19
src/app/login/login.module.ts
Normal file
19
src/app/login/login.module.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { LoginComponent } from './login.component';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { CookieService } from 'ngx-cookie-service';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [LoginComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
HttpClientModule
|
||||
]
|
||||
})
|
||||
export class LoginModule { }
|
0
src/app/navbar/navbar.component.css
Normal file
0
src/app/navbar/navbar.component.css
Normal file
35
src/app/navbar/navbar.component.html
Normal file
35
src/app/navbar/navbar.component.html
Normal file
@ -0,0 +1,35 @@
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/">
|
||||
<img src="assets/logo.png" alt="" width="30" height="30" class="d-inline-block align-text-top">
|
||||
PROXIMA.TV
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<div class="row" style="width: 100%;">
|
||||
<div class="col-10" style="padding-left: 25%; padding-right: 10%; padding-top: 10px;">
|
||||
<form class="d-flex">
|
||||
<input class="form-control me-2" id="search" type="search" placeholder="Find Your Poisen!" aria-label="Find Your Poisen!">
|
||||
<a class="btn btn-outline-success" type="submit" onclick="window.location.href = '/search/'+document.getElementById('search').value">Search</a>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-2" style="padding-top: 10px;">
|
||||
<span *ngIf="!isLoggedIn"><a href="/login">Login</a> | <a href="/register">Register</a></span>
|
||||
<div class="dropdown" *ngIf="isLoggedIn">
|
||||
<button class="btn dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false" style="width: 100%;">
|
||||
<img src="https://cdn.slpnetwork.de/img/sys/users/Thesteev.png" width="30px" height="30px" style="border-radius: 50%;"> {{username}}
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1" style="width: 100%;">
|
||||
<li><a class="dropdown-item" href="/profile">Profile</a></li>
|
||||
<li><a class="dropdown-item" href="/upload">Upload</a></li>
|
||||
<li><a class="dropdown-item" href="/settings">Settings</a></li>
|
||||
<li><a class="dropdown-item" (click)="logout()" style="color: #e74c3c;" href="#">Logout</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
25
src/app/navbar/navbar.component.spec.ts
Normal file
25
src/app/navbar/navbar.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { NavbarComponent } from './navbar.component';
|
||||
|
||||
describe('NavbarComponent', () => {
|
||||
let component: NavbarComponent;
|
||||
let fixture: ComponentFixture<NavbarComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ NavbarComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NavbarComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
36
src/app/navbar/navbar.component.ts
Normal file
36
src/app/navbar/navbar.component.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { AuthService } from '../auth.service';
|
||||
import { CookiesService } from '../cookies.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-navbar',
|
||||
templateUrl: './navbar.component.html',
|
||||
styleUrls: ['./navbar.component.css']
|
||||
})
|
||||
export class NavbarComponent implements OnInit {
|
||||
static isLoggedIn: Boolean;
|
||||
username:string;
|
||||
|
||||
constructor(
|
||||
private cookieService: CookiesService,
|
||||
private authService: AuthService,
|
||||
private router:Router
|
||||
) { }
|
||||
|
||||
isLoggedIn = false;
|
||||
|
||||
ngOnInit(): void {
|
||||
console.log(this.authService.loggedIn());
|
||||
// checks for login cookie to ensure the proper menu is shown
|
||||
this.isLoggedIn = this.authService.loggedIn();
|
||||
this.username = this.cookieService.getCookie('proxima-login-cookie').split(',')[0];
|
||||
}
|
||||
|
||||
logout(){
|
||||
console.log('logout')
|
||||
this.cookieService.deleteCookie('proxima-login-cookie');
|
||||
this.isLoggedIn = false;
|
||||
this.router.navigate(['/login'])
|
||||
}
|
||||
}
|
0
src/app/questions/questions.component.css
Normal file
0
src/app/questions/questions.component.css
Normal file
51
src/app/questions/questions.component.html
Normal file
51
src/app/questions/questions.component.html
Normal file
@ -0,0 +1,51 @@
|
||||
<div class="container">
|
||||
<div id="accordion">
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingOne">
|
||||
<h5 class="mb-0">
|
||||
<button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true"
|
||||
aria-controls="collapseOne">
|
||||
Was ist Proxima-Tv ?
|
||||
</button>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
|
||||
<div class="card-body">
|
||||
Proxima-Tv ist ein brandneuer Sreamingdienst. Wir bieten für die Premium-Nutzer eine Vielfalt von Inhalten und
|
||||
das ohne Werbung
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingTwo">
|
||||
<h5 class="mb-0">
|
||||
<button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false"
|
||||
aria-controls="collapseTwo">
|
||||
Was kann man auf Proxima-Tv sehen ?
|
||||
</button>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordion">
|
||||
<div class="card-body">
|
||||
Eine Vielzahl von Videos und Filmen ohne Begrenzung und ohne zusätzlichen kosten.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingThree">
|
||||
<h5 class="mb-0">
|
||||
<button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapseThree" aria-expanded="false"
|
||||
aria-controls="collapseThree">
|
||||
Wie kann ich kündigen.
|
||||
</button>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="collapseThree" class="collapse" aria-labelledby="headingThree" data-parent="#accordion">
|
||||
<div class="card-body">
|
||||
Man kann aus dem Abo nicht mehr aussteigen. Bei nicht Zahlung bleibt das Abo trotzdem bestehen und es erhöht
|
||||
sich einfach monatlich um wenige Euro.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
25
src/app/questions/questions.component.spec.ts
Normal file
25
src/app/questions/questions.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { QuestionsComponent } from './questions.component';
|
||||
|
||||
describe('QuestionsComponent', () => {
|
||||
let component: QuestionsComponent;
|
||||
let fixture: ComponentFixture<QuestionsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ QuestionsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(QuestionsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
15
src/app/questions/questions.component.ts
Normal file
15
src/app/questions/questions.component.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-questions',
|
||||
templateUrl: './questions.component.html',
|
||||
styleUrls: ['./questions.component.css']
|
||||
})
|
||||
export class QuestionsComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
26
src/app/register/register.component.css
Normal file
26
src/app/register/register.component.css
Normal file
@ -0,0 +1,26 @@
|
||||
.form-signin {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
padding: 15px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.form-signin .checkbox {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.form-signin .form-floating:focus-within {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.form-signin input[type="email"] {
|
||||
margin-bottom: -1px;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.form-signin input[type="password"] {
|
||||
margin-bottom: 10px;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
39
src/app/register/register.component.html
Normal file
39
src/app/register/register.component.html
Normal file
@ -0,0 +1,39 @@
|
||||
<div class="form-signin">
|
||||
<form (ngSubmit)="onSubmit()" style="margin-top: 20%;">
|
||||
<h1 class="h3 mb-3 fw-normal" style="text-align: center;">Register</h1>
|
||||
<p style="text-align: center;"><span style="color: #ff7675;">*</span> Symbolizes required fields</p>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-floating">
|
||||
<input type="email" class="form-control" id="floatingInput" placeholder="name@example.com" [(ngModel)]="email" name="email">
|
||||
<label for="floatingInput">Email<span style="color: #ff7675;">*</span></label>
|
||||
</div>
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" id="floatingInput" placeholder="name@example.com" [(ngModel)]="username" name="username">
|
||||
<label for="floatingInput">Username<span style="color: #ff7675;">*</span></label>
|
||||
</div>
|
||||
<div class="form-floating">
|
||||
<input type="password" class="form-control" id="floatingInput" placeholder="Secure Password" [(ngModel)]="password" name="password">
|
||||
<label for="floatingInput">Password<span style="color: #ff7675;">*</span></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" id="floatingInput" placeholder="name@example.com" [(ngModel)]="firstname" name="firstname">
|
||||
<label for="floatingInput">Firstname</label>
|
||||
</div>
|
||||
<div class="form-floating">
|
||||
<input type="text" class="form-control" id="floatingInput" placeholder="name@example.com" [(ngModel)]="lastname" name="lastname">
|
||||
<label for="floatingInput">Lastname</label>
|
||||
</div>
|
||||
<div class="form-floating">
|
||||
<input type="password" class="form-control" id="floatingInput" placeholder="Secure Password x2" [(ngModel)]="password_verify" name="password_verify">
|
||||
<label for="floatingInput">Verify Password<span style="color: #ff7675;">*</span></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<button class="w-100 btn btn-lg btn-primary" type="submit">Register now</button>
|
||||
<a href="/login">Already registered?</a>
|
||||
</form>
|
||||
</div>
|
25
src/app/register/register.component.spec.ts
Normal file
25
src/app/register/register.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { RegisterComponent } from './register.component';
|
||||
|
||||
describe('RegisterComponent', () => {
|
||||
let component: RegisterComponent;
|
||||
let fixture: ComponentFixture<RegisterComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ RegisterComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(RegisterComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
52
src/app/register/register.component.ts
Normal file
52
src/app/register/register.component.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { last } from 'rxjs';
|
||||
import { AuthService } from '../auth.service';
|
||||
import { ConfigService } from '../config.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-register',
|
||||
templateUrl: './register.component.html',
|
||||
styleUrls: ['./register.component.css']
|
||||
})
|
||||
export class RegisterComponent implements OnInit {
|
||||
|
||||
username:string;
|
||||
password:string;
|
||||
password_verify:string;
|
||||
email:string;
|
||||
firstname = null;
|
||||
lastname = null;
|
||||
name = null;
|
||||
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
private router: Router,
|
||||
private config: ConfigService
|
||||
) { }
|
||||
|
||||
ngOnInit(): void { }
|
||||
|
||||
onSubmit(){
|
||||
if(this.password == this.password_verify) {
|
||||
// TODO check that password matches required complexity
|
||||
|
||||
if(this.firstname != null) this.name += this.firstname;
|
||||
if(this.lastname != null) this.name += this.lastname;
|
||||
|
||||
const user = {
|
||||
username: this.username,
|
||||
email: this.email,
|
||||
password: this.password.toString(),
|
||||
name: this.name
|
||||
}
|
||||
|
||||
// TODO send to auth service to register at the backend
|
||||
this.http.post<any>(this.config.hostname + '/user/register', user).subscribe(data => {
|
||||
console.log(data['success']);
|
||||
this.router.navigate(['/login']);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
18
src/app/register/register.module.ts
Normal file
18
src/app/register/register.module.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { RegisterComponent } from './register.component';
|
||||
import { HttpClient, HttpClientModule, HttpHandler } from '@angular/common/http';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [RegisterComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
HttpClientModule
|
||||
]
|
||||
})
|
||||
export class RegisterModule { }
|
12
src/app/search-page/search-page.component.css
Normal file
12
src/app/search-page/search-page.component.css
Normal file
@ -0,0 +1,12 @@
|
||||
.selector {
|
||||
border: 1px solid #bdc3c7;
|
||||
padding: 10px;
|
||||
transition-duration: 200ms;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.selector:hover {
|
||||
border: 1px solid #3498db;
|
||||
}
|
||||
.selected {
|
||||
border: 1px solid #3498db;
|
||||
}
|
12
src/app/search-page/search-page.component.html
Normal file
12
src/app/search-page/search-page.component.html
Normal file
@ -0,0 +1,12 @@
|
||||
<div class="container">
|
||||
<div class="row" style="padding: 0;">
|
||||
<div class="col-1"></div>
|
||||
<div class="col-10" style="padding:0">
|
||||
<h2>Proxima Found {{searchAmnt}} Results </h2>
|
||||
<hr>
|
||||
<div class="row" #searchList>
|
||||
|
||||
</div>
|
||||
<div class="col-1"></div>
|
||||
</div>
|
||||
</div>
|
25
src/app/search-page/search-page.component.spec.ts
Normal file
25
src/app/search-page/search-page.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SearchPageComponent } from './search-page.component';
|
||||
|
||||
describe('SearchPageComponent', () => {
|
||||
let component: SearchPageComponent;
|
||||
let fixture: ComponentFixture<SearchPageComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SearchPageComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SearchPageComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
65
src/app/search-page/search-page.component.ts
Normal file
65
src/app/search-page/search-page.component.ts
Normal file
@ -0,0 +1,65 @@
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { Component, ElementRef, OnInit, Renderer2, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ConfigService } from '../config.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-search-page',
|
||||
templateUrl: './search-page.component.html',
|
||||
styleUrls: ['./search-page.component.css']
|
||||
})
|
||||
export class SearchPageComponent implements OnInit {
|
||||
@ViewChild('searchList')cl:ElementRef;
|
||||
searchAmnt:number;
|
||||
constructor(
|
||||
private http:HttpClient,
|
||||
private rednerer:Renderer2,
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private config: ConfigService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
const query = {
|
||||
query: this.activatedRoute.snapshot.params['query']
|
||||
};
|
||||
|
||||
let params = new HttpParams()
|
||||
.set('query',JSON.stringify(query));
|
||||
|
||||
this.http.get<any>(this.config.hostname + '/videos/search', {
|
||||
params: params
|
||||
}).subscribe(data => {
|
||||
console.log(data);
|
||||
this.searchAmnt = data.length;
|
||||
for(let i = 0; i < data.length; i++) {
|
||||
// TODO: construct html for the page to load
|
||||
// ALSO TODO: determing what data is needed on this exact page
|
||||
const topDiv:HTMLDivElement = this.rednerer.createElement("div");
|
||||
const Anchor:HTMLAnchorElement = this.rednerer.createElement("a");
|
||||
const div:HTMLDivElement = this.rednerer.createElement("div");
|
||||
const Img:HTMLImageElement = this.rednerer.createElement("img");
|
||||
const bottomdiv:HTMLDivElement = this.rednerer.createElement("div")
|
||||
const title: HTMLTitleElement = this.rednerer.createElement("h2");
|
||||
const titleText = this.rednerer.createText(data[i]["title"])
|
||||
|
||||
topDiv.appendChild(Anchor);
|
||||
topDiv.classList.add("col-4");
|
||||
Anchor.appendChild(div);
|
||||
Anchor.href = "/watch/" + data[i]["vid_id"];
|
||||
div.appendChild(Img);
|
||||
div.classList.add("card");
|
||||
div.classList.add("bg-dark");
|
||||
div.appendChild(bottomdiv);
|
||||
bottomdiv.appendChild(title);
|
||||
bottomdiv.classList.add("card-img-overlay");
|
||||
bottomdiv.style.backgroundColor = "rgba(0, 0, 0, 0.432)";
|
||||
title.appendChild(titleText);
|
||||
title.classList.add("card-title");
|
||||
title.style.color = "white";
|
||||
Img.classList.add("card-img");
|
||||
Img.src = "https://proxima-tv.github.io/poster.jpg";
|
||||
this.cl.nativeElement.prepend(topDiv);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
14
src/app/search-page/search-page.module.ts
Normal file
14
src/app/search-page/search-page.module.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [
|
||||
CommonModule,
|
||||
HttpClient
|
||||
]
|
||||
})
|
||||
export class SearchPageModule { }
|
0
src/app/search/search.component.css
Normal file
0
src/app/search/search.component.css
Normal file
8
src/app/search/search.component.html
Normal file
8
src/app/search/search.component.html
Normal file
@ -0,0 +1,8 @@
|
||||
<div class="input-group">
|
||||
<div class="form-outline">
|
||||
<input id="search-input" type="text" id="form1" class="form-control" />
|
||||
<label class="form-label" for="form1">Find Your Poisen!</label>
|
||||
</div>
|
||||
<button id="search-button" type="button" class="btn btn-primary">
|
||||
</button>
|
||||
</div>
|
25
src/app/search/search.component.spec.ts
Normal file
25
src/app/search/search.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SearchComponent } from './search.component';
|
||||
|
||||
describe('SearchComponent', () => {
|
||||
let component: SearchComponent;
|
||||
let fixture: ComponentFixture<SearchComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SearchComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SearchComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
17
src/app/search/search.component.ts
Normal file
17
src/app/search/search.component.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-search',
|
||||
templateUrl: './search.component.html',
|
||||
styleUrls: ['./search.component.css']
|
||||
})
|
||||
export class SearchComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
18
src/app/search/search.module.ts
Normal file
18
src/app/search/search.module.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { SearchComponent } from './search.component';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [SearchComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
HttpClientModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule
|
||||
]
|
||||
})
|
||||
export class SearchModule { }
|
61
src/app/service-preview/service-preview.component.css
Normal file
61
src/app/service-preview/service-preview.component.css
Normal file
@ -0,0 +1,61 @@
|
||||
.b-example-divider {
|
||||
height: 3rem;
|
||||
background-color: rgba(0, 0, 0, .1);
|
||||
border: solid rgba(0, 0, 0, .15);
|
||||
border-width: 1px 0;
|
||||
box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
|
||||
}
|
||||
|
||||
.bi {
|
||||
vertical-align: -.125em;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 2rem;
|
||||
color: #fff;
|
||||
border-radius: .75rem;
|
||||
}
|
||||
|
||||
.icon-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
.icon-link > .bi {
|
||||
margin-top: .125rem;
|
||||
margin-left: .125rem;
|
||||
transition: transform .25s ease-in-out;
|
||||
fill: currentColor;
|
||||
}
|
||||
.icon-link:hover > .bi {
|
||||
transform: translate(.25rem);
|
||||
}
|
||||
|
||||
.icon-square {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
font-size: 1.5rem;
|
||||
border-radius: .75rem;
|
||||
}
|
||||
|
||||
.rounded-4 { border-radius: .5rem; }
|
||||
.rounded-5 { border-radius: 1rem; }
|
||||
|
||||
.text-shadow-1 { text-shadow: 0 .125rem .25rem rgba(0, 0, 0, .25); }
|
||||
.text-shadow-2 { text-shadow: 0 .25rem .5rem rgba(0, 0, 0, .25); }
|
||||
.text-shadow-3 { text-shadow: 0 .5rem 1.5rem rgba(0, 0, 0, .25); }
|
||||
|
||||
.card-cover {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
}
|
19
src/app/service-preview/service-preview.component.html
Normal file
19
src/app/service-preview/service-preview.component.html
Normal file
@ -0,0 +1,19 @@
|
||||
<div class="container" id="featured-3">
|
||||
<h2 class="pb-2 border-bottom">Columns with icons</h2>
|
||||
<div class="row">
|
||||
<div class="feature col">
|
||||
<div class="feature-icon bg-primary bg-gradient">
|
||||
<img src="assets/lowcost.png" alt="" width="48" height="48">
|
||||
</div>
|
||||
<h2>Mostly free</h2>
|
||||
<p>Sounds to good to be true? well it is true! Proxima.TV does not lock main content behind paywalls our premium service brings features to enhance Your experience and more special content</p>
|
||||
</div>
|
||||
<div class="feature col">
|
||||
<div class="feature-icon bg-primary bg-gradient">
|
||||
<img class="bi" src="assets/desktop.png" alt="" width="48" height="48">
|
||||
</div>
|
||||
<h2>Watch where you like</h2>
|
||||
<p>We are always expanding the supported platforms proxima.tv can run on. with our website that was created to work on any devices, we introduced our first step towards true multiplatforming.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
25
src/app/service-preview/service-preview.component.spec.ts
Normal file
25
src/app/service-preview/service-preview.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ServicePreviewComponent } from './service-preview.component';
|
||||
|
||||
describe('ServicePreviewComponent', () => {
|
||||
let component: ServicePreviewComponent;
|
||||
let fixture: ComponentFixture<ServicePreviewComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ServicePreviewComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ServicePreviewComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
15
src/app/service-preview/service-preview.component.ts
Normal file
15
src/app/service-preview/service-preview.component.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-service-preview',
|
||||
templateUrl: './service-preview.component.html',
|
||||
styleUrls: ['./service-preview.component.css']
|
||||
})
|
||||
export class ServicePreviewComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
0
src/app/settings/settings.component.css
Normal file
0
src/app/settings/settings.component.css
Normal file
81
src/app/settings/settings.component.html
Normal file
81
src/app/settings/settings.component.html
Normal file
@ -0,0 +1,81 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-6" style="border-radius: 5px; padding: 5px;">
|
||||
<div style="padding: 0 5px 0;">
|
||||
<h1>General Profile Settings</h1>
|
||||
<div class="mb-3">
|
||||
<div class="row">
|
||||
<div class="col-10">
|
||||
<label for="formFile" class="form-label">Update Profile Picture:</label>
|
||||
<input class="form-control" type="file" id="formFile">
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<img src="{{profile_pic}}" style="border-radius: 5px;" width="64" alt="profile-picture">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="exampleFormControlInput1" class="form-label">Email address:</label>
|
||||
<input type="email" class="form-control" id="exampleFormControlInput1" value="{{email}}">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="exampleFormControlTextarea1" class="form-label">Profile Bio:</label>
|
||||
<div class="input-group">
|
||||
<textarea class="form-control" aria-label="With textarea" value="{{profile_bio}}"></textarea>
|
||||
</div>
|
||||
<button class="btn btn-success">Save</button></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6" style="border-radius: 5px; padding: 5px;">
|
||||
<div style="padding: 0 5px 0;">
|
||||
<h1>Security Settings</h1>
|
||||
<div class="mb-3">
|
||||
<label for="exampleFormControlInput1" class="form-label">New Password:</label>
|
||||
<input type="password" class="form-control" id="exampleFormControlInput1">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="exampleFormControlInput1" class="form-label">Confirm New Password:</label>
|
||||
<input type="password" class="form-control" id="exampleFormControlInput1">
|
||||
</div>
|
||||
<hr>
|
||||
<div class="mb-3">
|
||||
<label for="exampleFormControlInput1" class="form-label">Old Password:</label>
|
||||
<input type="password" class="form-control" id="exampleFormControlInput1">
|
||||
</div>
|
||||
<button class="btn btn-success">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<br>
|
||||
<h1>Misc Settings:</h1>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="flexCheckIndeterminate">
|
||||
<label class="form-check-label" for="flexCheckIndeterminate">
|
||||
Subscribe to Newsletter
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<br>
|
||||
<h1>Privacy Settings:</h1>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="flexCheckIndeterminate">
|
||||
<label class="form-check-label" for="flexCheckIndeterminate">
|
||||
Show Profile Public
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="flexCheckIndeterminate">
|
||||
<label class="form-check-label" for="flexCheckIndeterminate">
|
||||
Show Stats Public
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="flexCheckIndeterminate">
|
||||
<label class="form-check-label" for="flexCheckIndeterminate">
|
||||
Show Watch History Public
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
25
src/app/settings/settings.component.spec.ts
Normal file
25
src/app/settings/settings.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SettingsComponent } from './settings.component';
|
||||
|
||||
describe('SettingsComponent', () => {
|
||||
let component: SettingsComponent;
|
||||
let fixture: ComponentFixture<SettingsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SettingsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SettingsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
50
src/app/settings/settings.component.ts
Normal file
50
src/app/settings/settings.component.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ConfigService } from '../config.service';
|
||||
import { CookiesService } from '../cookies.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings',
|
||||
templateUrl: './settings.component.html',
|
||||
styleUrls: ['./settings.component.css']
|
||||
})
|
||||
export class SettingsComponent implements OnInit {
|
||||
|
||||
username:string;
|
||||
name: string;
|
||||
email: string;
|
||||
profile_bio: string;
|
||||
profile_pic: string;
|
||||
|
||||
constructor(
|
||||
private cookies: CookiesService,
|
||||
private http: HttpClient,
|
||||
private config: ConfigService
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
let cookie = this.cookies.getCookie('proxima-login-cookie').split(",");
|
||||
console.log(cookie);
|
||||
const query = {
|
||||
email: cookie[1]
|
||||
};
|
||||
|
||||
let params = new HttpParams()
|
||||
.set('user',JSON.stringify(query));
|
||||
|
||||
this.http.get<any>(this.config.hostname + '/user/settings', {
|
||||
params: params
|
||||
}).subscribe(data => {
|
||||
let fetched = data[0];
|
||||
console.log(fetched);
|
||||
// TODO: construct html for the page to load
|
||||
// ALSO TODO: determing what data is needed on this exact page
|
||||
this.username = fetched["username"];
|
||||
this.name = fetched["name"];
|
||||
this.email = fetched["email"];
|
||||
this.profile_bio = fetched["profile_bio"];
|
||||
this.profile_pic = fetched["profile_pic"];
|
||||
});
|
||||
}
|
||||
onChange(): void { }
|
||||
}
|
18
src/app/settings/settings.module.ts
Normal file
18
src/app/settings/settings.module.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { SettingsComponent } from './settings.component';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [SettingsComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
HttpClientModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule
|
||||
]
|
||||
})
|
||||
export class SettingsModule { }
|
0
src/app/stats/stats.component.css
Normal file
0
src/app/stats/stats.component.css
Normal file
15
src/app/stats/stats.component.html
Normal file
15
src/app/stats/stats.component.html
Normal file
@ -0,0 +1,15 @@
|
||||
<div class="container">
|
||||
<h1>Viewing Stats: </h1>
|
||||
<div class="row">
|
||||
<div class="col-md-6" style="padding: 0 2% 0;"> </div>
|
||||
<div class="col-md-6" style="padding: 0 2% 0;"> </div>
|
||||
<div class="col-md-6" style="padding: 0 2% 0;">
|
||||
<br>
|
||||
<app-history></app-history>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<br>
|
||||
<app-comments></app-comments>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
25
src/app/stats/stats.component.spec.ts
Normal file
25
src/app/stats/stats.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { StatsComponent } from './stats.component';
|
||||
|
||||
describe('StatsComponent', () => {
|
||||
let component: StatsComponent;
|
||||
let fixture: ComponentFixture<StatsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ StatsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(StatsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
22
src/app/stats/stats.component.ts
Normal file
22
src/app/stats/stats.component.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { CookiesService } from '../cookies.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-stats',
|
||||
templateUrl: './stats.component.html',
|
||||
styleUrls: ['./stats.component.css']
|
||||
})
|
||||
export class StatsComponent implements OnInit {
|
||||
CookieService: any;
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
let reload = this.CookieService.get("proxima-login-reload");
|
||||
if(reload != null) {
|
||||
this.CookieService.deleteCookie("proxima-login-reload");
|
||||
document.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
0
src/app/uploads/uploads.component.css
Normal file
0
src/app/uploads/uploads.component.css
Normal file
33
src/app/uploads/uploads.component.html
Normal file
33
src/app/uploads/uploads.component.html
Normal file
@ -0,0 +1,33 @@
|
||||
<div class="container">
|
||||
<form (ngSubmit)="onSubmit()" enctype="multipart/form-data">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h3>Do not Close this Site, during an Upload</h3>
|
||||
<h6>Status: {{status}}</h6>
|
||||
<div class="progress">
|
||||
<div class="progress-bar" role="progressbar" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100" [style.width.%]="progress">{{status}}</div>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="mb-3">
|
||||
<label for="vidName" class="form-label">Video Title</label>
|
||||
<input type="text" class="form-control" id="vidName" placeholder="Videoname..." [(ngModel)]="vidName">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="vidfile" class="form-label">The Video File</label>
|
||||
<input class="form-control" type="file" id="vidfile" (change)="onFileSelected($event)" accept="video/mp4">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<img src="" class="img-fluid" alt="Thumbnail Preview">
|
||||
<div class="mb-3">
|
||||
<label for="vidThumbnail" class="form-label">Video Thumbnail</label>
|
||||
<input class="form-control" type="file" id="vidThumbnail" [(ngModel)]="vidThumbnail" accept="image/*">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="w-100 btn btn-lg btn-primary" type="submit">Submit</button>
|
||||
</form>
|
||||
</div>
|
25
src/app/uploads/uploads.component.spec.ts
Normal file
25
src/app/uploads/uploads.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { UploadsComponent } from './uploads.component';
|
||||
|
||||
describe('UploadsComponent', () => {
|
||||
let component: UploadsComponent;
|
||||
let fixture: ComponentFixture<UploadsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ UploadsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(UploadsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
68
src/app/uploads/uploads.component.ts
Normal file
68
src/app/uploads/uploads.component.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { HttpClient, HttpEvent, HttpEventType } from '@angular/common/http';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { catchError, Observable } from 'rxjs';
|
||||
import { ConfigService } from '../config.service';
|
||||
import { CookiesService } from '../cookies.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-uploads',
|
||||
templateUrl: './uploads.component.html',
|
||||
styleUrls: ['./uploads.component.css']
|
||||
})
|
||||
export class UploadsComponent implements OnInit {
|
||||
public vidName: any;
|
||||
public vidFile: File;
|
||||
public vidThumbnail: File;
|
||||
public progress: number = 0;
|
||||
public status: string = "idle";
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
private config: ConfigService,
|
||||
private cookies: CookiesService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
onSubmit():void {
|
||||
const userCookie = this.cookies.getCookie('proxima-login-cookie');
|
||||
const formData = new FormData();
|
||||
formData.append("title", this.vidName);
|
||||
formData.append("file", this.vidFile);
|
||||
formData.append("thumbnail", this.vidThumbnail);
|
||||
formData.append("creator", this.cookies.getCookie('proxima-login-cookie').split(',')[2])
|
||||
|
||||
console.log("sending Data")
|
||||
|
||||
this.http.post<any>(this.config.hostname + '/videos/upload', formData, {
|
||||
reportProgress: true,
|
||||
observe: 'events',
|
||||
}).subscribe((event: HttpEvent<any>) => {
|
||||
switch (event.type) {
|
||||
case HttpEventType.Sent:
|
||||
console.log('Request has been made!');
|
||||
break;
|
||||
case HttpEventType.ResponseHeader:
|
||||
console.log('Response header has been received!');
|
||||
break;
|
||||
case HttpEventType.UploadProgress:
|
||||
var eventTotal = event.total ? event.total : 0;
|
||||
this.progress = Math.round(event.loaded / eventTotal * 100);
|
||||
this.status = `Uploaded! ${this.progress}%`;
|
||||
console.log(`Uploaded! ${this.progress}%`);
|
||||
break;
|
||||
case HttpEventType.Response:
|
||||
console.log('Video Upload Successfully!', event.body);
|
||||
this.status = 'Video Upload Successfully!';
|
||||
setTimeout(() => {
|
||||
this.progress = 0;
|
||||
this.status = "idle";
|
||||
}, 1500);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
onFileSelected(event):void {
|
||||
this.vidFile = event.target.files[0];
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user