abstract out the install button functionality as there is a lot of it and it is used in multiple components
parent
96dee79905
commit
39244314a9
|
@ -0,0 +1,71 @@
|
|||
<ng-container [ngSwitch]="installStatus">
|
||||
|
||||
<!-- Give the user the ability to remove an installed skill -->
|
||||
<button
|
||||
*ngSwitchCase="'installed'"
|
||||
fxLayout="row"
|
||||
fxLayoutAlign="center center"
|
||||
mat-flat-button
|
||||
class="uninstall-button"
|
||||
(click)="uninstallSkill()"
|
||||
[ngStyle]="installButtonStyle"
|
||||
>
|
||||
<fa-icon [icon]="removeIcon"></fa-icon>
|
||||
<span>REMOVE</span>
|
||||
</button>
|
||||
|
||||
<!-- System skills cannot be removed so show a lock icon and disable -->
|
||||
<button
|
||||
*ngSwitchCase="'system'"
|
||||
fxLayout="row"
|
||||
fxLayoutAlign="center center"
|
||||
mat-flat-button
|
||||
class="installed-button"
|
||||
[disabled]="true"
|
||||
[ngStyle]="installButtonStyle"
|
||||
>
|
||||
<fa-icon [icon]="skillLocked"></fa-icon>
|
||||
<span>ADDED</span>
|
||||
</button>
|
||||
|
||||
<!-- Use the button to indicate to the user that the install is in progress -->
|
||||
<button
|
||||
*ngSwitchCase="'installing'"
|
||||
fxLayout="row"
|
||||
fxLayoutAlign="center center"
|
||||
mat-flat-button
|
||||
class="installing-button"
|
||||
[ngStyle]="installButtonStyle"
|
||||
>
|
||||
<div class="installing-spinner"></div>
|
||||
ADDING...
|
||||
</button>
|
||||
|
||||
<!-- Use the button to indicate to the user that an uninstall is in progress -->
|
||||
<button
|
||||
*ngSwitchCase="'uninstalling'"
|
||||
fxLayout="row"
|
||||
fxLayoutAlign="center center"
|
||||
mat-flat-button
|
||||
class="uninstalling-button"
|
||||
[ngStyle]="installButtonStyle"
|
||||
>
|
||||
<div class="uninstalling-spinner"></div>
|
||||
REMOVING...
|
||||
</button>
|
||||
|
||||
<!-- Allow the user to add a skill to their devices -->
|
||||
<button
|
||||
*ngSwitchDefault
|
||||
fxLayout="row"
|
||||
fxLayoutAlign="center center"
|
||||
class="install-button"
|
||||
mat-flat-button
|
||||
(click)="install_skill()"
|
||||
[ngStyle]="installButtonStyle"
|
||||
>
|
||||
<fa-icon [icon]="addIcon"></fa-icon>
|
||||
<span>ADD</span>
|
||||
</button>
|
||||
|
||||
</ng-container>
|
|
@ -0,0 +1,78 @@
|
|||
@import '../../../../stylesheets/global.scss';
|
||||
|
||||
@mixin install-status {
|
||||
border-radius: 4px;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
// The angular material spinner was limiting in color choices we built our own
|
||||
@mixin spinner-common {
|
||||
animation: spin 1s ease-in-out infinite;
|
||||
border: 2px solid rgba(255,255,255,.3);
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
height: 15px;
|
||||
margin-right: 10px;
|
||||
width: 15px;
|
||||
}
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
fa-icon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.install-button {
|
||||
@include install-status;
|
||||
color: $mycroft-white;
|
||||
}
|
||||
.install-button:hover {
|
||||
@include install-status;
|
||||
background-color: $mycroft-tertiary-green;
|
||||
color: $mycroft-secondary;
|
||||
}
|
||||
|
||||
.installed-button {
|
||||
@include install-status;
|
||||
}
|
||||
|
||||
.installing-button {
|
||||
@include install-status;
|
||||
background-color: $mycroft-tertiary-green;
|
||||
color: $mycroft-secondary;
|
||||
mat-spinner {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
margin-top: 7px;
|
||||
}
|
||||
}
|
||||
.installing-spinner {
|
||||
@include spinner-common;
|
||||
border-right-color: $mycroft-secondary;
|
||||
border-top-color: $mycroft-secondary;
|
||||
}
|
||||
|
||||
|
||||
.uninstall-button {
|
||||
@include install-status;
|
||||
background-color: $mycroft-dark-grey;
|
||||
color: $mycroft-white;
|
||||
}
|
||||
.uninstall-button:hover {
|
||||
@include install-status;
|
||||
border: none;
|
||||
background-color: #eb5757;
|
||||
color: $mycroft-white;
|
||||
}
|
||||
|
||||
.uninstalling-button {
|
||||
@include install-status;
|
||||
background-color: #eb5757;
|
||||
color: $mycroft-white;
|
||||
}
|
||||
.uninstalling-spinner {
|
||||
@include spinner-common;
|
||||
border-right-color: $mycroft-white;
|
||||
border-top-color: $mycroft-white;
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/**
|
||||
* This component does all things install button, which is a lot of things.
|
||||
*/
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { AvailableSkill } from "../../skills.service";
|
||||
|
||||
import { InstallService } from "../../install.service";
|
||||
import { faPlusCircle } from "@fortawesome/free-solid-svg-icons/faPlusCircle";
|
||||
import { faTrash } from "@fortawesome/free-solid-svg-icons/faTrash";
|
||||
import { faLock } from "@fortawesome/free-solid-svg-icons/faLock";
|
||||
import { MatSnackBar } from "@angular/material";
|
||||
|
||||
const fiveSeconds = 5000;
|
||||
const twentySeconds = 20000;
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'skill-install-button',
|
||||
templateUrl: './install-button.component.html',
|
||||
styleUrls: ['./install-button.component.scss']
|
||||
})
|
||||
export class InstallButtonComponent implements OnInit {
|
||||
public addIcon = faPlusCircle;
|
||||
@Input() private component: string;
|
||||
public installButtonStyle: object;
|
||||
public installStatus: string;
|
||||
public removeIcon = faTrash;
|
||||
@Input() public skill: AvailableSkill;
|
||||
public skillLocked = faLock;
|
||||
|
||||
constructor(private installSnackbar: MatSnackBar, private installService: InstallService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.installService.installStatuses.subscribe(
|
||||
(installStatuses) => {
|
||||
this.installStatus = this.installService.getSkillInstallStatus(
|
||||
this.skill,
|
||||
installStatuses
|
||||
)
|
||||
}
|
||||
);
|
||||
this.applyInstallButtonStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Some of the install button style elements are different depending on
|
||||
* which component it is displayed within. Use the ngStyle directive
|
||||
* to specify these styles.
|
||||
*/
|
||||
applyInstallButtonStyle() {
|
||||
if (this.component === 'skillDetail') {
|
||||
this.installButtonStyle = {'width': '140px'}
|
||||
} else if (this.component === 'skillSummary') {
|
||||
this.installButtonStyle = {'width': '320px', 'margin-bottom': '15px'}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a skill onto one or many devices
|
||||
*/
|
||||
install_skill() : void {
|
||||
this.installService.installSkill(this.skill).subscribe(
|
||||
(response) => {
|
||||
this.onInstallSuccess(response)
|
||||
},
|
||||
(response) => {
|
||||
this.onInstallFailure(response)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the successful install request
|
||||
*
|
||||
* This does not indicate that the install of the skill completed, only
|
||||
* that the request to install a skill succeeded. Change the install
|
||||
* button to an "installing" state.
|
||||
*
|
||||
* @param response
|
||||
*/
|
||||
onInstallSuccess(response) : void {
|
||||
this.installService.newInstallStatuses[this.skill.name] = 'installing';
|
||||
this.installService.applyInstallStatusChanges();
|
||||
this.installSnackbar.open(
|
||||
'The ' + this.skill.title + ' skill is being added ' +
|
||||
'to your devices. Please allow up to two minutes for ' +
|
||||
'installation to complete before using the skill.',
|
||||
null,
|
||||
{panelClass: 'mycroft-snackbar', duration: twentySeconds}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the failure to install a skill.
|
||||
*
|
||||
* If a user attempts to install a skill without being logged in, show a
|
||||
* snackbar to notify the user and give them the ability to log in.
|
||||
*
|
||||
* @param response - object representing the response from the API call
|
||||
*/
|
||||
onInstallFailure(response) : void {
|
||||
if (response.status === 401) {
|
||||
this.installSnackbar.open(
|
||||
'To install a skill, log in to your account.',
|
||||
'LOG IN',
|
||||
{panelClass: 'mycroft-snackbar', duration: fiveSeconds}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a skill from one or many devices
|
||||
*/
|
||||
uninstallSkill() : void {
|
||||
this.installService.uninstallSkill(this.skill).subscribe(
|
||||
(response) => {
|
||||
this.onUninstallSuccess(response)
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the successful install request
|
||||
*
|
||||
* This does not indicate that the install of the skill completed, only
|
||||
* that the request to install a skill succeeded. Change the install
|
||||
* button to an "installing" state.
|
||||
*
|
||||
* @param response
|
||||
*/
|
||||
onUninstallSuccess(response) : void {
|
||||
this.installService.newInstallStatuses[this.skill.name] = 'uninstalling';
|
||||
this.installService.applyInstallStatusChanges();
|
||||
this.installSnackbar.open(
|
||||
'The ' + this.skill.title + ' skill is ' +
|
||||
'uninstalling. Please allow up to a minute for the skill to be ' +
|
||||
'removed from devices.',
|
||||
null,
|
||||
{panelClass: 'mycroft-snackbar', duration: twentySeconds}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue