feat: Add POS UI optimization module for low-RAM devices, implementing incremental loading and safely removing event listeners.

This commit is contained in:
Suherdy Yacob 2026-03-20 08:34:32 +07:00
parent c238ec5e77
commit 896252b61e
3 changed files with 37 additions and 1 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
*.pyc
*~
__pycache__/
.DS_Store
.vscode/
.idea/

27
README.md Normal file
View File

@ -0,0 +1,27 @@
# POS UI Optimization
This Odoo 19 module optimizes the Point of Sale (POS) user interface for low-RAM devices (e.g., Android tablets with 2GB RAM).
## Features
- **Product List Incremental Loading**: Renders products in batches of 40 as you scroll, significantly reducing memory usage in categories with many products.
- **Order Cart Incremental Loading**: Efficiently handles large orders by rendering order lines incrementally as you scroll through the cart.
- **Improved Responsiveness**: Keeps the browser DOM light and prevents "white blank" screens caused by memory exhaustion.
- **Legacy Browser Support**: Designed without modern ES2020 JavaScript syntax (like optional chaining `?.`) to ensure compatibility with older Android browser engines found on specific legacy POS hardware.
## Installation
1. Place the `pos_ui_optimization` folder in your Odoo custom addons directory.
2. Restart your Odoo server.
3. In Odoo, activate **Developer Mode**.
4. Go to **Apps** -> **Update Apps List**.
5. Search for `POS UI Optimization`.
6. Click **Install**.
## Technical Details
This module uses Odoo's JavaScript patching mechanism (`patch` from `@web/core/utils/patch`) to extend the core POS components:
- `ProductScreen`: Adds `displayedProductsCount` state via `owl`'s `useEffect` and an overridden `onScroll` hook to the product container.
- `OrderDisplay`: Adds `displayedCount` state and a scroll listener to the combo sorted order lines container.
No core Odoo files are modified.

View File

@ -35,7 +35,10 @@ patch(OrderDisplay.prototype, {
});
onWillUnmount(() => {
this.scrollableRef.el?.removeEventListener("scroll", this.onScroll);
const el = this.scrollableRef.el;
if (el) {
el.removeEventListener("scroll", this.onScroll);
}
});
},