initial commit
This commit is contained in:
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
@@ -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"
|
||||
}
|
||||
@@ -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
|
||||
});
|
||||
};
|
||||
Generated
+19544
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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,0 +1,3 @@
|
||||
<app-navbar></app-navbar>
|
||||
<router-outlet></router-outlet>
|
||||
<app-footer></app-footer>
|
||||
@@ -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!');
|
||||
});
|
||||
});
|
||||
@@ -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';
|
||||
|
||||
|
||||
}
|
||||
@@ -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 { }
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@@ -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;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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,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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ConfigService {
|
||||
public hostname = "http://localhost:3000"
|
||||
constructor() { }
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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,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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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,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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
@@ -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,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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
.flex-center {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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']);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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,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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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,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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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']);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 { }
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 { }
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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,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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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 { }
|
||||
}
|
||||
@@ -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,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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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,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>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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
Reference in New Issue
Block a user