This repository has been archived by the owner on Jan 3, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(DockMonitor): Added dock monitor to wrap devtools.
- Loading branch information
1 parent
257c8a8
commit d10fb7a
Showing
10 changed files
with
361 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from './store'; | ||
export {LogMonitor} from './monitors/log-monitor'; | ||
export * from './monitors/dock-monitor'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import {Injectable} from 'angular2/core'; | ||
import {Action} from '@ngrx/store'; | ||
|
||
|
||
@Injectable() | ||
export class DockActions{ | ||
static TOGGLE_VISIBILITY = '@@redux-devtools-log-monitor/TOGGLE_VISIBILITY'; | ||
toggleVisibility(): Action { | ||
return { type: DockActions.TOGGLE_VISIBILITY }; | ||
} | ||
|
||
static CHANGE_POSITION = '@@redux-devtools-log-monitor/CHANGE_POSITION'; | ||
changePosition(): Action { | ||
return { type: DockActions.CHANGE_POSITION }; | ||
} | ||
|
||
static CHANGE_SIZE = '@@redux-devtools-log-monitor/CHANGE_SIZE'; | ||
changeSize(size: number): Action { | ||
return { type: DockActions.CHANGE_SIZE, payload: size }; | ||
} | ||
|
||
static CHANGE_MONITOR = '@@redux-devtools-log-monitor/CHANGE_MONITOR'; | ||
changeMonitor(): Action { | ||
return { type: DockActions.CHANGE_MONITOR }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import 'rxjs/add/operator/filter'; | ||
import 'rxjs/add/operator/map'; | ||
import {Component, Input, Output, Injectable, Renderer} from 'angular2/core'; | ||
import {Observable} from 'rxjs/Observable'; | ||
import {Subject} from 'rxjs/Subject'; | ||
import {Subscriber} from 'rxjs/Subscriber'; | ||
|
||
import {keycodes} from './keycodes'; | ||
|
||
export interface ParsedCommand{ | ||
name?: string; | ||
ctrl: boolean; | ||
meta: boolean; | ||
shift: boolean; | ||
alt: boolean; | ||
sequence?: string; | ||
} | ||
|
||
@Component({ | ||
selector: 'ngrx-commander', | ||
template: '', | ||
styles: [':host{ display: none }'], | ||
host: { | ||
'(document.keydown)': 'keydown$.next($event)' | ||
} | ||
}) | ||
export class Commander{ | ||
private keydown$ = new Subject<KeyboardEvent>(); | ||
private _ignoreTags = ['INPUT', 'SELECT', 'TEXTAREA']; | ||
|
||
constructor(private _renderer: Renderer){ } | ||
|
||
@Input() command: string; | ||
@Output() press = this.keydown$ | ||
.filter(e => this._ignoreTags.indexOf((e.target as HTMLElement).tagName) < 0) | ||
.filter(e => !((e.target as HTMLElement).isContentEditable)) | ||
.filter(e => { | ||
const command = this.parseCommand(this.command); | ||
|
||
if (!command) { | ||
return false; | ||
} | ||
|
||
const charCode = e.keyCode || e.which; | ||
const char = String.fromCharCode(charCode); | ||
return command.name.toUpperCase() === char.toUpperCase() && | ||
command.alt === e.altKey && | ||
command.ctrl === e.ctrlKey && | ||
command.meta === e.metaKey && | ||
command.shift === e.shiftKey; | ||
}) | ||
.map(e => { | ||
e.preventDefault(); | ||
|
||
return { command: this.command }; | ||
}); | ||
|
||
parseCommand(s: string): ParsedCommand { | ||
var keyString = s.trim().toLowerCase(); | ||
|
||
if ( !/^(ctrl-|shift-|alt-|meta-){0,4}\w+$/.test(keyString) ){ | ||
throw new Error('The string to parse needs to be of the format "c", "ctrl-c", "shift-ctrl-c".'); | ||
} | ||
|
||
const parts = keyString.split('-'); | ||
const key: ParsedCommand = { | ||
ctrl: false, | ||
meta: false, | ||
shift: false, | ||
alt: false | ||
}; | ||
|
||
let c; | ||
|
||
key.name = parts.pop(); | ||
|
||
while((c = parts.pop())) { | ||
key[c] = true; | ||
} | ||
|
||
if(key.ctrl) { | ||
key.sequence = keycodes.ctrl[key.name] || key.name; | ||
} | ||
else { | ||
key.sequence = keycodes.nomod[key.name] || key.name; | ||
} | ||
|
||
if (key.shift && key.sequence && key.sequence.length === 1) { | ||
key.sequence = key.sequence.toUpperCase(); | ||
} | ||
|
||
return key; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import 'rxjs/add/observable/merge'; | ||
import 'rxjs/add/operator/filter'; | ||
import 'rxjs/add/operator/map'; | ||
import 'rxjs/add/operator/distinctUntilChanged'; | ||
import {StoreDevtools} from '../../store/devtools'; | ||
import {Component, ChangeDetectionStrategy} from 'angular2/core'; | ||
import {Subject} from 'rxjs/Subject'; | ||
import {Observable} from 'rxjs/Observable'; | ||
import {Subscription} from 'rxjs/Subscription'; | ||
|
||
import {DockState} from './reducer'; | ||
import {Commander} from './commander'; | ||
import {Dock} from './dock'; | ||
import {DockActions} from './actions'; | ||
|
||
|
||
@Component({ | ||
selector: 'dock-monitor', | ||
changeDetection: ChangeDetectionStrategy.OnPush, | ||
directives: [ Dock, Commander ], | ||
providers: [ DockActions ], | ||
template: ` | ||
<ngrx-commander [command]="toggleCommand" (press)="toggle$.next($event)"></ngrx-commander> | ||
<ngrx-commander [command]="positionCommand" (press)="changePosition$.next($event)"></ngrx-commander> | ||
<ngrx-dock | ||
[visible]="visible$ | async" | ||
[position]="position$ | async" | ||
[size]="size$ | async"> | ||
<ng-content></ng-content> | ||
</ngrx-dock> | ||
` | ||
}) | ||
export class DockMonitor { | ||
constructor( | ||
private tools: StoreDevtools, | ||
private actions: DockActions, | ||
private commander: Commander | ||
){ | ||
Observable | ||
.merge(this.toggleAction$, this.positionAction$) | ||
.subscribe(this.tools); | ||
} | ||
|
||
private state$ = this.tools.liftedState.map<DockState>(s => s.monitorState.dock); | ||
private visible$ = this.state$.map(s => s.visible).distinctUntilChanged(); | ||
private position$ = this.state$.map(s => s.position).distinctUntilChanged(); | ||
private size$ = this.state$.map(s => s.size).distinctUntilChanged(); | ||
|
||
private toggleCommand = 'ctrl-h'; | ||
private toggle$ = new Subject(); | ||
private toggleAction$ = this.toggle$ | ||
.map(() => this.actions.toggleVisibility()); | ||
|
||
private positionCommand = 'ctrl-m'; | ||
private changePosition$ = new Subject(); | ||
private positionAction$ = this.changePosition$ | ||
.map(() => this.actions.changePosition()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import {Component, HostListener, HostBinding, Input} from 'angular2/core'; | ||
import {PositionsType} from './reducer'; | ||
|
||
|
||
@Component({ | ||
selector: 'ngrx-dock', | ||
template: ` | ||
<div class="dock"> | ||
<div class="dock-content"> | ||
<ng-content></ng-content> | ||
</div> | ||
</div> | ||
`, | ||
styles: [` | ||
:host { | ||
position: fixed; | ||
top: 0; | ||
left: 0; | ||
right: 0; | ||
bottom: 0; | ||
transition: all 0.3s; | ||
z-index: 9999; | ||
} | ||
.dock { | ||
position: absolute; | ||
z-index: 1; | ||
box-shadow: 0 0 4px rgba(0, 0, 0, 0.3); | ||
background-color: white; | ||
left: 0; | ||
top: 0; | ||
width: 100%; | ||
height: 100%; | ||
} | ||
.dock-content { | ||
width: 100%; | ||
height: 100%; | ||
overflow: auto; | ||
} | ||
`] | ||
}) | ||
export class Dock{ | ||
@Input() position: PositionsType = 'right'; | ||
@Input() size: number = 0.3; | ||
@Input() visible: boolean = true; | ||
|
||
get absoluteSize(){ | ||
return `${100 * this.size}%`; | ||
} | ||
|
||
get restSize(){ | ||
return `${100 - (100 * this.size)}%`; | ||
} | ||
|
||
@HostBinding('style.left') get leftPosition(){ | ||
return this.calculatePosition('left', 'right'); | ||
} | ||
|
||
@HostBinding('style.right') get rightPosition(){ | ||
return this.calculatePosition('right', 'left'); | ||
} | ||
|
||
@HostBinding('style.top') get topPosition(){ | ||
return this.calculatePosition('top', 'bottom'); | ||
} | ||
|
||
@HostBinding('style.bottom') get bottomPosition(){ | ||
return this.calculatePosition('bottom', 'top'); | ||
} | ||
|
||
calculatePosition(primary: PositionsType, secondary: PositionsType) { | ||
if(this.visible){ | ||
switch (this.position) { | ||
case secondary: | ||
return this.restSize; | ||
default: | ||
return '0%'; | ||
} | ||
} | ||
else { | ||
switch (this.position) { | ||
case primary: | ||
return `-${this.absoluteSize}`; | ||
case secondary: | ||
return '100%'; | ||
default: | ||
return '0%'; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// Most of these are according to this table: http://www.ssicom.org/js/x171166.htm | ||
// However where nodejs readline diverges, they are adjusted to conform to it | ||
export const keycodes = { | ||
nomod: { | ||
escape: '\u001b', | ||
space: ' ' // actually '\u0020' | ||
}, | ||
ctrl: { | ||
' ': '\u0000', | ||
'a': '\u0001', | ||
'b': '\u0002', | ||
'c': '\u0003', | ||
'd': '\u0004', | ||
'e': '\u0005', | ||
'f': '\u0006', | ||
'g': '\u0007', | ||
'h': '\u0008', | ||
'i': '\u0009', | ||
'j': '\u000a', | ||
'k': '\u000b', | ||
'm': '\u000c', | ||
'n': '\u000d', | ||
'l': '\u000e', | ||
'o': '\u000f', | ||
'p': '\u0010', | ||
'q': '\u0011', | ||
'r': '\u0012', | ||
's': '\u0013', | ||
't': '\u0014', | ||
'u': '\u0015', | ||
'v': '\u0016', | ||
'w': '\u0017', | ||
'x': '\u0018', | ||
'y': '\u0019', | ||
'z': '\u001a', | ||
'[': '\u001b', | ||
'\\':'\u001c', | ||
']': '\u001d', | ||
'^': '\u001e', | ||
'_': '\u001f', | ||
'space': '\u0000' | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import {combineReducers, Reducer} from '@ngrx/store'; | ||
import {DockActions} from './actions'; | ||
|
||
export const POSITIONS = ['left', 'top', 'right', 'bottom']; | ||
export type PositionsType = 'left' | 'top' | 'right' | 'bottom'; | ||
|
||
function position(state: PositionsType = 'right', action) { | ||
return (action.type === DockActions.CHANGE_POSITION) ? | ||
POSITIONS[(POSITIONS.indexOf(state) + 1) % POSITIONS.length] : | ||
state; | ||
} | ||
|
||
function size(state: number = 0.3, action) { | ||
return (action.type === DockActions.CHANGE_SIZE) ? | ||
action.size : | ||
state; | ||
} | ||
|
||
function visible(state: boolean = true, action) { | ||
return (action.type === DockActions.TOGGLE_VISIBILITY) ? | ||
!state : | ||
state; | ||
} | ||
|
||
export interface DockState{ | ||
position?: PositionsType; | ||
visible?: boolean; | ||
size?: number; | ||
} | ||
|
||
export const dockReducer = combineReducers({ | ||
position, | ||
visible, | ||
size | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters