Implement Email button

Allow optional GMT conversion
This commit is contained in:
Haocen Xu 2019-08-21 17:36:22 -04:00
parent 8e874dbea3
commit 8717d5cd9a
No known key found for this signature in database
GPG Key ID: 3F0D955A0F6AD729
5 changed files with 183 additions and 7 deletions

BIN
img/icon_email.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 B

View File

@ -411,6 +411,45 @@ jQuery.PrivateBin = (function($, RawDeflate) {
baseUri = null;
};
/**
* calculate expiration date
*
* @name Helper.calculateExpirationDate
* @function
* @param {Date} initialDate - may not be empty
* @param {string|number} expirationDisplayStringOrSecondsToExpire - may not be empty
* @return {Date}
*/
me.calculateExpirationDate = function(initialDate, expirationDisplayStringOrSecondsToExpire) {
let expirationDate = new Date(initialDate);
const expirationDisplayStringToSecondsDict = {
'5min': 300,
'10min': 600,
'1hour': 3500,
'1day': 86400,
'1week': 604800,
'1month': 2592000,
'1year': 31536000,
'never': 0
};
let secondsToExpiration = expirationDisplayStringOrSecondsToExpire;
if (typeof expirationDisplayStringOrSecondsToExpire === 'string') {
secondsToExpiration = expirationDisplayStringToSecondsDict[expirationDisplayStringOrSecondsToExpire];
}
if (typeof secondsToExpiration !== 'number') {
throw new Error('Cannot calculate expiration date.');
}
if (secondsToExpiration === 0) {
return null;
}
expirationDate = expirationDate.setUTCSeconds(expirationDate.getUTCSeconds() + secondsToExpiration);
return expirationDate;
}
return me;
})();
@ -3292,9 +3331,10 @@ jQuery.PrivateBin = (function($, RawDeflate) {
$passwordInput,
$rawTextButton,
$qrCodeLink,
$emailLink,
$sendButton,
$retryButton,
pasteExpiration = '1week',
pasteExpiration = null,
retryButtonCallback;
/**
@ -3502,6 +3542,64 @@ jQuery.PrivateBin = (function($, RawDeflate) {
$('#qrcode-display').html(qrCanvas);
}
/**
* Send Email with current paste (URL).
*
* @name TopNav.sendEmail
* @private
* @function
* @param {Date|null} expirationDate date of expiration
* @param {bool} isBurnafterreading whether it is burn after reading
*/
function sendEmail(expirationDate, isBurnafterreading)
{
const EOL = '\n';
const BULLET = ' - ';
let emailBody = '';
const expirationDateRoundedToSecond = new Date(expirationDate);
// round down at least 30 seconds to make up for the delay of request
expirationDateRoundedToSecond.setUTCSeconds(
expirationDateRoundedToSecond.getUTCSeconds() - 30
);
expirationDateRoundedToSecond.setUTCSeconds(0);
const expirationDateString = window.confirm(
I18n._('Recipient may become aware of your timezone, convert time to GMT?')
) ? expirationDateRoundedToSecond.toUTCString() : expirationDateRoundedToSecond.toLocaleString();
if (expirationDate !== null || isBurnafterreading) {
emailBody += I18n._('Notice:');
emailBody += EOL;
if (expirationDate !== null) {
emailBody += EOL;
emailBody += BULLET;
emailBody += I18n._(
'This link will expire after %s.',
expirationDateString
);
}
if (isBurnafterreading) {
emailBody += EOL;
emailBody += BULLET;
emailBody += I18n._(
'This link can only be accessed once, do not use back or refresh button in your browser.'
);
}
emailBody += EOL;
emailBody += EOL;
}
emailBody += I18n._('Link:');
emailBody += EOL;
emailBody += `${window.location.href}`;
window.open(
`mailto:?body=${encodeURIComponent(emailBody)}`,
'_self',
'noopener, noreferrer'
);
}
/**
* Shows all navigation elements for viewing an existing paste
*
@ -3538,6 +3636,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
$newButton.addClass('hidden');
$rawTextButton.addClass('hidden');
$qrCodeLink.addClass('hidden');
me.hideEmailbutton();
viewButtonsDisplayed = false;
};
@ -3635,6 +3734,47 @@ jQuery.PrivateBin = (function($, RawDeflate) {
$retryButton.addClass('hidden');
}
/**
* show the "email" button
*
* @name TopNav.showEmailbutton
* @function
* @param {function} optionalRemainingTimeInSeconds
*/
me.showEmailButton = function(optionalRemainingTimeInSeconds)
{
try {
// we cache expiration date in closure to avoid inaccurate expiration datetime
const expirationDate = Helper.calculateExpirationDate(new Date(), optionalRemainingTimeInSeconds || TopNav.getExpiration());
const isBurnafterreading = TopNav.getBurnAfterReading();
$emailLink.removeClass('hidden');
$emailLink.off('click.sendEmail');
$emailLink.on('click.sendEmail', function(expirationDate, isBurnafterreading) {
return function() {
sendEmail(expirationDate, isBurnafterreading);
};
} (expirationDate, isBurnafterreading));
} catch (error) {
console.error(error);
Alert.showError(
I18n._('Cannot calculate expiration date.')
);
}
}
/**
* hide the "email" button
*
* @name TopNav.hideEmailbutton
* @function
*/
me.hideEmailbutton = function()
{
$emailLink.addClass('hidden');
$emailLink.off('click.sendEmail');
}
/**
* only hides the clone button
*
@ -3657,6 +3797,30 @@ jQuery.PrivateBin = (function($, RawDeflate) {
$rawTextButton.addClass('hidden');
};
/**
* only hides the qr code button
*
* @name TopNav.hideQrCodeButton
* @function
*/
me.hideQrCodeButton = function()
{
$qrCodeLink.addClass('hidden');
}
/**
* hide all irrelevant buttons when viewing burn after reading paste
*
* @name TopNav.hideBurnAfterReadingButtons
* @function
*/
me.hideBurnAfterReadingButtons = function()
{
me.hideCloneButton();
me.hideQrCodeButton();
me.hideEmailbutton();
}
/**
* hides the file selector in attachment
*
@ -3744,7 +3908,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
/**
* returns the state of the burn after reading checkbox
*
* @name TopNav.getExpiration
* @name TopNav.getBurnAfterReading
* @function
* @return {bool}
*/
@ -3873,6 +4037,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
$retryButton = $('#retrybutton');
$sendButton = $('#sendbutton');
$qrCodeLink = $('#qrcodelink');
$emailLink = $('#emaillink');
// bootstrap template drop down
$('#language ul.dropdown-menu li a').click(setLanguage);
@ -4219,6 +4384,10 @@ jQuery.PrivateBin = (function($, RawDeflate) {
history.pushState({type: 'newpaste'}, document.title, url);
TopNav.showViewButtons();
// this cannot be grouped with showViewButtons due to remaining time calculation
TopNav.showEmailButton();
TopNav.hideRawButton();
Editor.hide();
@ -4684,7 +4853,10 @@ jQuery.PrivateBin = (function($, RawDeflate) {
// discourage cloning (it cannot really be prevented)
if (paste.isBurnAfterReadingEnabled()) {
TopNav.hideCloneButton();
TopNav.hideBurnAfterReadingButtons();
} else {
// we have to pass in remaining_time here
TopNav.showEmailButton(paste.getTimeToLive());
}
})
.catch((err) => {

View File

@ -326,7 +326,7 @@ describe('TopNav', function () {
'returns the currently selected expiration date',
function () {
$.PrivateBin.TopNav.init();
assert.ok($.PrivateBin.TopNav.getExpiration() === '1week');
assert.ok($.PrivateBin.TopNav.getExpiration() === null);
}
);
});

View File

@ -71,7 +71,7 @@ if ($MARKDOWN):
endif;
?>
<script type="text/javascript" data-cfasync="false" src="js/purify-1.0.11.js" integrity="sha512-p7UyJuyBkhMcMgE4mDsgK0Lz70OvetLefua1oXs1OujWv9gOxh4xy8InFux7bZ4/DAZsTmO4rgVwZW9BHKaTaw==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-86VTqw2HsaCQ0DAunK2MH68P+8RLbbaK7HZP8nwDtwNoF44usxDCptmD8TC+zwQc7HM46AkrvVFb3ZkIb6VhMQ==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-8251Z4qH1bUpYvy/+jWLtohx3xt0JE7M0/l38TZzB+RpEGGSKZZF0Ii4sFCj6jIXOKUyKAlvAl84rRU4mu8SNw==" crossorigin="anonymous"></script>
<!--[if IE]>
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;}</style>
<![endif]-->
@ -173,6 +173,9 @@ endif;
<button id="rawtextbutton" type="button" class="hidden btn btn-<?php echo $isDark ? 'warning' : 'default'; ?> navbar-btn">
<span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> <?php echo I18n::_('Raw text'), PHP_EOL; ?>
</button>
<button id="emaillink" type="button" class="hidden btn btn-<?php echo $isDark ? 'warning' : 'default'; ?> navbar-btn">
<span class="glyphicon glyphicon-envelope" aria-hidden="true"></span> <?php echo I18n::_('Email'), PHP_EOL; ?>
</button>
<?php
if ($QRCODE):
?>
@ -561,4 +564,4 @@ if ($FILEUPLOAD):
endif;
?>
</body>
</html>
</html>

View File

@ -49,7 +49,7 @@ if ($MARKDOWN):
endif;
?>
<script type="text/javascript" data-cfasync="false" src="js/purify-1.0.11.js" integrity="sha512-p7UyJuyBkhMcMgE4mDsgK0Lz70OvetLefua1oXs1OujWv9gOxh4xy8InFux7bZ4/DAZsTmO4rgVwZW9BHKaTaw==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-86VTqw2HsaCQ0DAunK2MH68P+8RLbbaK7HZP8nwDtwNoF44usxDCptmD8TC+zwQc7HM46AkrvVFb3ZkIb6VhMQ==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-8251Z4qH1bUpYvy/+jWLtohx3xt0JE7M0/l38TZzB+RpEGGSKZZF0Ii4sFCj6jIXOKUyKAlvAl84rRU4mu8SNw==" crossorigin="anonymous"></script>
<!--[if IE]>
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;}</style>
<![endif]-->
@ -105,6 +105,7 @@ endif;
<button id="sendbutton" class="hidden"><img src="img/icon_send.png" width="18" height="15" alt="" /><?php echo I18n::_('Send'); ?></button>
<button id="clonebutton" class="hidden"><img src="img/icon_clone.png" width="15" height="17" alt="" /><?php echo I18n::_('Clone'); ?></button>
<button id="rawtextbutton" class="hidden"><img src="img/icon_raw.png" width="15" height="15" alt="" /><?php echo I18n::_('Raw text'); ?></button>
<button id="emaillink" class="hidden"><img src="img/icon_email.png" width="15" height="15" alt="" /><?php echo I18n::_('Email'); ?></button>
<?php
if ($QRCODE):
?>