Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/app/button-page/button-page.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { OBFBoard, Button, LoadBoardAction } from '../obfboard';
import { Subscription, Subscriber } from 'rxjs';
import { ScanningService, ScanningModel, ScannableCollectionProvider, ScannableCollection, Scannable } from '../scanning.service';
import { ConfigService } from '../config.service';
import { CustomActionService } from '../custom-action.service';

class ScannableButton extends Scannable {
static TYPE = 'OBFButton';
Expand Down Expand Up @@ -131,8 +132,13 @@ export class ButtonPageComponent implements OnInit, OnDestroy {
':space': this.speechbarService.space.bind(this.speechbarService)
};

constructor(private boardService: BoardService, private speechbarService: SpeechbarService,
private scanningService: ScanningService, private configService: ConfigService) { }
constructor(
private boardService: BoardService,
private speechbarService: SpeechbarService,
private scanningService: ScanningService,
private configService: ConfigService,
private customActionService: CustomActionService
) { }

ngOnInit() {
this.loadBoard();
Expand Down Expand Up @@ -221,6 +227,8 @@ export class ButtonPageComponent implements OnInit, OnDestroy {

if (action.startsWith('+')) {
this.speechbarService.appendButton(button, action);
} else if (action.startsWith(':ext')) {
this.customActionService.handle(button, action);
} else {
const actionPerformer = this.actionPerformers[action];

Expand Down
15 changes: 15 additions & 0 deletions src/app/custom-action.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';

import { CustomActionService } from './custom-action.service';

describe('CustomActionService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [CustomActionService]
});
});

it('should be created', inject([CustomActionService], (service: CustomActionService) => {
expect(service).toBeTruthy();
}));
});
102 changes: 102 additions & 0 deletions src/app/custom-action.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { Injectable } from '@angular/core';
import { Button } from './obfboard';
import { LocalStorage } from 'ngx-store';

interface Scripts {
name: string;
src: string;
}
export const ScriptStore: Scripts[] = [
{
name: 'lib1',
src: 'https://dl.dropbox.com/s/yf06gz438yz9ftb/helloLib.js?dl=1'
},
{
name: 'iftttLib',
src: '/assets/libraries/iftttLib.js'
}
];

declare var document: any;

@Injectable({
providedIn: 'root'
})
export class CustomActionService {

private scripts: any = {};

@LocalStorage()
private _iftttLibConfig;

constructor() {
ScriptStore.forEach((script: any) => {
this.scripts[script.name] = {
loaded: false,
src: script.src
};
});
}

load(...scripts: string[]) {
const promises: any[] = [];
scripts.forEach((script) => promises.push(this.loadScript(script)));
return Promise.all(promises);
}

// TODO: tidy this up and get config involved
loadScript(name: string) {
return new Promise((resolve, reject) => {
// resolve if already loaded
if (this.scripts[name].loaded) {
resolve({ script: name, loaded: true, status: 'Already Loaded' });
} else {
// load script
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = this.scripts[name].src;
if (script.readyState) { // IE
script.onreadystatechange = () => {
if (script.readyState === 'loaded' || script.readyState === 'complete') {
script.onreadystatechange = null;
this.scripts[name].loaded = true;
resolve({ script: name, loaded: true, status: 'Loaded' });
}
};
} else { // Others
script.onload = () => {
this.scripts[name].loaded = true;
resolve({ script: name, loaded: true, status: 'Loaded' });
};
}
script.onerror = (error: any) => resolve({ script: name, loaded: false, status: 'Loaded' });
document.getElementsByTagName('head')[0].appendChild(script);
}
});
}

handle(button: Button, action: string) {

if (action.startsWith(':ext_ovf_js:')) {
console.log(action);
const jsCall = action.slice(12);
// TODO: this doesn't make sense now! Load everything up front?
// Or interogate for namespace...(would still require loading!)
this.load('iftttLib').then(data => {
console.log('script loaded ', data);
let func = window;
for (const ns of jsCall.split('.')) {
// TODO: sometimes this will fail!
func = func[ns];
}
if (typeof func === 'function') {
const context = {
'button': button
};
const config = this._iftttLibConfig;
(<any>func)(context, config);
}
}).catch(error => console.log(error));
}
}
}
16 changes: 16 additions & 0 deletions src/assets/libraries/iftttLib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
var iftttLib = (function () {
var self = {};

var sendRequest = function(trigger, key) {
var url = "https://maker.ifttt.com/trigger/" + trigger + "/with/key/" + key
var http = new XMLHttpRequest();
http.open("GET", url);
http.send();
}

self.trigger = function(context, config) {
sendRequest(context.button.id, config['key']);
}

return self;
}());