Skip to content

Commit

Permalink
widgets model update optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikita-Polyakov committed Mar 18, 2024
1 parent 553df1d commit 1b28bee
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 24 deletions.
54 changes: 33 additions & 21 deletions src/components/shared/Widget/Grid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,15 @@
<script lang="ts">
import debounce from 'lodash/debounce';
import cloneDeep from 'lodash/fp/cloneDeep';
import isEmpty from 'lodash/fp/isEmpty';
import isEqual from 'lodash/fp/isEqual';
import { GridLayout, GridItem } from 'vue-grid-layout';
import { Component, Emit, Prop, Vue, Watch } from 'vue-property-decorator';
import { Breakpoint, BreakpointKey } from '@/consts/layout';
import type { Layout, LayoutConfig, ResponsiveLayouts, LayoutWidget } from '@/types/layout';
import type { Layout, LayoutConfig, ResponsiveLayouts, LayoutWidget, WidgetsVisibilityModel } from '@/types/layout';
import { layoutsStorage } from '@/utils/storage';
type WidgetsVisibilityModel = Record<string, boolean>;
const DEFAULT_BREAKPOINTS: LayoutConfig = {
[BreakpointKey.lg]: Breakpoint.HugeDesktop, // 2092
[BreakpointKey.md]: Breakpoint.LargeDesktop, // 1440
Expand All @@ -58,6 +57,17 @@ const DEFAULT_COLS: LayoutConfig = {
[BreakpointKey.xss]: 4,
};
function findWidgetInLayout(layout: Nullable<Layout>, widgetId: string) {
return layout?.find((widget: LayoutWidget) => widget.i === widgetId);
}
function shallowDiff<T>(a: T, b: T): Partial<T> {
return Object.entries(a).reduce(
(diff, [key, value]) => (isEqual(b[key], value) ? diff : { ...diff, [key]: value }),
{}
);
}
@Component({
components: {
GridLayout,
Expand All @@ -66,7 +76,7 @@ const DEFAULT_COLS: LayoutConfig = {
})
export default class WidgetsGrid extends Vue {
/** Layout ID to sync it with storage */
@Prop({ default: '', type: String }) readonly id!: string;
@Prop({ default: '', type: String }) readonly gridId!: string;
/** Default layouts */
@Prop({ default: () => ({}), type: Object }) readonly defaultLayouts!: ResponsiveLayouts;
Expand All @@ -85,27 +95,29 @@ export default class WidgetsGrid extends Vue {
/** Update layouts depends on widgets visibility */
@Watch('value')
private updateLayoutWidgets(curr: WidgetsVisibilityModel, prev: WidgetsVisibilityModel): void {
if (!!prev && !!curr && isEqual(curr)(prev)) return;
const diff = shallowDiff(curr, prev);
if (isEmpty(diff)) return;
const layouts = cloneDeep(this.layouts);
Object.entries(this.value).forEach(([widgetId, visibilityFlag]) => {
Object.keys(layouts).forEach((key) => {
for (const [widgetId, visibilityFlag] of Object.entries(diff)) {
for (const breakpoint in layouts) {
if (visibilityFlag) {
const currentWidget = layouts[key].find((widget: LayoutWidget) => widget.i === widgetId);
const currentWidget = findWidgetInLayout(layouts[breakpoint], widgetId);
if (!currentWidget) {
const defaultWidget = this.defaultLayouts[key].find((widget: LayoutWidget) => widget.i === widgetId);
if (currentWidget) continue;
if (defaultWidget) {
layouts[key] = [...layouts[key], { ...defaultWidget }];
}
const defaultWidget = findWidgetInLayout(this.defaultLayouts[breakpoint], widgetId);
if (defaultWidget) {
layouts[breakpoint].push(defaultWidget);
}
} else {
layouts[key] = layouts[key].filter((widget: LayoutWidget) => widget.i !== widgetId);
layouts[breakpoint] = layouts[breakpoint].filter((widget: LayoutWidget) => widget.i !== widgetId);
}
});
});
}
}
this.saveLayouts(layouts);
}
Expand Down Expand Up @@ -152,7 +164,7 @@ export default class WidgetsGrid extends Vue {
}
created(): void {
const storedLayouts = layoutsStorage.get(this.id);
const storedLayouts = layoutsStorage.get(this.gridId);
this.layouts = storedLayouts ? JSON.parse(storedLayouts) : cloneDeep(this.defaultLayouts);
Expand All @@ -162,18 +174,18 @@ export default class WidgetsGrid extends Vue {
private saveLayouts(layouts: ResponsiveLayouts): void {
this.layouts = cloneDeep(layouts);
// update layouts in storage
if (this.id) {
layoutsStorage.set(this.id, JSON.stringify(this.layouts));
if (this.gridId) {
layoutsStorage.set(this.gridId, JSON.stringify(this.layouts));
}
}
onBreakpointChanged(newBreakpoint: BreakpointKey): void {
this.breakpoint = newBreakpoint;
}
onResize(id: string, rect: DOMRect): void {
onResize(widgetId: string, rect: DOMRect): void {
const layout = cloneDeep(this.layout);
const widget = layout.find((item: LayoutWidget) => item.i === id);
const widget = findWidgetInLayout(layout, widgetId);
if (!widget) return;
Expand Down
1 change: 0 additions & 1 deletion src/store/swap/getters.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { LiquiditySourceTypes } from '@sora-substrate/liquidity-proxy/build/consts';
import { api } from '@soramitsu/soraneo-wallet-web';
import { defineGetters } from 'direct-vuex';
import isEmpty from 'lodash/fp/isEmpty';

import {
LiquiditySourceForMarketAlgorithm,
Expand Down
2 changes: 2 additions & 0 deletions src/types/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ export type LayoutConfig = BreakpointConfig<number>;
export type Layout = LayoutWidget[];

export type ResponsiveLayouts = Partial<BreakpointConfig<Layout>>;

export type WidgetsVisibilityModel = Record<string, boolean>;
5 changes: 3 additions & 2 deletions src/views/Swap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
</div>
</div>
<widgets-grid
grid-id="swapGrid"
class="swap-container"
:draggable="draggable"
:resizable="resizable"
Expand Down Expand Up @@ -59,7 +60,7 @@ import TranslationMixin from '@/components/mixins/TranslationMixin';
import { Components, PageNames } from '@/consts';
import { lazyComponent } from '@/router';
import { action, getter, state } from '@/store/decorators';
import type { ResponsiveLayouts } from '@/types/layout';
import type { ResponsiveLayouts, WidgetsVisibilityModel } from '@/types/layout';
import type { AccountAsset } from '@sora-substrate/util/build/assets/types';
Expand Down Expand Up @@ -116,7 +117,7 @@ export default class Swap extends Mixins(mixins.LoadingMixin, TranslationMixin,
compact = false;
lines = false;
widgets = {
widgets: WidgetsVisibilityModel = {
[SwapWidgets.Form]: true,
[SwapWidgets.Chart]: true,
[SwapWidgets.Distribution]: true,
Expand Down

0 comments on commit 1b28bee

Please sign in to comment.