Refactor RoomView component to MyRoom; update imports and related references

- Removed RoomIllustration component and replaced it with MyRoom component in RoomView.
- Updated import paths in exploRUG, roomView-react, and tsconfig.json to reflect the new component structure.
- Enhanced WindowExtended interface in canvasutils to include ordersheet properties.
- Modified convertArrIntoRad function to accept any type for input array.
- Cleaned up encoding function for colors to improve readability.
This commit is contained in:
2026-04-24 14:41:09 +05:45
parent daaa5bd7ad
commit b95ab43425
12 changed files with 3393 additions and 1827 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
// src/room-illustration.ts
import {LitElement, html, css} from 'lit';
import {customElement, property, query, state} from 'lit/decorators.js';
import {RoomViewHelper} from './helpers/MyRoomViewHelper';
import type {
RoomData,
DesignDetails,
CarpetOptions,
AvailableSize,
} from './types';
let roomViewHelper = new RoomViewHelper();
@customElement('room-illustration')
export class RoomIllustration extends LitElement {
// ─── Props in (replaces all useXxxState() hook reads) ────────────────
@property({type: Object}) roomData: RoomData | null = null;
@property({type: Object}) designDetails: DesignDetails | null = null;
@property({type: Object}) carpetOptions: CarpetOptions | null = null;
@property({type: Object}) activeColor: {Color: string} | null = null;
@property({type: Object}) selectedSize: AvailableSize | null = null;
@property({type: Boolean}) isIdle = false;
// ─── Internal state (replaces useState) ──────────────────────────────
@state() private shotReady = false;
@state() private transition = -1;
// ─── Canvas refs (replaces useRef) ───────────────────────────────────
@query('.container') private containerEl!: HTMLDivElement;
@query('.bg-canvas') private bgCanvas!: HTMLCanvasElement;
@query('.three-canvas') private threeCanvas!: HTMLCanvasElement;
@query('.mask-canvas') private maskCanvas!: HTMLCanvasElement;
@query('.shadow-canvas') private shadowCanvas!: HTMLCanvasElement;
@query('.input-canvas') private inputCanvas!: HTMLCanvasElement;
@query('.obj-container') private objContainer!: HTMLDivElement;
// ─── Lifecycle ────────────────────────────────────────────────────────
override firstUpdated() {
// Equivalent to useMount in React — canvases are in the DOM
// roomViewHelper.initCanvas({
// bgCanvas: this.bgCanvas,
// threeCanvas: this.threeCanvas,
// maskCanvas: this.maskCanvas,
// shadowCanvas: this.shadowCanvas,
// container: this.containerEl,
// inputCanvas: this.inputCanvas,
// objCanvasContainer: this.objContainer,
// });
window.addEventListener('resize', () => this.sizeContainers());
}
override updated(changed: Map<string, unknown>) {
// if (changed.has('roomData') && this.roomData) {
// this.loadRoom();
// }
// if (changed.has('carpetOptions') && this.carpetOptions && this.shotReady) {
// this.updateCarpet();
// }
// if (changed.has('activeColor') && this.activeColor && this.shotReady) {
// roomViewHelper.updateBackground({
// dominantColorHex: this.activeColor.Color,
// });
// roomViewHelper.updateMask();
// roomViewHelper.updateShadow();
// }
// if (changed.has('selectedSize') && this.selectedSize) {
// roomViewHelper.change3dObjectScale(this.selectedSize);
// }
}
override disconnectedCallback() {
super.disconnectedCallback();
window.removeEventListener('resize', () => this.sizeContainers());
// roomViewHelper.clearAll();
}
// ─── Internal methods (replaces inline useEffect logic) ──────────────
private async loadRoom() {
// if (!this.roomData) return;
// const {config, baseUrl, files, shot} = this.roomData;
// roomViewHelper.clearAll();
// roomViewHelper.initConfig({baseUrl, config, files});
// this.sizeContainers();
// await this.initShot({shot: shot ?? config.defaultShot});
}
private async initShot(options: {shot: string}) {
// mirrors initShot logic from IllustrationView/index.jsx
// ...
this.shotReady = true;
this.emitRenderingComplete();
}
private async updateCarpet() {
if (!this.carpetOptions) return;
// await roomViewHelper.updateCarpetRotation(this.carpetOptions.rotation);
// await roomViewHelper.updateCarpetPosition(this.carpetOptions.position);
// await roomViewHelper.updateShadow();
}
private sizeContainers() {
// resize canvas to container size
}
// ─── Events out (replaces callback props) ────────────────────────────
private emitRenderingComplete() {
this.dispatchEvent(
new CustomEvent('rendering-complete', {bubbles: true, composed: true})
);
}
private emitSizesChange(sizes: AvailableSize[]) {
this.dispatchEvent(
new CustomEvent('sizes-change', {
detail: sizes,
bubbles: true,
composed: true,
})
);
}
private emitActiveClick() {
this.dispatchEvent(
new CustomEvent('active-click', {bubbles: true, composed: true})
);
}
// ─── Template (replaces JSX canvas layout) ───────────────────────────
static override styles = css`
:host {
display: block;
position: relative;
width: 100%;
height: 100%;
}
.container {
position: relative;
width: 100%;
height: 100%;
}
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
`;
override render() {
return html`
<div class="container">
<canvas class="bg-canvas"></canvas>
<canvas class="three-canvas"></canvas>
<canvas class="mask-canvas"></canvas>
<canvas class="shadow-canvas"></canvas>
<canvas class="input-canvas"></canvas>
<div class="obj-container"></div>
</div>
`;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,168 +0,0 @@
// src/room-illustration.ts
import {LitElement, html, css} from 'lit';
import {customElement, property, query, state} from 'lit/decorators.js';
import {RoomViewHelper} from './helpers/RoomViewHelper';
import type {
RoomData,
DesignDetails,
CarpetOptions,
AvailableSize,
} from './types';
let roomViewHelper = new RoomViewHelper();
@customElement('room-illustration')
export class RoomIllustration extends LitElement {
// ─── Props in (replaces all useXxxState() hook reads) ────────────────
@property({type: Object}) roomData: RoomData | null = null;
@property({type: Object}) designDetails: DesignDetails | null = null;
@property({type: Object}) carpetOptions: CarpetOptions | null = null;
@property({type: Object}) activeColor: {Color: string} | null = null;
@property({type: Object}) selectedSize: AvailableSize | null = null;
@property({type: Boolean}) isIdle = false;
// ─── Internal state (replaces useState) ──────────────────────────────
@state() private shotReady = false;
@state() private transition = -1;
// ─── Canvas refs (replaces useRef) ───────────────────────────────────
@query('.container') private containerEl!: HTMLDivElement;
@query('.bg-canvas') private bgCanvas!: HTMLCanvasElement;
@query('.three-canvas') private threeCanvas!: HTMLCanvasElement;
@query('.mask-canvas') private maskCanvas!: HTMLCanvasElement;
@query('.shadow-canvas') private shadowCanvas!: HTMLCanvasElement;
@query('.input-canvas') private inputCanvas!: HTMLCanvasElement;
@query('.obj-container') private objContainer!: HTMLDivElement;
// ─── Lifecycle ────────────────────────────────────────────────────────
override firstUpdated() {
// Equivalent to useMount in React — canvases are in the DOM
// roomViewHelper.initCanvas({
// bgCanvas: this.bgCanvas,
// threeCanvas: this.threeCanvas,
// maskCanvas: this.maskCanvas,
// shadowCanvas: this.shadowCanvas,
// container: this.containerEl,
// inputCanvas: this.inputCanvas,
// objCanvasContainer: this.objContainer,
// });
window.addEventListener('resize', () => this.sizeContainers());
}
override updated(changed: Map<string, unknown>) {
// if (changed.has('roomData') && this.roomData) {
// this.loadRoom();
// }
// if (changed.has('carpetOptions') && this.carpetOptions && this.shotReady) {
// this.updateCarpet();
// }
// if (changed.has('activeColor') && this.activeColor && this.shotReady) {
// roomViewHelper.updateBackground({
// dominantColorHex: this.activeColor.Color,
// });
// roomViewHelper.updateMask();
// roomViewHelper.updateShadow();
// }
// if (changed.has('selectedSize') && this.selectedSize) {
// roomViewHelper.change3dObjectScale(this.selectedSize);
// }
}
override disconnectedCallback() {
super.disconnectedCallback();
window.removeEventListener('resize', () => this.sizeContainers());
// roomViewHelper.clearAll();
}
// ─── Internal methods (replaces inline useEffect logic) ──────────────
private async loadRoom() {
// if (!this.roomData) return;
// const {config, baseUrl, files, shot} = this.roomData;
// roomViewHelper.clearAll();
// roomViewHelper.initConfig({baseUrl, config, files});
// this.sizeContainers();
// await this.initShot({shot: shot ?? config.defaultShot});
}
private async initShot(options: {shot: string}) {
// mirrors initShot logic from IllustrationView/index.jsx
// ...
this.shotReady = true;
this.emitRenderingComplete();
}
private async updateCarpet() {
if (!this.carpetOptions) return;
// await roomViewHelper.updateCarpetRotation(this.carpetOptions.rotation);
// await roomViewHelper.updateCarpetPosition(this.carpetOptions.position);
// await roomViewHelper.updateShadow();
}
private sizeContainers() {
// resize canvas to container size
}
// ─── Events out (replaces callback props) ────────────────────────────
private emitRenderingComplete() {
this.dispatchEvent(
new CustomEvent('rendering-complete', {bubbles: true, composed: true})
);
}
private emitSizesChange(sizes: AvailableSize[]) {
this.dispatchEvent(
new CustomEvent('sizes-change', {
detail: sizes,
bubbles: true,
composed: true,
})
);
}
private emitActiveClick() {
this.dispatchEvent(
new CustomEvent('active-click', {bubbles: true, composed: true})
);
}
// ─── Template (replaces JSX canvas layout) ───────────────────────────
static override styles = css`
:host {
display: block;
position: relative;
width: 100%;
height: 100%;
}
.container {
position: relative;
width: 100%;
height: 100%;
}
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
`;
override render() {
return html`
<div class="container">
<canvas class="bg-canvas"></canvas>
<canvas class="three-canvas"></canvas>
<canvas class="mask-canvas"></canvas>
<canvas class="shadow-canvas"></canvas>
<canvas class="input-canvas"></canvas>
<div class="obj-container"></div>
</div>
`;
}
}

View File

@@ -1,2 +1,2 @@
import '../Components/RoomView/index.js'; import '../Components/MyRoom/index.js';
import '../react-wrapper/roomView-react.js'; import '../react-wrapper/roomView-react.js';

View File

@@ -8,7 +8,13 @@ declare const AppProvider: {
interface WindowExtended extends Window { interface WindowExtended extends Window {
flutter_inappwebview?: {callHandler: (name: string, data: string) => void}; flutter_inappwebview?: {callHandler: (name: string, data: string) => void};
isNativeApp?: boolean; isNativeApp?: boolean;
flags: {inhouseChanges: {saveFunctionForFlutter?: boolean}}; flags: {
inhouseChanges: {saveFunctionForFlutter?: boolean};
ordersheet: {
showAreaInM2?: boolean;
showTotalAreaInYards?: boolean;
};
};
getByteData?: string; getByteData?: string;
} }

View File

@@ -86,8 +86,8 @@ export const convertUnits = (
return convertedValue; return convertedValue;
}; };
export function convertArrIntoRad(arrDeg: number[]): number[] { export function convertArrIntoRad(arrDeg: any) {
return arrDeg.map((angle) => (angle * Math.PI) / 180); return arrDeg.map((angle: any) => (angle * Math.PI) / 180);
} }
export const convertArrintoDeg = (arrRad: number[]): number[] => export const convertArrintoDeg = (arrRad: number[]): number[] =>
@@ -579,7 +579,9 @@ export const decodeColorsFromString = (str: string): unknown => {
export const encodeColorsToString = (colors: unknown): string => { export const encodeColorsToString = (colors: unknown): string => {
const compressed = Pako.deflate(JSON.stringify(colors)); const compressed = Pako.deflate(JSON.stringify(colors));
const binaryStr = Array.from(compressed, (c) => String.fromCharCode(c)).join(''); const binaryStr = Array.from(compressed, (c) => String.fromCharCode(c)).join(
''
);
return window.btoa(binaryStr); return window.btoa(binaryStr);
}; };

View File

@@ -1,7 +1,7 @@
// react-wrapper/index.ts // react-wrapper/index.ts
import {createComponent} from '@lit/react'; import {createComponent} from '@lit/react';
import React from 'react'; import React from 'react';
import {RoomIllustration} from '../Components/RoomView'; import {RoomIllustration} from '../Components/MyRoom';
export const RoomIllustrationReact = createComponent({ export const RoomIllustrationReact = createComponent({
react: React, react: React,

View File

@@ -29,6 +29,6 @@
], ],
"types": ["mocha"] "types": ["mocha"]
}, },
"include": ["src/**/*.ts", "src/Components/RoomView/helpers/RoomViewHelper.js"], "include": ["src/**/*.ts", "src/Components/MyRoom/helpers/RoomViewHelper.js"],
"exclude": [] "exclude": []
} }