diff --git a/img/crowdcube.png b/img/crowdcube.png new file mode 100644 index 0000000000000000000000000000000000000000..6f15ba707528bd6658dfad4098f714982abc6fc7 Binary files /dev/null and b/img/crowdcube.png differ diff --git a/l10n/de.js b/l10n/de.js index 26bd31c01c9cfc5cb14f2c378735626d9b00e786..a5dcd6f31fff47e6f7e98e01684ddd75ec8ffa08 100644 --- a/l10n/de.js +++ b/l10n/de.js @@ -85,6 +85,7 @@ OC.L10N.register( "Captcha is not verified!": "Captcha wird nicht überprüft!", "A server-side error occurred while processing your request! Please try again later.": "Ein serverseitiger Fehler ist bei der Bearbeitung Ihrer Anfrage aufgetreten! Bitte versuchen Sie es später noch einmal.", "An error occurred while creating your account!": "Beim Anlegen Ihres Kontos ist ein Fehler aufgetreten!", - "The domain of this email address is blacklisted. Please provide another recovery address.": "Die Domäne dieser E-Mailadresse ist auf der Sperrliste. Bitte geben Sie eine andere E-Mailadresse an." + "The domain of this email address is blacklisted. Please provide another recovery address.": "Die Domäne dieser E-Mailadresse ist auf der Sperrliste. Bitte geben Sie eine andere E-Mailadresse an.", + "Own a Part of Murena!": "Besitzen Sie einen Teil von Murena!" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/de.json b/l10n/de.json index 581f0a74d6fe392e0ba0f1ac3c7fe8581fb7a154..b2e6e195252db2666ffbe786253df6e06342bbda 100644 --- a/l10n/de.json +++ b/l10n/de.json @@ -83,7 +83,8 @@ "Captcha is not verified!": "Captcha wird nicht überprüft!", "A server-side error occurred while processing your request! Please try again later.": "Ein serverseitiger Fehler ist bei der Bearbeitung Ihrer Anfrage aufgetreten! Bitte versuchen Sie es später noch einmal.", "An error occurred while creating your account!": "Beim Anlegen Ihres Kontos ist ein Fehler aufgetreten!", - "The domain of this email address is blacklisted. Please provide another recovery address.": "Die Domäne dieser E-Mailadresse ist auf der Sperrliste. Bitte geben Sie eine andere E-Mailadresse an." + "The domain of this email address is blacklisted. Please provide another recovery address.": "Die Domäne dieser E-Mailadresse ist auf der Sperrliste. Bitte geben Sie eine andere E-Mailadresse an.", + "Own a Part of Murena!": "Besitzen Sie einen Teil von Murena!" }, "pluralForm": "nplurals=2; plural=(n != 1);" } diff --git a/l10n/en.js b/l10n/en.js index b25bf722096e77033efb6c418d6718b57e761578..4136a50067eafd786b1170814aa5983bd2bced29 100644 --- a/l10n/en.js +++ b/l10n/en.js @@ -89,6 +89,7 @@ OC.L10N.register( "Captcha is not verified!": "Captcha is not verified!", "A server-side error occurred while processing your request! Please try again later.": "A server-side error occurred while processing your request! Please try again later.", "An error occurred while creating your account!": "An error occurred while creating your account!", - "The domain of this email address is blacklisted. Please provide another recovery address.": "The domain of this email address is blacklisted. Please provide another recovery address." + "The domain of this email address is blacklisted. Please provide another recovery address.": "The domain of this email address is blacklisted. Please provide another recovery address.", + "Own a Part of Murena!": "Own a Part of Murena!" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/en.json b/l10n/en.json index be378a0a3f41d137df72a90ae03f860d3517c702..f4f22a4fe99f17d7bf395a7c9e12f1900001a226 100644 --- a/l10n/en.json +++ b/l10n/en.json @@ -85,7 +85,8 @@ "Captcha is not verified!": "Captcha is not verified!", "A server-side error occurred while processing your request! Please try again later.": "A server-side error occurred while processing your request! Please try again later.", "An error occurred while creating your account!": "An error occurred while creating your account!", - "The domain of this email address is blacklisted. Please provide another recovery address.": "The domain of this email address is blacklisted. Please provide another recovery address." + "The domain of this email address is blacklisted. Please provide another recovery address.": "The domain of this email address is blacklisted. Please provide another recovery address.", + "Own a Part of Murena!": "Own a Part of Murena!" }, "pluralForm": "nplurals=2; plural=(n != 1);" } diff --git a/l10n/es.js b/l10n/es.js index 19fa33c78166b5c3f303859ed96c028886d6aced..940e8f2a0ee458e1de2ba29e1e1996f8d52765ea 100644 --- a/l10n/es.js +++ b/l10n/es.js @@ -87,6 +87,7 @@ OC.L10N.register( "Captcha is not verified!": "¡Captcha no está verificado!", "A server-side error occurred while processing your request! Please try again later.": "Hubo un error en el servidor al procesar tu solicitud. Por favor, inténtalo más tarde.", "An error occurred while creating your account!": "¡Hubo un error creando tu cuenta!", - "The domain of this email address is blacklisted. Please provide another recovery address.": "El dominio de esta dirección de correo electrónico está en lista negra. Por favor, proporciona otra dirección de recuperación." + "The domain of this email address is blacklisted. Please provide another recovery address.": "El dominio de esta dirección de correo electrónico está en lista negra. Por favor, proporciona otra dirección de recuperación.", + "Own a Part of Murena!": "¡Sea dueño de una parte de Murena!" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/es.json b/l10n/es.json index 867f150d23f64979e34524a5d2607fb5073ef574..a935c2d60513882bab11f87cf41afd5811a13b90 100644 --- a/l10n/es.json +++ b/l10n/es.json @@ -86,7 +86,8 @@ "Captcha is not verified!": "¡Captcha no está verificado!", "A server-side error occurred while processing your request! Please try again later.": "Hubo un error en el servidor al procesar tu solicitud. Por favor, inténtalo más tarde.", "An error occurred while creating your account!": "¡Hubo un error creando tu cuenta!", - "The domain of this email address is blacklisted. Please provide another recovery address.": "El dominio de esta dirección de correo electrónico está en lista negra. Por favor, proporciona otra dirección de recuperación." + "The domain of this email address is blacklisted. Please provide another recovery address.": "El dominio de esta dirección de correo electrónico está en lista negra. Por favor, proporciona otra dirección de recuperación.", + "Own a Part of Murena!": "¡Sea dueño de una parte de Murena!" }, "pluralForm": "nplurals=2; plural=(n != 1);" } diff --git a/l10n/fr.js b/l10n/fr.js index 6efaeeca5d3313287d35f2fa0b890a48e29cd1c6..36f4bb42cc2ef193b8b3ea2f8bc1c00ccd13118d 100644 --- a/l10n/fr.js +++ b/l10n/fr.js @@ -86,6 +86,7 @@ OC.L10N.register( "Captcha is not verified!": "Captcha n'est pas vérifié !", "A server-side error occurred while processing your request! Please try again later.": "Erreur du serveur dans la gestion de votre demande ! Merci d'essayer ultérieurement.", "An error occurred while creating your account!": "Une erreur s'est produite lors de la création de votre compte!", - "The domain of this email address is blacklisted. Please provide another recovery address.": "Le domain de cette adresse e-mail est sur liste noire. Merci de bien vouloir fournir une autre adresse de récupération." + "The domain of this email address is blacklisted. Please provide another recovery address.": "Le domain de cette adresse e-mail est sur liste noire. Merci de bien vouloir fournir une autre adresse de récupération.", + "Own a Part of Murena!": "Une partie de Murena vous appartient !" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/fr.json b/l10n/fr.json index 19facc3020f5d4e52d2c1edefc1efaf4d59c0410..a97f62b9f6038ee27103d9c7fd45fcef78262c98 100644 --- a/l10n/fr.json +++ b/l10n/fr.json @@ -85,7 +85,8 @@ "Captcha is not verified!": "Captcha n'est pas vérifié !", "A server-side error occurred while processing your request! Please try again later.": "Erreur du serveur dans la gestion de votre demande ! Merci d'essayer ultérieurement.", "An error occurred while creating your account!": "Une erreur s'est produite lors de la création de votre compte!", - "The domain of this email address is blacklisted. Please provide another recovery address.": "Le domain de cette adresse e-mail est sur liste noire. Merci de bien vouloir fournir une autre adresse de récupération." + "The domain of this email address is blacklisted. Please provide another recovery address.": "Le domain de cette adresse e-mail est sur liste noire. Merci de bien vouloir fournir une autre adresse de récupération.", + "Own a Part of Murena!": "Une partie de Murena vous appartient !" }, "pluralForm": "nplurals=2; plural=(n != 1);" } diff --git a/l10n/it.js b/l10n/it.js index 84c211cd0278b6b30f84a0ea53f76df4e5a2650e..cafd57177a01c72b15f8cf2233c7c1052296db9f 100644 --- a/l10n/it.js +++ b/l10n/it.js @@ -86,6 +86,7 @@ OC.L10N.register( "Captcha is not verified!": "Il Captcha non è verificato!", "A server-side error occurred while processing your request! Please try again later.": "Si è verificato un errore lato server nel processare la tua richiesta! Ritenta più tardi.", "An error occurred while creating your account!": "Si è verificato un errore nella creazione dell'account!", - "The domain of this email address is blacklisted. Please provide another recovery address.": "Il dominio cui appartiene questo indirizzo e-mail è contenuto in una black list. Inserisci un indirizzo di recovery differente." + "The domain of this email address is blacklisted. Please provide another recovery address.": "Il dominio cui appartiene questo indirizzo e-mail è contenuto in una black list. Inserisci un indirizzo di recovery differente.", + "Own a Part of Murena!": "Possedere una parte di Murena!" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/it.json b/l10n/it.json index 2685c394b55388e6f571ca7c1675214645c6eeb0..57299854a0a671fb2356c6b2ab99fa74d867a892 100644 --- a/l10n/it.json +++ b/l10n/it.json @@ -81,7 +81,8 @@ "Captcha is not verified!": "Il Captcha non è verificato!", "A server-side error occurred while processing your request! Please try again later.": "Si è verificato un errore lato server nel processare la tua richiesta! Ritenta più tardi.", "An error occurred while creating your account!": "Si è verificato un errore nella creazione dell'account!", - "The domain of this email address is blacklisted. Please provide another recovery address.": "Il dominio cui appartiene questo indirizzo e-mail è contenuto in una black list. Inserisci un indirizzo di recovery differente." + "The domain of this email address is blacklisted. Please provide another recovery address.": "Il dominio cui appartiene questo indirizzo e-mail è contenuto in una black list. Inserisci un indirizzo di recovery differente.", + "Own a Part of Murena!": "Possedere una parte di Murena!" }, "pluralForm": "nplurals=2; plural=(n != 1);" } diff --git a/lib/Listeners/BeforeTemplateRenderedListener.php b/lib/Listeners/BeforeTemplateRenderedListener.php index adece9c3c691e046cc4b562afef4d6accca6be81..6b4b2d54a1d9495d805a7a008a64d631a80eaeb3 100644 --- a/lib/Listeners/BeforeTemplateRenderedListener.php +++ b/lib/Listeners/BeforeTemplateRenderedListener.php @@ -6,6 +6,8 @@ namespace OCA\EcloudAccounts\Listeners; use OCP\App\IAppManager; use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Services\IInitialState; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\IConfig; @@ -26,8 +28,10 @@ class BeforeTemplateRenderedListener implements IEventListener { private const SNAPPYMAIL_APP_ID = 'snappymail'; private const SNAPPYMAIL_URL = '/apps/snappymail/'; private const SNAPPYMAIL_AUTOLOGIN_PWD = '1'; + private IInitialState $initialState; + private $userId; - public function __construct($appName, IUserSession $userSession, IRequest $request, ISession $session, IConfig $config, IAppManager $appManager, Util $util) { + public function __construct($appName, IUserSession $userSession, IRequest $request, ISession $session, IConfig $config, IAppManager $appManager, Util $util, $userId, IInitialState $initialState) { $this->appName = $appName; $this->userSession = $userSession; $this->request = $request; @@ -35,6 +39,8 @@ class BeforeTemplateRenderedListener implements IEventListener { $this->config = $config; $this->appManager = $appManager; $this->util = $util; + $this->initialState = $initialState; + $this->userId = $userId; } public function handle(Event $event): void { @@ -50,6 +56,12 @@ class BeforeTemplateRenderedListener implements IEventListener { $this->util->addStyle($this->appName, $this->appName . '-userregistration'); } + if (($event->getResponse()->getRenderAs() === TemplateResponse::RENDER_AS_USER) && $event->isLoggedIn()) { + $userLocation = 'USA'; + $this->initialState->provideInitialState('userLocation', $userLocation); + $this->util->addStyle($this->appName, 'business-banner'); + $this->util->addScript($this->appName, $this->appName . '-business-banner'); + } } diff --git a/scss/business-banner.scss b/scss/business-banner.scss new file mode 100644 index 0000000000000000000000000000000000000000..2b4dbf0a85c61535fef9100070233b7ba05cc6c4 --- /dev/null +++ b/scss/business-banner.scss @@ -0,0 +1,65 @@ +.business-banner { + display: inline-flex; + position: absolute; + top: 0px; + width: 100%; + min-height: 50px; + box-sizing: border-box; + justify-content: center; + align-items: center; + background: #333333; + color: #ffffff; + font-size: 16px; + font-weight: 400; + line-height: 24px; + padding: 16px 6%; + #business-banner-container{ + display:inline-flex; + img { + padding-right:10px; + align-self: start; + height: 25px; + width: auto; + } + p{ + margin: 0 auto; + } + } + + a { + color: #ffffff; + padding-left: 24px; + text-decoration: underline; + font-size: 16px; + font-weight: 600; + } + + span { + position: absolute; + right: 20px; + cursor: pointer; + } + +} + +@media only screen and (max-width: 768px) { + .business-banner { + display: block; + a{ + padding: 8px 0 0 30px; + } + } +} + +[data-object-type="business-banner-important"] a.external { + background-color: var(--color-primary-element); + color: var(--color-primary-element-text); + text-decoration: none; + display: block; + text-align: center; + padding: 10px 12px; + border-radius: 30px; + font-size: 12px; + font-weight: bold; + width: fit-content; +} diff --git a/src/business-banner.js b/src/business-banner.js new file mode 100644 index 0000000000000000000000000000000000000000..f9d0bc3b6048bb0919774d99cccbc3c3a014103c --- /dev/null +++ b/src/business-banner.js @@ -0,0 +1,200 @@ +import { generateUrl } from '@nextcloud/router' +import { loadState } from '@nextcloud/initial-state' + +const userLocation = loadState('ecloud-accounts', 'userLocation') +const APPLICATION_NAME = 'ecloud-accounts' +document.addEventListener('DOMContentLoaded', function() { + if (!localStorage.getItem('bannerClosed')) { + const newDiv = createNewDiv('business-banner') + const contentDiv = document.createElement('div') + contentDiv.id = 'business-banner-container' + if (userLocation === 'USA') { + const img = createImageElement(APPLICATION_NAME) + contentDiv.appendChild(img) + } + const textNode = createTextNode(APPLICATION_NAME) + const link = createLinkElement(APPLICATION_NAME) + const closeButton = createCloseButton(newDiv) + + contentDiv.appendChild(textNode) + newDiv.appendChild(contentDiv) + newDiv.appendChild(link) + newDiv.appendChild(closeButton) + insertIntoDOM(newDiv) + // Measure the height after the element is inserted into the DOM + const banner = document.getElementById('business-banner') + if (banner) { + const bannerHeight = banner.clientHeight + 'px' + const topHeight = (banner.clientHeight + 50) + 'px' + adjustHeaderContent(banner, bannerHeight, topHeight) + } + } +}) + +/** + * Sets the 'top' style to an element once it becomes available in the DOM. + * + * @param {string} selector - The CSS selector for the element. + * @param {string} topValue - The value to be set for the 'top' property. + */ + +/** + * + * @param selector + * @param topValue + */ +function setTopStyleWhenElementAvailable(selector, topValue) { + // Function to check each node and apply style if it matches the selector + /** + * + * @param node + */ + function checkAndApplyStyle(node) { + if (node.nodeType === Node.ELEMENT_NODE) { + if (node.matches(selector)) { + node.style.top = topValue + } + + // Check all child nodes + node.querySelectorAll(selector).forEach(childNode => { + childNode.style.top = topValue + }) + } + } + + // Set up a MutationObserver to watch for added nodes + const observer = new MutationObserver(mutations => { + mutations.forEach(mutation => { + mutation.addedNodes.forEach(checkAndApplyStyle) + }) + }) + + // Start observing the document body for added nodes + observer.observe(document.body, { childList: true, subtree: true }) +} + +/** + * Sets the 'top' style property of an element. + * The element is selected based on the provided CSS selector. + * + * @param {string} selector + * @param {string} topValue + */ +function setTopStyle(selector, topValue) { + const element = document.querySelector(selector) + if (element) { + element.style.top = topValue + } +} + +/** + * Apply a margin-top style with !important and calculate a new height for the element. + * + * @param {string} selector - The CSS selector for the element. + * @param {string} topValue - The value for the margin-top property. + */ + +/** + * + * @param selector + * @param topValue + */ +function setMarginTopAndHeight(selector, topValue) { + const element = document.querySelector(selector) + if (element) { + element.style.cssText += `margin-top: ${topValue} !important;` + const heightValue = `calc(100% - env(safe-area-inset-bottom) - ${topValue} - var(--body-container-margin)) !important` + element.style.cssText += `height: ${heightValue};` + } +} +/** + * + * @param className + */ +function createNewDiv(className) { + const div = document.createElement('div') + div.className = className + div.id = className + return div +} + +/** + * + * @param appName + */ +function createImageElement(appName) { + const img = document.createElement('img') + img.src = generateUrl('/custom_apps/' + appName + '/img/crowdcube.png') + return img +} + +/** + * + * @param appName + */ +function createTextNode(appName) { + const p = document.createElement('p') + const labelText = t(appName, 'Own a Part of Murena!') + const text = document.createTextNode(labelText) + p.appendChild(text) + return p +} + +/** + * + * @param appName + */ +function createLinkElement(appName) { + const link = document.createElement('a') + const labelText = t(appName, 'LEARN MORE') + link.textContent = labelText + link.href = 'https://murena.com/investors/' + link.style.display = 'block' + return link +} +/** + * + * @param appName + * @param banner + */ +function createCloseButton(banner) { + const span = document.createElement('span') + const labelText = 'X' + span.textContent = labelText + span.style.display = 'block' + span.style.cursor = 'pointer' + span.addEventListener('click', function() { + banner.style.display = 'none' + localStorage.setItem('bannerClosed', 'true') + const bannerHeight = '0' + const topHeight = 'auto' + adjustHeaderContent(banner, bannerHeight, topHeight) + }) + return span +} + +/** + * + * @param element + */ +function insertIntoDOM(element) { + const targetElement = document.getElementById('header') + const parentElement = targetElement.parentNode + parentElement.insertBefore(element, targetElement) +} + +/** + * + * @param banner + * @param bannerHeight + * @param topHeight + */ +function adjustHeaderContent(banner, bannerHeight, topHeight) { + setTopStyle('#header', bannerHeight) + setMarginTopAndHeight('#content', topHeight) + setMarginTopAndHeight('#content-vue', topHeight) + setTopStyleWhenElementAvailable('#header-menu-user-menu', topHeight) + setTopStyleWhenElementAvailable('#header-menu-notifications', topHeight) + setTopStyle('#header-menu-unified-search', topHeight) + banner.style.height = bannerHeight +} diff --git a/webpack.config.js b/webpack.config.js index b6eaacbad759d6b97381556dbaa35e18123dbeca..e4d82caadd4fe66ae83b2bcafdcf2c0d8e2de739 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -9,6 +9,7 @@ module.exports = { 'delete-shop-account-setting': path.join(__dirname, 'src/delete-shop-account-setting.js'), 'delete-account-listeners': path.join(__dirname, 'src/delete-account-listeners.js'), 'beta-user-setting': path.join(__dirname, 'src/beta-user-setting.js'), - 'signup': path.join(__dirname, 'src/signup.js') + 'signup': path.join(__dirname, 'src/signup.js'), + 'business-banner': path.join(__dirname, 'src/business-banner.js'), }, }