[IMP] website: switch to fullscreen when pressing esc

See merge commit for more information.

task-2687506

Co-authored-by: Arthur Detroux <ard@odoo.com>
This commit is contained in:
Younn Olivier
2022-06-24 10:28:05 +02:00
committed by qsm-odoo
co-authored by Arthur Detroux
parent 028efcbffe
commit d2ed93f780
8 changed files with 96 additions and 90 deletions
+2 -1
View File
@@ -125,7 +125,6 @@
'website/static/src/js/utils.js',
'website/static/src/js/content/website_root.js',
'website/static/src/js/widgets/dialog.js',
'website/static/src/components/fullscreen_indication/fullscreen_indication.js',
'website/static/src/js/content/compatibility.js',
'website/static/src/js/content/menu.js',
'website/static/src/js/content/snippets.animation.js',
@@ -179,6 +178,8 @@
'website/static/src/components/dialog/dialog.scss',
'website/static/src/components/switch/switch.js',
'website/static/src/components/switch/switch.scss',
'website/static/src/components/fullscreen_indication/fullscreen_indication.js',
'website/static/src/components/fullscreen_indication/fullscreen_indication.scss',
'website/static/src/systray_items/*.js',
'website/static/src/systray_items/*.scss',
],
@@ -116,6 +116,12 @@ export class WebsitePreview extends Component {
window.location.replace(href);
}
});
this.iframe.el.contentDocument.addEventListener('keydown', ev => {
this.iframe.el.dispatchEvent(new KeyboardEvent('keydown', ev));
});
this.iframe.el.contentDocument.addEventListener('keyup', ev => {
this.iframe.el.dispatchEvent(new KeyboardEvent('keyup', ev));
});
}
}
WebsitePreview.template = 'website.WebsitePreview';
@@ -9,3 +9,19 @@
border: none;
}
}
.o_website_fullscreen, .editor_has_snippets {
header {
.o_main_navbar {
height: 0px;
transform: translateY(-$o-navbar-height);
border-bottom: 0px;
}
}
}
header {
.o_main_navbar {
transition: transform 400ms ease, height 400ms ease, border-bottom 400ms ease;
}
}
@@ -1,40 +1,27 @@
/** @odoo-module **/
import Widget from 'web.Widget';
const { Component, xml, useState } = owl;
export const FullscreenIndication = Widget.extend({
xmlDependencies: ['/website/static/src/xml/website.xml'],
template: 'website.fullscreen_indication',
export class FullscreenIndication extends Component {
setup() {
this.state = useState({ isVisible: false });
this.props.bus.on('FULLSCREEN-INDICATION-SHOW', this, this.show);
this.props.bus.on('FULLSCREEN-INDICATION-HIDE', this, this.hide);
}
init: function () {
this.visible = false;
this.displayTime = 2000;
this._super(...arguments);
},
show() {
setTimeout(() => this.state.isVisible = true);
this.autofade = setTimeout(() => this.state.isVisible = false, 2000);
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* Displays the fullscreen indication modal
*/
show: function () {
clearTimeout(this.autofade);
this.visible = true;
this.el.classList.add('o_transition', 'o_visible');
this.autofade = setTimeout(() => {
this.hide(true);
}, this.displayTime);
},
/**
* Hides the fullscreen indication modal with optionnal transition
*
* @param {boolean} [withTransition=false]
*/
hide: function (withTransition = false) {
this.el.classList.toggle('o_transition', withTransition);
this.el.classList.remove('o_visible');
this.visible = false;
},
});
hide() {
if (this.state.isVisible) {
this.state.isVisible = false;
clearTimeout(this.autofade);
}
}
}
FullscreenIndication.template = xml`
<div class="o_fullscreen_indication" t-att-class="{ o_visible: state.isVisible }">
<p>Press <span>esc</span> to exit full screen</p>
</div>`;
@@ -0,0 +1,29 @@
.o_fullscreen_indication {
display: flex;
position: absolute;
width: 100%;
align-items: center;
justify-content: center;
top: 0;
margin-top: $o-navbar-height!important;
opacity: 0;
pointer-events: none;
transition: opacity 400ms ease;
p {
padding: 15px 30px;
background-color: rgba(0, 0, 0, 0.7);
color: white;
span {
border: 1px solid white;
border-color: white;
border-radius: 5px;
padding: 7px 5px;
margin: 5px;
}
}
&.o_visible {
opacity: 1;
}
}
@@ -7,6 +7,8 @@ const _t = str => str;
/**
* This script, served with frontend pages, displays buttons in the top left
* corner to provide the authenticated user an access to his odoo backend.
* In the case of the page being viewed in the website_preview client action,
* it will forward some events to its parent.
*/
document.addEventListener('DOMContentLoaded', () => {
if (session.is_website_user) {
@@ -7,7 +7,6 @@ import {Markup} from 'web.utils';
import session from 'web.session';
import publicRootData from 'web.public.root';
import "web.zoomodoo";
import { FullscreenIndication } from '@website/components/fullscreen_indication/fullscreen_indication';
export const WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMixin, {
// TODO remove KeyboardNavigationMixin in master
@@ -35,16 +34,6 @@ export const WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMi
});
return this._super(...arguments);
},
/**
* @override
*/
willStart: async function () {
this.fullscreenIndication = new FullscreenIndication(this);
return Promise.all([
this._super(...arguments),
this.fullscreenIndication.appendTo(document.body),
]);
},
/**
* @override
*/
@@ -170,45 +159,6 @@ export const WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMi
}
return this._gmapAPILoading;
},
/**
* Toggles the fullscreen mode.
*
* @private
* @param {boolean} state toggle fullscreen on/off (true/false)
*/
_toggleFullscreen(state) {
this.isFullscreen = state;
if (this.isFullscreen) {
this.fullscreenIndication.show();
} else {
this.fullscreenIndication.hide();
}
document.body.classList.add('o_fullscreen_transition');
document.body.classList.toggle('o_fullscreen', this.isFullscreen);
document.body.style.overflowX = 'hidden';
let resizing = true;
window.requestAnimationFrame(function resizeFunction() {
window.dispatchEvent(new Event('resize'));
if (resizing) {
window.requestAnimationFrame(resizeFunction);
}
});
let stopResizing;
const onTransitionEnd = ev => {
if (ev.target === document.body && ev.propertyName === 'padding-top') {
stopResizing();
}
};
stopResizing = () => {
resizing = false;
document.body.style.overflowX = '';
document.body.removeEventListener('transitionend', onTransitionEnd);
document.body.classList.remove('o_fullscreen_transition');
};
document.body.addEventListener('transitionend', onTransitionEnd);
// Safeguard in case the transitionend event doesn't trigger for whatever reason.
window.setTimeout(() => stopResizing(), 500);
},
//--------------------------------------------------------------------------
// Handlers
@@ -329,7 +279,6 @@ export const WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMi
if (ev.keyCode !== $.ui.keyCode.ESCAPE || !document.body.contains(ev.target) || ev.target.closest('.modal')) {
return KeyboardNavigationMixin._onKeyDown.apply(this, arguments);
}
this._toggleFullscreen(!this.isFullscreen);
},
});
@@ -2,7 +2,9 @@
import { registry } from '@web/core/registry';
const { reactive } = owl;
import { FullscreenIndication } from '../components/fullscreen_indication/fullscreen_indication';
const { reactive, EventBus } = owl;
const websiteSystrayRegistry = registry.category('website_systray');
@@ -18,19 +20,33 @@ export const unslugHtmlDataObject = (repr) => {
};
export const websiteService = {
dependencies: ['orm', 'action'],
async start(env, { orm, action }) {
dependencies: ['orm', 'action', 'hotkey'],
async start(env, { orm, action, hotkey }) {
let websites = [];
let currentWebsiteId;
let currentMetadata = {};
let fullscreen;
const context = reactive({
showNewContentModal: false,
});
const bus = new EventBus();
const setCurrentWebsiteId = id => {
currentWebsiteId = id;
websiteSystrayRegistry.trigger('EDIT-WEBSITE');
};
hotkey.add("escape", () => {
// Toggle fullscreen mode when pressing escape.
if (currentWebsiteId) {
fullscreen = !fullscreen;
document.body.classList.toggle('o_website_fullscreen', fullscreen);
bus.trigger((fullscreen ? 'FULLSCREEN-INDICATION-SHOW' : 'FULLSCREEN-INDICATION-HIDE'));
}
});
registry.category('main_components').add('FullscreenIndication', {
Component: FullscreenIndication,
props: { bus },
});
return {
set currentWebsiteId(id) {
setCurrentWebsiteId(id);