Skip to content

Commit

Permalink
fix: freeze Content components while editing text
Browse files Browse the repository at this point in the history
Closes: #576
  • Loading branch information
semiaddict committed Jan 10, 2023
1 parent bd9ab0d commit 2ec2384
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
preview,
dragging,
resizing,
frozen,
'drag-over': dragOver,
}"
@click="onClick"
Expand Down Expand Up @@ -181,6 +182,9 @@ export default {
locked() {
return this.store.isComponentLocked(this.component);
},
frozen() {
return this.store.isComponentFrozen(this.component);
},
interactable() {
return (
(this.model.$isPositionable || this.model.$isResizable) &&
Expand Down
20 changes: 19 additions & 1 deletion packages/editor/modules/app_preview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { readonly } from "vue";
import { storeToRefs } from "pinia";
import AbstractModule from "@metascore-library/core/services/module-manager/AbstractModule";
import useStore from "./store";
import storePlugin from "./store/plugin";
import AppComponents from "@metascore-library/core/modules/app_components";
import AppRenderer from "@metascore-library/core/modules/app_renderer";
import ContextMenu from "@metascore-library/core/modules/contextmenu";
Expand Down Expand Up @@ -31,7 +32,7 @@ export default class AppPreviewModule extends AbstractModule {
MediaPlayer,
];

constructor({ app }) {
constructor({ app, pinia }) {
super(arguments);

// Override the app_components' component-wrapper.
Expand All @@ -43,6 +44,8 @@ export default class AppPreviewModule extends AbstractModule {
app.component("AppZoomController", AppZoomController);
app.component("AppDimensionsController", AppDimensionsController);
app.component("AppPreviewToggler", AppPreviewToggler);

pinia.use(storePlugin);
}

get preview() {
Expand Down Expand Up @@ -88,6 +91,21 @@ export default class AppPreviewModule extends AbstractModule {
return store.unlockComponent(component);
}

isComponentFrozen(component) {
const store = useStore();
return store.isComponentFrozen(component);
}

freezeComponent(component) {
const store = useStore();
return store.freezeComponent(component);
}

unfreezeComponent(component) {
const store = useStore();
return store.unfreezeComponent(component);
}

componentHasSelectedDescendents(component) {
const store = useStore();
return store.componentHasSelectedDescendents(component);
Expand Down
134 changes: 88 additions & 46 deletions packages/editor/modules/app_preview/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ export default defineStore("app-preview", {
zoom: 1,
preview: false,
iframe: null,
selectedComponents: [],
lockedComponents: [],
selectedComponents: {},
lockedComponents: {},
frozenComponents: {},
activeSnapTargets: [],
};
},
Expand All @@ -33,24 +34,28 @@ export default defineStore("app-preview", {
};
},
isComponentSelected() {
return (component) => {
return ({ type, id }) => {
const { getComponent } = useModule("app_components");
return this.selectedComponents.some(({ type, id }) => {
return (
component.type === type &&
component.id === id &&
getComponent(type, id)
);
});
return (
this.selectedComponents[type]?.includes(id) && getComponent(type, id)
);
};
},
getSelectedComponents() {
const { getComponent } = useModule("app_components");
return this.selectedComponents
.map(({ type, id }) => {
return getComponent(type, id);
})
.filter((c) => c);
return Object.entries(this.selectedComponents).reduce(
(acc, [type, ids]) => {
return [
...acc,
...ids
.map((id) => {
return getComponent(type, id);
})
.filter((c) => c),
];
},
[]
);
},
componentHasSelectedDescendents() {
return (component) => {
Expand All @@ -66,24 +71,42 @@ export default defineStore("app-preview", {
};
},
isComponentLocked() {
return (component) => {
return ({ type, id }) => {
const { getComponent } = useModule("app_components");
return this.lockedComponents.some(({ type, id }) => {
return (
component.type === type &&
component.id === id &&
getComponent(type, id)
);
});
return (
this.lockedComponents[type]?.includes(id) && getComponent(type, id)
);
};
},
getLockedComponents() {
const { getComponent } = useModule("app_components");
return this.lockedComponents
.map(({ type, id }) => {
return getComponent(type, id);
})
.filter((c) => c);
return Object.entries(this.lockedComponents).reduce(
(acc, [type, ids]) => {
return [
...acc,
...ids
.map((id) => {
return getComponent(type, id);
})
.filter((c) => c),
];
},
[]
);
},
isComponentFrozen() {
return ({ type, id }) => {
return (
type in this.frozenComponents && id in this.frozenComponents[type]
);
};
},
getFrozenComponent() {
return ({ type, id }) => {
if (this.isComponentFrozen({ type, id })) {
return this.frozenComponents[type][id];
}
};
},
},
actions: {
Expand All @@ -92,24 +115,25 @@ export default defineStore("app-preview", {
this.deselectAllComponents();
}
if (!this.isComponentSelected(component)) {
this.selectedComponents.push({
type: component.type,
id: component.id,
});
this.selectedComponents[component.type] =
this.selectedComponents[component.type] || [];
this.selectedComponents[component.type].push(component.id);
}
},
deselectComponent(component) {
this.selectedComponents = this.selectedComponents.filter(
({ type, id }) => {
return !(component.type === type && component.id === id);
}
);
if (this.isComponentSelected(component)) {
this.selectedComponents[component.type] = this.selectedComponents[
component.type
].filter((id) => {
return component.id !== id;
});
}
},
deselectComponents(components) {
components.map(this.deselectComponent);
},
deselectAllComponents() {
this.selectedComponents = [];
this.selectedComponents = {};
},
moveComponentSelection(reverse = false) {
const selected = this.getSelectedComponents;
Expand Down Expand Up @@ -137,25 +161,43 @@ export default defineStore("app-preview", {
},
lockComponent(component) {
if (!this.isComponentLocked(component)) {
this.lockedComponents.push({
type: component.type,
id: component.id,
});
this.lockedComponents[component.type] =
this.lockedComponents[component.type] || [];
this.lockedComponents[component.type].push(component.id);
}
},
lockComponents(components) {
components.map(this.lockComponent);
},
unlockComponent(component) {
this.lockedComponents = this.lockedComponents.filter(({ type, id }) => {
return !(component.type === type && component.id === id);
});
if (this.isComponentLocked(component)) {
this.lockedComponents[component.type] = this.lockedComponents[
component.type
].filter((id) => {
return component.id !== id;
});
}
},
unlockComponents(components) {
components.map(this.unlockComponent);
},
unlockAllComponents() {
this.lockedComponents = [];
this.lockedComponents = {};
},
freezeComponent(component) {
if (!this.isComponentFrozen(component)) {
const { getComponent } = useModule("app_components");
this.frozenComponents[component.type] =
this.frozenComponents[component.type] || {};
this.frozenComponents[component.type][component.id] = structuredClone(
getComponent(component.type, component.id)
);
}
},
unfreezeComponent(component) {
if (this.isComponentFrozen(component)) {
delete this.frozenComponents[component.type][component.id];
}
},
copyComponents(components) {
const { setData: setClipboardData } = useModule("clipboard");
Expand Down
26 changes: 26 additions & 0 deletions packages/editor/modules/app_preview/store/plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import useStore from "./";

export default function ({ store }) {
if (store.$id !== "app-components") return;

const original_get = store.get;

return {
/**
* Override the app-components's "get" action.
*
* @param {string} type The component's type
* @param {string} id The component's id
* @returns {object} The component's data
*/
get(type, id) {
const { isComponentFrozen, getFrozenComponent } = useStore();
if (isComponentFrozen({ type, id })) {
// Get frozen component data.
return getFrozenComponent({ type, id });
}

return original_get(type, id);
},
};
}
Loading

0 comments on commit 2ec2384

Please sign in to comment.