Commit b4f2faef authored by Sheetal Umesh Kumar's avatar Sheetal Umesh Kumar

Add copy to clipboard functionality.

Add basic copy to clipboard functionality so user can use a button
click to copy a direct link to his clipboard, when supported by the
browser.

* Refactor annotation share dialog into a component.
* Add tests for annotation share dialog.
parent 60cc1766
......@@ -154,7 +154,9 @@ module.exports = angular.module('h', [
.directive('aboutThisVersionDialog', require('./directive/about-this-version-dialog'))
.directive('annotation', require('./directive/annotation').directive)
.directive('annotationShareDialog', require('./directive/annotation-share-dialog'))
.directive('deepCount', require('./directive/deep-count'))
.directive('dropdownMenuBtn', require('./directive/dropdown-menu-btn'))
.directive('excerpt', require('./directive/excerpt').directive)
.directive('feedbackLink', require('./directive/feedback-link'))
.directive('formInput', require('./directive/form-input'))
......@@ -164,20 +166,19 @@ module.exports = angular.module('h', [
.directive('loggedoutMessage', require('./directive/loggedout-message'))
.directive('loginForm', require('./directive/login-form').directive)
.directive('markdown', require('./directive/markdown'))
.directive('simpleSearch', require('./directive/simple-search'))
.directive('statusButton', require('./directive/status-button'))
.directive('thread', require('./directive/thread'))
.directive('threadFilter', require('./directive/thread-filter'))
.directive('spinner', require('./directive/spinner'))
.directive('shareDialog', require('./directive/share-dialog'))
.directive('windowScroll', require('./directive/window-scroll'))
.directive('dropdownMenuBtn', require('./directive/dropdown-menu-btn'))
.directive('publishAnnotationBtn', require('./directive/publish-annotation-btn'))
.directive('searchStatusBar', require('./directive/search-status-bar'))
.directive('shareDialog', require('./directive/share-dialog'))
.directive('sidebarTutorial', require('./directive/sidebar-tutorial').directive)
.directive('signinControl', require('./directive/signin-control'))
.directive('simpleSearch', require('./directive/simple-search'))
.directive('sortDropdown', require('./directive/sort-dropdown'))
.directive('spinner', require('./directive/spinner'))
.directive('statusButton', require('./directive/status-button'))
.directive('thread', require('./directive/thread'))
.directive('threadFilter', require('./directive/thread-filter'))
.directive('topBar', require('./directive/top-bar'))
.directive('windowScroll', require('./directive/window-scroll'))
.filter('converter', require('./filter/converter'))
......
'use strict';
var angular = require('angular');
module.exports = function () {
return {
bindToController: true,
controllerAs: 'vm',
restrict: 'E',
template: require('../../../templates/client/annotation_share_dialog.html'),
// @ngInject
controller: function ($scope, $element) {
var shareLinkInput = $element.find('input')[0];
$scope.$watch('vm.isOpen', function (isOpen) {
if (isOpen) {
// Focus the input and select it once the dialog has become visible
setTimeout(function () {
shareLinkInput.focus();
shareLinkInput.select();
});
var hideListener = function (event) {
$scope.$apply(function () {
if (!$element[0].contains(event.target)) {
document.removeEventListener('click', hideListener);
this.onClose();
}
}.bind(this));
}.bind(this);
// Stop listening for clicks outside the dialog once it is closed.
// The setTimeout() here is to ignore the initial click that opens
// the dialog.
setTimeout(function () {
document.addEventListener('click', hideListener);
},
0
);
}
}.bind(this));
this.copyToClipboard = function (event) {
var $container = angular.element(event.currentTarget).parent();
var shareLinkInput = $container.find('input')[0];
try {
shareLinkInput.select();
// In some browsers, execCommand() returns false if it fails,
// in others, it may throw an exception instead.
if (!document.execCommand('copy')) {
throw new Error('Copying link failed');
}
this.copyToClipboardMessage = 'Link copied to clipboard!';
} catch (ex) {
this.copyToClipboardMessage = 'Select and copy to share.';
} finally {
setTimeout(function () {
this.copyToClipboardMessage = null;
$scope.$digest();
}.bind(this),
1000);
}
}.bind(this);
},
scope: {
group: '<',
uri: '<',
isPrivate: '<',
isOpen: '<',
onClose: '&',
}
};
};
......@@ -235,6 +235,9 @@ function AnnotationController(
/** True if the annotation is currently being saved. */
vm.isSaving = false;
/** True if the 'Share' dialog for this annotation is currently open. */
vm.showShareDialog = false;
/** The domain model, contains the currently saved version of the
* annotation from the server (or in the case of new annotations that
* haven't been saved yet - the data that will be saved to the server when
......@@ -652,22 +655,6 @@ function AnnotationController(
vm.isPrivate = (privacy === 'private');
};
vm.share = function(event) {
var $container = angular.element(event.currentTarget).parent();
$container.addClass('open');
var shareLinkInput = $container.find('input')[0];
shareLinkInput.focus();
shareLinkInput.select();
// We have to stop propagation here otherwise this click event will
// re-close the share dialog immediately.
event.stopPropagation();
$document.one('click', function() {
$container.removeClass('open');
});
};
/**
* @ngdoc method
* @name annotation.AnnotationController#tagsAutoComplete.
......
'use strict';
var angular = require('angular');
var util = require('./util');
describe('annotationShareDialog', function () {
var element;
function getCopyBtn() {
return element.find('.annotation-share-dialog-link__btn');
}
before(function () {
angular.module('app', [])
.directive('annotationShareDialog',
require('../annotation-share-dialog'));
});
beforeEach(function () {
angular.mock.module('app');
});
describe('The annotation share dialog', function () {
it('has class is-open set when it is open', function () {
element = util.createDirective(document, 'annotationShareDialog', {
isOpen: true
});
assert.isOk(element.find('.annotation-share-dialog').hasClass('is-open'));
});
it('does not have class is-open set when it is not open', function () {
element = util.createDirective(document, 'annotationShareDialog', {
isOpen: false
});
assert.isNotOk(element.find('.annotation-share-dialog').hasClass('is-open'));
});
});
describe('vm.copyToClipboard()', function () {
var stub;
beforeEach(function () {
stub = sinon.stub(document, 'execCommand').returns(true);
element = util.createDirective(document,
'annotationShareDialog',
{
group: {
name: 'Public',
type: 'public',
public: true
},
uri: 'fakeURI',
isPrivate: false,
}
);
});
afterEach(function () {
stub.restore();
});
it('displays message after successful copy', function () {
var expectedMessage = 'Link copied to clipboard!';
getCopyBtn().click();
var actualMessage = element.find('.annotation-share-dialog-link__feedback').text();
assert.include(actualMessage, expectedMessage);
});
it('hides message after a delay after a successful copy', function () {
var clock = sinon.useFakeTimers();
var expectedMessage = 'Link copied to clipboard!';
getCopyBtn().click();
clock.tick(1999);
clock.restore();
var actualMessage = element.find('.annotation-share-dialog-link__feedback').text();
assert.notInclude(actualMessage, expectedMessage);
});
it('displays message after failed copy', function () {
stub.returns(false);
var expectedMessage = 'Select and copy to share';
getCopyBtn().click();
var actualMessage = element.find('.annotation-share-dialog-link__feedback').text();
assert.include(actualMessage, expectedMessage);
});
});
describe('The message when a user wants to share an annotation shows that the annotation', function () {
it('is available to a group', function () {
element = util.createDirective(document, 'annotationShareDialog', {
group: {
public: false
},
isPrivate: false
});
var actualMessage = element.find('.annotation-share-dialog-msg').text();
var actualAudience = element.find('.annotation-share-dialog-msg__audience').text();
var expectedMessage = 'Only group members will be able to view this annotation.';
var expectedAudience = 'Group.';
assert.include(actualMessage, expectedMessage);
assert.include(actualAudience, expectedAudience);
});
it('is private', function () {
element = util.createDirective(document, 'annotationShareDialog', {
isPrivate: true
});
var actualMessage = element.find('.annotation-share-dialog-msg').text();
var actualAudience = element.find('.annotation-share-dialog-msg__audience').text();
var expectedMessage = 'No one else will be able to view this annotation.';
var expectedAudience = 'Only me.';
assert.include(actualMessage, expectedMessage);
assert.include(actualAudience, expectedAudience);
});
});
});
......@@ -999,18 +999,6 @@ describe('annotation', function() {
});
});
describe('share', function() {
it('sets and unsets the open class on the share wrapper', function() {
var parts = createDirective();
var dialog = parts.element.find('.share-dialog-wrapper');
dialog.find('button').click();
parts.scope.$digest();
assert.ok(dialog.hasClass('open'));
util.ngModule(inject, '$document').click();
assert.notOk(dialog.hasClass('open'));
});
});
describe('deleteAnnotation() method', function() {
beforeEach(function() {
fakeAnnotationMapper.deleteAnnotation = sandbox.stub();
......
.annotation-share-dialog.is-open {
display: flex;
flex-direction: column;
}
.annotation-share-dialog {
display: none;
position: absolute;
right: 0;
bottom: 130%;
z-index: 1;
background: $white;
border: 1px solid $gray-lighter;
border-radius: 2px;
width: 200px;
font-size: $body1-font-size;
cursor: default;
box-shadow: 0px 0px 4px 0px rgba(0,0,0,0.15);
// Styling for the dialog box tail pointing down at the
// 'Share' button
&:after, &:before {
top: 100%;
right: 10px;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
&:after {
border-color: rgba(255, 255, 255, 0);
border-top-color: $white;
border-width: 5px;
margin-right: -5px;
}
&:before {
border-color: rgba(211, 211, 211, 0);
border-top-color: $gray-lighter;
border-width: 6px;
margin-right: -6px;
}
}
.annotation-share-dialog-msg {
color: $gray-light;
margin: -5px 10px 10px 10px;
line-height: 15px;
font-size: 11px;
}
.annotation-share-dialog-msg__audience {
font-style: italic;
}
.annotation-share-dialog-link {
position: relative;
font-size: $body1-font-size;
margin: 10px;
padding: 5px;
color: $text-color;
border: 1px solid $gray-lighter;
border-radius: 2px;
background: $lg-3;
white-space: nowrap;
overflow: hidden;
display: flex;
flex-direction: row;
}
.annotation-share-dialog-link:hover {
color: $gray-dark;
}
.annotation-share-dialog-link__text {
overflow: hidden;
border: none;
width: 100%;
background: inherit;
height: 22px;
}
.annotation-share-dialog-link__btn {
color: $dg-3;
padding: 0px;
margin-left: 7px;
}
.annotation-share-dialog-link__btn:hover {
color: $dg-1;
}
.annotation-share-dialog-target {
display: flex;
flex-direction: row;
justify-content: space-between;
border-bottom: 1px solid $gray-lighter;
font-size: $body1-font-size;
padding: 10px;
}
.annotation-share-dialog-target__label {
font-weight: bold;
}
.annotation-share-dialog-target__icon {
color: $dg-3;
text-decoration: none;
font-size: 20px;
cursor: pointer;
}
.annotation-share-dialog-target__icon:hover {
color: $dg-1;
}
// Feedback message displayed after the user copies the link to the clipboard
.annotation-share-dialog-link__feedback {
position: absolute;
left: 5px;
top: 5px;
bottom: 5px;
// leave a margin on the right before the copy to clipboard icon
// just enough to hide the text from the input box behind.
right: 28px;
display: flex;
flex-direction: row;
justify-content: center;
font-size: 11px;
background: white;
border: 1px solid #d3d3d3;
border-radius: 2px;
}
......@@ -152,88 +152,6 @@ $annotation-card-left-padding: 10px;
}
}
// Share dialog
// ------------
.share-dialog-wrapper {
position: relative;
.share-dialog {
display: none;
}
&.open .share-dialog {
display: flex;
flex-direction: column;
}
&.open .share-dialog--actions {
display: block;
}
}
.share-dialog {
position: absolute;
right: 0;
bottom: 130%;
z-index: 1;
background: $white;
border: 1px solid $gray-lighter;
border-radius: 2px;
width: 200px;
font-size: $body1-font-size;
cursor: default;
box-shadow: 0px 0px 4px 0px rgba(0,0,0,0.15);
&:after, &:before {
top: 100%;
right: 10px;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
&:after {
border-color: rgba(255, 255, 255, 0);
border-top-color: $white;
border-width: 5px;
margin-right: -5px;
}
&:before {
border-color: rgba(211, 211, 211, 0);
border-top-color: $gray-lighter;
border-width: 6px;
margin-right: -6px;
}
}
.share-dialog--actions {
padding: 3px;
width: inherit;
}
.share-dialog__link {
padding: 0;
width: 220px;
border: none;
color: $text-color;
}
.share-dialog-msg {
color: $gray-light;
margin: -5px 10px 10px 10px;
line-height: 15px;
font-size: 11px;
}
.share-dialog-msg__audience {
font-style: italic;
}
.annotation-collapsed-replies {
display: none;
}
......@@ -257,6 +175,26 @@ $annotation-card-left-padding: 10px;
}
}
.share-dialog-wrapper {
position: relative;
&.open .share-dialog--actions {
display: block;
}
}
.share-dialog--actions {
padding: 3px;
width: inherit;
}
.share-dialog__link {
padding: 0;
width: 220px;
border: none;
color: $text-color;
}
// the actions for publishing annotations and reverting changes
// at the bottom of an annotation card
.annotation-form-actions {
......
......@@ -12,6 +12,7 @@ $base-line-height: 20px;
// ----------
@import './about-this-version-dialog';
@import './annotation';
@import './annotation-share-dialog';
@import './api-token-input';
@import './dropdown-menu-btn';
@import './excerpt';
......
......@@ -16,20 +16,6 @@
color: $gray-dark;
}
.share-dialog-link {
font-size: $body1-font-size;
margin: 10px;
padding: 5px;
color: $text-color;
border: 1px solid $gray-lighter;
border-radius: 2px;
background: #F2F2F2;
}
.share-dialog-link:hover {
color: $gray-dark;
}
.share-link-field {
padding: 3px;
padding-top: 5px;
......@@ -41,30 +27,6 @@
width: 100%;
}
.share-dialog-target {
display: flex;
flex-direction: row;
justify-content: space-between;
border-bottom: 1px solid $gray-lighter;
font-size: $body1-font-size;
padding: 10px;
}
.share-dialog-target__label {
font-weight: bold;
}
.share-dialog-target__icon {
color: #7A7A7A;
text-decoration: none;
font-size: 20px;
cursor: pointer;
}
.share-dialog-target__icon:hover {
color: #202020;
}
.share-link-icons {
display: flex;
flex-direction: row;
......
{
"IcoMoonType": "selection",
"icons": [
{
"icon": {
"paths": [
"M640 64c0-35.593-28.624-64-63.933-64h-64.134c-35.603 0-63.933 28.654-63.933 64h-63.813c-36.163 0-64.187 28.624-64.187 63.933l-128.096 0.067c-35.265 0-63.904 28.85-63.904 64.438v767.124c0 35.641 28.611 64.438 63.904 64.438h704.192c35.265 0 63.904-28.85 63.904-64.438v-767.124c0-35.641-28.611-64.438-63.904-64.438h-128.096v-0.067c0-35.603-28.738-63.933-64.187-63.933h-63.813zM256 128h64v128h448v-128h64v192h-576v-192z"
],
"attrs": [
{
"fill": "rgb(166, 166, 166)"
}
],
"isMulticolor": false,
"grid": 16,
"tags": [
"clipboard"
],
"colorPermutations": {
"12212212211661661661": [
1
]
}
},
"attrs": [
{
"fill": "rgb(166, 166, 166)"
}
],
"properties": {
"order": 70,
"id": 38,
"name": "clipboard",
"prevSize": 24,
"code": 59660
},
"setIdx": 0,
"setId": 1,
"iconIdx": 0
},
{
"icon": {
"paths": [
......@@ -37,7 +74,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 0
"iconIdx": 1
},
{
"icon": {
......@@ -74,7 +111,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 38
"iconIdx": 2
},
{
"icon": {
......@@ -112,7 +149,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 39
"iconIdx": 3
},
{
"icon": {
......@@ -159,7 +196,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 40
"iconIdx": 4
},
{
"icon": {
......@@ -196,7 +233,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 41
"iconIdx": 5
},
{
"icon": {
......@@ -244,7 +281,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 42
"iconIdx": 6
},
{
"icon": {
......@@ -281,7 +318,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 43
"iconIdx": 7
},
{
"icon": {
......@@ -334,7 +371,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 44
"iconIdx": 8
},
{
"icon": {
......@@ -371,7 +408,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 45
"iconIdx": 9
},
{
"icon": {
......@@ -409,7 +446,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 46
"iconIdx": 10
},
{
"icon": {
......@@ -454,7 +491,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 47
"iconIdx": 11
},
{
"icon": {
......@@ -499,7 +536,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 48
"iconIdx": 12
},
{
"icon": {
......@@ -530,7 +567,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 49
"iconIdx": 13
},
{
"icon": {
......@@ -561,7 +598,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 50
"iconIdx": 14
},
{
"icon": {
......@@ -602,7 +639,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 51
"iconIdx": 15
},
{
"icon": {
......@@ -634,7 +671,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 52
"iconIdx": 16
},
{
"icon": {
......@@ -665,7 +702,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 53
"iconIdx": 17
},
{
"icon": {
......@@ -695,7 +732,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 54
"iconIdx": 18
},
{
"icon": {
......@@ -728,7 +765,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 55
"iconIdx": 19
},
{
"icon": {
......@@ -782,7 +819,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 56
"iconIdx": 20
},
{
"icon": {
......@@ -822,7 +859,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 57
"iconIdx": 21
},
{
"icon": {
......@@ -856,7 +893,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 58
"iconIdx": 22
},
{
"icon": {
......@@ -883,7 +920,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 59
"iconIdx": 23
},
{
"icon": {
......@@ -911,7 +948,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 1
"iconIdx": 24
},
{
"icon": {
......@@ -939,7 +976,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 2
"iconIdx": 25
},
{
"icon": {
......@@ -967,7 +1004,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 3
"iconIdx": 26
},
{
"icon": {
......@@ -995,7 +1032,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 4
"iconIdx": 27
},
{
"icon": {
......@@ -1023,7 +1060,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 5
"iconIdx": 28
},
{
"icon": {
......@@ -1051,7 +1088,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 6
"iconIdx": 29
},
{
"icon": {
......@@ -1079,7 +1116,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 7
"iconIdx": 30
},
{
"icon": {
......@@ -1107,7 +1144,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 8
"iconIdx": 31
},
{
"icon": {
......@@ -1135,7 +1172,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 9
"iconIdx": 32
},
{
"icon": {
......@@ -1163,7 +1200,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 10
"iconIdx": 33
},
{
"icon": {
......@@ -1192,7 +1229,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 11
"iconIdx": 34
},
{
"icon": {
......@@ -1220,7 +1257,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 12
"iconIdx": 35
},
{
"icon": {
......@@ -1248,7 +1285,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 13
"iconIdx": 36
},
{
"icon": {
......@@ -1276,7 +1313,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 14
"iconIdx": 37
},
{
"icon": {
......@@ -1304,7 +1341,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 15
"iconIdx": 38
},
{
"icon": {
......@@ -1332,7 +1369,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 16
"iconIdx": 39
},
{
"icon": {
......@@ -1360,7 +1397,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 17
"iconIdx": 40
},
{
"icon": {
......@@ -1388,7 +1425,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 18
"iconIdx": 41
},
{
"icon": {
......@@ -1416,7 +1453,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 19
"iconIdx": 42
},
{
"icon": {
......@@ -1445,7 +1482,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 20
"iconIdx": 43
},
{
"icon": {
......@@ -1473,7 +1510,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 21
"iconIdx": 44
},
{
"icon": {
......@@ -1501,7 +1538,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 22
"iconIdx": 45
},
{
"icon": {
......@@ -1529,7 +1566,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 23
"iconIdx": 46
},
{
"icon": {
......@@ -1557,7 +1594,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 24
"iconIdx": 47
},
{
"icon": {
......@@ -1585,7 +1622,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 25
"iconIdx": 48
},
{
"icon": {
......@@ -1613,7 +1650,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 26
"iconIdx": 49
},
{
"icon": {
......@@ -1641,7 +1678,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 27
"iconIdx": 50
},
{
"icon": {
......@@ -1669,7 +1706,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 28
"iconIdx": 51
},
{
"icon": {
......@@ -1697,7 +1734,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 29
"iconIdx": 52
},
{
"icon": {
......@@ -1725,7 +1762,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 30
"iconIdx": 53
},
{
"icon": {
......@@ -1753,7 +1790,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 31
"iconIdx": 54
},
{
"icon": {
......@@ -1781,7 +1818,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 32
"iconIdx": 55
},
{
"icon": {
......@@ -1809,7 +1846,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 33
"iconIdx": 56
},
{
"icon": {
......@@ -1837,7 +1874,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 34
"iconIdx": 57
},
{
"icon": {
......@@ -1865,7 +1902,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 35
"iconIdx": 58
},
{
"icon": {
......@@ -1893,7 +1930,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 36
"iconIdx": 59
},
{
"icon": {
......@@ -1922,7 +1959,7 @@
},
"setIdx": 0,
"setId": 1,
"iconIdx": 37
"iconIdx": 60
}
],
"height": 1024,
......
......@@ -20,6 +20,9 @@
-moz-osx-font-smoothing: grayscale;
}
.h-icon-clipboard:before {
content: "\e90c";
}
.h-icon-hypothesis-logo:before {
content: "\e90b";
}
......
......@@ -181,7 +181,7 @@
</button>
<span class="share-dialog-wrapper" ng-if="!vm.feature('direct_linking')">
<button class="btn btn-clean annotation-action-btn"
ng-click="vm.share($event)">
ng-click="vm.showShareDialog = !vm.showShareDialog">
<i class="h-icon-link btn-icon "></i>
<span class="annotation-action-btn__label">
Link
......@@ -198,45 +198,19 @@
</span>
<span class="share-dialog-wrapper" ng-if="vm.feature('direct_linking')">
<button class="btn btn-clean annotation-action-btn"
ng-click="vm.share($event)">
ng-click="vm.showShareDialog = true">
<i class="h-icon-annotation-share btn-icon "></i>
<span class="annotation-action-btn__label">
Share
</span>
</button>
<span class="share-dialog" ng-click="$event.stopPropagation()">
<span class="share-dialog-target">
<span class="share-dialog-target__label">Share:</span>
<a href="https://twitter.com/intent/tweet?url={{vm.annotationURI}}"
target="_blank"
title="Tweet link"
class="share-dialog-target__icon h-icon-twitter"></a>
<a href="https://www.facebook.com/sharer/sharer.php?u={{vm.annotationURI}}"
target="_blank"
title="Share on Facebook"
class="share-dialog-target__icon h-icon-facebook"></a>
<a href="https://plus.google.com/share?url={{vm.annotationURI}}"
target="_blank"
title="Post on Google Plus"
class="share-dialog-target__icon h-icon-google-plus"></a>
<a href="mailto:?subject=Let's%20Annotate&amp;body={{vm.annotationURI}}"
title="Share via email"
class="share-dialog-target__icon h-icon-mail"></a>
</span>
<input class="share-dialog-link" type="text" value="{{vm.annotationURI}}" readonly>
<span class="share-dialog-msg" ng-if="vm.group() && !vm.group().public && !vm.isPrivate">
<span class="share-dialog-msg__audience">
Group.
</span>
Only group members will be able to view this annotation.
</span>
<span class="share-dialog-msg" ng-if="vm.isPrivate">
<span class="share-dialog-msg__audience">
Only me.
</span>
No one else will be able to view this annotation.
</span>
</span>
<annotation-share-dialog
group="vm.group()"
uri="vm.annotationURI"
is-private="vm.isPrivate"
is-open="vm.showShareDialog"
on-close="vm.showShareDialog = false">
</annotation-share-dialog>
</span>
</div>
</footer>
......
<div class="annotation-share-dialog" ng-class="{'is-open': vm.isOpen}">
<div class="annotation-share-dialog-target">
<span class="annotation-share-dialog-target__label">Share:</span>
<a href="https://twitter.com/intent/tweet?url={{vm.uri}}"
target="_blank"
title="Tweet link"
class="annotation-share-dialog-target__icon h-icon-twitter"></a>
<a href="https://www.facebook.com/sharer/sharer.php?u={{vm.uri}}"
target="_blank"
title="Share on Facebook"
class="annotation-share-dialog-target__icon h-icon-facebook"></a>
<a href="https://plus.google.com/share?url={{vm.uri}}"
target="_blank"
title="Post on Google Plus"
class="annotation-share-dialog-target__icon h-icon-google-plus"></a>
<a href="mailto:?subject=Let's%20Annotate&amp;body={{vm.uri}}"
title="Share via email"
class="annotation-share-dialog-target__icon h-icon-mail"></a>
</div>
<div class="annotation-share-dialog-link" type="text">
<input class="annotation-share-dialog-link__text"
value="{{vm.uri}}" readonly>
<span class="annotation-share-dialog-link__feedback" ng-if="vm.copyToClipboardMessage">
{{vm.copyToClipboardMessage}}
</span>
<button class="btn btn-clean annotation-share-dialog-link__btn"
ng-click="vm.copyToClipboard($event)">
<i class="h-icon-clipboard btn-icon"></i>
</button>
</div>
<div class="annotation-share-dialog-msg" ng-if="vm.group && !vm.group.public && !vm.isPrivate">
<span class="annotation-share-dialog-msg__audience">
Group.
</span>
Only group members will be able to view this annotation.
</div>
<div class="annotation-share-dialog-msg" ng-if="vm.isPrivate">
<span class="annotation-share-dialog-msg__audience">
Only me.
</span>
No one else will be able to view this annotation.
</div>
</div>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment