Skip to content

Commit

Permalink
Updating uxGenie dependency. Adding features due to this upgrade to t…
Browse files Browse the repository at this point in the history
…he demo. Forgot to add tests to last commit so including those now.
  • Loading branch information
Kent C. Dodds committed Dec 27, 2013
1 parent a8f274e commit e259c2a
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 72 deletions.
93 changes: 60 additions & 33 deletions demo-files/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
app.constant('genie', genie);

app.controller('GenieCtrl', function($scope, genie, ga) {
$scope.demoContext = 'genie-demo';
$scope.iconPrefix = 'glyphicon glyphicon-';
$scope.iconPrefix = {
b: 'glyphicon glyphicon-',
f: 'fa fa-'
}
genie.context($scope.demoContext);

$scope.genieVisible = false;

Expand Down Expand Up @@ -34,82 +41,102 @@
$scope.addWishFromInput = function() {
if ($scope.wishMagicWords) {
ga('send', 'event', 'button', 'click', 'Create Wish: ' + $scope.wishMagicWords);
addWish($scope.wishMagicWords);
addWish($scope.wishMagicWords, null, {
uxGenie: {
iIcon: 'glyphicon glyphicon-exclamation-sign'
}
});
$scope.wishMagicWords = '';
}
};

function addWish(magicWords, action) {
function addWish(magicWords, action, data) {
if (typeof magicWords === 'string') {
magicWords = magicWords.split(',');
}
return genie({
magicWords: magicWords,
action: action || function(wish) {
alert('Your "' + wish.magicWords[0] + '" wish is my command!');
}
},
context: $scope.demoContext,
data: data
});
}

function addStyleWish(style, altStyle, property) {
function addStyleWish(style, altStyle, property, iIcon, altiIcon) {
var originalWish, altWish;
function swapWishes(wish) {
genie.removeContext(wish.context.all);
genie.addContext(wish.data.otherWish.context.all);
}
function applyStyleAndSwapWishes(wish) {
$scope.genieStyle[property] = wish.data.style.toLowerCase();
genie.deregisterWish(wish);
genie(wish.data.otherWish);
swapWishes(wish);
}
originalWish = genie({
magicWords: 'Style the lamp: ' + style,
magicWords: 'Make lamp ' + style,
context: {
all: ['genie-style-' + property + '-' + style, $scope.demoContext]
},
action: applyStyleAndSwapWishes,
data: {
style: style
style: style,
uxGenie: {
iIcon: 'glyphicon glyphicon-' + iIcon
}
}
});
altWish = genie({
magicWords: 'Style the lamp: ' + altStyle,
magicWords: 'Make lamp ' + altStyle,
context: {
all: ['genie-style-' + property + '-' + altStyle, $scope.demoContext]
},
action: applyStyleAndSwapWishes,
data: {
style: altStyle,
otherWish: originalWish
otherWish: originalWish,
uxGenie: {
iIcon: 'glyphicon glyphicon-' + altiIcon
}
}
});
originalWish.data.otherWish = altWish;
genie.deregisterWish(altWish);
}

function addDestinationWish(magicWord, destination) {
addWish('Navigate: ' + magicWord, {
destination: destination,
openNewTab: true
$scope.$watch('genieStyle["' + property + '"]', function(newVal) {
if (newVal === style.toLowerCase()) {
swapWishes(originalWish);
} else {
swapWishes(altWish);
}
});
}

addDestinationWish('Genie on GitHub', 'http://www.github.com/kentcdodds/genie');
addDestinationWish('UX-Genie on GitHub', 'http://www.github.com/kentcdodds/ux-genie');
addDestinationWish('Genie Tests', './test');

addStyleWish('Dark', 'Light', 'color');
addStyleWish('Small', 'Large', 'size');
addStyleWish('Slow', 'Fast', 'animationSpeed');
addStyleWish('Dark', 'Light', 'color', 'picture', 'picture');
addStyleWish('Small', 'Large', 'size', 'resize-small', 'resize-full');
addStyleWish('Slow', 'Fast', 'animationSpeed', 'fast-backward', 'fast-forward');

var genieTagline = encodeURIComponent('Genie: Better than keyboard shortcuts');
var genieHome = encodeURIComponent('http://kent.doddsfamily.us/genie');

function addNavigateWishWithoutPrefix(magicWord, shareUrl) {
function addNavigateWishWithoutPrefix(magicWord, shareUrl, iIcon) {
addWish(magicWord, {
destination: shareUrl,
openNewTab: true
}, {
uxGenie: {
iIcon: iIcon
}
});
}

addNavigateWishWithoutPrefix('Tweet #GenieJS', 'https://twitter.com/intent/tweet?hashtags=GenieJS&original_referer=' + genieHome + '&text=' + genieTagline + '&tw_p=tweetbutton&url=' + genieHome + '&via=kentcdodds');
addNavigateWishWithoutPrefix('Share #GenieJS on Google+', 'http://plus.google.com/share?&url=' + genieHome);
addNavigateWishWithoutPrefix('Email about GenieJS', 'mailto:?&subject=' + encodeURIComponent('Cool JavaScript Library: Genie') + '&body=' + genieTagline + encodeURIComponent('\nCheck it out here: ') + genieHome);

addNavigateWishWithoutPrefix('Code with @kentcdodds', 'http://www.github.com/kentcdodds');
addNavigateWishWithoutPrefix('Follow @kentcdodds', 'https://twitter.com/intent/follow?original_referer=' + genieHome + '&region=follow_link&screen_name=kentcdodds&tw_p=followbutton&variant=2.0');
addNavigateWishWithoutPrefix('Circle +KentCDodds', 'http://plus.google.com/+KentCDodds');
addNavigateWishWithoutPrefix('Visit Kent\'s website', 'http://kent.doddsfamily.us');
addNavigateWishWithoutPrefix('Tweet #GenieJS', 'https://twitter.com/intent/tweet?hashtags=GenieJS&original_referer=' + genieHome + '&text=' + genieTagline + '&tw_p=tweetbutton&url=' + genieHome + '&via=kentcdodds', $scope.iconPrefix.f + 'share');
addNavigateWishWithoutPrefix('Share #GenieJS on Google+', 'http://plus.google.com/share?&url=' + genieHome, $scope.iconPrefix.f + 'share');
addNavigateWishWithoutPrefix('Email about GenieJS', 'mailto:?&subject=' + encodeURIComponent('Cool JavaScript Library: Genie') + '&body=' + genieTagline + encodeURIComponent('\nCheck it out here: ') + genieHome, $scope.iconPrefix.f + 'envelope');
addNavigateWishWithoutPrefix('Code with @kentcdodds', 'http://www.github.com/kentcdodds', $scope.iconPrefix.f + 'github');
addNavigateWishWithoutPrefix('Follow @kentcdodds', 'https://twitter.com/intent/follow?original_referer=' + genieHome + '&region=follow_link&screen_name=kentcdodds&tw_p=followbutton&variant=2.0', $scope.iconPrefix.f + 'twitter');
addNavigateWishWithoutPrefix('Circle +KentCDodds', 'http://plus.google.com/+KentCDodds', $scope.iconPrefix.f + 'google-plus');
addNavigateWishWithoutPrefix('Visit Kent\'s website', 'http://kent.doddsfamily.us', $scope.iconPrefix.f + 'globe');

});

Expand Down
Binary file added demo-files/images/mocha.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 16 additions & 2 deletions demo-files/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ h3 {
.genie-wish {
}

.genie-wish > img, .genie-wish > i {
vertical-align: text-top;
}

.genie-wish.focused {
-mos-border-radius: 8px;
border-radius: 8px;
Expand Down Expand Up @@ -149,6 +153,11 @@ h3 {
line-height: 50px;
}

#uxLampContainer.large .genie-wish > img, #uxLampContainer.large .genie-wish > i {
height: 35px;
margin-right: 10px;
}

/* ng-genie small styles */
#uxLampContainer.small .genie-container {
width: 300px;
Expand All @@ -165,10 +174,15 @@ h3 {

#uxLampContainer.small .genie-wishes {
max-height: 216px;
font-size: 24px;
font-size: 18px;
}

#uxLampContainer.small .genie-wish {
padding: 0px 12px 0px 12px;
line-height: 36px;
}
}

#uxLampContainer.small .genie-wish > img, #uxLampContainer.small .genie-wish > i {
height: 20px;
margin-right: 5px;
}
79 changes: 71 additions & 8 deletions demo-files/vendor/uxGenie.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@
return ['<div class="genie-container"' + ngShow + '>',
'<input type="text" ng-model="genieInput" class="lamp-input input form-control" />',
'<div ng-show="matchingWishes.length > 0" class="genie-wishes">',
'<div class="genie-wish" ' +
'ng-repeat="wish in matchingWishes" ' +
'ng-class="{focused: focusedWish == wish}" ' +
'ng-click="makeWish(wish)" ' +
'ng-mouseenter="focusOnWish(wish, false)">',
'{{wish.data.displayText || wish.magicWords[0]}}',
'<div class="genie-wish" ' +
'ng-repeat="wish in matchingWishes" ' +
'ng-class="{focused: focusedWish == wish}" ' +
'ng-click="makeWish(wish)" ' +
'ng-mouseenter="focusOnWish(wish, false)">',
'<img ng-if="wish.data.uxGenie.imgIcon" ng-src="{{wish.data.uxGenie.imgIcon}}">',
'<i ng-if="wish.data.uxGenie.iIcon" class="{{wish.data.uxGenie.iIcon}}"></i>',
'{{wish.data.uxGenie.displayText || wish.magicWords[0]}}',
'</div></div></div>'].join('');
},
scope: {
Expand Down Expand Up @@ -175,7 +177,6 @@
scope.wishCallback(genie.makeWish(wish, scope.genieInput));
saveToLocalStorage(wish);
scope.$apply(function() {
updateMatchingWishes(scope.genieInput);
scope.lampVisible = false;
});
}
Expand Down Expand Up @@ -207,6 +208,7 @@
if (scope.rubClass) {
scope.$watch('lampVisible', function(newVal) {
if (newVal) {
updateMatchingWishes(scope.genieInput);
el.addClass(scope.rubClass);
// Needs to be lampVisible before it can be selected
$timeout(function() {
Expand Down Expand Up @@ -239,4 +241,65 @@
}
}
}]);
}));

uxGenie.directive('genieWish', ['genie', function(genie) {
return {
scope: {
wishData: '=?',
wishAction: '&?'
},
link: function(scope, el, attrs) {
var id = attrs.wishId;
var context = attrs.wishContext ? attrs.wishContext.split(',') : null;
var data = scope.wishData || {};
var uxGenieData = data.uxGenie = data.uxGenie || {};

uxGenieData.element = el[0];
uxGenieData.event = attrs.wishEvent || uxGenieData.event || 'click';
uxGenieData.iIcon = attrs.wishIIcon;
uxGenieData.imgIcon = attrs.wishImgIcon;

var action = function(wish) {
var modifiers = [];
if (attrs.eventModifiers) {
modifiers = attrs.eventModifiers.split(',');
}
var event = new MouseEvent(wish.data.uxGenie.event, {
view: window,
bubbles: true,
cancelable: true,
ctrlKey: modifiers.indexOf('ctrlKey') > -1,
altKey: modifiers.indexOf('altKey') > -1,
shiftKey: modifiers.indexOf('shiftKey') > -1,
metaKey: modifiers.indexOf('metaKey') > -1
});
wish.data.uxGenie.element.dispatchEvent(event);

if (attrs.wishAction) {
scope.wishAction({wish: wish});
}
};

// get magic words
var magicWords = null;
['genieWish', 'name', 'id'].every(function(attrName) {
magicWords = attrs[attrName];
return !magicWords;
});
if (magicWords) {
magicWords = magicWords.split(',');
} else {
throw new Error('Thrown by the genie-wish directive: All genie-wish elements must have a magic-words, id, or name attribute.');
}

genie({
id: id,
magicWords: magicWords,
context: context,
action: action,
data: data
});
}
}
}]);
}));
36 changes: 24 additions & 12 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<meta name="keywords" content="GenieJS, Alfred App, JavaScript, User Experience, UX">
<meta name="description" content="GenieJS is a JavaScript library to improve user experience by allowing users to perform actions with their keyboard. GenieJS also learns the user's preferences over time.">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" />
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css">
<link rel="stylesheet" href="./demo-files/style.css" />
</head>
<body>
Expand All @@ -18,24 +19,28 @@
<header>
<h1>GenieJS</h1>
<h2 id="wish-output">Press Ctrl+Space (or click

<span class="rub-the-lamp" ng-click="genieVisible=!genieVisible; $event.stopPropagation();" ga>here</span>)

to <a href="http://www.youtube.com/watch?v=pwsTXpDJSVE" ga>rub the lamp</a></h2>
<span class="rub-the-lamp" ng-click="genieVisible=!genieVisible; $event.stopPropagation();" ga>here</span>) to rub the lamp</h2>
<h3>Then type an apostrophe ( ' ) to see all the wishes</h3>
<h4>Wishes made: {{wishesMade}}</h4>
<p>
GenieJS was built to simulate the behavior in apps like <a href="http://www.alfredapp.com/" ga>Alfred</a>.<br />
GenieJS was built to simulate the behavior in apps like
<a href="http://www.alfredapp.com/" genie-wish="What is Alfred?" wish-context="{{demoContext}}" wish-i-icon="{{iconPrefix.b}}question-sign" target="_blank" ga>Alfred</a>.<br />

Essentially, you register actions with keywords and then you can find those actions via a keyword search.<br />
For info on the <a href="https://github.com/kentcdodds/genie#vernacular" ga>vernacular</a> of wishes and magic words,
see the <a href="https://github.com/kentcdodds/genie" ga>project on GitHub</a>.<br />
I'm in the process of moving tests to Mocha. Go <a href="./test/testrunner.html" ga>here</a> to run the Mocha tests,
click <a href="./test/old-tests" ga>here</a> to run the old tests...

For info on the <a href="https://github.com/kentcdodds/genie#vernacular" genie-wish="What's a wish?" wish-context="{{demoContext}}" wish-i-icon="{{iconPrefix.b}}question-sign" target="_blank" ga>vernacular</a> of wishes and magic words,
see the <a href="https://github.com/kentcdodds/genie" genie-wish="See Genie on GitHub" wish-context="{{demoContext}}" wish-i-icon="{{iconPrefix.f}}github" target="_blank" ga>project on GitHub</a>.<br />

There's also an <a href="http://www.angularjs.org/" target="_blank" genie-wish="What's AngularJS?" wish-context="{{demoContext}}" wish-i-icon="{{iconPrefix.b}}question-sign" ga>AngularJS</a>
module with a few useful directives called <a href="http://www.github.com/kentcdodds/ux-genie" target="_blank" genie-wish="See uxGenie on GitHub" wish-context="{{demoContext}}" wish-i-icon="{{iconPrefix.f}}github" ga>uxGenie on GitHub</a>.<br />

I'm in the process of moving tests to Mocha. Go <a href="./test/testrunner.html" genie-wish="Run Tests" wish-context="{{demoContext}}" wish-img-icon="./demo-files/images/mocha.png" target="_blank" ga>here</a> to run the Mocha tests,
click <a href="./test/old-tests" target="_blank" ga>here</a> to run the old tests...
</p>
<p>
<strong>Note:</strong> If you're on a mobile device, you will not be able to use this demo. Instead you can watch this
<a href="http://www.youtube.com/watch?v=nJrtn8B4FzM" ga>demo video</a>. Please also visit the
<a href="https://github.com/kentcdodds/genie" ga>GitHub project</a>.
<a href="http://www.youtube.com/watch?v=nJrtn8B4FzM" genie-wish="Watch Demo Video" wish-context="{{demoContext}}" wish-i-icon="{{iconPrefix.f}}youtube-play" target="_blank" ga>demo video</a>. Please also visit the
<a href="https://github.com/kentcdodds/genie" target="_blank" ga>GitHub project</a>.
</p>
</header>

Expand All @@ -47,7 +52,14 @@ <h4>Wishes made: {{wishesMade}}</h4>
</p>
<ol id="instructions-list">
<li>Press Ctrl+Space to open the Genie Search Box</li>
<li>Optionally type an apostrophe (') to show all wishes (<a href="https://github.com/kentcdodds/ux-genie#view-all-wishes" ga>about this feature</a>)</li>
<li>Optionally type an apostrophe (') to show all wishes
(<a href="https://github.com/kentcdodds/ux-genie#view-all-wishes"
target="_blank"
genie-wish="Read about the ' feature"
wish-i-icon="{{iconPrefix.f}}github"
wish-context="{{demoContext}}"
ga>about this feature</a>)
</li>
<li>Type anything to filter the wishes</li>
<li>Mouse over or arrow down to the wish you wish and click/press return</li>
<li>Notice how genie organizes the wishes as you make them</li>
Expand Down
Loading

0 comments on commit e259c2a

Please sign in to comment.