mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
119 lines
3.1 KiB
JavaScript
119 lines
3.1 KiB
JavaScript
|
|
// In this example, we show how one can design an application that is responsive:
|
||
|
|
// its UI is different in mobile mode or in desktop mode.
|
||
|
|
//
|
||
|
|
// The main idea is to have a "isMobile" key in the environment, then listen
|
||
|
|
// to resize events and update the env if needed. Then, the whole interface
|
||
|
|
// will be updated, creating and destroying components as needed.
|
||
|
|
//
|
||
|
|
// To see this in action, try resizing the window. The application will switch
|
||
|
|
// to mobile mode whenever it has less than 768px.
|
||
|
|
import { Component, useState, mount, reactive, useEnv } from "@odoo/owl";
|
||
|
|
|
||
|
|
//------------------------------------------------------------------------------
|
||
|
|
// Helpers
|
||
|
|
//------------------------------------------------------------------------------
|
||
|
|
|
||
|
|
function debounce(func, wait, immediate) {
|
||
|
|
let timeout;
|
||
|
|
return function () {
|
||
|
|
const context = this;
|
||
|
|
const args = arguments;
|
||
|
|
function later() {
|
||
|
|
timeout = null;
|
||
|
|
if (!immediate) {
|
||
|
|
func.apply(context, args);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const callNow = immediate && !timeout;
|
||
|
|
clearTimeout(timeout);
|
||
|
|
timeout = setTimeout(later, wait);
|
||
|
|
if (callNow) {
|
||
|
|
func.apply(context, args);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
//------------------------------------------------------------------------------
|
||
|
|
// Responsive hook
|
||
|
|
//------------------------------------------------------------------------------
|
||
|
|
|
||
|
|
function createUI() {
|
||
|
|
const getIsMobile = () => window.innerWidth <= 768;
|
||
|
|
|
||
|
|
const ui = reactive({ isMobile: getIsMobile() });
|
||
|
|
|
||
|
|
const updateEnv = debounce(() => {
|
||
|
|
const isMobile = getIsMobile();
|
||
|
|
if (ui.isMobile !== isMobile) {
|
||
|
|
ui.isMobile = isMobile;
|
||
|
|
}
|
||
|
|
}, 15);
|
||
|
|
window.addEventListener("resize", updateEnv);
|
||
|
|
return ui;
|
||
|
|
}
|
||
|
|
|
||
|
|
function useUI() {
|
||
|
|
const env = useEnv();
|
||
|
|
return useState(env.ui);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//------------------------------------------------------------------------------
|
||
|
|
// Components
|
||
|
|
//------------------------------------------------------------------------------
|
||
|
|
class Navbar extends Component {
|
||
|
|
static template = "Navbar";
|
||
|
|
}
|
||
|
|
|
||
|
|
class MobileSearchView extends Component {
|
||
|
|
static template = "MobileSearchView";
|
||
|
|
}
|
||
|
|
|
||
|
|
class ControlPanel extends Component {
|
||
|
|
static template = "ControlPanel";
|
||
|
|
static components = { MobileSearchView };
|
||
|
|
setup() {
|
||
|
|
this.ui = useUI();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
class AdvancedComponent extends Component {
|
||
|
|
static template = "AdvancedComponent";
|
||
|
|
}
|
||
|
|
|
||
|
|
class FormView extends Component {
|
||
|
|
static template = "FormView";
|
||
|
|
static components = { AdvancedComponent };
|
||
|
|
setup() {
|
||
|
|
this.ui = useUI();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
class Chatter extends Component {
|
||
|
|
static template = "Chatter";
|
||
|
|
|
||
|
|
setup() {
|
||
|
|
this.messages = Array.from(Array(100).keys());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
class Root extends Component {
|
||
|
|
static template = "Root";
|
||
|
|
static components = { Navbar, ControlPanel, FormView, Chatter };
|
||
|
|
|
||
|
|
setup() {
|
||
|
|
this.ui = useUI();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//------------------------------------------------------------------------------
|
||
|
|
// Application Startup
|
||
|
|
//------------------------------------------------------------------------------
|
||
|
|
const env = {
|
||
|
|
ui: createUI()
|
||
|
|
};
|
||
|
|
|
||
|
|
mount(Root, document.body, { templates: TEMPLATES, env, dev: true });
|