mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Added Google Viewer Integration (Preview Microsoft Word, Excel and PowerPoint files)
This commit is contained in:
parent
1638b55411
commit
139f412b6a
15 changed files with 254 additions and 42 deletions
|
|
@ -117,6 +117,22 @@
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AbstractApp.prototype.googlePreviewSupportedCache = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
AbstractApp.prototype.googlePreviewSupported = function ()
|
||||||
|
{
|
||||||
|
if (null === this.googlePreviewSupportedCache)
|
||||||
|
{
|
||||||
|
this.googlePreviewSupportedCache = !!Settings.settingsGet('AllowGoogleSocial') &&
|
||||||
|
!!Settings.settingsGet('AllowGoogleSocialPreview');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.googlePreviewSupportedCache;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} sTitle
|
* @param {string} sTitle
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,15 @@
|
||||||
return this.sServer + '/Raw/' + this.sSubQuery + this.sSpecSuffix + '/ViewAsPlain/' + sDownload;
|
return this.sServer + '/Raw/' + this.sSubQuery + this.sSpecSuffix + '/ViewAsPlain/' + sDownload;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} sDownload
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
Links.prototype.attachmentFramed = function (sDownload)
|
||||||
|
{
|
||||||
|
return this.sServer + '/Raw' + this.sSubQuery + this.sSpecSuffix + '/FramedView/' + sDownload;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1093,10 +1093,19 @@
|
||||||
oData.googleEnable = ko.observable(false);
|
oData.googleEnable = ko.observable(false);
|
||||||
oData.googleEnable.auth = ko.observable(false);
|
oData.googleEnable.auth = ko.observable(false);
|
||||||
oData.googleEnable.drive = ko.observable(false);
|
oData.googleEnable.drive = ko.observable(false);
|
||||||
|
oData.googleEnable.preview = ko.observable(false);
|
||||||
oData.googleClientID = ko.observable('');
|
oData.googleClientID = ko.observable('');
|
||||||
oData.googleClientSecret = ko.observable('');
|
oData.googleClientSecret = ko.observable('');
|
||||||
oData.googleApiKey = ko.observable('');
|
oData.googleApiKey = ko.observable('');
|
||||||
|
|
||||||
|
oData.googleEnable.requireClientSettings = ko.computed(function () {
|
||||||
|
return oData.googleEnable() && (oData.googleEnable.auth() || oData.googleEnable.drive());
|
||||||
|
});
|
||||||
|
|
||||||
|
oData.googleEnable.requireApiKey = ko.computed(function () {
|
||||||
|
return oData.googleEnable() && oData.googleEnable.drive();
|
||||||
|
});
|
||||||
|
|
||||||
oData.dropboxEnable = ko.observable(false);
|
oData.dropboxEnable = ko.observable(false);
|
||||||
oData.dropboxApiKey = ko.observable('');
|
oData.dropboxApiKey = ko.observable('');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
this.value = oParams.value || '';
|
this.value = oParams.value || '';
|
||||||
this.size = oParams.size || 0;
|
this.size = oParams.size || 0;
|
||||||
this.label = oParams.label || '';
|
this.label = oParams.label || '';
|
||||||
this.enable = oParams.enable || true;
|
this.enable = Utils.isUnd(oParams.enable) ? true : oParams.enable;
|
||||||
this.trigger = oParams.trigger && oParams.trigger.subscribe ? oParams.trigger : null;
|
this.trigger = oParams.trigger && oParams.trigger.subscribe ? oParams.trigger : null;
|
||||||
this.placeholder = oParams.placeholder || '';
|
this.placeholder = oParams.placeholder || '';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
this.folder = '';
|
this.folder = '';
|
||||||
this.uid = '';
|
this.uid = '';
|
||||||
this.mimeIndex = '';
|
this.mimeIndex = '';
|
||||||
|
this.framed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_.extend(AttachmentModel.prototype, AbstractModel.prototype);
|
_.extend(AttachmentModel.prototype, AbstractModel.prototype);
|
||||||
|
|
@ -62,6 +63,7 @@
|
||||||
AttachmentModel.prototype.folder = '';
|
AttachmentModel.prototype.folder = '';
|
||||||
AttachmentModel.prototype.uid = '';
|
AttachmentModel.prototype.uid = '';
|
||||||
AttachmentModel.prototype.mimeIndex = '';
|
AttachmentModel.prototype.mimeIndex = '';
|
||||||
|
AttachmentModel.prototype.framed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {AjaxJsonAttachment} oJsonAttachment
|
* @param {AjaxJsonAttachment} oJsonAttachment
|
||||||
|
|
@ -83,6 +85,7 @@
|
||||||
this.folder = oJsonAttachment.Folder;
|
this.folder = oJsonAttachment.Folder;
|
||||||
this.uid = oJsonAttachment.Uid;
|
this.uid = oJsonAttachment.Uid;
|
||||||
this.mimeIndex = oJsonAttachment.MimeIndex;
|
this.mimeIndex = oJsonAttachment.MimeIndex;
|
||||||
|
this.framed = !!oJsonAttachment.Framed;
|
||||||
|
|
||||||
this.friendlySize = Utils.friendlySize(this.estimatedSize);
|
this.friendlySize = Utils.friendlySize(this.estimatedSize);
|
||||||
this.cidWithOutTags = this.cid.replace(/^<+/, '').replace(/>+$/, '');
|
this.cidWithOutTags = this.cid.replace(/^<+/, '').replace(/>+$/, '');
|
||||||
|
|
@ -120,6 +123,15 @@
|
||||||
return Globals.bAllowPdfPreview && 'application/pdf' === this.mimeType;
|
return Globals.bAllowPdfPreview && 'application/pdf' === this.mimeType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
AttachmentModel.prototype.isFramed = function ()
|
||||||
|
{
|
||||||
|
return this.framed && (Globals.__APP__ && Globals.__APP__.googlePreviewSupported()) &&
|
||||||
|
!this.isPdf() && !this.isText() && !this.isImage();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
|
|
@ -136,6 +148,14 @@
|
||||||
return Links.attachmentPreview(this.download);
|
return Links.attachmentPreview(this.download);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
AttachmentModel.prototype.linkFramed = function ()
|
||||||
|
{
|
||||||
|
return Links.attachmentFramed(this.download);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
'AdminSettingsSecurity', 'Security', 'security');
|
'AdminSettingsSecurity', 'Security', 'security');
|
||||||
|
|
||||||
kn.addSettingsViewModel(require('Settings/Admin/Social'),
|
kn.addSettingsViewModel(require('Settings/Admin/Social'),
|
||||||
'AdminSettingsSocial', 'Social', 'social');
|
'AdminSettingsSocial', 'Integrations', 'integrations');
|
||||||
|
|
||||||
kn.addSettingsViewModel(require('Settings/Admin/Plugins'),
|
kn.addSettingsViewModel(require('Settings/Admin/Plugins'),
|
||||||
'AdminSettingsPlugins', 'Plugins', 'plugins');
|
'AdminSettingsPlugins', 'Plugins', 'plugins');
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,12 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.googleEnable.preview.subscribe(function (bValue) {
|
||||||
|
Remote.saveAdminConfig(Utils.emptyFunction, {
|
||||||
|
'GoogleEnablePreview': bValue ? '1' : '0'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
self.googleClientID.subscribe(function (sValue) {
|
self.googleClientID.subscribe(function (sValue) {
|
||||||
Remote.saveAdminConfig(f5, {
|
Remote.saveAdminConfig(f5, {
|
||||||
'GoogleClientID': Utils.trim(sValue)
|
'GoogleClientID': Utils.trim(sValue)
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@
|
||||||
this.googleEnable(!!Settings.settingsGet('AllowGoogleSocial'));
|
this.googleEnable(!!Settings.settingsGet('AllowGoogleSocial'));
|
||||||
this.googleEnable.auth(!!Settings.settingsGet('AllowGoogleSocialAuth'));
|
this.googleEnable.auth(!!Settings.settingsGet('AllowGoogleSocialAuth'));
|
||||||
this.googleEnable.drive(!!Settings.settingsGet('AllowGoogleSocialDrive'));
|
this.googleEnable.drive(!!Settings.settingsGet('AllowGoogleSocialDrive'));
|
||||||
|
this.googleEnable.preview(!!Settings.settingsGet('AllowGoogleSocialPreview'));
|
||||||
this.googleClientID(Settings.settingsGet('GoogleClientID'));
|
this.googleClientID(Settings.settingsGet('GoogleClientID'));
|
||||||
this.googleClientSecret(Settings.settingsGet('GoogleClientSecret'));
|
this.googleClientSecret(Settings.settingsGet('GoogleClientSecret'));
|
||||||
this.googleApiKey(Settings.settingsGet('GoogleApiKey'));
|
this.googleApiKey(Settings.settingsGet('GoogleApiKey'));
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "RainLoop",
|
"name": "RainLoop",
|
||||||
"title": "RainLoop Webmail",
|
"title": "RainLoop Webmail",
|
||||||
"version": "1.6.10",
|
"version": "1.6.10",
|
||||||
"release": "185",
|
"release": "190",
|
||||||
"description": "Simple, modern & fast web-based email client",
|
"description": "Simple, modern & fast web-based email client",
|
||||||
"homepage": "http://rainloop.net",
|
"homepage": "http://rainloop.net",
|
||||||
"main": "gulpfile.js",
|
"main": "gulpfile.js",
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,8 @@ class Account
|
||||||
$this->sParentEmail, // 6
|
$this->sParentEmail, // 6
|
||||||
\RainLoop\Utils::GetShortToken(), // 7
|
\RainLoop\Utils::GetShortToken(), // 7
|
||||||
$this->sProxyAuthUser, // 8
|
$this->sProxyAuthUser, // 8
|
||||||
$this->sProxyAuthPassword // 9
|
$this->sProxyAuthPassword, // 9
|
||||||
|
0 // 10
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,22 @@ class Actions
|
||||||
return $this->sSpecAuthToken;
|
return $this->sSpecAuthToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetShortLifeSpecAuthToken($iLife = 60)
|
||||||
|
{
|
||||||
|
$sToken = $this->getAuthToken();
|
||||||
|
$aAccountHash = \RainLoop\Utils::DecodeKeyValues($sToken);
|
||||||
|
if (!empty($aAccountHash[0]) && 'token' === $aAccountHash[0] && is_array($aAccountHash))
|
||||||
|
{
|
||||||
|
$aAccountHash[10] = \time() + $iLife;
|
||||||
|
return \RainLoop\Utils::EncodeKeyValues($aAccountHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \RainLoop\Application
|
* @return \RainLoop\Application
|
||||||
*/
|
*/
|
||||||
|
|
@ -471,7 +487,7 @@ class Actions
|
||||||
private function getAuthToken()
|
private function getAuthToken()
|
||||||
{
|
{
|
||||||
$sToken = $this->GetSpecAuthToken();
|
$sToken = $this->GetSpecAuthToken();
|
||||||
return $sToken && '_' === \substr($sToken, 0, 1) ? \substr($sToken, 1) : '';
|
return !empty($sToken) && '_' === \substr($sToken, 0, 1) ? \substr($sToken, 1) : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -887,13 +903,13 @@ class Actions
|
||||||
if (!empty($aAccountHash[0]) && 'token' === $aAccountHash[0] && // simple token validation
|
if (!empty($aAccountHash[0]) && 'token' === $aAccountHash[0] && // simple token validation
|
||||||
8 <= \count($aAccountHash) && // length checking
|
8 <= \count($aAccountHash) && // length checking
|
||||||
!empty($aAccountHash[7]) && // does short token exist
|
!empty($aAccountHash[7]) && // does short token exist
|
||||||
(!$bValidateShortToken || \RainLoop\Utils::GetShortToken() === $aAccountHash[7]) // check short token if needed
|
(!$bValidateShortToken || \RainLoop\Utils::GetShortToken() === $aAccountHash[7] || // check short token if needed
|
||||||
|
(isset($aAccountHash[10]) && 0 < $aAccountHash[10] && \time() < $aAccountHash[10]))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
$oAccount = $this->LoginProvide($aAccountHash[1], $aAccountHash[2], $aAccountHash[3],
|
$oAccount = $this->LoginProvide($aAccountHash[1], $aAccountHash[2], $aAccountHash[3],
|
||||||
empty($aAccountHash[5]) ? '' : $aAccountHash[5], $bThrowExceptionOnFalse);
|
empty($aAccountHash[5]) ? '' : $aAccountHash[5], $bThrowExceptionOnFalse);
|
||||||
|
|
||||||
|
|
||||||
if ($oAccount instanceof \RainLoop\Account)
|
if ($oAccount instanceof \RainLoop\Account)
|
||||||
{
|
{
|
||||||
if (!empty($aAccountHash[8]) && !empty($aAccountHash[9])) // init proxy user/password
|
if (!empty($aAccountHash[8]) && !empty($aAccountHash[9])) // init proxy user/password
|
||||||
|
|
@ -1129,19 +1145,30 @@ class Actions
|
||||||
$aResult['AllowGoogleSocial'] = (bool) $oConfig->Get('social', 'google_enable', false);
|
$aResult['AllowGoogleSocial'] = (bool) $oConfig->Get('social', 'google_enable', false);
|
||||||
$aResult['AllowGoogleSocialAuth'] = (bool) $oConfig->Get('social', 'google_enable_auth', true);
|
$aResult['AllowGoogleSocialAuth'] = (bool) $oConfig->Get('social', 'google_enable_auth', true);
|
||||||
$aResult['AllowGoogleSocialDrive'] = (bool) $oConfig->Get('social', 'google_enable_drive', true);
|
$aResult['AllowGoogleSocialDrive'] = (bool) $oConfig->Get('social', 'google_enable_drive', true);
|
||||||
|
$aResult['AllowGoogleSocialPreview'] = (bool) $oConfig->Get('social', 'google_enable_preview', true);
|
||||||
|
|
||||||
$aResult['GoogleClientID'] = \trim($oConfig->Get('social', 'google_client_id', ''));
|
$aResult['GoogleClientID'] = \trim($oConfig->Get('social', 'google_client_id', ''));
|
||||||
$aResult['GoogleApiKey'] = \trim($oConfig->Get('social', 'google_api_key', ''));
|
$aResult['GoogleApiKey'] = \trim($oConfig->Get('social', 'google_api_key', ''));
|
||||||
if ($aResult['AllowGoogleSocial'] && (
|
|
||||||
'' === \trim($oConfig->Get('social', 'google_client_id', '')) || '' === \trim($oConfig->Get('social', 'google_client_secret', ''))))
|
if (!$aResult['AllowGoogleSocial'] || ($aResult['AllowGoogleSocial'] && (
|
||||||
|
'' === \trim($oConfig->Get('social', 'google_client_id', '')) || '' === \trim($oConfig->Get('social', 'google_client_secret', '')))))
|
||||||
{
|
{
|
||||||
$aResult['AllowGoogleSocial'] = false;
|
|
||||||
$aResult['AllowGoogleSocialAuth'] = false;
|
$aResult['AllowGoogleSocialAuth'] = false;
|
||||||
$aResult['AllowGoogleSocialDrive'] = false;
|
$aResult['AllowGoogleSocialDrive'] = false;
|
||||||
$aResult['GoogleClientID'] = '';
|
$aResult['GoogleClientID'] = '';
|
||||||
$aResult['GoogleApiKey'] = '';
|
$aResult['GoogleApiKey'] = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$aResult['AllowGoogleSocial'])
|
||||||
|
{
|
||||||
|
$aResult['AllowGoogleSocialPreview'] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($aResult['AllowGoogleSocial'] && !$aResult['AllowGoogleSocialAuth'] && !$aResult['AllowGoogleSocialDrive'] && !$aResult['AllowGoogleSocialPreview'])
|
||||||
|
{
|
||||||
|
$aResult['AllowGoogleSocial'] = false;
|
||||||
|
}
|
||||||
|
|
||||||
$aResult['AllowFacebookSocial'] = (bool) $oConfig->Get('social', 'fb_enable', false);
|
$aResult['AllowFacebookSocial'] = (bool) $oConfig->Get('social', 'fb_enable', false);
|
||||||
if ($aResult['AllowFacebookSocial'] && (
|
if ($aResult['AllowFacebookSocial'] && (
|
||||||
'' === \trim($oConfig->Get('social', 'fb_app_id', '')) || '' === \trim($oConfig->Get('social', 'fb_app_secret', ''))))
|
'' === \trim($oConfig->Get('social', 'fb_app_id', '')) || '' === \trim($oConfig->Get('social', 'fb_app_secret', ''))))
|
||||||
|
|
@ -1197,6 +1224,7 @@ class Actions
|
||||||
$aResult['AllowGoogleSocial'] = (bool) $oConfig->Get('social', 'google_enable', false);
|
$aResult['AllowGoogleSocial'] = (bool) $oConfig->Get('social', 'google_enable', false);
|
||||||
$aResult['AllowGoogleSocialAuth'] = (bool) $oConfig->Get('social', 'google_enable_auth', true);
|
$aResult['AllowGoogleSocialAuth'] = (bool) $oConfig->Get('social', 'google_enable_auth', true);
|
||||||
$aResult['AllowGoogleSocialDrive'] = (bool) $oConfig->Get('social', 'google_enable_drive', true);
|
$aResult['AllowGoogleSocialDrive'] = (bool) $oConfig->Get('social', 'google_enable_drive', true);
|
||||||
|
$aResult['AllowGoogleSocialPreview'] = (bool) $oConfig->Get('social', 'google_enable_preview', true);
|
||||||
|
|
||||||
$aResult['GoogleClientID'] = (string) $oConfig->Get('social', 'google_client_id', '');
|
$aResult['GoogleClientID'] = (string) $oConfig->Get('social', 'google_client_id', '');
|
||||||
$aResult['GoogleClientSecret'] = (string) $oConfig->Get('social', 'google_client_secret', '');
|
$aResult['GoogleClientSecret'] = (string) $oConfig->Get('social', 'google_client_secret', '');
|
||||||
|
|
@ -2495,6 +2523,7 @@ class Actions
|
||||||
$this->setConfigFromParams($oConfig, 'GoogleEnable', 'social', 'google_enable', 'bool');
|
$this->setConfigFromParams($oConfig, 'GoogleEnable', 'social', 'google_enable', 'bool');
|
||||||
$this->setConfigFromParams($oConfig, 'GoogleEnableAuth', 'social', 'google_enable_auth', 'bool');
|
$this->setConfigFromParams($oConfig, 'GoogleEnableAuth', 'social', 'google_enable_auth', 'bool');
|
||||||
$this->setConfigFromParams($oConfig, 'GoogleEnableDrive', 'social', 'google_enable_drive', 'bool');
|
$this->setConfigFromParams($oConfig, 'GoogleEnableDrive', 'social', 'google_enable_drive', 'bool');
|
||||||
|
$this->setConfigFromParams($oConfig, 'GoogleEnablePreview', 'social', 'google_enable_preview', 'bool');
|
||||||
$this->setConfigFromParams($oConfig, 'GoogleClientID', 'social', 'google_client_id', 'string');
|
$this->setConfigFromParams($oConfig, 'GoogleClientID', 'social', 'google_client_id', 'string');
|
||||||
$this->setConfigFromParams($oConfig, 'GoogleClientSecret', 'social', 'google_client_secret', 'string');
|
$this->setConfigFromParams($oConfig, 'GoogleClientSecret', 'social', 'google_client_secret', 'string');
|
||||||
$this->setConfigFromParams($oConfig, 'GoogleApiKey', 'social', 'google_api_key', 'string');
|
$this->setConfigFromParams($oConfig, 'GoogleApiKey', 'social', 'google_api_key', 'string');
|
||||||
|
|
@ -6438,6 +6467,50 @@ class Actions
|
||||||
}, $sFolder, $iUid, true, $sMimeIndex);
|
}, $sFolder, $iUid, true, $sMimeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function RawFramedView()
|
||||||
|
{
|
||||||
|
$oAccount = $this->getAccountFromToken(false);
|
||||||
|
if ($oAccount)
|
||||||
|
{
|
||||||
|
$sRawKey = (string) $this->GetActionParam('RawKey', '');
|
||||||
|
$aParams = $this->GetActionParam('Params', null);
|
||||||
|
$this->Http()->ServerNoCache();
|
||||||
|
|
||||||
|
$aData = \RainLoop\Utils::DecodeKeyValues($sRawKey);
|
||||||
|
if (isset($aParams[0], $aParams[1], $aParams[2]) &&
|
||||||
|
'Raw' === $aParams[0] && 'FramedView' === $aParams[2] && isset($aData['Framed']) && $aData['Framed'] && $aData['FileName'])
|
||||||
|
{
|
||||||
|
if ($this->isFileHasFramedPreview($aData['FileName']))
|
||||||
|
{
|
||||||
|
$sNewSpecAuthToken = $this->GetShortLifeSpecAuthToken();
|
||||||
|
if (!empty($sNewSpecAuthToken))
|
||||||
|
{
|
||||||
|
$aParams[1] = '_'.$sNewSpecAuthToken;
|
||||||
|
$aParams[2] = 'View';
|
||||||
|
|
||||||
|
\array_shift($aParams);
|
||||||
|
|
||||||
|
$sUrl = $this->Http()->GetFullUrl().'?/Raw/&/s/=/'.implode('/', $aParams);
|
||||||
|
$sFullUrl = 'http://docs.google.com/viewer?embedded=true&url='.urlencode($sUrl);
|
||||||
|
|
||||||
|
@\header('Content-Type: text/html; charset=utf-8');
|
||||||
|
echo '<html style="height: 100%; width: 100%; margin: 0; padding: 0"><head></head>'.
|
||||||
|
'<body style="height: 100%; width: 100%; margin: 0; padding: 0">'.
|
||||||
|
'<iframe style="height: 100%; width: 100%; margin: 0; padding: 0; border: 0" src="'.$sFullUrl.'"></iframe>'.
|
||||||
|
'</body></html>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
|
|
@ -6659,6 +6732,17 @@ class Actions
|
||||||
return $this->rawSmart(false);
|
return $this->rawSmart(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sFileName
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isFileHasFramedPreview($sFileName)
|
||||||
|
{
|
||||||
|
$sExt = \MailSo\Base\Utils::GetFileExtension($sFileName);
|
||||||
|
return \in_array($sExt, array('doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
|
|
@ -7709,6 +7793,7 @@ class Actions
|
||||||
$mResult = \array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
|
$mResult = \array_merge($this->objectData($mResponse, $sParent, $aParameters), array(
|
||||||
'Folder' => $mResponse->Folder(),
|
'Folder' => $mResponse->Folder(),
|
||||||
'Uid' => (string) $mResponse->Uid(),
|
'Uid' => (string) $mResponse->Uid(),
|
||||||
|
'Framed' => false,
|
||||||
'MimeIndex' => (string) $mResponse->MimeIndex(),
|
'MimeIndex' => (string) $mResponse->MimeIndex(),
|
||||||
'MimeType' => $mResponse->MimeType(),
|
'MimeType' => $mResponse->MimeType(),
|
||||||
'FileName' => \MailSo\Base\Utils::ClearFileName(
|
'FileName' => \MailSo\Base\Utils::ClearFileName(
|
||||||
|
|
@ -7721,6 +7806,8 @@ class Actions
|
||||||
($mFoundedContentLocationUrls && \in_array(\trim($mResponse->ContentLocation()), $mFoundedContentLocationUrls))
|
($mFoundedContentLocationUrls && \in_array(\trim($mResponse->ContentLocation()), $mFoundedContentLocationUrls))
|
||||||
));
|
));
|
||||||
|
|
||||||
|
$mResult['Framed'] = $this->isFileHasFramedPreview($mResult['FileName']);
|
||||||
|
|
||||||
$mResult['Download'] = \RainLoop\Utils::EncodeKeyValues(array(
|
$mResult['Download'] = \RainLoop\Utils::EncodeKeyValues(array(
|
||||||
'V' => APP_VERSION,
|
'V' => APP_VERSION,
|
||||||
'Account' => $oAccount ? \md5($oAccount->Hash()) : '',
|
'Account' => $oAccount ? \md5($oAccount->Hash()) : '',
|
||||||
|
|
@ -7728,7 +7815,8 @@ class Actions
|
||||||
'Uid' => $mResult['Uid'],
|
'Uid' => $mResult['Uid'],
|
||||||
'MimeIndex' => $mResult['MimeIndex'],
|
'MimeIndex' => $mResult['MimeIndex'],
|
||||||
'MimeType' => $mResult['MimeType'],
|
'MimeType' => $mResult['MimeType'],
|
||||||
'FileName' => $mResult['FileName']
|
'FileName' => $mResult['FileName'],
|
||||||
|
'Framed' => $mResult['Framed']
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
else if ('MailSo\Mail\Folder' === $sClassName)
|
else if ('MailSo\Mail\Folder' === $sClassName)
|
||||||
|
|
|
||||||
|
|
@ -191,6 +191,7 @@ Examples:
|
||||||
'google_enable' => array(false, 'Google'),
|
'google_enable' => array(false, 'Google'),
|
||||||
'google_enable_auth' => array(true),
|
'google_enable_auth' => array(true),
|
||||||
'google_enable_drive' => array(true),
|
'google_enable_drive' => array(true),
|
||||||
|
'google_enable_preview' => array(true),
|
||||||
'google_client_id' => array(''),
|
'google_client_id' => array(''),
|
||||||
'google_client_secret' => array(''),
|
'google_client_secret' => array(''),
|
||||||
'google_api_key' => array(''),
|
'google_api_key' => array(''),
|
||||||
|
|
|
||||||
|
|
@ -395,7 +395,8 @@ class ServiceActions
|
||||||
{
|
{
|
||||||
$sRawError = '';
|
$sRawError = '';
|
||||||
$this->oActions->SetActionParams(array(
|
$this->oActions->SetActionParams(array(
|
||||||
'RawKey' => empty($this->aPaths[3]) ? '' : $this->aPaths[3]
|
'RawKey' => empty($this->aPaths[3]) ? '' : $this->aPaths[3],
|
||||||
|
'Params' => $this->aPaths
|
||||||
), $sMethodName);
|
), $sMethodName);
|
||||||
|
|
||||||
if (!\call_user_func(array($this->oActions, $sMethodName)))
|
if (!\call_user_func(array($this->oActions, $sMethodName)))
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,24 @@
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<div data-bind="component: {
|
<div data-bind="component: {
|
||||||
name: 'Checkbox',
|
name: 'Checkbox',
|
||||||
params: { value: googleEnable.auth, label: 'Authentication' }
|
params: {
|
||||||
|
value: googleEnable.auth,
|
||||||
|
label: 'Authentication'
|
||||||
|
}
|
||||||
}"></div>
|
}"></div>
|
||||||
<div data-bind="component: {
|
<div data-bind="component: {
|
||||||
name: 'Checkbox',
|
name: 'Checkbox',
|
||||||
params: { value: googleEnable.drive, label: 'Google Drive Integration (Compose view)' }
|
params: {
|
||||||
|
value: googleEnable.drive,
|
||||||
|
label: 'Google Drive Integration (Compose view)'
|
||||||
|
}
|
||||||
|
}"></div>
|
||||||
|
<div data-bind="component: {
|
||||||
|
name: 'Checkbox',
|
||||||
|
params: {
|
||||||
|
value: googleEnable.preview,
|
||||||
|
label: 'Google Viewer Integration (Preview Microsoft Word, Excel and PowerPoint files)'
|
||||||
|
}
|
||||||
}"></div>
|
}"></div>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -35,9 +48,16 @@
|
||||||
Client ID
|
Client ID
|
||||||
</label>
|
</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
<div data-bind="component: {
|
||||||
data-bind="value: googleClientID, saveTrigger: googleTrigger1" />
|
name: 'Input',
|
||||||
<div data-bind="saveTrigger: googleTrigger1"></div>
|
params: {
|
||||||
|
name: 'xx',
|
||||||
|
value: googleClientID,
|
||||||
|
trigger: googleTrigger1,
|
||||||
|
enable: googleEnable.requireClientSettings,
|
||||||
|
size: 5
|
||||||
|
}
|
||||||
|
}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
|
|
@ -45,9 +65,15 @@
|
||||||
Client Secret
|
Client Secret
|
||||||
</label>
|
</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
<div data-bind="component: {
|
||||||
data-bind="value: googleClientSecret, saveTrigger: googleTrigger2" />
|
name: 'Input',
|
||||||
<div data-bind="saveTrigger: googleTrigger2"></div>
|
params: {
|
||||||
|
value: googleClientSecret,
|
||||||
|
trigger: googleTrigger2,
|
||||||
|
enable: googleEnable.requireClientSettings,
|
||||||
|
size: 5
|
||||||
|
}
|
||||||
|
}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
|
|
@ -62,7 +88,7 @@
|
||||||
value: googleApiKey,
|
value: googleApiKey,
|
||||||
trigger: googleTrigger3,
|
trigger: googleTrigger3,
|
||||||
size: 5,
|
size: 5,
|
||||||
enable: googleEnable.drive
|
enable: googleEnable.requireApiKey
|
||||||
}
|
}
|
||||||
}"></div>
|
}"></div>
|
||||||
<blockquote style="margin-top: 10px; margin-bottom: 0">
|
<blockquote style="margin-top: 10px; margin-bottom: 0">
|
||||||
|
|
@ -90,9 +116,15 @@
|
||||||
App ID
|
App ID
|
||||||
</label>
|
</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
<div data-bind="component: {
|
||||||
data-bind="value: facebookAppID, saveTrigger: facebookTrigger1" />
|
name: 'Input',
|
||||||
<div data-bind="saveTrigger: facebookTrigger1"></div>
|
params: {
|
||||||
|
value: facebookAppID,
|
||||||
|
trigger: facebookTrigger1,
|
||||||
|
enable: facebookEnable,
|
||||||
|
size: 5
|
||||||
|
}
|
||||||
|
}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
|
|
@ -100,9 +132,15 @@
|
||||||
App Secret
|
App Secret
|
||||||
</label>
|
</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
<div data-bind="component: {
|
||||||
data-bind="value: facebookAppSecret, saveTrigger: facebookTrigger2" />
|
name: 'Input',
|
||||||
<div data-bind="saveTrigger: facebookTrigger2"></div>
|
params: {
|
||||||
|
value: facebookAppSecret,
|
||||||
|
trigger: facebookTrigger2,
|
||||||
|
enable: facebookEnable,
|
||||||
|
size: 5
|
||||||
|
}
|
||||||
|
}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -122,9 +160,15 @@
|
||||||
Consumer Key
|
Consumer Key
|
||||||
</label>
|
</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
<div data-bind="component: {
|
||||||
data-bind="value: twitterConsumerKey, saveTrigger: twitterTrigger1" />
|
name: 'Input',
|
||||||
<div data-bind="saveTrigger: twitterTrigger1"></div>
|
params: {
|
||||||
|
value: twitterConsumerKey,
|
||||||
|
trigger: twitterTrigger1,
|
||||||
|
enable: twitterEnable,
|
||||||
|
size: 5
|
||||||
|
}
|
||||||
|
}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
|
|
@ -132,9 +176,15 @@
|
||||||
Consumer Secret
|
Consumer Secret
|
||||||
</label>
|
</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
<div data-bind="component: {
|
||||||
data-bind="value: twitterConsumerSecret, saveTrigger: twitterTrigger2" />
|
name: 'Input',
|
||||||
<div data-bind="saveTrigger: twitterTrigger2"></div>
|
params: {
|
||||||
|
value: twitterConsumerSecret,
|
||||||
|
trigger: twitterTrigger2,
|
||||||
|
enable: twitterEnable,
|
||||||
|
size: 5
|
||||||
|
}
|
||||||
|
}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="legend">
|
<div class="legend">
|
||||||
|
|
@ -153,9 +203,15 @@
|
||||||
Api Key
|
Api Key
|
||||||
</label>
|
</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" class="span5" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
<div data-bind="component: {
|
||||||
data-bind="value: dropboxApiKey, saveTrigger: dropboxTrigger1" />
|
name: 'Input',
|
||||||
<div data-bind="saveTrigger: dropboxTrigger1"></div>
|
params: {
|
||||||
|
value: dropboxApiKey,
|
||||||
|
trigger: dropboxTrigger1,
|
||||||
|
enable: dropboxEnable,
|
||||||
|
size: 5
|
||||||
|
}
|
||||||
|
}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -282,6 +282,10 @@
|
||||||
data-bind="visible: isPdf(), attr: {href: linkPreview(), title: fileName}" target="_blank">
|
data-bind="visible: isPdf(), attr: {href: linkPreview(), title: fileName}" target="_blank">
|
||||||
<i class="icon-eye"></i>
|
<i class="icon-eye"></i>
|
||||||
</a>
|
</a>
|
||||||
|
<a class="attachmentPreview pull-left"
|
||||||
|
data-bind="visible: isFramed(), attr: {href: linkFramed(), title: fileName}" target="_blank">
|
||||||
|
<i class="icon-eye"></i>
|
||||||
|
</a>
|
||||||
<span class="attachmentSize pull-right" data-bind="text: friendlySize"></span>
|
<span class="attachmentSize pull-right" data-bind="text: friendlySize"></span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue