diff --git a/dev/Stores/Theme.js b/dev/Stores/Theme.js index 01c7a4afa..4a739791b 100644 --- a/dev/Stores/Theme.js +++ b/dev/Stores/Theme.js @@ -1,5 +1,5 @@ import ko from 'ko'; -import { doc, $htmlCL, elementById, leftPanelDisabled, Settings, SettingsGet } from 'Common/Globals'; +import { $htmlCL, elementById, leftPanelDisabled, Settings, SettingsGet } from 'Common/Globals'; import { isArray, arrayLength } from 'Common/Utils'; import { serverRequestRaw } from 'Common/Links'; import { SaveSettingStatus } from 'Common/Enums'; @@ -7,6 +7,8 @@ import { SaveSettingStatus } from 'Common/Enums'; let __themeTimer = 0; export const + appEl = () => elementById('rl-app'), + ThemeStore = { theme: ko.observable(''), themes: ko.observableArray(), @@ -65,7 +67,7 @@ ThemeStore.isMobile.subscribe(value => $htmlCL.toggle('rl-mobile', value)); ThemeStore.fontSansSerif.subscribe(value => { if (null != value) { - let cl = elementById('rl-app').classList; + let cl = appEl().classList; cl.forEach(name => { if (name.startsWith('font') && !/font(Serif|Mono)/.test(name)) { cl.remove(name); @@ -76,25 +78,20 @@ ThemeStore.fontSansSerif.subscribe(value => { }); ThemeStore.fontSerif.subscribe(value => { if (null != value) { - let cl = elementById('rl-app').classList; + let cl = appEl().classList; cl.forEach(name => name.startsWith('fontSerif') && cl.remove(name)); value && cl.add('fontSerif'+value); } }); ThemeStore.fontMono.subscribe(value => { if (null != value) { - let cl = elementById('rl-app').classList; + let cl = appEl().classList; cl.forEach(name => name.startsWith('fontMono') && cl.remove(name)); value && cl.add('fontMono'+value); } }); ThemeStore.userBackgroundHash.subscribe(value => { - if (value) { - $htmlCL.add('UserBackground'); - doc.body.style.backgroundImage = "url("+serverRequestRaw('UserBackground', value)+")"; - } else { - $htmlCL.remove('UserBackground'); - doc.body.removeAttribute('style'); - } + appEl().classList.toggle('UserBackground', !!value); + appEl().style.backgroundImage = value ? "url("+serverRequestRaw('UserBackground', value)+")" : null; }); diff --git a/dev/Styles/User/Layout.less b/dev/Styles/User/Layout.less index 2e02fc836..04d98fbee 100644 --- a/dev/Styles/User/Layout.less +++ b/dev/Styles/User/Layout.less @@ -1,5 +1,5 @@ -.UserBackground body { +#rl-app.UserBackground { background-size: cover; background-repeat: no-repeat; background-position: center; diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions.php index 9d9600c62..d9037efe1 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions.php @@ -1028,90 +1028,6 @@ class Actions return $this->DefaultResponse(__FUNCTION__, $aResponse); } - public function UploadBackground(): array - { - $oAccount = $this->getAccountFromToken(); - - if (!$this->GetCapa(Enumerations\Capa::USER_BACKGROUND)) { - return $this->FalseResponse(__FUNCTION__); - } - - $sName = ''; - $sHash = ''; - - $aFile = $this->GetActionParam('File', null); - $iError = $this->GetActionParam('Error', Enumerations\UploadError::UNKNOWN); - - if ($oAccount && UPLOAD_ERR_OK === $iError && \is_array($aFile)) { - $sMimeType = \SnappyMail\File\MimeType::fromFile($aFile['tmp_name'], $aFile['name']) - ?: \SnappyMail\File\MimeType::fromFilename($aFile['name']) - ?: $aFile['type']; - if (\in_array($sMimeType, array('image/png', 'image/jpg', 'image/jpeg', 'image/webp'))) { - $sSavedName = 'upload-post-' . \md5($aFile['name'] . $aFile['tmp_name']) - . \SnappyMail\File\MimeType::toExtension($sContentType); - if (!$this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $aFile['tmp_name'])) { - $iError = Enumerations\UploadError::ON_SAVING; - } else { - $rData = $this->FilesProvider()->GetFile($oAccount, $sSavedName); - if (\is_resource($rData)) { - $sData = \stream_get_contents($rData); - if (!empty($sData) && \strlen($sData)) { - $sName = $aFile['name']; - if (empty($sName)) { - $sName = '_'; - } - - if ($this->StorageProvider()->Put($oAccount, - Providers\Storage\Enumerations\StorageType::CONFIG, - 'background', - Utils::jsonEncode(array( - 'Name' => $aFile['name'], - 'ContentType' => $sMimeType, - 'Raw' => \base64_encode($sData) - )) - )) { - $oSettings = $this->SettingsProvider()->Load($oAccount); - if ($oSettings) { - $sHash = \MailSo\Base\Utils::Sha1Rand($sName . APP_VERSION . APP_SALT); - - $oSettings->SetConf('UserBackgroundName', $sName); - $oSettings->SetConf('UserBackgroundHash', $sHash); - $this->SettingsProvider()->Save($oAccount, $oSettings); - } - } - } - - unset($sData); - } - - if (\is_resource($rData)) { - \fclose($rData); - } - - unset($rData); - } - - $this->FilesProvider()->Clear($oAccount, $sSavedName); - } else { - $iError = Enumerations\UploadError::FILE_TYPE; - } - } - - if (UPLOAD_ERR_OK !== $iError) { - $iClientError = Enumerations\UploadError::NORMAL; - $sError = $this->getUploadErrorMessageByCode($iError, $iClientError); - - if (!empty($sError)) { - return $this->FalseResponse(__FUNCTION__, $iClientError, $sError); - } - } - - return $this->DefaultResponse(__FUNCTION__, !empty($sName) && !empty($sHash) ? array( - 'Name' => $sName, - 'Hash' => $sHash - ) : false); - } - public function Capa(bool $bAdmin, ?Model\Account $oAccount = null): array { static $aResult; diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Themes.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Themes.php index 45d63cf66..b148c4aeb 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Themes.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Themes.php @@ -127,4 +127,88 @@ trait Themes return $bLess ? (new \LessPHP\lessc())->compile($mResult) : $mResult; // : \str_replace(';}', '}', \preg_replace('/\\s*([:;{},])\\s*/', '\1', \preg_replace('/\\s+/', ' ', \preg_replace('#/\\*.*?\\*/#s', '', $mResult)))); } + + public function UploadBackground(): array + { + $oAccount = $this->getAccountFromToken(); + + if (!$this->GetCapa(\RainLoop\Enumerations\Capa::USER_BACKGROUND)) { + return $this->FalseResponse(__FUNCTION__); + } + + $sName = ''; + $sHash = ''; + + $aFile = $this->GetActionParam('File', null); + $iError = $this->GetActionParam('Error', \RainLoop\Enumerations\UploadError::UNKNOWN); + + if ($oAccount && UPLOAD_ERR_OK === $iError && \is_array($aFile)) { + $sMimeType = \SnappyMail\File\MimeType::fromFile($aFile['tmp_name'], $aFile['name']) + ?: \SnappyMail\File\MimeType::fromFilename($aFile['name']) + ?: $aFile['type']; + if (\in_array($sMimeType, array('image/png', 'image/jpg', 'image/jpeg', 'image/webp'))) { + $sSavedName = 'upload-post-' . \md5($aFile['name'] . $aFile['tmp_name']) + . \SnappyMail\File\MimeType::toExtension($sMimeType); + if (!$this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $aFile['tmp_name'])) { + $iError = \RainLoop\Enumerations\UploadError::ON_SAVING; + } else { + $rData = $this->FilesProvider()->GetFile($oAccount, $sSavedName); + if (\is_resource($rData)) { + $sData = \stream_get_contents($rData); + if (!empty($sData) && \strlen($sData)) { + $sName = $aFile['name']; + if (empty($sName)) { + $sName = '_'; + } + + if ($this->StorageProvider()->Put($oAccount, + \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, + 'background', + \RainLoop\Utils::jsonEncode(array( + 'Name' => $aFile['name'], + 'ContentType' => $sMimeType, + 'Raw' => \base64_encode($sData) + )) + )) { + $oSettings = $this->SettingsProvider()->Load($oAccount); + if ($oSettings) { + $sHash = \MailSo\Base\Utils::Sha1Rand($sName . APP_VERSION . APP_SALT); + + $oSettings->SetConf('UserBackgroundName', $sName); + $oSettings->SetConf('UserBackgroundHash', $sHash); + $this->SettingsProvider()->Save($oAccount, $oSettings); + } + } + } + + unset($sData); + } + + if (\is_resource($rData)) { + \fclose($rData); + } + + unset($rData); + } + + $this->FilesProvider()->Clear($oAccount, $sSavedName); + } else { + $iError = \RainLoop\Enumerations\UploadError::FILE_TYPE; + } + } + + if (UPLOAD_ERR_OK !== $iError) { + $iClientError = \RainLoop\Enumerations\UploadError::NORMAL; + $sError = $this->getUploadErrorMessageByCode($iError, $iClientError); + + if (!empty($sError)) { + return $this->FalseResponse(__FUNCTION__, $iClientError, $sError); + } + } + + return $this->DefaultResponse(__FUNCTION__, !empty($sName) && !empty($sHash) ? array( + 'Name' => $sName, + 'Hash' => $sHash + ) : false); + } }