Merge branch 'master' into Fit-in-view-option

This commit is contained in:
Piotr Pekala 2019-10-17 01:49:23 -07:00
commit eac1662294
21 changed files with 195 additions and 107 deletions

View File

@ -72,7 +72,7 @@
"svg-crowbar": "^0.2.3",
"tree-kill": "^1.2.1",
"typeface-roboto": "^0.0.75",
"xterm": "^3.14.5",
"xterm": "^4.0.0",
"yargs": "^13.3.0",
"zone.js": "^0.9.1"
},

View File

@ -1 +1,2 @@
<router-outlet></router-outlet>
<app-notification-box></app-notification-box>

View File

@ -7,6 +7,7 @@ import { SettingsService } from './services/settings.service';
import { PersistenceService } from 'angular-persistence';
import { ElectronService, NgxElectronModule } from 'ngx-electron';
import createSpyObj = jasmine.createSpyObj;
import { NO_ERRORS_SCHEMA } from '@angular/core';
describe('AppComponent', () => {
let component: AppComponent;
@ -18,7 +19,8 @@ describe('AppComponent', () => {
TestBed.configureTestingModule({
declarations: [AppComponent],
imports: [RouterTestingModule, MatIconModule, NgxElectronModule],
providers: [SettingsService, PersistenceService]
providers: [SettingsService, PersistenceService],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
electronService = TestBed.get(ElectronService);

View File

@ -185,6 +185,7 @@ import { AdbutlerComponent } from './components/adbutler/adbutler.component';
import { ConsoleService } from './services/settings/console.service';
import { DefaultConsoleService } from './services/settings/default-console.service';
import { NodeCreatedLabelStylesFixer } from './components/project-map/helpers/node-created-label-styles-fixer';
import { NotificationBoxComponent } from './components/notification-box/notification-box.component';
import { NonNegativeValidator } from './validators/non-negative-validator';
import { RotationValidator } from './validators/rotation-validator';
import { DuplicateActionComponent } from './components/project-map/context-menu/actions/duplicate-action/duplicate-action.component';
@ -363,6 +364,7 @@ if (environment.production) {
ShowNodeActionComponent,
ConsoleComponent,
NodesMenuComponent,
NotificationBoxComponent,
ProjectMapMenuComponent,
HelpComponent,
ConfigEditorDialogComponent,

View File

@ -1,15 +1 @@
<table class="butler" style="width: 600px; border: 0px solid #C0C0C0; background-color: #263238" cellSpacing=0 cellPadding=3>
<tr><td height=80 style="background-color: #263238" #code>
<div id="{{ this.divId }}"></div>
<!-- Begin Ad Code -->
<!-- End Ad Code -->
</td></tr>
</table>
<div class="ad" #ad></div>

View File

@ -1,7 +1,30 @@
.butler a {
.ad {
background-color: #263238;
width: 400px;
padding-top: 10px;
padding-bottom: 10px;
font-size: 12px;
}
button {
background-color: #0097a7;
margin-top: 10px;
border: none;
outline: none;
padding: 5px;
color: white;
font-weight: bold;
padding-right: 15px;
padding-left: 15px;
border-radius: 4px;
}
a {
color: #0097a7;
}
.butler {
font-size: 14px;
}
button {
a {
color: white;
}
}

View File

@ -2,7 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AdbutlerComponent } from './adbutler.component';
describe('AdbutlerComponent', () => {
xdescribe('AdbutlerComponent', () => {
let component: AdbutlerComponent;
let fixture: ComponentFixture<AdbutlerComponent>;
@ -19,7 +19,7 @@ describe('AdbutlerComponent', () => {
fixture.detectChanges();
});
it('should create', () => {
xit('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,4 +1,6 @@
import { Component, OnInit, ElementRef, ViewChild, AfterViewInit, ViewEncapsulation, OnDestroy } from '@angular/core';
import { Component, OnInit, ElementRef, ViewChild, ViewEncapsulation, Input } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { AdButlerResponse } from '../../models/adbutler';
@Component({
selector: 'app-adbutler',
@ -6,63 +8,19 @@ import { Component, OnInit, ElementRef, ViewChild, AfterViewInit, ViewEncapsulat
styleUrls: ['./adbutler.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class AdbutlerComponent implements OnInit, AfterViewInit, OnDestroy {
id: number;
setId: number;
rnd: number;
abkw: string;
sparkCounter: number;
divId: string;
export class AdbutlerComponent implements OnInit {
@ViewChild('ad', {static: false}) ad: ElementRef;
@Input() theme: string;
htmlCode: string;
@ViewChild('code', {static: false}) code: ElementRef;
constructor() { }
constructor(
private httpClient: HttpClient
) {}
ngOnInit() {
var loadedTextAds355353 = (window as any).loadedTextAds355353;
if(loadedTextAds355353 == null) {
(window as any).loadedTextAds355353 = new Array();
}
(window as any).id355353 = 165803;
(window as any).setID355353 = 355353;
(window as any).rnd = (window as any).rnd || Math.floor(Math.random()*10e6);
(window as any).abkw = (window as any).abkw ||'';
var sparkCounter355353 = (window as any).sparkCounter355353;
if(sparkCounter355353 == null) {
sparkCounter355353 = 1;
}
else {
sparkCounter355353 = sparkCounter355353 + 1
}
(window as any).sparkCounter355353 = sparkCounter355353;
(window as any).loadedTextAds355353[sparkCounter355353] = false;
this.id = (window as any).id355353;
this.divId = "abta355353" + sparkCounter355353;
this.setId = (window as any).setID355353;
this.abkw = (window as any).abkw;
this.rnd = (window as any).rnd;
this.sparkCounter = (window as any).sparkCounter355353;
this.httpClient.get('https://servedbyadbutler.com/adserve/;ID=165803;size=0x0;setID=371476;type=json;').subscribe((response: AdButlerResponse) => {
this.htmlCode = response.placements.placement_1.body;
this.ad.nativeElement.insertAdjacentHTML('beforeend', this.htmlCode);
});
}
ngAfterViewInit() {
const scriptUrl = "https://servedbyadbutler.com/adserve/;ID=" + this.id + ";setID=" + this.setId + ";type=textad;kw=" + this.abkw + ";pid=" + this.rnd + ";layoutID=" + this.sparkCounter;
const scriptElement = document.createElement('script');
scriptElement.src = scriptUrl;
scriptElement.type = 'text/javascript';
scriptElement.async = true;
scriptElement.charset = 'utf-8';
this.code.nativeElement.appendChild(scriptElement);
}
ngOnDestroy() {
// start from 0 when switching pages
(window as any).sparkCounter355353 = 0;
delete (window as any).loadedTextAds355353[this.sparkCounter];
}
}

View File

@ -14,7 +14,7 @@
</ng-container>
<ng-container *ngIf="row.type === 'adbutler'">
<app-adbutler></app-adbutler>
<app-adbutler theme="dark"></app-adbutler>
</ng-container>
</mat-cell>
</ng-container>

View File

@ -0,0 +1,9 @@
<div class="notification-box" *ngIf="isVisible">
<mat-progress-bar mode="determinate" [value]="progress"></mat-progress-bar>
<div style="display: flex; height: 102px;">
<div class="content">
<app-adbutler theme="dark"></app-adbutler>
<mat-icon (click)="closeNotification()" class="close-button">close</mat-icon>
</div>
</div>
</div>

View File

@ -0,0 +1,31 @@
.notification-box {
position: fixed;
bottom: 20px;
right: 20px;
width: 412px;
height: 108px;
}
.content {
background-color: #263238;
padding-left: 8px;
border-left: 2px solid #0097a7;
border-right: 2px solid #0097a7;
border-bottom: 2px solid #0097a7;
}
.close-button {
position: fixed;
bottom: 90px;
right: 30px;
cursor: pointer;
}
.mat-icon:hover {
color: #0097a7;
}
.check-button {
background-color: #0097a7;
margin-top: -10px;
}

View File

@ -0,0 +1,71 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { timer, Observable, Subscription } from 'rxjs';
@Component({
selector: 'app-notification-box',
templateUrl: './notification-box.component.html',
styleUrls: ['./notification-box.component.scss']
})
export class NotificationBoxComponent implements OnInit, OnDestroy {
timer: Observable<number>;
viewTimer: Observable<number>;
timerSubscription: Subscription;
viewTimerSubscription: Subscription;
viewsCounter = 0;
ticks: number = 1000;
progress: number = 0;
isVisible = false;
interval = 10;
delayTime: number = 5000;
breakTime: number = 20;
isEndless: boolean = false;
numberOfViews: number = 1;
constructor(){}
ngOnInit() {
this.startTimer();
}
startTimer() {
this.timer = timer(this.delayTime, 1000);
this.timerSubscription = this.timer.subscribe(() => {
this.ticks++;
if (this.ticks > this.breakTime && !this.isVisible && navigator.onLine) {
this.ticks = 0;
this.showNotification();
this.viewsCounter++;
if (!this.isEndless){
if (this.viewsCounter === this.numberOfViews) {
this.timerSubscription.unsubscribe();
}
}
}
});
}
showNotification() {
this.viewTimer = timer(0, 100);
this.isVisible = true;
this.progress = 0;
this.viewTimerSubscription = this.viewTimer.subscribe(() => {
this.progress += 1;
if (this.progress > 100) {
this.isVisible = false;
this.viewTimerSubscription.unsubscribe();
}
});
}
closeNotification() {
this.isVisible = false;
}
ngOnDestroy() {
this.timerSubscription.unsubscribe();
this.viewTimerSubscription.unsubscribe();
}
}

View File

@ -142,11 +142,11 @@
<app-context-menu [project]="project" [server]="server"></app-context-menu>
</div>
<div id="zoom-buttons">
<!-- <div id="zoom-buttons">
<button class="zoom-button" (click)="zoomIn()">+</button>
<button class="zoom-button" (click)="resetZoom()"><mat-icon>adjust</mat-icon></button>
<button class="zoom-button" (click)="zoomOut()">-</button>
</div>
</div> -->
<app-progress></app-progress>
<app-project-map-shortcuts *ngIf="project" [project]="project" [server]="server"></app-project-map-shortcuts>

View File

@ -3,7 +3,6 @@
<div class="row">
<h1 class="col">Projects</h1>
<button
*ngIf="settings.experimental_features"
class="col"
mat-raised-button
color="primary"
@ -13,7 +12,6 @@
Add blank project
</button>
<button
*ngIf="settings.experimental_features"
class="col"
mat-raised-button
color="primary"

View File

@ -15,11 +15,11 @@
>
</div>
<div>
<!-- <div>
<mat-checkbox [(ngModel)]="settings.experimental_features"
>Enable experimental features (WARNING: IT CAN BREAK YOU LABS!)</mat-checkbox
>
</div>
</div> -->
<!-- <div>
<mat-checkbox [(ngModel)]="settings.angular_map"

View File

@ -0,0 +1,23 @@
export interface Placement1 {
banner_id: string;
width: string;
height: string;
alt_text: string;
accompanied_html: string;
target: string;
tracking_pixel: string;
body: string;
redirect_url: string;
refresh_url: string;
refresh_time: string;
image_url: string;
}
export interface Placements {
placement_1: Placement1;
}
export interface AdButlerResponse {
status: string;
placements: Placements;
}

View File

@ -158,20 +158,4 @@ describe('ProjectService', () => {
expect(service.isReadOnly(project)).toEqual(true);
});
it('project should be readonly when experimentalFeatures disabled ', () => {
const project = new Project();
project.readonly = false;
spyOn(settingsService, 'isExperimentalEnabled').and.returnValue(false);
expect(service.isReadOnly(project)).toEqual(true);
});
it('project should not be readonly when experimentalFeatures enabled ', () => {
const project = new Project();
project.readonly = false;
spyOn(settingsService, 'isExperimentalEnabled').and.returnValue(true);
expect(service.isReadOnly(project)).toEqual(false);
});
});

View File

@ -91,6 +91,6 @@ export class ProjectService {
if (project.readonly) {
return project.readonly;
}
return !this.settingsService.isExperimentalEnabled();
return false;
}
}

View File

@ -9128,10 +9128,10 @@ xtend@~2.1.1:
dependencies:
object-keys "~0.4.0"
xterm@^3.14.5:
version "3.14.5"
resolved "https://registry.npmjs.org/xterm/-/xterm-3.14.5.tgz#c9d14e48be6873aa46fb429f22f2165557fd2dea"
integrity sha512-DVmQ8jlEtL+WbBKUZuMxHMBgK/yeIZwkXB81bH+MGaKKnJGYwA+770hzhXPfwEIokK9On9YIFPRleVp/5G7z9g==
xterm@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.0.0.tgz#eac93e08cbe69cf238cbace9185ed9e38873df1a"
integrity sha512-Xbx3vvf9FnrUcI1qU31Jww7/fc/NqpXGqgByTvjj7+g3/yPvt/RvLkP/LLMcof2kLAC3evzZGMiovs7NkjdWDw==
y18n@^3.2.1:
version "3.2.1"