Merge branch 'master' into list-border-refactor
@ -94,6 +94,7 @@ export function getPageFor(hash) {
|
||||
'checkbox': inputs.CheckboxPage,
|
||||
'radio': inputs.RadioPage,
|
||||
'range': inputs.RangePage,
|
||||
'segment': inputs.SegmentPage,
|
||||
'select': inputs.SelectPage,
|
||||
'switch': inputs.SwitchPage,
|
||||
|
||||
|
BIN
demos/component-docs/img/thumbnail-kitten-1.jpg
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
demos/component-docs/img/thumbnail-kitten-2.jpg
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
demos/component-docs/img/thumbnail-kitten-3.jpg
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
demos/component-docs/img/thumbnail-kitten-4.jpg
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
demos/component-docs/img/thumbnail-puppy-1.jpg
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
demos/component-docs/img/thumbnail-puppy-2.jpg
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
demos/component-docs/img/thumbnail-puppy-3.jpg
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
demos/component-docs/img/thumbnail-puppy-4.jpg
Normal file
After Width: | Height: | Size: 59 KiB |
@ -1,5 +1,6 @@
|
||||
export * from './checkbox/pages';
|
||||
export * from './radio/pages';
|
||||
export * from './range/pages';
|
||||
export * from './segment/pages';
|
||||
export * from './select/pages';
|
||||
export * from './switch/pages';
|
||||
|
14
demos/component-docs/inputs/segment/pages.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import {Page} from 'ionic/ionic';
|
||||
import {forwardRef} from 'angular2/angular2';
|
||||
import {AndroidAttribute} from '../../helpers';
|
||||
|
||||
@Page({
|
||||
templateUrl: 'inputs/segment/template.html',
|
||||
directives: [forwardRef(() => AndroidAttribute)]
|
||||
})
|
||||
export class SegmentPage{
|
||||
constructor() {
|
||||
this.pet = "puppies";
|
||||
}
|
||||
|
||||
}
|
80
demos/component-docs/inputs/segment/template.html
Normal file
@ -0,0 +1,80 @@
|
||||
<ion-navbar *navbar hide-back-button class="android-attr">
|
||||
|
||||
<ion-title>
|
||||
Segment
|
||||
</ion-title>
|
||||
|
||||
</ion-navbar>
|
||||
|
||||
|
||||
<ion-content>
|
||||
|
||||
<div padding>
|
||||
<ion-segment [(ng-model)]="pet">
|
||||
<ion-segment-button value="kittens">
|
||||
Kittens
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="puppies">
|
||||
Puppies
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
</div>
|
||||
|
||||
<div [ng-switch]="pet">
|
||||
<ion-list *ng-switch-when="'puppies'">
|
||||
<ion-item>
|
||||
<ion-thumbnail item-left>
|
||||
<img src="img/thumbnail-puppy-1.jpg">
|
||||
</ion-thumbnail>
|
||||
<h2>Ruby</h2>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-thumbnail item-left>
|
||||
<img src="img/thumbnail-puppy-2.jpg">
|
||||
</ion-thumbnail>
|
||||
<h2>Oscar</h2>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-thumbnail item-left>
|
||||
<img src="img/thumbnail-puppy-4.jpg">
|
||||
</ion-thumbnail>
|
||||
<h2>Zoey</h2>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-thumbnail item-left>
|
||||
<img src="img/thumbnail-puppy-3.jpg">
|
||||
</ion-thumbnail>
|
||||
<h2>Otto</h2>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<ion-list *ng-switch-when="'kittens'">
|
||||
<ion-item>
|
||||
<ion-thumbnail item-left>
|
||||
<img src="img/thumbnail-kitten-1.jpg">
|
||||
</ion-thumbnail>
|
||||
<h2>Luna</h2>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-thumbnail item-left>
|
||||
<img src="img/thumbnail-kitten-3.jpg">
|
||||
</ion-thumbnail>
|
||||
<h2>Milo</h2>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-thumbnail item-left>
|
||||
<img src="img/thumbnail-kitten-4.jpg">
|
||||
</ion-thumbnail>
|
||||
<h2>Bandit</h2>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-thumbnail item-left>
|
||||
<img src="img/thumbnail-kitten-2.jpg">
|
||||
</ion-thumbnail>
|
||||
<h2>Nala</h2>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</div>
|
||||
|
||||
|
||||
</ion-content>
|
@ -1,9 +1,8 @@
|
||||
import {forwardRef, Directive, Host, EventEmitter, ElementRef} from 'angular2/angular2';
|
||||
import {Component, forwardRef, Directive, Host, EventEmitter, ElementRef} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonicApp} from '../app/app';
|
||||
import {Config} from '../../config/config';
|
||||
import {ConfigComponent} from '../../config/decorators';
|
||||
import {Platform} from '../../platform/platform';
|
||||
import {Keyboard} from '../../util/keyboard';
|
||||
import * as gestures from './menu-gestures';
|
||||
@ -44,20 +43,24 @@ import * as gestures from './menu-gestures';
|
||||
* <ion-menu [content]="contentRef" type="overlay"></ion-menu>
|
||||
* ```
|
||||
*/
|
||||
@ConfigComponent({
|
||||
@Component({
|
||||
selector: 'ion-menu',
|
||||
inputs: [
|
||||
'content',
|
||||
'dragThreshold',
|
||||
'id'
|
||||
'id',
|
||||
'side',
|
||||
'type'
|
||||
],
|
||||
defaultInputs: {
|
||||
'side': 'left',
|
||||
'type': 'reveal'
|
||||
'menuType': 'reveal'
|
||||
},
|
||||
outputs: ['opening'],
|
||||
host: {
|
||||
'role': 'navigation'
|
||||
'role': 'navigation',
|
||||
'[attr.side]': 'side',
|
||||
'[attr.type]': 'type'
|
||||
},
|
||||
template: '<ng-content></ng-content><backdrop tappable disable-activated></backdrop>',
|
||||
directives: [forwardRef(() => MenuBackdrop)]
|
||||
@ -94,6 +97,10 @@ export class Menu extends Ion {
|
||||
return console.error('Menu: must have a [content] element to listen for drag events on. Example:\n\n<ion-menu [content]="content"></ion-menu>\n\n<ion-nav #content></ion-nav>');
|
||||
}
|
||||
|
||||
if (this.side !== 'left' && this.side !== 'right') {
|
||||
this.side = 'left';
|
||||
}
|
||||
|
||||
if (!this.id) {
|
||||
// Auto register
|
||||
this.id = 'menu';
|
||||
@ -130,16 +137,12 @@ export class Menu extends Ion {
|
||||
}
|
||||
|
||||
_initType(type) {
|
||||
type = type && type.trim().toLowerCase() || FALLBACK_MENU_TYPE;
|
||||
|
||||
let menuTypeCls = menuTypes[type];
|
||||
|
||||
if (!menuTypeCls) {
|
||||
type = FALLBACK_MENU_TYPE;
|
||||
menuTypeCls = menuTypes[type];
|
||||
type = type && type.trim().toLowerCase();
|
||||
if (!type) {
|
||||
type = this.config.get('menuType');
|
||||
}
|
||||
|
||||
this._type = new menuTypeCls(this);
|
||||
this._type = new menuTypes[type](this);
|
||||
this.type = type;
|
||||
|
||||
if (this.config.get('animate') === false) {
|
||||
@ -307,7 +310,6 @@ export class Menu extends Ion {
|
||||
}
|
||||
|
||||
let menuTypes = {};
|
||||
const FALLBACK_MENU_TYPE = 'reveal';
|
||||
|
||||
|
||||
/**
|
||||
|
@ -30,10 +30,6 @@ export class ViewController {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} instance TODO
|
||||
*/
|
||||
setInstance(instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
@ -50,9 +46,6 @@ export class ViewController {
|
||||
this._destroys.push(destroyFn);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
destroy() {
|
||||
for (let i = 0; i < this._destroys.length; i++) {
|
||||
this._destroys[i]();
|
||||
@ -108,66 +101,38 @@ export class ViewController {
|
||||
return this._nbDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
hasNavbar() {
|
||||
return !!this.getNavbar();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
navbarRef() {
|
||||
let navbar = this.getNavbar();
|
||||
return navbar && navbar.getElementRef();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
titleRef() {
|
||||
let navbar = this.getNavbar();
|
||||
return navbar && navbar.getTitleRef();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
navbarItemRefs() {
|
||||
let navbar = this.getNavbar();
|
||||
return navbar && navbar.getItemRefs();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
backBtnRef() {
|
||||
let navbar = this.getNavbar();
|
||||
return navbar && navbar.getBackButtonRef();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
backBtnTextRef() {
|
||||
let navbar = this.getNavbar();
|
||||
return navbar && navbar.getBackButtonTextRef();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
navbarBgRef() {
|
||||
let navbar = this.getNavbar();
|
||||
return navbar && navbar.getNativeElement().querySelector('.toolbar-background');
|
||||
return navbar && navbar.getBackgroundRef();
|
||||
}
|
||||
|
||||
hideBackButton(shouldHide) {
|
||||
|
@ -38,13 +38,25 @@ class BackButton extends Ion {
|
||||
@Directive({
|
||||
selector: '.back-button-text'
|
||||
})
|
||||
class BackButtonText extends Ion {
|
||||
class BackButtonText {
|
||||
constructor(
|
||||
elementRef: ElementRef,
|
||||
@Optional() @Inject(forwardRef(() => Navbar)) navbar: Navbar
|
||||
@Inject(forwardRef(() => Navbar)) navbar: Navbar
|
||||
) {
|
||||
super(elementRef, null);
|
||||
navbar && navbar.setBackButtonTextRef(elementRef);
|
||||
navbar.setBackButtonTextRef(elementRef);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Directive({
|
||||
selector: 'toolbar-background'
|
||||
})
|
||||
class ToolbarBackground {
|
||||
constructor(
|
||||
elementRef: ElementRef,
|
||||
@Inject(forwardRef(() => Navbar)) navbar: Navbar
|
||||
) {
|
||||
navbar.setBackgroundRef(elementRef);
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,19 +64,19 @@ class BackButtonText extends Ion {
|
||||
@Component({
|
||||
selector: 'ion-navbar',
|
||||
template:
|
||||
'<div class="toolbar-inner">' +
|
||||
'<button class="back-button" [hidden]="hideBackButton">' +
|
||||
'<icon class="back-button-icon" [name]="bbIcon"></icon>' +
|
||||
'<span class="back-button-text">' +
|
||||
'<span class="back-default">{{bbDefault}}</span>' +
|
||||
'</span>' +
|
||||
'</button>' +
|
||||
'<ng-content select="[menu-toggle]"></ng-content>' +
|
||||
'<ng-content select="ion-title"></ng-content>' +
|
||||
'<ng-content select="ion-nav-items[primary]"></ng-content>' +
|
||||
'<ng-content select="ion-nav-items[secondary]"></ng-content>' +
|
||||
'</div>' +
|
||||
'<div class="toolbar-background"></div>',
|
||||
'<toolbar-background></toolbar-background>' +
|
||||
'<button class="back-button" [hidden]="hideBackButton">' +
|
||||
'<icon class="back-button-icon" [name]="bbIcon"></icon>' +
|
||||
'<span class="back-button-text">' +
|
||||
'<span class="back-default">{{bbDefault}}</span>' +
|
||||
'</span>' +
|
||||
'</button>' +
|
||||
'<ng-content select="[menu-toggle]"></ng-content>' +
|
||||
'<ng-content select="ion-nav-items[primary]"></ng-content>' +
|
||||
'<ng-content select="ion-nav-items[secondary]"></ng-content>' +
|
||||
'<toolbar-content>' +
|
||||
'<ng-content></ng-content>' +
|
||||
'</toolbar-content>',
|
||||
host: {
|
||||
'[hidden]': '_hidden'
|
||||
},
|
||||
@ -72,7 +84,7 @@ class BackButtonText extends Ion {
|
||||
'hideBackButton',
|
||||
'navbarStyle'
|
||||
],
|
||||
directives: [BackButton, BackButtonText, Icon]
|
||||
directives: [BackButton, BackButtonText, Icon, ToolbarBackground]
|
||||
})
|
||||
export class Navbar extends ToolbarBase {
|
||||
constructor(
|
||||
@ -105,7 +117,7 @@ export class Navbar extends ToolbarBase {
|
||||
if (typeof hideBackButton === 'string') {
|
||||
this.hideBackButton = (hideBackButton === '' || hideBackButton === 'true');
|
||||
}
|
||||
|
||||
|
||||
if (this.navbarStyle) {
|
||||
this.renderer.setElementAttribute(this.elementRef, this.navbarStyle, '');
|
||||
}
|
||||
@ -127,6 +139,14 @@ export class Navbar extends ToolbarBase {
|
||||
this.bbtRef = backButtonTextElementRef;
|
||||
}
|
||||
|
||||
setBackgroundRef(backgrouneElementRef) {
|
||||
this.bgRef = backgrouneElementRef;
|
||||
}
|
||||
|
||||
getBackgroundRef() {
|
||||
return this.bgRef;
|
||||
}
|
||||
|
||||
didEnter() {
|
||||
this.app.setTitle(this.getTitleText());
|
||||
}
|
||||
|
@ -67,8 +67,8 @@ export class Popup {
|
||||
constructor(ctrl: OverlayController, config: Config) {
|
||||
this.ctrl = ctrl;
|
||||
this._defaults = {
|
||||
enterAnimation: config.get('popupPopIn'),
|
||||
leaveAnimation: config.get('popupPopOut'),
|
||||
enterAnimation: config.get('popupEnter'),
|
||||
leaveAnimation: config.get('popupLeave'),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,6 @@ ion-segment {
|
||||
.toolbar {
|
||||
|
||||
ion-segment {
|
||||
width: 95%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
@ -99,12 +99,16 @@ class Tab3 {}
|
||||
</ion-content>
|
||||
</ion-menu>
|
||||
|
||||
<ion-tabs #content tabbar-style="secondary">
|
||||
<ion-tabs #content>
|
||||
<ion-tab tab-title="Plain List" tab-icon="star" [root]="root1"></ion-tab>
|
||||
<ion-tab tab-title="Schedule" tab-icon="globe" [root]="root2"></ion-tab>
|
||||
<ion-tab tab-title="Stopwatch" tab-icon="stopwatch" [root]="root3"></ion-tab>
|
||||
</ion-tabs>
|
||||
`
|
||||
`,
|
||||
config: {
|
||||
navbarStyle: 'secondary',
|
||||
tabbarStyle: 'secondary'
|
||||
}
|
||||
})
|
||||
export class TabsPage {
|
||||
constructor() {
|
||||
|
@ -1 +0,0 @@
|
||||
|
@ -25,7 +25,7 @@ export function initTapClick(windowInstance, documentInstance, appInstance, conf
|
||||
activator = new RippleActivator(app, config, fastdom);
|
||||
|
||||
} else if (config.get('activator') == 'highlight') {
|
||||
activator = new Activator(app, config, fastdom));
|
||||
activator = new Activator(app, config, fastdom);
|
||||
}
|
||||
|
||||
isTapPolyfill = (config.get('tapPolyfill') === true);
|
||||
|
@ -71,7 +71,7 @@ $toolbar-ios-title-font-size: 1.7rem !default;
|
||||
|
||||
}
|
||||
|
||||
.toolbar .toolbar-background {
|
||||
.toolbar toolbar-background {
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
@ -105,6 +105,6 @@ ion-nav-items[secondary] {
|
||||
order: map-get($toolbar-order-ios, secondary);
|
||||
}
|
||||
|
||||
&.hairlines .toolbar .toolbar-background {
|
||||
&.hairlines .toolbar toolbar-background {
|
||||
border-bottom-width: 0.55px;
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
|
||||
<ion-toolbar>
|
||||
<a menu-toggle>
|
||||
<icon menu></icon>
|
||||
</a>
|
||||
<ion-title>menu-toggle left. This is the title that never ends. It just goes on and on my friend.</ion-title>
|
||||
<ion-title>This is the title that never ends. It just goes on and on my friend.</ion-title>
|
||||
</ion-toolbar>
|
||||
|
||||
|
||||
@ -168,6 +165,32 @@
|
||||
</ion-toolbar>
|
||||
|
||||
|
||||
<ion-toolbar>
|
||||
<a menu-toggle>
|
||||
<icon menu></icon>
|
||||
</a>
|
||||
<ion-nav-items primary>
|
||||
<button>
|
||||
<icon star></icon>
|
||||
</button>
|
||||
</ion-nav-items>
|
||||
<ion-title>Left side menu toggle</ion-title>
|
||||
</ion-toolbar>
|
||||
|
||||
|
||||
<ion-toolbar>
|
||||
<ion-nav-items secondary>
|
||||
<button>
|
||||
<icon star></icon>
|
||||
</button>
|
||||
</ion-nav-items>
|
||||
<ion-title>Right side menu toggle</ion-title>
|
||||
<a menu-toggle secondary>
|
||||
<icon menu></icon>
|
||||
</a>
|
||||
</ion-toolbar>
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
.toolbar {
|
||||
|
@ -7,7 +7,7 @@ $toolbar-padding: 4px !default;
|
||||
$toolbar-order: (
|
||||
backButton: 10,
|
||||
menu-toggle-primary: 20,
|
||||
title: 30,
|
||||
content: 30,
|
||||
primary: 40,
|
||||
secondary: 50,
|
||||
menu-toggle-secondary: 60,
|
||||
@ -37,7 +37,7 @@ $toolbar-order: (
|
||||
}
|
||||
}
|
||||
|
||||
.toolbar .toolbar-background {
|
||||
.toolbar toolbar-background {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
@ -52,6 +52,12 @@ $toolbar-order: (
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
toolbar-content {
|
||||
display: block;
|
||||
flex: 1;
|
||||
order: map-get($toolbar-order, content);
|
||||
}
|
||||
|
||||
.toolbar button:hover:not(.disable-hover),
|
||||
.toolbar [button]:hover:not(.disable-hover),
|
||||
.toolbar button.activated,
|
||||
@ -64,15 +70,8 @@ $toolbar-order: (
|
||||
order: $flex-order-toolbar-bottom;
|
||||
}
|
||||
|
||||
.toolbar-inner {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
ion-title {
|
||||
flex: 1;
|
||||
order: map-get($toolbar-order, title);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
@ -132,7 +131,7 @@ ion-nav-items div {
|
||||
|
||||
.toolbar[#{$color-name}] {
|
||||
|
||||
.toolbar-background {
|
||||
toolbar-background {
|
||||
background-color: $color-value;
|
||||
border-color: darken($color-value, 10%);
|
||||
}
|
||||
|
@ -58,13 +58,13 @@ export class ToolbarBase extends Ion {
|
||||
@Component({
|
||||
selector: 'ion-toolbar',
|
||||
template:
|
||||
'<div class="toolbar-inner">' +
|
||||
'<ng-content select="[menu-toggle]"></ng-content>' +
|
||||
'<ng-content select="ion-title,ion-searchbar,ion-segment"></ng-content>' +
|
||||
'<ng-content select="ion-nav-items[primary]"></ng-content>' +
|
||||
'<ng-content select="ion-nav-items[secondary]"></ng-content>' +
|
||||
'</div>' +
|
||||
'<div class="toolbar-background"></div>'
|
||||
'<toolbar-background></toolbar-background>' +
|
||||
'<ng-content select="[menu-toggle]"></ng-content>' +
|
||||
'<ng-content select="ion-nav-items[primary]"></ng-content>' +
|
||||
'<ng-content select="ion-nav-items[secondary]"></ng-content>' +
|
||||
'<toolbar-content>' +
|
||||
'<ng-content></ng-content>' +
|
||||
'</toolbar-content>'
|
||||
})
|
||||
export class Toolbar extends ToolbarBase {
|
||||
constructor(
|
||||
|
@ -16,14 +16,16 @@ Config.setModeConfig('ios', {
|
||||
|
||||
iconMode: 'ios',
|
||||
|
||||
menuType: 'reveal',
|
||||
|
||||
modalEnter: 'modal-slide-in',
|
||||
modalLeave: 'modal-slide-out',
|
||||
|
||||
pageTransition: 'ios',
|
||||
pageTransitionDelay: 16,
|
||||
|
||||
popupPopIn: 'popup-pop-in',
|
||||
popupPopOut: 'popup-pop-out',
|
||||
popupEnter: 'popup-pop-in',
|
||||
popupLeave: 'popup-pop-out',
|
||||
|
||||
tabbarPlacement: 'bottom',
|
||||
});
|
||||
@ -43,16 +45,16 @@ Config.setModeConfig('md', {
|
||||
|
||||
iconMode: 'md',
|
||||
|
||||
type: 'overlay',
|
||||
menuType: 'overlay',
|
||||
|
||||
modalEnter: 'modal-md-slide-in',
|
||||
modalLeave: 'modal-md-slide-out',
|
||||
|
||||
pageTransition: 'md',
|
||||
pageTransitionDelay: 80,
|
||||
pageTransitionDelay: 120,
|
||||
|
||||
popupPopIn: 'popup-md-pop-in',
|
||||
popupPopOut: 'popup-md-pop-out',
|
||||
popupEnter: 'popup-md-pop-in',
|
||||
popupLeave: 'popup-md-pop-out',
|
||||
|
||||
tabbarHighlight: true,
|
||||
tabbarPlacement: 'top',
|
||||
|
@ -55,7 +55,3 @@ $ionicons: true !default;
|
||||
@if ($ionicons) {
|
||||
@import "fonts/ionicons";
|
||||
}
|
||||
|
||||
|
||||
// Engine
|
||||
@import "platform/cordova";
|
||||
|
@ -20,4 +20,5 @@
|
||||
"components/searchbar/modes/ios",
|
||||
"components/segment/modes/ios",
|
||||
"components/switch/modes/ios",
|
||||
"components/tabs/modes/ios";
|
||||
"components/tabs/modes/ios",
|
||||
"platform/cordova-ios";
|
||||
|
@ -9,7 +9,6 @@ export * from './components'
|
||||
|
||||
export * from './platform/platform'
|
||||
export * from './platform/registry'
|
||||
export * from './platform/plugins'
|
||||
export * from './platform/storage'
|
||||
|
||||
export * from './util/click-block'
|
||||
@ -22,7 +21,5 @@ export * from './transitions/transition'
|
||||
export * from './transitions/ios-transition'
|
||||
export * from './transitions/md-transition'
|
||||
|
||||
export * from './platform/plugins'
|
||||
|
||||
export * from './translation/translate'
|
||||
export * from './translation/translate_pipe'
|
||||
|
@ -1,70 +0,0 @@
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
/**
|
||||
* Open installed apps on the device. Note: Android and iOS have different ways of
|
||||
* opening and specifying launch params, so they have separate launch functions.
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* ```js
|
||||
* if(platform.is('ios') {
|
||||
* AppLinks.check('twitter://').then((installed) => {
|
||||
* AppLinks.openIOS('twitter://user?screen_name=ionicframework')
|
||||
* }, (err) => {
|
||||
*
|
||||
* })
|
||||
* } else if(platform.is('android') {
|
||||
* AppLinks.check('com.twitter.android').then((installed) => {
|
||||
* AppLinks.openAndroid([["action", "VIEW"], ['twitter://user?screen_name=ionicframework']])
|
||||
* })
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'AppLinks',
|
||||
platforms: ['ios', 'android'],
|
||||
engines: {
|
||||
cordova: 'com.lampa.startapp'
|
||||
},
|
||||
pluginCheck: () => {
|
||||
return !!navigator.startApp;
|
||||
}
|
||||
})
|
||||
export class AppLinks {
|
||||
/**
|
||||
* Open app on iOS with a given URL (iOS), or scheme (Android)
|
||||
*/
|
||||
static openIOS(url) {
|
||||
this.ifPlugin(() => {
|
||||
navigator.startApp.start(url)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Open app on Android with a given scheme and params.
|
||||
*/
|
||||
static openAndroid(args) {
|
||||
this.ifPlugin(() => {
|
||||
navigator.startApp.start(...args);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an installed app can be opened from the given URL.
|
||||
*/
|
||||
static canOpen(urlOrScheme) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let hasPlugin = this.ifPlugin(() => {
|
||||
navigator.startApp.check(urlOrScheme, (message) => {
|
||||
resolve(message);
|
||||
}, function(err) {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
|
||||
if(!hasPlugin) {
|
||||
reject('Plugin not installed');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
/**
|
||||
* Scan barcodes and QR codes.
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* ## Scanning a code
|
||||
*
|
||||
* ```js
|
||||
* Barcode.scan().then((data) => {
|
||||
* console.log("Result: " + result.text + "\n" + "Format: " + result.format + "\n" + "Cancelled: " + result.cancelled);
|
||||
* }, (err) => {
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* ## Encoding data
|
||||
*
|
||||
* ```js
|
||||
* Barcode.encode(Barcode.TEXT_TYPE).then((data) => {}, (fail) => {});
|
||||
* ```
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'Barcode',
|
||||
platforms: ['ios', 'android'],
|
||||
engines: {
|
||||
cordova: 'phonegap-plugin-barcodescanner'
|
||||
},
|
||||
pluginCheck: () => {
|
||||
return window.cordova && window.cordova.plugins && window.cordova.plugins.barcodeScanner;
|
||||
}
|
||||
})
|
||||
export class Barcode {
|
||||
static TEXT_TYPE = "TEXT_TYPE"
|
||||
static EMAIL_TYPE = "EMAIL_TYPE"
|
||||
static PHONE_TYPE = "PHONE_TYPE"
|
||||
static SMS_TYPE = "SMS_TYPE"
|
||||
|
||||
/**
|
||||
* Scan a barcode.
|
||||
*
|
||||
* @return Promise that resolves with an object of the format: {
|
||||
* text: text that was scanned,
|
||||
* format: format of barcode,
|
||||
* cancelled: was it canceled?
|
||||
* }
|
||||
*/
|
||||
static scan() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let hasPlugin = this.ifPlugin(() => {
|
||||
window.cordova.plugins.barcodeScanner.scan((result) => {
|
||||
resolve(result);
|
||||
}, (err) => {
|
||||
reject(err);
|
||||
})
|
||||
});
|
||||
|
||||
if(!hasPlugin) {
|
||||
reject('No scanner available');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given data in a barcode.
|
||||
*
|
||||
* @param type the type to use for encoding (if in doubt, use TYPE_TEXT).
|
||||
* @param data the data to encode
|
||||
* @return Promise
|
||||
*/
|
||||
static encode(type, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let hasPlugin = this.ifPlugin(() => {
|
||||
window.cordova.plugins.barcodeScanner.encode(type, data, (result) => {
|
||||
resolve(result);
|
||||
}, (err) => {
|
||||
reject(err);
|
||||
})
|
||||
});
|
||||
|
||||
if(!hasPlugin) {
|
||||
reject('No scanner available');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
import * as util from 'ionic/util';
|
||||
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
/**
|
||||
* Track battery status. Uses the HTMl5 Battery API if available or
|
||||
* the `cordova-plugin-battery-status` plugin.
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* ```js
|
||||
* Battery.getStatus().then((data) => {
|
||||
* console.log(data.charging, data.level, data.chargingTime, data.dischargingTime)
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'Battery',
|
||||
platforms: ['ios', 'android', 'web'],
|
||||
engines: {
|
||||
cordova: 'cordova-plugin-battery-status'
|
||||
}
|
||||
})
|
||||
export class Battery {
|
||||
|
||||
/**
|
||||
* Get the status of the battery. Data is of the format:
|
||||
* { charging, level, chargingTime, dischargingTime }
|
||||
*
|
||||
* Note: certain fields might not be available depending on the platform.
|
||||
*
|
||||
* @return {object} battery status
|
||||
*/
|
||||
static getStatus() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(navigator.getBattery) {
|
||||
|
||||
navigator.getBattery().then((battery) => {
|
||||
this.battery = battery;
|
||||
resolve(Battery._format(battery));
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
var fnCb = function fnCb(battery) {
|
||||
resolve(battery);
|
||||
window.removeEventListener('batterystatus', fnCb);
|
||||
}
|
||||
window.addEventListener('batterystatus', fnCb);
|
||||
}
|
||||
});
|
||||
}
|
||||
static _format(batteryObj) {
|
||||
if(typeof batteryObj.isPlugged !== 'undefined') {
|
||||
// This is the old format, map it to the new format
|
||||
util.extend(batteryObj, {
|
||||
charging: batteryObj.isPlugged,
|
||||
level: batteryObj.level / 100,
|
||||
chargingTime: 0, //not provided,
|
||||
dischargingTime: 0 //not provided
|
||||
});
|
||||
}
|
||||
return batteryObj;
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
/**
|
||||
* Save and load photos from the Camera Roll (currently iOS only).
|
||||
*
|
||||
* Requires the Cordiva plugin `cordova-plugin-camera-roll`
|
||||
*
|
||||
* @usage
|
||||
* ```js
|
||||
* CameraRoll.save(base64EncodedImage).then(() => {
|
||||
* // success
|
||||
* }, (err) => {})
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'CameraRoll',
|
||||
platforms: ['ios'],
|
||||
engines: {
|
||||
cordova: 'cordova-plugin-camera-roll'
|
||||
},
|
||||
pluginCheck: () => {
|
||||
return !!window.CameraRoll;
|
||||
}
|
||||
})
|
||||
export class CameraRoll {
|
||||
/**
|
||||
* Save the base64 encoded image to the camera roll.
|
||||
*
|
||||
* @param base64String {String} base-64 encoded image
|
||||
* @return {Promise}
|
||||
*/
|
||||
static save(base64String) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.ifPlugin(() => {
|
||||
window.CameraRoll.saveToCameraRoll(base64String, () => {
|
||||
resolve();
|
||||
}, (err) => {
|
||||
reject(err);
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get photos from the camera roll.
|
||||
*/
|
||||
static getPhotos(options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.ifPlugin(() => {
|
||||
window.CameraRoll.getPhotos((photos) => {
|
||||
resolve(photos);
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
import * as util from 'ionic/util';
|
||||
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
/**
|
||||
* Take a photo or capture video.
|
||||
*
|
||||
* Requires Cordova plugin: `cordova-plugin-camera`. For more info, please see the [Cordova Camera Plugin Docs](https://github.com/apache/cordova-plugin-camera).
|
||||
*
|
||||
* @usage
|
||||
* ```js
|
||||
* Camera.getPicture(options).then((imageData) => {
|
||||
* // imageData is either a base64 encoded string or a file URI
|
||||
* // If it's base64:
|
||||
* let base64Image = "data:image/jpeg;base64," + imageData;
|
||||
* }, (err) => {
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'Camera',
|
||||
platforms: ['ios', 'android'],
|
||||
engines: {
|
||||
cordova: 'cordova-plugin-camera'
|
||||
},
|
||||
pluginCheck: () => {
|
||||
return !!navigator.camera;
|
||||
}
|
||||
})
|
||||
export class Camera {
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
static DestinationType = {
|
||||
/** Return base64 encoded string */
|
||||
DATA_URL: 0,
|
||||
/** Return file uri (content://media/external/images/media/2 for Android) */
|
||||
FILE_URI: 1,
|
||||
/** Return native uri (eg. asset-library://... for iOS) */
|
||||
NATIVE_URI: 2
|
||||
}
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
static EncodingType = {
|
||||
/** Return JPEG encoded image */
|
||||
JPEG: 0,
|
||||
/** Return PNG encoded image */
|
||||
PNG: 1
|
||||
}
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
static MediaType = {
|
||||
/** Allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType */
|
||||
PICTURE: 0,
|
||||
/** Allow selection of video only, ONLY RETURNS URL */
|
||||
VIDEO: 1,
|
||||
/** Allow selection from all media types */
|
||||
ALLMEDIA : 2
|
||||
}
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
static PictureSourceType = {
|
||||
/** Choose image from picture library (same as SAVEDPHOTOALBUM for Android) */
|
||||
PHOTOLIBRARY : 0,
|
||||
/** Take picture from camera */
|
||||
CAMERA : 1,
|
||||
/** Choose image from picture library (same as PHOTOLIBRARY for Android) */
|
||||
SAVEDPHOTOALBUM : 2
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches iOS UIPopoverArrowDirection constants to specify arrow location on popover.
|
||||
* @enum {number}
|
||||
*/
|
||||
static PopoverArrowDirection = {
|
||||
ARROW_UP : 1,
|
||||
ARROW_DOWN : 2,
|
||||
ARROW_LEFT : 4,
|
||||
ARROW_RIGHT : 8,
|
||||
ARROW_ANY : 15
|
||||
}
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
static Direction = {
|
||||
/** Use the back-facing camera */
|
||||
BACK: 0,
|
||||
/** Use the front-facing camera */
|
||||
FRONT: 1
|
||||
}
|
||||
|
||||
/**
|
||||
* Let the user take a photo or capture video.
|
||||
*
|
||||
* @param options {object} options for the photo. Of the form (with defaults):
|
||||
* {
|
||||
* quality: 80,
|
||||
* destinationType: window.Camera.DestinationType.DATA_URL,
|
||||
* sourceType: window.Camera.PictureSourceType.CAMERA (VIDEO or ALLMEDIA for both),
|
||||
* allowEdit: true,
|
||||
* encodingType: window.Camera.EncodingType.JPEG,
|
||||
* popoverOptions: window.CameraPopoverOptions,
|
||||
* saveToPhotoAlbum: false
|
||||
* }
|
||||
* @return {Promise} resolving with data or rejecting on error
|
||||
*/
|
||||
static getPicture(options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!navigator.camera) {
|
||||
this.pluginWarn();
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
|
||||
var options = util.defaults({
|
||||
quality: 80,
|
||||
destinationType: window.Camera.DestinationType.DATA_URL,
|
||||
sourceType: window.Camera.PictureSourceType.CAMERA,
|
||||
allowEdit: true,
|
||||
encodingType: window.Camera.EncodingType.JPEG,
|
||||
popoverOptions: window.CameraPopoverOptions,
|
||||
saveToPhotoAlbum: false
|
||||
}, options);
|
||||
|
||||
navigator.camera.getPicture(function (imageData) {
|
||||
resolve(imageData);
|
||||
}, function (err) {
|
||||
reject(err);
|
||||
}, options);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* If using FILE_URI and taking photos, photos will be stored temporarily. To
|
||||
* remove them, call cleanup when the camera session is finished.
|
||||
* @return {Promise}
|
||||
*/
|
||||
static cleanup() {
|
||||
return new Promise((resolve, reject) => {
|
||||
navigator.camera.cleanup(function () {
|
||||
resolve();
|
||||
}, function (err) {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
/**
|
||||
* Access and manage Contacts on the device.
|
||||
*
|
||||
* Requires plugin: `cordova-plugin-contacts`
|
||||
* For full info, please see the [Cordova Contacts Docs](https://github.com/apache/cordova-plugin-contacts)
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* ```js
|
||||
* Contacts.save({
|
||||
* displayName: "Mr. Ionitron"
|
||||
* }).then((contact) => {}, (err) => {})
|
||||
* ```
|
||||
*
|
||||
* See the `save()` docs for a full list of fields.
|
||||
*
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'Contacts',
|
||||
platforms: ['ios', 'android'],
|
||||
engines: {
|
||||
cordova: 'cordova-plugin-contacts'
|
||||
}
|
||||
})
|
||||
export class Contacts {
|
||||
/**
|
||||
* Save a contact into the contacts database.
|
||||
*
|
||||
* Valid fields:
|
||||
* {
|
||||
* id: A globally unique identifier. (DOMString)
|
||||
* displayName: The name of this Contact, suitable for display to end-users. (DOMString)
|
||||
* name: An object containing all components of a persons name. (ContactName)
|
||||
* nickname: A casual name by which to address the contact. (DOMString)
|
||||
* phoneNumbers: An array of all the contact's phone numbers. (ContactField[])
|
||||
* emails: An array of all the contact's email addresses. (ContactField[])
|
||||
* addresses: An array of all the contact's addresses. (ContactAddress[])
|
||||
* ims: An array of all the contact's IM addresses. (ContactField[])
|
||||
* organizations: An array of all the contact's organizations. (ContactOrganization[])
|
||||
* birthday: The birthday of the contact. (Date)
|
||||
* note: A note about the contact. (DOMString)
|
||||
* photos: An array of the contact's photos. (ContactField[])
|
||||
* categories: An array of all the user-defined categories associated with the contact. (ContactField[])
|
||||
* urls: An array of web pages associated with the contact. (ContactField[])
|
||||
* }
|
||||
*
|
||||
* @param contact {object} the contact to save.
|
||||
* @return {Promise} that resolves with the created and saved contact
|
||||
*/
|
||||
static save(contact) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(!navigator.contacts) {
|
||||
this.pluginWarn();
|
||||
reject('Contacts plugin not installed');
|
||||
}
|
||||
var deviceContact = navigator.contacts.create(contact);
|
||||
|
||||
deviceContact.save(function (result) {
|
||||
resolve(deviceContact);
|
||||
}, function (err) {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
static remove(contact) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(!navigator.contacts) {
|
||||
this.pluginWarn();
|
||||
reject('Contacts plugin not installed');
|
||||
}
|
||||
var deviceContact = navigator.contacts.create(contact);
|
||||
|
||||
deviceContact.remove(function (result) {
|
||||
resolve(result);
|
||||
}, function (err) {
|
||||
reject(err);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
static clone(contact) {
|
||||
if(!navigator.contacts) {
|
||||
this.pluginWarn();
|
||||
return null;
|
||||
}
|
||||
var deviceContact = navigator.contacts.create(contact);
|
||||
return deviceContact.clone(contact);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Search for contacts in the Contacts list.
|
||||
*
|
||||
* Example: Contacts.find({ filter: 'Max' }) // will search for a displayName of 'Max'
|
||||
*
|
||||
* @param options the options to query with
|
||||
*
|
||||
* filter: The search string used to find navigator.contacts. (DOMString) (Default: "")
|
||||
* multiple: Determines if the find operation returns multiple navigator.contacts. (Boolean) (Default: false)
|
||||
* desiredFields: Contact fields to be returned back. If specified, the resulting Contact object only features values for these fields. (DOMString[]) [Optional]
|
||||
* hasPhoneNumber(Android only): Filters the search to only return contacts with a phone number informed. (Boolean) (Default: false)
|
||||
*
|
||||
* @return {Promise} that resolves with the search results
|
||||
*/
|
||||
static find(options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var fields = options.fields || ['id', 'displayName'];
|
||||
delete options.fields;
|
||||
|
||||
navigator.contacts.find(fields, function (results) {
|
||||
resolve(results);
|
||||
}, function (err) {
|
||||
reject(err);
|
||||
}, options || undefined);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a native contact picker control.
|
||||
*
|
||||
* @return {Promise} resolves with the picked contact.
|
||||
*/
|
||||
static pickContact() {
|
||||
return new Promise((resolve, reject) => {
|
||||
navigator.contacts.pickContact(function (contact) {
|
||||
resolve(contact);
|
||||
}, function (err) {
|
||||
reject(err);
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
23
ionic/platform/cordova-ios.scss
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
// iOS Cordova
|
||||
// --------------------------------------------------
|
||||
|
||||
$cordova-ios-toolbar-padding: 2rem !default;
|
||||
|
||||
|
||||
&.platform-cordova.platform-ios {
|
||||
|
||||
ion-navbar-section,
|
||||
ion-navbar,
|
||||
ion-menu > ion-toolbar {
|
||||
min-height: $toolbar-ios-height + $cordova-ios-toolbar-padding;
|
||||
height: $toolbar-ios-height + $cordova-ios-toolbar-padding;
|
||||
}
|
||||
|
||||
ion-navbar,
|
||||
ion-navbar ion-title,
|
||||
ion-menu > ion-toolbar {
|
||||
padding-top: $cordova-ios-toolbar-padding;
|
||||
}
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
|
||||
// Cordova
|
||||
// --------------------------------------------------
|
||||
|
||||
.platform-cordova {
|
||||
|
||||
|
||||
// iOS Cordova
|
||||
// ------------
|
||||
&.platform-ios ion-navbar-section,
|
||||
&.platform-ios ion-navbar,
|
||||
&.platform-ios ion-menu > ion-toolbar {
|
||||
min-height: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
&.platform-ios .toolbar-inner {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
}
|
@ -1,117 +0,0 @@
|
||||
// TODO: temporary until https://github.com/angular/angular/issues/4390 decided
|
||||
// var Rx = require('@reactivex/rxjs/dist/cjs/Rx');
|
||||
// var {Observable} = Rx;
|
||||
|
||||
import * as util from 'ionic/util';
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
|
||||
/**
|
||||
* Respond to device movement in the x/y/z axes.
|
||||
*
|
||||
* @usage
|
||||
* ```js
|
||||
* let watch = DeviceMotion.watchAcceleration();
|
||||
* watch.source.subscribe((data) => {
|
||||
* // data.acceleration.x
|
||||
* // data.acceleration.y
|
||||
* // data.acceleration.z
|
||||
* })
|
||||
*
|
||||
* watch.clear() // to stop watching
|
||||
* ```
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'Device Motion',
|
||||
platforms: ['ios', 'android', 'web'],
|
||||
engines: {
|
||||
cordova: 'cordova-plugin-device-motion'
|
||||
}
|
||||
})
|
||||
export class DeviceMotion {
|
||||
static _wrap(result) {
|
||||
// Mimic the DeviceMotionEvent
|
||||
return util.extend({
|
||||
acceleration: result, // result will be x/y/z accel
|
||||
accelerationIncludingGravity: result, //TODO: I know this isn't correct but not sure how to normalize from native plugin
|
||||
rotationRate: 0,
|
||||
interval: 0,
|
||||
native: true
|
||||
}, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current acceleration from the device. Generally, watchAcceleration
|
||||
* is more commonly used.
|
||||
*
|
||||
* @return {Promise} that resolves with current motion data.
|
||||
*/
|
||||
static getCurrentAcceleration() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(window.DeviceMotionEvent || ('listenForDeviceMovement' in window)) {
|
||||
var fnCb = function fnCb(eventData) {
|
||||
resolve(DeviceMotion._wrap(eventData));
|
||||
window.removeEventListener('devicemotion', fnCb);
|
||||
}
|
||||
window.addEventListener('devicemotion', fnCb);
|
||||
} else if(navigator.accelerometer) {
|
||||
navigator.accelerometer.getCurrentAcceleration(function (result) {
|
||||
resolve(DeviceMotion._wrap(result));
|
||||
}, function (err) {
|
||||
reject(err);
|
||||
});
|
||||
} else {
|
||||
this.pluginWarn();
|
||||
reject('The Device does not support device motion events.');
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Watch for device motion.
|
||||
*/
|
||||
static watchAcceleration(options) {
|
||||
if(window.DeviceMotionEvent || ('listenForDeviceMovement' in window)) {
|
||||
let watchID;
|
||||
|
||||
let source = Rx.Observable.create((observer) => {
|
||||
|
||||
var fnCb = function fnCb(eventData) {
|
||||
observer.onNext(DeviceMotion._wrap(eventData));
|
||||
};
|
||||
|
||||
window.addEventListener('devicemotion', fnCb);
|
||||
|
||||
});
|
||||
|
||||
return {
|
||||
source: source,
|
||||
watchID: watchID,
|
||||
clear: () => {
|
||||
window.removeEventListener('devicemotion', fnCb);
|
||||
}
|
||||
}
|
||||
} else if(navigator.accelerometer) {
|
||||
let watchID;
|
||||
|
||||
let source = Rx.Observable.create((observer) => {
|
||||
|
||||
watchID = navigator.accelerometer.watchAcceleration(function (result) {
|
||||
observer.onNext(DeviceMotion._wrap(result));
|
||||
}, function (err) {
|
||||
observer.onError(err, observer);
|
||||
}, options);
|
||||
|
||||
});
|
||||
|
||||
return {
|
||||
source: source,
|
||||
watchID: watchID,
|
||||
clear: () => {
|
||||
navigator.accelerometer.clearWatch(watchID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
// TODO: temporary until https://github.com/angular/angular/issues/4390 decided
|
||||
// var Rx = require('@reactivex/rxjs/dist/cjs/Rx');
|
||||
// var {Observable} = Rx;
|
||||
|
||||
import * as util from 'ionic/util';
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
|
||||
/**
|
||||
* Respond to device orientation changes (compass).
|
||||
*
|
||||
* @usage
|
||||
* ```js
|
||||
* let watch = DeviceOrientation.watchHeading();
|
||||
* watch.source.subscribe((data) => {
|
||||
* // data.alpha is the compass heading
|
||||
* })
|
||||
*
|
||||
* watch.clear() // to stop watching
|
||||
* ```
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'Device Orientation',
|
||||
platforms: ['ios', 'android', 'web'],
|
||||
engines: {
|
||||
cordova: 'cordova-plugin-device-orientation'
|
||||
}
|
||||
})
|
||||
export class DeviceOrientation {
|
||||
static _wrap(result) {
|
||||
return util.extend({
|
||||
alpha: result.magneticHeading,
|
||||
magneticHeading: result.webkitCompassHeading || result.alpha
|
||||
}, result);
|
||||
}
|
||||
|
||||
static getCurrentHeading() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(window.DeviceOrientationEvent) {
|
||||
var fnCb = function fnCb(eventData) {
|
||||
resolve(DeviceOrientation._wrap(eventData));
|
||||
window.removeEventListener('deviceorientation', fnCb);
|
||||
}
|
||||
window.addEventListener('deviceorientation', fnCb);
|
||||
} else if(navigator.compass) {
|
||||
navigator.compass.getCurrentHeading(function (result) {
|
||||
resolve(DeviceOrientation._wrap(result));
|
||||
}, function (err) {
|
||||
reject(err);
|
||||
});
|
||||
} else {
|
||||
this.pluginWarn();
|
||||
reject('The Device does not support device orientation events.');
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static watchHeading(options) {
|
||||
if(window.DeviceOrientationEvent) {
|
||||
let watchID;
|
||||
|
||||
let source = Rx.Observable.create((observer) => {
|
||||
|
||||
var fnCb = function fnCb(eventData) {
|
||||
observer.onNext(DeviceOrientation._wrap(eventData));
|
||||
};
|
||||
|
||||
window.addEventListener('deviceorientation', fnCb);
|
||||
|
||||
});
|
||||
|
||||
return {
|
||||
source: source,
|
||||
watchID: watchID,
|
||||
clear: () => {
|
||||
window.removeEventListener('deviceorientation', fnCb);
|
||||
}
|
||||
}
|
||||
} else if(navigator.accelerometer) {
|
||||
let watchID;
|
||||
|
||||
let source = Rx.Observable.create((observer) => {
|
||||
|
||||
watchID = navigator.compass.watchHeading(function (result) {
|
||||
observer.onNext(DeviceOrientation._wrap(result));
|
||||
}, function (err) {
|
||||
observer.onError(err, observer);
|
||||
}, options);
|
||||
|
||||
});
|
||||
|
||||
return {
|
||||
source: source,
|
||||
watchID: watchID,
|
||||
clear: () => {
|
||||
navigator.compass.clearWatch(watchID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
|
||||
/**
|
||||
* Access information about the underlying device and platform.
|
||||
*
|
||||
* @usage
|
||||
* ```js
|
||||
* let info = Device.getDevice();
|
||||
* // Device sits below
|
||||
* ```
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'Device',
|
||||
plugins: ['ios', 'android', 'web'],
|
||||
engines: {
|
||||
cordova: 'cordova-plugin-device'
|
||||
},
|
||||
pluginCheck: () => {
|
||||
return !!window.device;
|
||||
}
|
||||
})
|
||||
export class Device {
|
||||
/**
|
||||
* Returns the whole device object.
|
||||
* @see https://github.com/apache/cordova-plugin-device
|
||||
* @returns {Object} The device object.
|
||||
*/
|
||||
static getDevice() {
|
||||
return this.ifPlugin(() => {
|
||||
return device;
|
||||
}, () => {
|
||||
return {
|
||||
name: Device.getName(),
|
||||
model: Device.getModel(),
|
||||
platform: Device.getPlatform(),
|
||||
uuid: Device.getUUID(),
|
||||
version: Device.getVersion()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Cordova version.
|
||||
* @see https://github.com/apache/cordova-plugin-device#devicecordova
|
||||
* @returns {String} The Cordova version.
|
||||
*/
|
||||
static getCordova() {
|
||||
this.ifPlugin(() => {
|
||||
return device.cordova;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the device's model or product.
|
||||
* @see https://github.com/apache/cordova-plugin-device#devicemodel
|
||||
* @returns {String} The name of the device's model or product.
|
||||
*/
|
||||
static getModel() {
|
||||
this.ifPlugin(() => {
|
||||
return device.model;
|
||||
}, () => {
|
||||
return 'unknown'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated device.name is deprecated as of version 2.3.0. Use device.model instead.
|
||||
* @returns {String}
|
||||
*/
|
||||
static getName() {
|
||||
this.ifPlugin(() => {
|
||||
return device.name;
|
||||
}, () => {
|
||||
return 'unknown'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the device's operating system name.
|
||||
* @see https://github.com/apache/cordova-plugin-device#deviceplatform
|
||||
* @returns {String} The device's operating system name.
|
||||
*/
|
||||
static getPlatform() {
|
||||
this.ifPlugin(() => {
|
||||
return device.name;
|
||||
}, () => {
|
||||
return 'unknown'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the device's Universally Unique Identifier.
|
||||
* @see https://github.com/apache/cordova-plugin-device#deviceuuid
|
||||
* @returns {String} The device's Universally Unique Identifier
|
||||
*/
|
||||
static getUUID() {
|
||||
this.ifPlugin(() => {
|
||||
return device.uuid;
|
||||
}, () => {
|
||||
return 'unknown';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the operating system version.
|
||||
* @see https://github.com/apache/cordova-plugin-device#deviceversion
|
||||
* @returns {String}
|
||||
*/
|
||||
static getVersion() {
|
||||
this.ifPlugin(() => {
|
||||
return device.version;
|
||||
}, () => {
|
||||
return 'unknown';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the device manufacturer.
|
||||
* @returns {String}
|
||||
*/
|
||||
static getManufacturer() {
|
||||
this.ifPlugin(() => {
|
||||
return device.manufacturer;
|
||||
}, () => {
|
||||
return 'unknown';
|
||||
});
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
/**
|
||||
* A native dialogs system. Native dialogs can give you a bit more
|
||||
* control over the UI than the browser built-ins, though the Dialogs
|
||||
* plugin will fall back to the built-ins when necessary.
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'Dialogs',
|
||||
platforms: ['ios', 'android', 'web'],
|
||||
engines: {
|
||||
cordova: 'cordova-plugin-dialogs'
|
||||
}
|
||||
})
|
||||
export class Dialogs {
|
||||
/**
|
||||
* Trigger an alert prompt.
|
||||
*
|
||||
* @param message the message to show
|
||||
* @param title the title to show
|
||||
* @param buttonName the button label to use (not available on browser fallback)
|
||||
* @return Promise
|
||||
*/
|
||||
static alert(message, title, buttonName) {
|
||||
return new Promise((resolve,reject) => {
|
||||
if(!navigator.notification) {
|
||||
this.pluginWarn();
|
||||
alert(message);
|
||||
resolve();
|
||||
} else {
|
||||
navigator.notification.alert(message, () => {
|
||||
resolve();
|
||||
}, title, buttonName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a confirm prompt.
|
||||
*
|
||||
* @param message the message to show
|
||||
* @param title the title to show
|
||||
* @param buttonLabels the button labels to use (not available on browser fallback)
|
||||
* @return Promise that resolves with the index of the button selected (zero indexed). 1 is OK on browser fallback
|
||||
*/
|
||||
static confirm(message, title, buttonLabels) {
|
||||
return new Promise((resolve,reject) => {
|
||||
if(!navigator.notification) {
|
||||
this.pluginWarn();
|
||||
var ok = confirm(message);
|
||||
// Use 2 as OK
|
||||
resolve(ok ? 2 : 0);
|
||||
} else {
|
||||
navigator.notification.confirm(message, (buttonIndex) => {
|
||||
resolve(buttonIndex - 1);
|
||||
}, title, buttonLabels);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static prompt(message, title, buttonLabels, defaultText) {
|
||||
return new Promise((resolve,reject) => {
|
||||
if(!navigator.notification) {
|
||||
this.pluginWarn();
|
||||
var response = prompt(message);
|
||||
// Use 1 as OK
|
||||
resolve(response);
|
||||
} else {
|
||||
navigator.notification.prompt(message, (results) => {
|
||||
resolve(results.input1, buttonIndex - 1);
|
||||
}, title, buttonLabels, defaultText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Beep n times. Not available on browser.
|
||||
* @param times the number of times to beep
|
||||
*/
|
||||
static beep(times) {
|
||||
navigator.notification && navigator.notification.beep(times);
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
// TODO: temporary until https://github.com/angular/angular/issues/4390 decided
|
||||
// var Rx = require('@reactivex/rxjs/dist/cjs/Rx');
|
||||
// var {Observable} = Rx;
|
||||
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
/**
|
||||
* Get geolocation data.
|
||||
*
|
||||
* @usage
|
||||
* ```js
|
||||
* Geolocation.getCurrentPosition().then((resp) => {
|
||||
* //resp.coords.latitude
|
||||
* //resp.coords.longitude
|
||||
* })
|
||||
*
|
||||
* let watch = Geolocation.watchPosition();
|
||||
* watch.source.subscribe((data) => {
|
||||
* //data.coords.latitude
|
||||
* //data.coords.longitude
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'Geolocation',
|
||||
platforms: ['ios', 'android', 'web'],
|
||||
engines: {
|
||||
cordova: 'cordova-plugin-geolocation'
|
||||
}
|
||||
})
|
||||
export class Geolocation {
|
||||
/**
|
||||
* Get the current GPS location.
|
||||
*/
|
||||
static getCurrentPosition(options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
navigator.geolocation.getCurrentPosition(function (result) {
|
||||
resolve(result);
|
||||
}, function (err) {
|
||||
reject(err);
|
||||
}, options);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Watch for location changes.
|
||||
*/
|
||||
static watchPosition(options) {
|
||||
let watchID;
|
||||
|
||||
let source = Rx.Observable.create((observer) => {
|
||||
watchID = navigator.geolocation.watchPosition(function (result) {
|
||||
observer.onNext(result)
|
||||
}, function(err) {
|
||||
observer.onError(err, observer);
|
||||
}, options);
|
||||
})
|
||||
|
||||
return {
|
||||
source: source,
|
||||
watchID: watchID,
|
||||
clear: () => {
|
||||
navigator.geolocation.clearWatch(watchID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear a specific watch by watch ID. Generally, you'll call
|
||||
* clear() on the returned watch from `getCurrentPosition` or `watchPosition` above.
|
||||
*/
|
||||
static clearWatch(watchID) {
|
||||
return navigator.geolocation.clearWatch(watchID);
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
/**
|
||||
* Manage the native keyboard. Note: this plugin performs mainly in the native
|
||||
* app context. Most operations are non-functional in a normal web browser as
|
||||
* keyboard control is limited.
|
||||
*
|
||||
* @usage
|
||||
* ```js
|
||||
* // Hide the accessory bar
|
||||
* Keyboard.setAccessoryBarVisible(false)
|
||||
*
|
||||
* Keyboard.close()
|
||||
* ```
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'Keyboard',
|
||||
platforms: ['ios', 'android'],
|
||||
engines: {
|
||||
cordova: 'ionic-plugin-keyboard'
|
||||
},
|
||||
pluginCheck: () => {
|
||||
return window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard;
|
||||
}
|
||||
})
|
||||
export class Keyboard {
|
||||
/**
|
||||
* Set whether the accessory bar is visible.
|
||||
*
|
||||
* Note: this only works while running natively (accessory bar cannot be removed
|
||||
* in most web browsers), and by default the bar is hidden when running natively.
|
||||
*
|
||||
* @param isVisible whether the accessory bar is visible
|
||||
*/
|
||||
static setAccessoryBarVisible(isVisible) {
|
||||
this.ifPlugin(() => {
|
||||
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(!isVisible);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the keyboard.
|
||||
*/
|
||||
static close() {
|
||||
this.ifPlugin(() => {
|
||||
cordova.plugins.Keyboard.close();
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the keyboard. Does nothing on iOS (has to be triggered from an input)
|
||||
*/
|
||||
static show() {
|
||||
this.ifPlugin(() => {
|
||||
cordova.plugins.Keyboard.show();
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the visibility of the keyboard.
|
||||
*/
|
||||
static isVisible() {
|
||||
return this.ifPlugin(() => {
|
||||
return cordova.plugins.Keyboard.isVisible;
|
||||
});
|
||||
}
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
/**
|
||||
* Simple loading popup indicators.
|
||||
*
|
||||
* Uses the `cordova-plugin-progressindicator` Cordova plugin. See the [plugin docs](http://paolobernasconi.com/cordova-progressIndicator/)
|
||||
* for more information.
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* ```js
|
||||
* Loading.show(true, 'Waiting...') // Dim the background and show label
|
||||
* ```
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'Loading',
|
||||
platforms: ['ios', 'android', 'web'],
|
||||
engines: {
|
||||
cordova: 'cordova-plugin-progressindicator'
|
||||
},
|
||||
pluginCheck: () => {
|
||||
return !!window.ProgressIndicator;
|
||||
}
|
||||
})
|
||||
export class Loading {
|
||||
|
||||
/**
|
||||
* Show a simple loading box.
|
||||
*
|
||||
* @param dim {Boolean} whether the dim the background
|
||||
* @param label {String} the custom label
|
||||
* @param detail {String} any detail text
|
||||
*/
|
||||
static simple(dim, label, detail) {
|
||||
this.ifPlugin(() => {
|
||||
if(typeof label === 'undefined') {
|
||||
window.ProgressIndicator.showSimple(dim);
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof detail === 'undefined') {
|
||||
window.ProgressIndicator.showSimpleWithLabel(dim, label);
|
||||
return;
|
||||
}
|
||||
|
||||
window.ProgressIndicator.showSimpleWithLabelDetail(dim, label, detail);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a deteriminate loading box with progress bar
|
||||
* that completes after a certain amount of time
|
||||
*
|
||||
* @param dim {Boolean} whether the dim the background
|
||||
* @param timeout {Integer} the timeout for the loading box
|
||||
* @param label {String} the custom label
|
||||
*/
|
||||
static determinate(dim, timeout, label) {
|
||||
this.ifPlugin(() => {
|
||||
if(typeof label === 'undefined') {
|
||||
window.ProgressIndicator.showDeterminate(dim, timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof detail === 'undefined') {
|
||||
window.ProgressIndicator.showSimpleWithLabel(dim, timeout, label);
|
||||
return;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a spinning circle
|
||||
*
|
||||
* @param dim {Boolean} whether the dim the background
|
||||
* @param timeout {Integer} the timeout for the loading box
|
||||
* @param label {String} the custom label
|
||||
*/
|
||||
static annular(dim, timeout, label) {
|
||||
this.ifPlugin(() => {
|
||||
if(typeof label === 'undefined') {
|
||||
window.ProgressIndicator.showAnnular(dim, timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof detail === 'undefined') {
|
||||
window.ProgressIndicator.showAnnularWithLabel(dim, timeout, label);
|
||||
return;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a bar
|
||||
*
|
||||
* @param dim {Boolean} whether the dim the background
|
||||
* @param timeout {Integer} the timeout for the loading box
|
||||
* @param label {String} the custom label
|
||||
*/
|
||||
static bar(dim, timeout, label) {
|
||||
this.ifPlugin(() => {
|
||||
if(typeof label === 'undefined') {
|
||||
window.ProgressIndicator.showBar(dim, timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof detail === 'undefined') {
|
||||
window.ProgressIndicator.showBarWithLabel(dim, timeout, label);
|
||||
return;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a success checkmark
|
||||
*
|
||||
* @param dim {Boolean} whether the dim the background
|
||||
* @param label {String} the custom label
|
||||
*/
|
||||
static success(dim, label) {
|
||||
this.ifPlugin(() => {
|
||||
window.ProgressIndicator.showSuccess(dim, label);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide a loading box
|
||||
*/
|
||||
static hide() {
|
||||
this.ifPlugin(() => {
|
||||
window.ProgressIndicator.hide();
|
||||
})
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
/**
|
||||
* Access Network information and respond to changes in network state.
|
||||
*
|
||||
* @usage
|
||||
* ```js
|
||||
* let networkInfo = Network.getNetwork()
|
||||
* let isOnline = Network.isOnline()
|
||||
* let isOffline = Network.isOffline()
|
||||
* ```
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'Network',
|
||||
platforms: ['ios', 'android'],
|
||||
engines: {
|
||||
cordova: 'cordova-plugin-network-information'
|
||||
},
|
||||
pluginCheck: () => {
|
||||
return !!navigator.connection;
|
||||
}
|
||||
})
|
||||
@Injectable()
|
||||
export class Network {
|
||||
/**
|
||||
* Return network info.
|
||||
*/
|
||||
static info() {
|
||||
this.ifPlugin(() => {
|
||||
return navigator.connection.type;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether the device is online
|
||||
*/
|
||||
static isOnline() {
|
||||
this.ifPlugin(() => {
|
||||
var networkState = navigator.connection.type;
|
||||
return networkState !== window.Connection.UNKNOWN && networkState !== window.Connection.NONE;
|
||||
}, () => {
|
||||
return navigator.onLine
|
||||
});
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
export class NativePluginDecorator {
|
||||
constructor(cls, config) {
|
||||
this.cls = cls;
|
||||
this.config = config;
|
||||
|
||||
cls.ifPlugin = (cb, returnType=null) => {
|
||||
// Convert to boolean the plugin param
|
||||
var exists;
|
||||
if(typeof this.config.pluginCheck === 'function') {
|
||||
exists = this.config.pluginCheck();
|
||||
} else {
|
||||
console.error('Plugin "' + this.config.name + '" is missing a pluginCheck() function for plugin verification. Please add one."');
|
||||
return false;
|
||||
}
|
||||
if(exists) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
// We don't have the plugin, so print a warning message
|
||||
cls.pluginWarn();
|
||||
|
||||
// If the user supplied a default return value, return it here.
|
||||
if(returnType) {
|
||||
return (typeof returnType === 'function') ? returnType() : returnType;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
cls.pluginWarn = () => {
|
||||
if(cls._pluginWarned) {
|
||||
// Only warn once
|
||||
return;
|
||||
}
|
||||
|
||||
let platformString = [];
|
||||
for(var k in this.config.engines) {
|
||||
platformString.push('\t' + k + ': '+ this.config.engines[k]);
|
||||
}
|
||||
console.warn('Plugin for ' + this.config.name +
|
||||
' not installed. For native functionality, please install the correct plugin for your platform:\n' +
|
||||
platformString.join('\n'));
|
||||
|
||||
// Set a flag so we don't warn again
|
||||
cls._pluginWarned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function NativePlugin(config) {
|
||||
return function(cls) {
|
||||
var annotations = Reflect.getMetadata('annotations', cls) || [];
|
||||
annotations.push(new NativePluginDecorator(cls, config));
|
||||
Reflect.defineMetadata('annotations', annotations, cls);
|
||||
return cls;
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
export * from './plugin'
|
||||
export * from './applinks/applinks'
|
||||
export * from './barcode/barcode'
|
||||
export * from './battery/battery'
|
||||
export * from './camera/camera'
|
||||
export * from './contacts/contacts'
|
||||
export * from './dialogs/dialogs'
|
||||
export * from './device/device'
|
||||
export * from './device-motion/device-motion'
|
||||
export * from './device-orientation/device-orientation'
|
||||
export * from './geolocation/geolocation'
|
||||
export * from './keyboard/keyboard'
|
||||
export * from './statusbar/statusbar'
|
||||
export * from './vibration/vibration'
|
@ -47,10 +47,10 @@ Platform.register({
|
||||
'tablet'
|
||||
],
|
||||
settings: {
|
||||
mode: 'md',
|
||||
keyboardHeight: 290,
|
||||
scrollAssist: true,
|
||||
hoverCSS: false,
|
||||
keyboardHeight: 290,
|
||||
mode: 'md',
|
||||
scrollAssist: true,
|
||||
},
|
||||
isMatch(p) {
|
||||
return p.isPlatform('android', 'android|silk');
|
||||
@ -70,19 +70,13 @@ Platform.register({
|
||||
'iphone'
|
||||
],
|
||||
settings: {
|
||||
mode: 'ios',
|
||||
scrollAssist: function(p) {
|
||||
return /iphone|ipad|ipod/i.test(p.navigatorPlatform());
|
||||
},
|
||||
tapPolyfill: function(p) {
|
||||
return /iphone|ipad|ipod/i.test(p.navigatorPlatform());
|
||||
},
|
||||
keyboardHeight: 290,
|
||||
hoverCSS: false,
|
||||
swipeBackEnabled: function(p) {
|
||||
return /iphone|ipad|ipod/i.test(p.navigatorPlatform());
|
||||
},
|
||||
keyboardHeight: 290,
|
||||
mode: 'ios',
|
||||
scrollAssist: isIOSDevice,
|
||||
swipeBackEnabled: isIOSDevice,
|
||||
swipeBackThreshold: 40,
|
||||
tapPolyfill: isIOSDevice,
|
||||
},
|
||||
isMatch(p) {
|
||||
return p.isPlatform('ios', 'iphone|ipad|ipod');
|
||||
@ -153,3 +147,12 @@ Platform.register({
|
||||
return !!(window.cordova || window.PhoneGap || window.phonegap);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function isIOSDevice(p) {
|
||||
// shortcut function to be reused internally
|
||||
// checks navigator.platform to see if it's an actual iOS device
|
||||
// this does not use the user-agent string because it is often spoofed
|
||||
// an actual iPad will return true, a chrome dev tools iPad will return false
|
||||
return /iphone|ipad|ipod/i.test(p.navigatorPlatform());
|
||||
}
|
||||
|
@ -1,116 +0,0 @@
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
/**
|
||||
* Manage the appearance of the native status bar.
|
||||
*
|
||||
* @usage
|
||||
* ```js
|
||||
* StatusBar.hide(); // Hide the bar
|
||||
*
|
||||
* StatusBar.setStyle(StatusBar.LIGHT_CONTENT) // Good for dark backgrounds
|
||||
* ```
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'StatusBar',
|
||||
platforms: ['ios', 'android'],
|
||||
engines: {
|
||||
cordova: 'cordova-plugin-statusbar'
|
||||
},
|
||||
pluginCheck: () => {
|
||||
return !!window.StatusBar;
|
||||
}
|
||||
})
|
||||
export class StatusBar {
|
||||
static DEFAULT = 0
|
||||
static LIGHT_CONTENT = 1
|
||||
static BLACK_TRANSLUCENT = 2
|
||||
static BLACK_OPAQUE = 3
|
||||
|
||||
/**
|
||||
* Show the StatusBar
|
||||
*/
|
||||
static show() {
|
||||
this.ifPlugin(() => {
|
||||
window.StatusBar.show();
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the StatusBar
|
||||
*/
|
||||
static hide() {
|
||||
this.ifPlugin(() => {
|
||||
window.StatusBar.hide();
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the StatusBar
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* StatusBar.DEFAULT
|
||||
* StatusBar.LIGHT_CONTENT
|
||||
* StatusBar.BLACK_TRANSLUCENT
|
||||
* StatusBar.BLACK_OPAQUE
|
||||
*
|
||||
* @param style the style from above
|
||||
*/
|
||||
static setStyle(style) {
|
||||
this.ifPlugin(() => {
|
||||
switch(style) {
|
||||
case StatusBar.DEFAULT:
|
||||
window.StatusBar.styleDefault();
|
||||
break;
|
||||
case StatusBar.LIGHT_CONTENT:
|
||||
window.StatusBar.styleLightContent();
|
||||
break;
|
||||
case StatusBar.BLACK_TRANSLUCENT:
|
||||
window.StatusBar.styleBlackTranslucent();
|
||||
break;
|
||||
case StatusBar.BLACK_OPAQUE:
|
||||
window.StatusBar.styleBlackOpaque();
|
||||
break;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the status bar to a specific hex color (CSS shorthand supported!).
|
||||
*
|
||||
* iOS note: you must call StatusBar.setOverlay(false) to enable color changing.
|
||||
*
|
||||
* @param hex the hex value of the color.
|
||||
*/
|
||||
static setHexColor(hex) {
|
||||
this.ifPlugin(() => {
|
||||
window.StatusBar.backgroundColorByHexString(hex);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the status bar to a specific named color. Valid options:
|
||||
* black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown.
|
||||
*
|
||||
* iOS note: you must call StatusBar.setOverlay(false) to enable color changing.
|
||||
*
|
||||
* @param name the name of the color (from above)
|
||||
*/
|
||||
static setNamedColor(name) {
|
||||
this.ifPlugin(() => {
|
||||
window.StatusBar.backgroundColorByName(name);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the status bar overlays the main app view. The default
|
||||
* is true.
|
||||
*
|
||||
* @param doesOverlay whether the status bar overlays the main app view.
|
||||
*/
|
||||
static setOverlays(doesOverlay) {
|
||||
this.ifPlugin(() => {
|
||||
window.StatusBar.overlaysWebView(doesOverlay);
|
||||
});
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
import {NativePlugin} from '../plugin';
|
||||
|
||||
/**
|
||||
* Vibrate the device. Uses the HTMl5 Vibration API or the `cordova-plugin-vibration` plugin (preferred)
|
||||
*
|
||||
* @usage
|
||||
* ```js
|
||||
* Vibration.vibrate();
|
||||
* ```
|
||||
*/
|
||||
@NativePlugin({
|
||||
name: 'Vibration',
|
||||
platforms: ['ios', 'android', 'web'],
|
||||
engines: {
|
||||
cordova: 'cordova-plugin-vibration'
|
||||
}
|
||||
})
|
||||
export class Vibration {
|
||||
/**
|
||||
* Vibrate the device. Note: iOS does not support the pattern parameter.
|
||||
*
|
||||
* @param pattern the vibration pattern in ms to use [1000,1000,1000] (vibrate three times, one second each)
|
||||
*/
|
||||
static vibrate(pattern) {
|
||||
if(!navigator.vibrate) {
|
||||
this.pluginWarn();
|
||||
console.log('Vibrate (dev): ', pattern);
|
||||
} else {
|
||||
navigator.vibrate(pattern);
|
||||
}
|
||||
}
|
||||
}
|