[IMP] website, web_editor: add mobile preview

See merge commit for more information.

task-2687506
This commit is contained in:
Younn Olivier
2022-06-24 10:28:06 +02:00
committed by qsm-odoo
parent 212a8bfdd2
commit 3588155534
8 changed files with 84 additions and 82 deletions
@@ -1349,6 +1349,7 @@ var SnippetsMenu = Widget.extend({
}, 50);
this.$window.on('resize.snippets_menu', debouncedCoverUpdate);
this.$body.on('content_changed.snippets_menu', debouncedCoverUpdate);
$(this.$body[0].ownerDocument.defaultView).on('resize.snippets_menu', debouncedCoverUpdate);
// On keydown add a class on the active overlay to hide it and show it
// again when the mouse moves
@@ -3390,8 +3391,8 @@ var SnippetsMenu = Widget.extend({
/**
* Preview on mobile.
*/
_onMobilePreviewClick: async function () {
throw new Error('implement me');
_onMobilePreviewClick: function () {
this.trigger_up('request_mobile_preview');
},
/**
* Undo..
@@ -1,3 +1,14 @@
@mixin o-iframe-position($height) {
// TODO review this, this should not be needed as we want the iframe to
// be centered and potentially respect its aspect ratio whatever the size.
$width: $height * (9 / 16);
height: $height;
width: $width;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.o_website_preview {
position: relative;
height: 100%;
@@ -7,11 +18,32 @@
margin-right: $o-we-sidebar-width !important;
}
> iframe {
@include o-position-absolute(0, 0, 0, 0);
width: 100%;
.o_iframe_container {
position: relative;
height: 100%;
border: none;
width: 100%;
iframe {
position: absolute;
border: none;
width: 100%;
height: 100%;
}
&.o_is_mobile {
@include media-breakpoint-up(md) {
@include o-iframe-position(720px);
@media(max-height: calc(720px + #{$o-navbar-height})) {
@include o-iframe-position(520px);
}
iframe {
border-radius: 25px;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);
}
}
}
}
}
@@ -2,16 +2,18 @@
<templates xml:space="preserve">
<t t-name="website.WebsitePreview" owl="1">
<div class="o_website_preview" t-att-class="{ 'editor_enable editor_has_snippets': this.websiteContext.snippetsLoaded }">
<iframe t-att-src="iframeFallbackUrl"
t-att-class="{ 'd-none': this.websiteContext.edition }"
t-ref="iframefallback"/>
<iframe t-att-src="initialUrl"
class="o_iframe"
t-ref="iframe"
t-on-load="_onPageLoaded"/>
<div class="o_iframe_container" t-att-class="{ 'o_is_mobile': this.websiteContext.isMobile }">
<iframe t-att-src="iframeFallbackUrl"
t-att-class="{ 'd-none': this.websiteContext.edition }"
t-ref="iframefallback"/>
<iframe t-att-src="initialUrl"
class="o_iframe"
t-ref="iframe"
t-on-load="_onPageLoaded"/>
</div>
<WebsiteEditorComponent t-if="websiteContext.edition"
reloadIframe.bind="this.reloadIframe"/>
</div>
<WebsiteEditorComponent t-if="websiteContext.edition"
reloadIframe.bind="this.reloadIframe"/>
</t>
<div t-name="website.homepage_editor_welcome_message" class="container text-center o_homepage_editor_welcome_message">
@@ -633,6 +633,13 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
iframeClone.remove();
}
}
/**
* Update the context to trigger a mobile view.
* @private
*/
_onMobilePreviewRequest() {
this.websiteService.context.isMobile = !this.websiteService.context.isMobile;
}
}
WysiwygAdapterComponent.prototype.events = {
'widgets_start_request': '_onRootEventRequest',
@@ -649,4 +656,5 @@ WysiwygAdapterComponent.prototype.events = {
'reload_bundles': '_reloadBundles',
'menu_dialog': '_onMenuDialogRequest',
'update_color_previews': '_onColorPreviewsUpdate',
'request_mobile_preview': '_onMobilePreviewRequest',
};
@@ -39,6 +39,7 @@ export const websiteService = {
edition: false,
isPublicRootReady: false,
snippetsLoaded: false,
isMobile: false,
});
const bus = new EventBus();
@@ -1,72 +1,19 @@
odoo.define('website.mobile', function (require) {
'use strict';
/** @odoo-module **/
const {_t} = require('web.core');
const {Markup} = require('web.utils');
var Dialog = require('web.Dialog');
var websiteNavbarData = require('website.navbar');
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";
const { registry } = require("@web/core/registry");
const { Component } = owl;
var MobilePreviewDialog = Dialog.extend({
/**
* Tweaks the modal so that it appears as a phone and modifies the iframe
* rendering to show more accurate mobile view.
*
* @override
*/
start: function () {
var self = this;
this.$modal.addClass('oe_mobile_preview');
this.$modal.on('click', '.modal-header', function () {
self.$el.toggleClass('o_invert_orientation');
});
this.$iframe = $('<iframe/>', {
id: 'mobile-viewport',
src: $.param.querystring(window.location.href, 'mobilepreview'),
});
this.$iframe.on('load', function (e) {
self.$iframe.contents().find('body').removeClass('o_connected_user');
self.$iframe.contents().find('#oe_main_menu_navbar').remove();
});
this.$iframe.appendTo(this.$el);
class MobilePreviewSystray extends Component {
setup() {
this.websiteService = useService('website');
}
}
MobilePreviewSystray.template = "website.MobilePreviewSystray";
return this._super.apply(this, arguments);
},
});
var MobileMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({
actions: _.extend({}, websiteNavbarData.WebsiteNavbarActionWidget.prototype.actions || {}, {
'show-mobile-preview': '_onMobilePreviewClick',
}),
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* Called when the mobile action is triggered -> instantiate the mobile
* preview dialog.
*
* @private
*/
_onMobilePreviewClick: function () {
if (this.mobilePreview && !this.mobilePreview.isDestroyed()) {
return this.mobilePreview.close();
}
this.mobilePreview = new MobilePreviewDialog(this, {
title: Markup(_.escape(_t('Mobile preview')) + ' <span class="fa fa-refresh"/>'),
}).open();
},
});
registry.category("website_navbar_widgets").add("MobileMenu", {
Widget: MobileMenu,
selector: '#mobile-menu',
});
return {
MobileMenu: MobileMenu,
MobilePreviewDialog: MobilePreviewDialog,
export const systrayItem = {
Component: MobilePreviewSystray,
};
});
registry.category("website_systray").add("MobilePreview", systrayItem, { sequence: 12 });
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="website.MobilePreviewSystray" owl="1">
<div class="o_mobile_preview o_menu_systray_item" t-on-click="() => this.websiteService.context.isMobile = !this.websiteService.context.isMobile">
<a href="#" accesskey="v"><span title="Mobile preview" role="img" aria-label="Mobile preview" class="fa fa-lg fa-mobile"/></a>
</div>
</t>
</templates>
@@ -3,6 +3,9 @@
<!-- Snippets menu -->
<template id="snippets" inherit_id="web_editor.snippets" primary="True" groups="base.group_user">
<xpath expr="//button[@data-action='cancel']" position="before">
<button type="button" class="btn btn-secondary" data-action="mobile" title="Mobile Preview" accesskey="v"><span class="fa fa-mobile" style="font-size: 18px;"/></button>
</xpath>
<xpath expr="//div[@id='snippets_menu']" position="inside">
<button type="button" tabindex="3" class="o_we_customize_theme_btn text-uppercase"
groups="website.group_website_designer" accesskey="2">