Skip to content

Commit

Permalink
Finished testing tooltip logic and made entityType used on server
Browse files Browse the repository at this point in the history
  • Loading branch information
MeoMix committed May 18, 2015
1 parent 0fa780d commit 03daeac
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 54 deletions.
4 changes: 4 additions & 0 deletions src/js/background/enum/entityType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
define({
None: 'none',
Playlist: 'playlist'
});
4 changes: 3 additions & 1 deletion src/js/background/model/playlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ define(function(require) {
var ShareCode = require('background/model/shareCode');
var YouTubeV3API = require('background/model/youTubeV3API');
var ListItemType = require('common/enum/listItemType');
var EntityType = require('background/enum/entityType');

// Playlist holds a collection of PlaylistItems as well as properties pertaining to a playlist.
// Provides methods to work with PlaylistItems such as getting, removing, updating, etc..
Expand Down Expand Up @@ -60,7 +61,8 @@ define(function(require) {
$.ajax({
url: Streamus.serverUrl + 'ShareCode/GetShareCode',
data: {
playlistId: this.get('id')
id: this.get('id'),
entityType: EntityType.Playlist
},
success: function(shareCodeJson) {
var shareCode = new ShareCode(shareCodeJson);
Expand Down
10 changes: 6 additions & 4 deletions src/js/background/model/shareCode.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
define(function() {
define(function(require) {
'use strict';

var EntityType = require('background/enum/entityType');

var ShareCode = Backbone.Model.extend({
defaults: {
id: null,
// TODO: Remove this or use it?
entityType: -1,
entityType: EntityType.None,
entityId: null,
shortId: null,
urlFriendlyEntityTitle: ''
Expand All @@ -16,9 +17,10 @@ define(function() {
},

copyUrl: function() {
var entityType = this.get('entityType');
var shortId = this.get('shortId');
var urlFriendlyEntityTitle = this.get('urlFriendlyEntityTitle');
var shareUrl = 'https://streamus.com/share/playlist/' + shortId + '/' + urlFriendlyEntityTitle;
var shareUrl = 'https://streamus.com/share/' + entityType + '/' + shortId + '/' + urlFriendlyEntityTitle;

Streamus.channels.clipboard.commands.trigger('copy:text', shareUrl);
}
Expand Down
4 changes: 3 additions & 1 deletion src/js/background/model/youTubeV3API.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,9 @@
// Filter out videos which have marked themselves as not able to be embedded since they won't be able to be played in Streamus.
// TODO: Notify the user that this has happened.
var embeddableItems = _.filter(response.items, function(item) {
return item.status.embeddable;
// Check for PT0S due to an issue in YouTube's API: https://code.google.com/p/gdata-issues/issues/detail?id=7172
// Songs with 0s duration are unable to be played.
return item.status.embeddable && item.contentDetails.duration !== 'PT0S';
});

var songs = this._itemListToSongs(embeddableItems);
Expand Down
2 changes: 1 addition & 1 deletion src/js/foreground/view/dialog/createPlaylistView.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
_onGetTitleSuccess: function(title) {
if (!this.isDestroyed) {
this.ui.title.val(title);
this.tit();
this._validateTitle();
this.ui.dataSource.removeClass('is-invalid').addClass('is-valid');
this.ui.dataSourceHint.text(chrome.i18n.getMessage('playlistLoaded'));
this.model.set('dataSourceValid', true);
Expand Down
82 changes: 39 additions & 43 deletions src/js/foreground/view/tooltip/tooltipRegion.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
// If it can't go along the bottom then flip it and place it along the top.
// If it can't fit in the center then shift it to the left or right until it fits.
_getAdjustedOffset: function(boundingClientRect, tooltipWidth, tooltipHeight) {
// adjustY is a feel good value for how far below the target the tooltip should be offset.
var adjustY = 8;
var targetHeight = boundingClientRect.height;
var targetWidth = boundingClientRect.width;
Expand All @@ -50,56 +51,51 @@
left: boundingClientRect.left + targetWidth / 2 - tooltipWidth / 2
};

// Note that these methods have side-effects on the targetOffset object.
this._shiftLeftOffset(targetOffset, window.innerWidth, targetWidth, tooltipWidth);
this._flipInvertTopOffset(targetOffset, window.innerHeight, adjustY, targetHeight, tooltipHeight);
var adjustedLeftOffset = this._shiftLeftOffset(targetOffset.left, window.innerWidth, tooltipWidth);
var adjustedTopOffset = this._flipInvertTopOffset(targetOffset.top, window.innerHeight, adjustY, targetHeight, tooltipHeight);

return targetOffset;
},
var adjustedOffset = {
top: adjustedTopOffset,
left: adjustedLeftOffset
}

// Credit to jquery.qtip2, http://qtip2.com/, for providing a lot of this math
// https://github.com/qTip2/qTip2/blob/master/src/position/viewport.js
// I've stripped the given math **way** down to just my specific use case.

// Perform math to figure out whether the element needs to be shifted left/right and, if so, how much it needs to shift.
_shiftLeftOffset: function(targetOffset, viewportLength, targetLength, tooltipLength) {
var initialOffset = targetOffset.left;
var myLength = -tooltipLength / 2;
var overflow1 = -initialOffset;
var overflow2 = initialOffset + tooltipLength - viewportLength;
var offset = -myLength;

// Adjust position but keep it within viewport dimensions
targetOffset.left += overflow1 > 0 ? overflow1 : overflow2 > 0 ? -overflow2 : 0;
targetOffset.left = Math.max(
initialOffset - offset,
Math.min(
Math.max(
viewportLength,
initialOffset + offset
),
targetOffset.left,
// Make sure we don't adjust complete off the element when using 'center'
initialOffset - myLength
)
);
return adjustedOffset;
},

// Perform math to figure out whether the element fits beneath the target. If not, flip it to the top.
_flipInvertTopOffset: function(targetOffset, viewportLength, adjust, targetLength, tooltipLength) {
var initialOffset = targetOffset.top;
var overflow1 = -initialOffset;
var overflow2 = initialOffset + tooltipLength - viewportLength;
var offset = tooltipLength + targetLength;
// Figure out whether the tooltip fits inside the viewport when centered over the target.
// If it is not inside the viewport then determine the amount of shifting it needs to fit.
_shiftLeftOffset: function(leftOffset, viewportLength, tooltipWidth) {
var adjustedLeftOffset = leftOffset;
var overflow = leftOffset + tooltipWidth - viewportLength;

// Shift the tooltip left/right based on how much it needs to shift to be able to fit inside the viewport.
if (leftOffset < 0) {
adjustedLeftOffset -= leftOffset;
} else if(overflow > 0) {
adjustedLeftOffset -= overflow;
}

return adjustedLeftOffset;
},

if (overflow1 > 0 && overflow2 > 0) {
// Check for overflow on the left/top
targetOffset.top -= offset + adjust;
// Figure out whether the tooltip fits beneath the target. If not, get a new topOffset for it to be flipped.
_flipInvertTopOffset: function(topOffset, viewportHeight, adjust, targetHeight, tooltipHeight) {
var adjustedTopOffset = topOffset;
var overflow = topOffset + tooltipHeight - viewportHeight;
// Double the adjust value because it has already been added once to topOffset before taking into account adjustments.
// So, need to double it when inverting to counter-act the existing amount.
var flipInvertAmount = tooltipHeight + targetHeight + (adjust * 2);

if (topOffset < 0) {
// This logic will move the tooltip from above the target to beneath the target.
adjustedTopOffset += flipInvertAmount;
}
else if (overflow2 > 0) {
// Check for overflow on the left/top
targetOffset.top -= offset + (adjust * 2);
else if (overflow > 0) {
// This logic will move the tooltip from beneath the target to above the target.
adjustedTopOffset -= flipInvertAmount;
}

return adjustedTopOffset;
}
});

Expand Down
2 changes: 2 additions & 0 deletions src/js/test/foreground/view/dialog/dialogSpecLoader.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
define(function(require) {
'use strict';

/* jshint ignore:start */
require('test/foreground/view/dialog/aboutStreamusDialogView.spec');
require('test/foreground/view/dialog/aboutStreamusView.spec');
require('test/foreground/view/dialog/browserSettingsDialogView.spec');
Expand All @@ -27,4 +28,5 @@
require('test/foreground/view/dialog/settingsView.spec');
require('test/foreground/view/dialog/updateStreamusDialogView.spec');
require('test/foreground/view/dialog/updateStreamusView.spec');
/* jshint ignore:end */
});
68 changes: 64 additions & 4 deletions src/js/test/foreground/view/tooltip/tooltipRegion.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,77 @@
tooltipView.showAtOffset.restore();
});

// TODO: Test the placement math. Need a lot of energy to check this correctly.
xit('should be able to get the adjusted offset', function() {
it('should be able to shift the left offset when it exceeds the right-side of the viewport', function() {
var leftOffset = 950;
var viewportWidth = 1000;
var tooltipWidth = 100;

var adjustedLeftOffset = this.tooltipRegion._shiftLeftOffset(leftOffset, viewportWidth, tooltipWidth);
expect(adjustedLeftOffset).not.to.equal(leftOffset);
expect(adjustedLeftOffset).to.equal(900);
});

it('should be able to shift the left offset when it exceeds the left-side of the viewport', function() {
var leftOffset = -50;
var viewportWidth = 1000;
var tooltipWidth = 100;

var adjustedLeftOffset = this.tooltipRegion._shiftLeftOffset(leftOffset, viewportWidth, tooltipWidth);
expect(adjustedLeftOffset).not.to.equal(leftOffset);
expect(adjustedLeftOffset).to.equal(0);
});

it('should be able to not shift the left offset when its left-edge fits in the viewport', function() {
var leftOffset = 0;
var viewportWidth = 1000;
var tooltipWidth = 100;

var adjustedLeftOffset = this.tooltipRegion._shiftLeftOffset(leftOffset, viewportWidth, tooltipWidth);
expect(adjustedLeftOffset).to.equal(leftOffset);
});

it('should be able to not shift the left offset when its right-edge fits in the viewport', function() {
var leftOffset = 900;
var viewportWidth = 1000;
var tooltipWidth = 100;

var adjustedLeftOffset = this.tooltipRegion._shiftLeftOffset(leftOffset, viewportWidth, tooltipWidth);
expect(adjustedLeftOffset).to.equal(leftOffset);
});

it('should be able to flipInvert the top offset when trying to position the element beneath the target', function() {
var topOffset = 950;
var viewportHeight = 1000;
var adjust = 0;
var targetHeight = 200;
var tooltipHeight = 100;

var adjustedTopOffset = this.tooltipRegion._flipInvertTopOffset(topOffset, viewportHeight, adjust, targetHeight, tooltipHeight);
expect(adjustedTopOffset).not.to.equal(topOffset);
expect(adjustedTopOffset).to.equal(650);
});

xit('should be able to get the shiftLeft offset', function() {
it('should be able to flipInvert the top offset when trying to position the element above the target', function() {
var topOffset = -50;
var viewportHeight = 1000;
var adjust = 0;
var targetHeight = 200;
var tooltipHeight = 100;

var adjustedTopOffset = this.tooltipRegion._flipInvertTopOffset(topOffset, viewportHeight, adjust, targetHeight, tooltipHeight);
expect(adjustedTopOffset).not.to.equal(topOffset);
expect(adjustedTopOffset).to.equal(250);
});

xit('should be able to get the flipInvertTop offset', function() {
it('should be able to not flipInvert the top offset', function() {
var topOffset = 0;
var viewportHeight = 1000;
var adjust = 0;
var targetHeight = 200;
var tooltipHeight = 100;

var adjustedTopOffset = this.tooltipRegion._flipInvertTopOffset(topOffset, viewportHeight, adjust, targetHeight, tooltipHeight);
expect(adjustedTopOffset).to.equal(topOffset);
});
});
});

0 comments on commit 03daeac

Please sign in to comment.