@ -917,60 +917,79 @@ define([
className : 'primary cp-share-with-friends' ,
className : 'primary cp-share-with-friends' ,
name : Messages . share _withFriends ,
name : Messages . share _withFriends ,
onClick : function ( ) {
onClick : function ( ) {
var href = Hash . getRelativeHref ( linkGetter ( ) ) ;
var href ;
var $friends = $div . find ( '.cp-usergrid-user.cp-selected' ) ;
NThen ( function ( waitFor ) {
$friends . each ( function ( i , el ) {
var w = waitFor ( ) ;
var curve = $ ( el ) . attr ( 'data-curve' ) ;
// linkGetter can be async if this is a burn after reading URL
// Check if the selected element is a friend or a team
var res = linkGetter ( { } , function ( url ) {
if ( curve ) { // Friend
if ( ! url ) {
if ( ! curve || ! friends [ curve ] ) { return ; }
waitFor . abort ( ) ;
var friend = friends [ curve ] ;
return ;
if ( ! friend . notifications || ! friend . curvePublic ) { return ; }
}
common . mailbox . sendTo ( "SHARE_PAD" , {
console . warn ( 'BAR' ) ;
href = url ;
setTimeout ( w ) ;
} ) ;
if ( res && /^http/ . test ( res ) ) {
href = Hash . getRelativeHref ( res ) ;
setTimeout ( w ) ;
return ;
}
} ) . nThen ( function ( ) {
var $friends = $div . find ( '.cp-usergrid-user.cp-selected' ) ;
$friends . each ( function ( i , el ) {
var curve = $ ( el ) . attr ( 'data-curve' ) ;
// Check if the selected element is a friend or a team
if ( curve ) { // Friend
if ( ! curve || ! friends [ curve ] ) { return ; }
var friend = friends [ curve ] ;
if ( ! friend . notifications || ! friend . curvePublic ) { return ; }
common . mailbox . sendTo ( "SHARE_PAD" , {
href : href ,
password : config . password ,
isTemplate : config . isTemplate ,
name : myName ,
title : title
} , {
channel : friend . notifications ,
curvePublic : friend . curvePublic
} ) ;
return ;
}
// Team
var ed = $ ( el ) . attr ( 'data-ed' ) ;
var team = teams [ ed ] ;
if ( ! team ) { return ; }
sframeChan . query ( 'Q_STORE_IN_TEAM' , {
href : href ,
href : href ,
password : config . password ,
password : config . password ,
isTemplate : config . isTemplate ,
path : config . isTemplate ? [ 'template' ] : undefined ,
name : myName ,
title : title ,
title : title
teamId : team . id
} , {
} , function ( err ) {
channel : friend . notifications ,
if ( err ) { return void console . error ( err ) ; }
curvePublic : friend . curvePublic
} ) ;
} ) ;
return ;
}
// Team
var ed = $ ( el ) . attr ( 'data-ed' ) ;
var team = teams [ ed ] ;
if ( ! team ) { return ; }
sframeChan . query ( 'Q_STORE_IN_TEAM' , {
href : href ,
password : config . password ,
path : config . isTemplate ? [ 'template' ] : undefined ,
title : title ,
teamId : team . id
} , function ( err ) {
if ( err ) { return void console . error ( err ) ; }
} ) ;
} ) ;
} ) ;
UI . findCancelButton ( ) . click ( ) ;
UI . findCancelButton ( ) . click ( ) ;
// Update the "recently shared with" array:
// Update the "recently shared with" array:
// Get the selected curves
// Get the selected curves
var curves = $friends . toArray ( ) . map ( function ( el ) {
var curves = $friends . toArray ( ) . map ( function ( el ) {
return ( $ ( el ) . attr ( 'data-curve' ) || '' ) . slice ( 0 , 8 ) ;
return ( $ ( el ) . attr ( 'data-curve' ) || '' ) . slice ( 0 , 8 ) ;
} ) . filter ( function ( x ) { return x ; } ) ;
} ) . filter ( function ( x ) { return x ; } ) ;
// Prepend them to the "order" array
// Prepend them to the "order" array
Array . prototype . unshift . apply ( order , curves ) ;
Array . prototype . unshift . apply ( order , curves ) ;
order = Util . deduplicateString ( order ) ;
order = Util . deduplicateString ( order ) ;
// Make sure we don't have "old" friends and save
// Make sure we don't have "old" friends and save
order = order . filter ( function ( curve ) {
order = order . filter ( function ( curve ) {
return smallCurves . indexOf ( curve ) !== - 1 ;
return smallCurves . indexOf ( curve ) !== - 1 ;
} ) ;
common . setAttribute ( [ 'general' , 'share-friends' ] , order ) ;
if ( onShare ) {
onShare . fire ( ) ;
}
} ) ;
} ) ;
common . setAttribute ( [ 'general' , 'share-friends' ] , order ) ;
if ( onShare ) {
onShare . fire ( ) ;
}
} ,
} ,
keys : [ 13 ]
keys : [ 13 ]
} ;
} ;
@ -1049,6 +1068,29 @@ define([
}
}
} ;
} ;
var makeBurnAfterReadingUrl = function ( common , href , channel , cb ) {
var keyPair = Hash . generateSignPair ( ) ;
var parsed = Hash . parsePadUrl ( href ) ;
console . error ( href , parsed ) ;
var newHref = parsed . getUrl ( {
ownerKey : keyPair . safeSignKey
} ) ;
var sframeChan = common . getSframeChannel ( ) ;
NThen ( function ( waitFor ) {
sframeChan . query ( 'Q_SET_PAD_METADATA' , {
channel : channel ,
command : 'ADD_OWNERS' ,
value : [ keyPair . validateKey ]
} , waitFor ( function ( err ) {
if ( err ) {
waitFor . abort ( ) ;
UI . warn ( Messages . error ) ;
}
} ) ) ;
} ) . nThen ( function ( ) {
cb ( newHref ) ;
} ) ;
} ;
UIElements . createShareModal = function ( config ) {
UIElements . createShareModal = function ( config ) {
var origin = config . origin ;
var origin = config . origin ;
var pathname = config . pathname ;
var pathname = config . pathname ;
@ -1078,6 +1120,7 @@ define([
var parsed = Hash . parsePadUrl ( pathname ) ;
var parsed = Hash . parsePadUrl ( pathname ) ;
var canPresent = [ 'code' , 'slide' ] . indexOf ( parsed . type ) !== - 1 ;
var canPresent = [ 'code' , 'slide' ] . indexOf ( parsed . type ) !== - 1 ;
var burnAfterReading ;
var rights = h ( 'div.msg.cp-inline-radio-group' , [
var rights = h ( 'div.msg.cp-inline-radio-group' , [
h ( 'label' , Messages . share _linkAccess ) ,
h ( 'label' , Messages . share _linkAccess ) ,
h ( 'div.radio-group' , [
h ( 'div.radio-group' , [
@ -1086,9 +1129,33 @@ define([
canPresent ? UI . createRadio ( 'accessRights' , 'cp-share-present' ,
canPresent ? UI . createRadio ( 'accessRights' , 'cp-share-present' ,
Messages . share _linkPresent , false , { mark : { tabindex : 1 } } ) : undefined ,
Messages . share _linkPresent , false , { mark : { tabindex : 1 } } ) : undefined ,
UI . createRadio ( 'accessRights' , 'cp-share-editable-true' ,
UI . createRadio ( 'accessRights' , 'cp-share-editable-true' ,
Messages . share _linkEdit , false , { mark : { tabindex : 1 } } ) ] )
Messages . share _linkEdit , false , { mark : { tabindex : 1 } } ) ] ) ,
burnAfterReading = hashes . viewHash ? UI . createRadio ( 'accessRights' , 'cp-share-bar' , Messages . burnAfterReading _linkBurnAfterReading ||
'View once and self-destruct' , false , { mark : { tabindex : 1 } , label : { style : "display: none;" } } ) : undefined // XXX temp KEY
] ) ;
] ) ;
// Burn after reading
// Check if we are an owner of this pad. If we are, we can show the burn after reading option.
// When BAR is selected, display a red message indicating the consequence and add
// the options to generate the BAR url
var barAlert = h ( 'div.alert.alert-danger.cp-alertify-bar-selected' , {
style : 'display: none;'
} , Messages . burnAfterReading _warningLink || " You have set this pad to self-destruct. Once a recipient opens this pad, it will be permanently deleted from the server." ) ; // XXX temp KEY
var channel = Hash . getSecrets ( 'pad' , hash , config . password ) . channel ;
common . getPadMetadata ( {
channel : channel
} , function ( obj ) {
if ( ! obj || obj . error ) { return ; }
var priv = common . getMetadataMgr ( ) . getPrivateData ( ) ;
// Not an owner: don't display the burn after reading option
if ( ! Array . isArray ( obj . owners ) || obj . owners . indexOf ( priv . edPublic ) === - 1 ) {
$ ( burnAfterReading ) . remove ( ) ;
return ;
}
// When the burn after reading option is selected, transform the modal buttons
$ ( burnAfterReading ) . show ( ) ;
} ) ;
var $rights = $ ( rights ) ;
var $rights = $ ( rights ) ;
var saveValue = function ( ) {
var saveValue = function ( ) {
@ -1100,13 +1167,25 @@ define([
} ) ;
} ) ;
} ;
} ;
var getLinkValue = function ( initValue ) {
var burnAfterReadingUrl ;
var getLinkValue = function ( initValue , cb ) {
var val = initValue || { } ;
var val = initValue || { } ;
var edit = val . edit !== undefined ? val . edit : Util . isChecked ( $rights . find ( '#cp-share-editable-true' ) ) ;
var edit = val . edit !== undefined ? val . edit : Util . isChecked ( $rights . find ( '#cp-share-editable-true' ) ) ;
var embed = val . embed ;
var embed = val . embed ;
var present = val . present !== undefined ? val . present : Util . isChecked ( $rights . find ( '#cp-share-present' ) ) ;
var present = val . present !== undefined ? val . present : Util . isChecked ( $rights . find ( '#cp-share-present' ) ) ;
var burnAfterReading = Util . isChecked ( $rights . find ( '#cp-share-bar' ) ) ;
if ( burnAfterReading && ! burnAfterReadingUrl ) {
if ( cb ) { // Called from the contacts tab, "share" button
var barHref = origin + pathname + '#' + ( hashes . viewHash || hashes . editHash ) ;
return makeBurnAfterReadingUrl ( common , barHref , channel , function ( url ) {
cb ( url ) ;
} ) ;
}
return Messages . burnAfterReading _generateLink || 'Click on the button below to generate a link' ; // XXX temp KEY
}
var hash = ( ! hashes . viewHash || ( edit && hashes . editHash ) ) ? hashes . editHash : hashes . viewHash ;
var hash = ( ! hashes . viewHash || ( edit && hashes . editHash ) ) ? hashes . editHash : hashes . viewHash ;
var href = origin + pathname + '#' + hash ;
var href = burnAfterReading ? burnAfterReadingUrl : ( origin + pathname + '#' + hash ) ;
var parsed = Hash . parsePadUrl ( href ) ;
var parsed = Hash . parsePadUrl ( href ) ;
return origin + parsed . getUrl ( { embed : embed , present : present } ) ;
return origin + parsed . getUrl ( { embed : embed , present : present } ) ;
} ;
} ;
@ -1160,8 +1239,8 @@ define([
} ) ;
} ) ;
} ) ;
} ) ;
linkContent . push ( $ ( barAlert ) . clone ( ) [ 0 ] ) ; // Burn after reading
var link = h ( 'div.cp-share-modal' , linkContent ) ;
var link = h ( 'div.cp-share-modal' , linkContent ) ;
var $link = $ ( link ) ;
var $link = $ ( link ) ;
@ -1169,7 +1248,7 @@ define([
var linkButtons = [
var linkButtons = [
makeCancelButton ( ) ,
makeCancelButton ( ) ,
! config . sharedFolder && {
! config . sharedFolder && {
className : 'secondary ',
className : 'secondary cp-nobar ',
name : Messages . share _linkOpen ,
name : Messages . share _linkOpen ,
onClick : function ( ) {
onClick : function ( ) {
saveValue ( ) ;
saveValue ( ) ;
@ -1180,9 +1259,8 @@ define([
return true ;
return true ;
} ,
} ,
keys : [ [ 13 , 'ctrl' ] ]
keys : [ [ 13 , 'ctrl' ] ]
} ,
} , {
{
className : 'primary cp-nobar' ,
className : 'primary' ,
name : Messages . share _linkCopy ,
name : Messages . share _linkCopy ,
onClick : function ( ) {
onClick : function ( ) {
saveValue ( ) ;
saveValue ( ) ;
@ -1193,26 +1271,26 @@ define([
if ( success ) { UI . log ( Messages . shareSuccess ) ; }
if ( success ) { UI . log ( Messages . shareSuccess ) ; }
} ,
} ,
keys : [ 13 ]
keys : [ 13 ]
} , {
className : 'primary cp-bar' ,
name : 'GENERATE LINK' ,
onClick : function ( ) {
var barHref = origin + pathname + '#' + ( hashes . viewHash || hashes . editHash ) ;
makeBurnAfterReadingUrl ( common , barHref , channel , function ( url ) {
burnAfterReadingUrl = url ;
$rights . find ( 'input[type="radio"]' ) . trigger ( 'change' ) ;
} ) ;
return true ;
} ,
keys : [ ]
}
}
] ;
] ;
// update values for link preview when radio btns change
$link . find ( '#cp-share-link-preview' ) . val ( getLinkValue ( ) ) ;
$rights . find ( 'input[type="radio"]' ) . on ( 'change' , function ( ) {
$link . find ( '#cp-share-link-preview' ) . val ( getLinkValue ( {
embed : Util . isChecked ( $link . find ( '#cp-share-embed' ) )
} ) ) ;
} ) ;
$link . find ( 'input[type="checkbox"]' ) . on ( 'change' , function ( ) {
$link . find ( '#cp-share-link-preview' ) . val ( getLinkValue ( {
embed : Util . isChecked ( $link . find ( '#cp-share-embed' ) )
} ) ) ;
} ) ;
var frameLink = UI . dialog . customModal ( link , {
var frameLink = UI . dialog . customModal ( link , {
buttons : linkButtons ,
buttons : linkButtons ,
onClose : config . onClose ,
onClose : config . onClose ,
} ) ;
} ) ;
$ ( frameLink ) . find ( '.cp-bar' ) . hide ( ) ;
// Share with contacts tab
// Share with contacts tab
@ -1240,10 +1318,17 @@ define([
] ) ) ;
] ) ) ;
}
}
$ ( contactsContent ) . append ( $ ( barAlert ) . clone ( ) ) ; // Burn after reading
var contactButtons = friendsObject . buttons ;
var contactButtons = friendsObject . buttons ;
contactButtons . unshift ( makeCancelButton ( ) ) ;
contactButtons . unshift ( makeCancelButton ( ) ) ;
var onShowContacts = function ( ) {
if ( ! hasFriends ) {
$rights . hide ( ) ;
}
} ;
var frameContacts = UI . dialog . customModal ( contactsContent , {
var frameContacts = UI . dialog . customModal ( contactsContent , {
buttons : contactButtons ,
buttons : contactButtons ,
onClose : config . onClose ,
onClose : config . onClose ,
@ -1282,26 +1367,60 @@ define([
keys : [ 13 ]
keys : [ 13 ]
} ] ;
} ] ;
var onShowEmbed = function ( ) {
$rights . find ( '#cp-share-bar' ) . closest ( 'label' ) . hide ( ) ;
$rights . find ( 'input[type="radio"]:enabled' ) . first ( ) . prop ( 'checked' , 'checked' ) ;
$rights . find ( 'input[type="radio"]' ) . trigger ( 'change' ) ;
} ;
var embed = h ( 'div.cp-share-modal' , embedContent ) ;
var embed = h ( 'div.cp-share-modal' , embedContent ) ;
var $embed = $ ( embed ) ;
var $embed = $ ( embed ) ;
// update values for link preview when radio btns change
var frameEmbed = UI . dialog . customModal ( embed , {
buttons : embedButtons ,
onClose : config . onClose ,
} ) ;
// update values for link and embed preview when radio btns change
$embed . find ( '#cp-embed-link-preview' ) . val ( getEmbedValue ( ) ) ;
$embed . find ( '#cp-embed-link-preview' ) . val ( getEmbedValue ( ) ) ;
$link . find ( '#cp-share-link-preview' ) . val ( getLinkValue ( ) ) ;
$rights . find ( 'input[type="radio"]' ) . on ( 'change' , function ( ) {
$rights . find ( 'input[type="radio"]' ) . on ( 'change' , function ( ) {
$link . find ( '#cp-share-link-preview' ) . val ( getLinkValue ( {
embed : Util . isChecked ( $link . find ( '#cp-share-embed' ) )
} ) ) ;
// Hide or show the burn after reading alert
if ( Util . isChecked ( $rights . find ( '#cp-share-bar' ) ) && ! burnAfterReadingUrl ) {
$ ( '.cp-alertify-bar-selected' ) . show ( ) ;
// Show burn after reading button
$ ( '.alertify' ) . find ( '.cp-bar' ) . show ( ) ;
$ ( '.alertify' ) . find ( '.cp-nobar' ) . hide ( ) ;
return ;
}
$embed . find ( '#cp-embed-link-preview' ) . val ( getEmbedValue ( ) ) ;
$embed . find ( '#cp-embed-link-preview' ) . val ( getEmbedValue ( ) ) ;
// Hide burn after reading button
$ ( '.alertify' ) . find ( '.cp-nobar' ) . show ( ) ;
$ ( '.alertify' ) . find ( '.cp-bar' ) . hide ( ) ;
$ ( '.cp-alertify-bar-selected' ) . hide ( ) ;
} ) ;
} ) ;
$link . find ( 'input[type="checkbox"]' ) . on ( 'change' , function ( ) {
var frameEmbed = UI . dialog . customModal ( embed , {
$link . find ( '#cp-share-link-preview' ) . val ( getLinkValue ( {
buttons : embedButtons ,
embed : Util . isChecked ( $link . find ( '#cp-share-embed' ) )
onClose : config . onClose ,
} ) ) ;
} ) ;
} ) ;
// Create modal
// Create modal
var resetTab = function ( ) {
$rights . show ( ) ;
$rights . find ( 'label.cp-radio' ) . show ( ) ;
} ;
var tabs = [ {
var tabs = [ {
title : Messages . share _contactCategory ,
title : Messages . share _contactCategory ,
icon : "fa fa-address-book" ,
icon : "fa fa-address-book" ,
content : frameContacts ,
content : frameContacts ,
active : hasFriends
active : hasFriends ,
onShow : onShowContacts ,
onHide : resetTab
} , {
} , {
title : Messages . share _linkCategory ,
title : Messages . share _linkCategory ,
icon : "fa fa-link" ,
icon : "fa fa-link" ,
@ -1310,7 +1429,9 @@ define([
} , {
} , {
title : Messages . share _embedCategory ,
title : Messages . share _embedCategory ,
icon : "fa fa-code" ,
icon : "fa fa-code" ,
content : frameEmbed
content : frameEmbed ,
onShow : onShowEmbed ,
onHide : resetTab
} ] ;
} ] ;
if ( typeof ( AppConfig . customizeShareOptions ) === 'function' ) {
if ( typeof ( AppConfig . customizeShareOptions ) === 'function' ) {
AppConfig . customizeShareOptions ( hashes , tabs , {
AppConfig . customizeShareOptions ( hashes , tabs , {
@ -3866,6 +3987,7 @@ define([
UIElements . onServerError = function ( common , err , toolbar , cb ) {
UIElements . onServerError = function ( common , err , toolbar , cb ) {
if ( [ "EDELETED" , "EEXPIRED" ] . indexOf ( err . type ) === - 1 ) { return ; }
if ( [ "EDELETED" , "EEXPIRED" ] . indexOf ( err . type ) === - 1 ) { return ; }
var priv = common . getMetadataMgr ( ) . getPrivateData ( ) ;
var msg = err . type ;
var msg = err . type ;
if ( err . type === 'EEXPIRED' ) {
if ( err . type === 'EEXPIRED' ) {
msg = Messages . expiredError ;
msg = Messages . expiredError ;
@ -3873,11 +3995,14 @@ define([
msg += Messages . errorCopy ;
msg += Messages . errorCopy ;
}
}
} else if ( err . type === 'EDELETED' ) {
} else if ( err . type === 'EDELETED' ) {
if ( priv . burnAfterReading ) { return void cb ( ) ; }
msg = Messages . deletedError ;
msg = Messages . deletedError ;
if ( err . loaded ) {
if ( err . loaded ) {
msg += Messages . errorCopy ;
msg += Messages . errorCopy ;
}
}
}
}
var sframeChan = common . getSframeChannel ( ) ;
sframeChan . event ( 'EV_SHARE_OPEN' , { hidden : true } ) ;
if ( toolbar && typeof toolbar . deleted === "function" ) { toolbar . deleted ( ) ; }
if ( toolbar && typeof toolbar . deleted === "function" ) { toolbar . deleted ( ) ; }
UI . errorLoadingScreen ( msg , true , true ) ;
UI . errorLoadingScreen ( msg , true , true ) ;
( cb || function ( ) { } ) ( ) ;
( cb || function ( ) { } ) ( ) ;
@ -3922,6 +4047,26 @@ define([
$password . find ( '.cp-password-input' ) . focus ( ) ;
$password . find ( '.cp-password-input' ) . focus ( ) ;
} ;
} ;
UIElements . displayBurnAfterReadingPage = function ( common , cb ) {
var info = h ( 'p.cp-password-info' , Messages . burnAfterReading _warning || 'This document will self-destruct as soon as you open it. It will be removed form the server, once you close this window you will not be able to access it again. If you are not ready to proceed you can close this window and come back later. ' ) ; // XXX temp KEY
var button = h ( 'button.primary' , Messages . burnAfterReading _proceed || 'view and delete' ) ; // XXX temp KEY
$ ( button ) . on ( 'click' , function ( ) {
cb ( ) ;
} ) ;
var block = h ( 'div#cp-loading-burn-after-reading' , [
info ,
button
] ) ;
UI . errorLoadingScreen ( block ) ;
} ;
UIElements . getBurnAfterReadingWarning = function ( common ) {
var priv = common . getMetadataMgr ( ) . getPrivateData ( ) ;
if ( ! priv . burnAfterReading ) { return ; }
return h ( 'div.alert.alert-danger.cp-burn-after-reading' , Messages . burnAfterReading _warningDeleted || 'This pad has been deleted from the server, once you close this window you will not be able to access it again.' ) ; // XXX temp KEY
} ;
var crowdfundingState = false ;
var crowdfundingState = false ;
UIElements . displayCrowdfunding = function ( common ) {
UIElements . displayCrowdfunding = function ( common ) {
if ( crowdfundingState ) { return ; }
if ( crowdfundingState ) { return ; }
@ -3979,6 +4124,9 @@ define([
if ( data && data . stored ) { return ; } // We won't display the popup for dropped files
if ( data && data . stored ) { return ; } // We won't display the popup for dropped files
var priv = common . getMetadataMgr ( ) . getPrivateData ( ) ;
var priv = common . getMetadataMgr ( ) . getPrivateData ( ) ;
// This pad will be deleted automatically, it shouldn't be stored
if ( priv . burnAfterReading ) { return ; }
var typeMsg = priv . pathname . indexOf ( '/file/' ) !== - 1 ? Messages . autostore _file :
var typeMsg = priv . pathname . indexOf ( '/file/' ) !== - 1 ? Messages . autostore _file :
priv . pathname . indexOf ( '/drive/' ) !== - 1 ? Messages . autostore _sf :
priv . pathname . indexOf ( '/drive/' ) !== - 1 ? Messages . autostore _sf :
Messages . autostore _pad ;
Messages . autostore _pad ;