Dock shortcuts

This commit is contained in:
Mo Bitar
2018-12-12 18:37:07 -06:00
parent 1877412ebf
commit 7cba67ce69
6 changed files with 120 additions and 12 deletions

View File

@@ -138,11 +138,68 @@ angular.module('app')
this.componentManager = componentManager;
this.rooms = [];
this.themes = [];
modelManager.addItemSyncObserver("room-bar", "SN|Component", (allItems, validItems, deletedItems, source) => {
this.rooms = modelManager.components.filter((candidate) => {return candidate.area == "rooms" && !candidate.deleted});
});
modelManager.addItemSyncObserver("footer-bar-themes", "SN|Theme", (allItems, validItems, deletedItems, source) => {
let themes = modelManager.validItemsForContentType("SN|Theme").filter((candidate) => {return !candidate.deleted}).sort((a, b) => {
return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
});
let differ = themes.length != this.themes.length;
this.themes = themes;
if(differ) {
this.reloadDockShortcuts();
}
});
this.reloadDockShortcuts = function() {
let shortcuts = [];
for(var theme of this.themes) {
var icon = theme.content.package_info.dock_icon;
if(!icon) {
continue;
}
shortcuts.push({
component: theme,
icon: icon
})
}
this.dockShortcuts = shortcuts.sort((a, b) => {
// circles first, then images
var aType = a.icon.type;
var bType = b.icon.type;
if(aType == bType) {
return 0;
} else if(aType == "circle" && bType == "svg") {
return -1;
} else if(bType == "circle" && aType == "svg") {
return 1;
}
});
}
this.initSvgForShortcut = function(shortcut) {
var id = "dock-svg-" + shortcut.component.uuid;
var element = document.getElementById(id);
var parser = new DOMParser();
var svg = shortcut.component.content.package_info.dock_icon.source;
var doc = parser.parseFromString(svg, "image/svg+xml");
element.appendChild(doc.documentElement);
}
this.selectShortcut = function(shortcut) {
componentManager.toggleComponent(shortcut.component);
}
componentManager.registerHandler({identifier: "roomBar", areas: ["rooms", "modal"], activationHandler: (component) => {
// RIP: There used to be code here that checked if component.active was true, and if so, displayed the component.
// However, we no longer want to persist active state for footer extensions. If you open Extensions on one computer,

View File

@@ -0,0 +1,15 @@
angular
.module('app')
.directive( 'elemReady', function( $parse ) {
return {
restrict: 'A',
link: function( $scope, elem, attrs ) {
elem.ready(function(){
$scope.$apply(function(){
var func = $parse(attrs.elemReady);
func($scope);
})
})
}
}
})

View File

@@ -81,6 +81,7 @@ class ComponentView {
// Add small timeout to, as $scope.loading controls loading overlay,
// which is used to avoid flicker when enabling extensions while having an enabled theme
// we don't use ng-show because it causes problems with rendering iframes after timeout, for some reason.
$timeout(() => {
$scope.loading = false;
$scope.issueLoading = false;

View File

@@ -631,22 +631,33 @@ class ComponentManager {
}
handleToggleComponentMessage(sourceComponent, targetComponent, message) {
if(targetComponent.area == "modal") {
this.openModalComponent(targetComponent);
this.toggleComponent(targetComponent);
}
toggleComponent(component) {
if(component.area == "modal") {
this.openModalComponent(component);
} else {
if(targetComponent.active) {
this.deactivateComponent(targetComponent);
if(component.active) {
this.deactivateComponent(component);
} else {
if(targetComponent.content_type == "SN|Theme" && !targetComponent.isLayerable()) {
if(component.content_type == "SN|Theme") {
// Deactive currently active theme if new theme is not layerable
var activeThemes = this.getActiveThemes();
for(var theme of activeThemes) {
if(theme && !theme.isLayerable()) {
this.deactivateComponent(theme);
}
// Activate current before deactivating others, so as not to flicker
this.activateComponent(component);
if(!component.isLayerable()) {
setTimeout(() => {
for(var theme of activeThemes) {
if(theme && !theme.isLayerable()) {
this.deactivateComponent(theme);
}
}
}, 10);
}
}
this.activateComponent(targetComponent);
}
}
}

View File

@@ -21,6 +21,20 @@
z-index: $z-index-footer-bar-item-panel;
margin-top: 15px;
}
&.dock-shortcut:hover .sk-app-bar-item-column {
border-bottom: 2px solid var(--sn-stylekit-info-color);
}
svg {
width: 12px;
height: 12px;
fill: var(--sn-stylekit-foreground-color);
&:hover {
fill: var(--sn-stylekit-info-color);
}
}
}
#account-panel {
@@ -41,6 +55,5 @@ a.disabled {
#footer-lock-icon {
margin-left: 5px;
padding-left: 8px;
border-left: 1px solid gray;
padding-left: 5px;
}

View File

@@ -1,6 +1,7 @@
.sn-component
#footer-bar.sk-app-bar.no-edges
.left
.sk-app-bar-item{"ng-click" => "ctrl.accountMenuPressed()", "click-outside" => "ctrl.clickOutsideAccountMenu()", "is-open" => "ctrl.showAccountMenu"}
.sk-app-bar-item-column
.sk-circle.small{"ng-class" => "ctrl.error ? 'danger' : (ctrl.getUser() ? 'info' : 'neutral')"}
@@ -39,6 +40,16 @@
.sk-app-bar-item{"ng-if" => "!ctrl.offline", "ng-click" => "ctrl.refreshData()"}
.sk-label Refresh
.sk-app-bar-item.border{"ng-if" => "ctrl.dockShortcuts.length > 0"}
.sk-app-bar-item.dock-shortcut{"ng-repeat" => "shortcut in ctrl.dockShortcuts"}
.sk-app-bar-item-column{"ng-click" => "ctrl.selectShortcut(shortcut)", "ng-class" => "{'underline': shortcut.component.active}"}
.div{"ng-if" => "shortcut.icon.type == 'circle'"}
.sk-circle.small{"ng-style" => "{'background-color': shortcut.icon.background_color, 'border-color': shortcut.icon.border_color}"}
.div{"ng-if" => "shortcut.icon.type == 'svg'"}
.svg-item{"ng-attr-id" => "dock-svg-{{shortcut.component.uuid}}", "elem-ready" => "ctrl.initSvgForShortcut(shortcut)"}
.sk-app-bar-item.border{"ng-if" => "ctrl.hasPasscode()"}
.sk-app-bar-item#lock-item{"ng-if" => "ctrl.hasPasscode()", "title" => "Locks application and wipes unencrypted data from memory."}
.sk-label
%i.icon.ion-locked#footer-lock-icon{"ng-if" => "ctrl.hasPasscode()", "ng-click" => "ctrl.lockApp()"}