Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Layout Editor #2356

Merged
merged 40 commits into from
Dec 20, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
dc05eca
Reorganize file structure
gettinToasty Dec 4, 2019
72de2e3
Merge branch 'staging' into sb_modular_editor_2
gettinToasty Dec 5, 2019
762d297
Add functionality to layout editor
gettinToasty Dec 6, 2019
332385e
Fix bug where element is dropped onto span tag
gettinToasty Dec 6, 2019
6494dd5
Add ability to drag placed elements
gettinToasty Dec 7, 2019
c3ea292
Add layout selector images
gettinToasty Dec 9, 2019
1ed78ce
Add templates for remaining layouts
gettinToasty Dec 9, 2019
18f1987
Add remaining layouts
gettinToasty Dec 9, 2019
d1883a8
Improve swappability of layout elements
gettinToasty Dec 10, 2019
06ed3ce
Split out MiniFeed and LegacyEvents
gettinToasty Dec 10, 2019
ee61bea
Fix resizing issue in Triplets
gettinToasty Dec 10, 2019
868aa2c
Address CC
gettinToasty Dec 10, 2019
f6b8250
Address CC
gettinToasty Dec 10, 2019
8cc0664
Fix resizing in OnePane and Triplets
gettinToasty Dec 10, 2019
3556cce
Fix resize for default template
gettinToasty Dec 11, 2019
30e3ac3
Port other layouts to new system
gettinToasty Dec 11, 2019
8e55ac6
Fix nested minimums
gettinToasty Dec 11, 2019
ed2b437
Fix setting the max size
gettinToasty Dec 12, 2019
d9331dc
Merge branch 'staging' into sb_modular_editor_2
gettinToasty Dec 12, 2019
ae9f470
Add default minimums
gettinToasty Dec 12, 2019
5dead29
Fix editor view while expanding chat
gettinToasty Dec 13, 2019
0f7c6c5
Merge branch 'staging' into sb_modular_editor_2
gettinToasty Dec 13, 2019
43862a7
Fix edge case with layout editor not clearing elements correctly
gettinToasty Dec 13, 2019
b05e6dd
Add migration for legacy events users
gettinToasty Dec 13, 2019
957ed23
Refactor layouts to inherit from a common base
gettinToasty Dec 14, 2019
47b35df
Fix zombie element
gettinToasty Dec 14, 2019
a8afc30
Fix performance mode
gettinToasty Dec 16, 2019
0e690e3
Fix no slotted elements error
gettinToasty Dec 16, 2019
989c68e
Fix unplaced elements re-appearing in some cases
gettinToasty Dec 16, 2019
0e13a5e
Make the cursor a pointer on the disable preview button
gettinToasty Dec 16, 2019
3716dcf
Fix object comparison for migration
gettinToasty Dec 16, 2019
9bca8b4
Remove un-needed imports
gettinToasty Dec 17, 2019
5e05ce8
Fix minimums being incorrectly set with blank components
gettinToasty Dec 17, 2019
2ee3cb1
Merge branch 'staging' into sb_modular_editor_2
gettinToasty Dec 17, 2019
587606d
Remove error causing console log
gettinToasty Dec 17, 2019
00ea945
Properly resize after chat expands
gettinToasty Dec 17, 2019
6ae3997
Fix jank while resizing some components
gettinToasty Dec 18, 2019
bc64aa8
Ensure vue reactivity with all elements in the editor
gettinToasty Dec 18, 2019
95c234c
Fix issue with resizing row-based layouts
gettinToasty Dec 18, 2019
3ee33c1
Fix resizing with single bar layouts
gettinToasty Dec 18, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix editor view while expanding chat
  • Loading branch information
gettinToasty committed Dec 13, 2019
commit 5dead29afa048e487851a1fdec2e88181a32a3e2
12 changes: 11 additions & 1 deletion app/components/editor/layouts/Classic.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import cx from 'classnames';
import TsxComponent, { createProps } from 'components/tsx-component';
import { Component } from 'vue-property-decorator';
import { Component, Watch } from 'vue-property-decorator';
import ResizeBar from 'components/shared/ResizeBar.vue';
import styles from './Layouts.m.less';
import { LayoutProps } from './Default';
Expand All @@ -10,11 +10,21 @@ export default class Classic extends TsxComponent<LayoutProps> {
mounted() {
window.addEventListener('resize', () => this.props.windowResizeHandler(this.mins));
this.props.windowResizeHandler(this.mins);
this.$emit('totalWidth', ['1', ['2', '3', '4']]);
}
destroyed() {
window.removeEventListener('resize', () => this.props.windowResizeHandler(this.mins));
}

get totalWidth() {
return this.props.elWidth;
}

@Watch('totalWidth')
updateSize() {
this.props.windowResizeHandler(this.mins);
}

get mins() {
return {
bar1: this.props.calculateMin(['2', '3', '4']),
Expand Down
13 changes: 12 additions & 1 deletion app/components/editor/layouts/Default.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import cx from 'classnames';
import TsxComponent, { createProps } from 'components/tsx-component';
import { Component } from 'vue-property-decorator';
import { Component, Watch } from 'vue-property-decorator';
import ResizeBar from 'components/shared/ResizeBar.vue';
import { LayoutSlot } from 'services/layout';
import styles from './Layouts.m.less';
Expand All @@ -13,6 +13,7 @@ export class LayoutProps {
setBarResize: (bar: 'bar1' | 'bar2', size: number, mins?: IResizeMins) => void = () => {};
windowResizeHandler: (mins: IResizeMins) => void = () => {};
resizes: { bar1: number; bar2: number } = null;
elWidth: number = 0;
}

// the minimums here represent the asbolute minimum of a viable component (minimized to invisibility)
Expand All @@ -28,11 +29,21 @@ export default class Default extends TsxComponent<LayoutProps> {
mounted() {
window.addEventListener('resize', () => this.props.windowResizeHandler(this.mins));
this.props.windowResizeHandler(this.mins);
this.$emit('totalWidth', ['1', '2', ['3', '4', '5']]);
}
destroyed() {
window.removeEventListener('resize', () => this.props.windowResizeHandler(this.mins));
}

get totalWidth() {
return this.props.elWidth;
}

@Watch('totalWidth')
updateSize() {
this.props.windowResizeHandler(this.mins);
}

get mins() {
return {
bar1: this.props.calculateMin(['2']),
Expand Down
12 changes: 11 additions & 1 deletion app/components/editor/layouts/FourByFour.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import cx from 'classnames';
import TsxComponent, { createProps } from 'components/tsx-component';
import { Component } from 'vue-property-decorator';
import { Component, Watch } from 'vue-property-decorator';
import ResizeBar from 'components/shared/ResizeBar.vue';
import styles from './Layouts.m.less';
import { LayoutProps } from './Default';
Expand All @@ -10,11 +10,21 @@ export default class FourByFour extends TsxComponent<LayoutProps> {
mounted() {
window.addEventListener('resize', () => this.props.windowResizeHandler(this.mins));
this.props.windowResizeHandler(this.mins);
this.$emit('totalWidth', ['1', ['2', '3'], ['4', '5']]);
}
destroyed() {
window.removeEventListener('resize', () => this.props.windowResizeHandler(this.mins));
}

get totalWidth() {
return this.props.elWidth;
}

@Watch('totalWidth')
updateSize() {
this.props.windowResizeHandler(this.mins);
}

get mins() {
return {
bar1: this.props.calculateMin(['2', '3']),
Expand Down
12 changes: 11 additions & 1 deletion app/components/editor/layouts/OnePane.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import cx from 'classnames';
import TsxComponent, { createProps } from 'components/tsx-component';
import { LayoutProps } from './Default';
import { Component } from 'vue-property-decorator';
import { Component, Watch } from 'vue-property-decorator';
import ResizeBar from 'components/shared/ResizeBar.vue';
import styles from './Layouts.m.less';

Expand All @@ -10,11 +10,21 @@ export default class OnePane extends TsxComponent<LayoutProps> {
mounted() {
window.addEventListener('resize', () => this.props.windowResizeHandler(this.mins));
this.props.windowResizeHandler(this.mins);
this.$emit('totalWidth', ['2', ['1', ['3', '4', '5']]]);
}
destroyed() {
window.removeEventListener('resize', () => this.props.windowResizeHandler(this.mins));
}

get totalWidth() {
return this.props.elWidth;
}

@Watch('totalWidth')
updateSize() {
this.props.windowResizeHandler(this.mins);
}

get mins() {
return {
bar1: this.props.calculateMin(['1', ['3', '4', '5']]),
Expand Down
12 changes: 11 additions & 1 deletion app/components/editor/layouts/Triplets.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import cx from 'classnames';
import TsxComponent, { createProps } from 'components/tsx-component';
import { LayoutProps } from './Default';
import { Component } from 'vue-property-decorator';
import { Component, Watch } from 'vue-property-decorator';
import ResizeBar from 'components/shared/ResizeBar.vue';
import styles from './Layouts.m.less';

Expand All @@ -10,11 +10,21 @@ export default class Triplets extends TsxComponent<LayoutProps> {
mounted() {
window.addEventListener('resize', () => this.props.windowResizeHandler(this.mins));
this.props.windowResizeHandler(this.mins);
this.$emit('totalWidth', [['1', '4'], ['2', '5'], ['3', '6']]);
}
destroyed() {
window.removeEventListener('resize', () => this.props.windowResizeHandler(this.mins));
}

get totalWidth() {
return this.props.elWidth;
}

@Watch('totalWidth')
updateSize() {
this.props.windowResizeHandler(this.mins);
}

get mins() {
return {
bar1: this.props.calculateMin(['2', '5']),
Expand Down
12 changes: 11 additions & 1 deletion app/components/editor/layouts/TwoPane.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import cx from 'classnames';
import TsxComponent, { createProps } from 'components/tsx-component';
import { LayoutProps } from './Default';
import { Component } from 'vue-property-decorator';
import { Component, Watch } from 'vue-property-decorator';
import ResizeBar from 'components/shared/ResizeBar.vue';
import styles from './Layouts.m.less';

Expand All @@ -10,11 +10,21 @@ export default class TwoPane extends TsxComponent<LayoutProps> {
mounted() {
window.addEventListener('resize', () => this.props.windowResizeHandler(this.mins));
this.props.windowResizeHandler(this.mins);
this.$emit('totalWidth', ['2', '5', ['1', ['3', '4']]]);
}
destroyed() {
window.removeEventListener('resize', () => this.props.windowResizeHandler(this.mins));
}

get totalWidth() {
return this.props.elWidth;
}

@Watch('totalWidth')
updateSize() {
this.props.windowResizeHandler(this.mins);
}

get mins() {
return {
bar1: this.props.calculateMin(['1', ['3', '4']]),
Expand Down
19 changes: 17 additions & 2 deletions app/components/pages/Studio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ export default class Studio extends TsxComponent {
return this.layoutService.state.slottedElements;
}

get elWidth() {
if (!this.$el) return 0;
return this.$el.getBoundingClientRect().width;
}

windowResizeHandler(mins: IResizeMins) {
// This is the maximum size we can use
this.max = this.isColumns
Expand Down Expand Up @@ -92,8 +97,16 @@ export default class Studio extends TsxComponent {
return this.layoutService.calculateMinimum(this.isColumns ? 'x' : 'y', slots);
}

calculateMax(topEl: number) {
return this.max - topEl;
totalWidthHandler(slots: (LayoutSlot | LayoutSlot[])[]) {
if (this.isColumns) {
this.$emit('totalWidth', this.layoutService.calculateColumnTotal(slots));
} else {
this.$emit('totalWidth', this.layoutService.calculateMinimum('x', slots));
}
}

calculateMax(restMin: number) {
return this.max - restMin;
}

underMaxSize(max: number) {
Expand Down Expand Up @@ -127,6 +140,8 @@ export default class Studio extends TsxComponent {
windowResizeHandler={(mins: IResizeMins) => this.windowResizeHandler(mins)}
resizes={this.resizes}
class="editor-page"
elWidth={this.elWidth}
onTotalWidth={(slots: (LayoutSlot | LayoutSlot[])[]) => this.totalWidthHandler(slots)}
>
{Object.keys(this.layoutService.state.slottedElements).map(widget => {
const Element = COMPONENT_MAP[widget];
Expand Down
4 changes: 3 additions & 1 deletion app/components/windows/Main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
class="main-page-container"
v-if="!showLoadingSpinner"
:is="page"
:params="params"/>
:params="params"
@totalWidth="(width) => handleEditorWidth(width)"
/>
<studio-footer v-if="!applicationLoading && (page !== 'Onboarding')" />
</div>

Expand Down
12 changes: 10 additions & 2 deletions app/components/windows/Main.vue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ export default class Main extends Vue {
this.handleResize();
}

minEditorWidth = 500;

get title() {
return this.windowsService.state.main.title;
}
Expand Down Expand Up @@ -227,6 +229,9 @@ export default class Main extends Vue {
clearTimeout(this.windowResizeTimeout);

this.hasLiveDock = this.windowWidth >= 1070;
if (this.page === 'Studio') {
this.hasLiveDock = this.windowWidth >= this.minEditorWidth + 100;
}
this.windowResizeTimeout = window.setTimeout(
() => this.windowsService.updateStyleBlockers('main', false),
200,
Expand All @@ -237,6 +242,10 @@ export default class Main extends Vue {
this.compactView = this.$refs.mainMiddle.clientWidth < 1200;
}

handleEditorWidth(width: number) {
this.minEditorWidth = width;
}

onResizeStartHandler() {
this.windowsService.updateStyleBlockers('main', true);
}
Expand All @@ -255,9 +264,8 @@ export default class Main extends Vue {

validateWidth(width: number): number {
const appRect = this.$root.$el.getBoundingClientRect();
const minEditorWidth = 500;
const minWidth = 290;
const maxWidth = Math.min(appRect.width - minEditorWidth, appRect.width / 2);
const maxWidth = Math.min(appRect.width - this.minEditorWidth, appRect.width / 2);
let constrainedWidth = Math.max(minWidth, width);
constrainedWidth = Math.min(maxWidth, width);
return constrainedWidth;
Expand Down
16 changes: 16 additions & 0 deletions app/services/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,22 @@ export class LayoutService extends PersistentStatefulService<ILayoutServiceState
this.SET_SLOTS(slottedElements);
}

calculateColumnTotal(slots: (LayoutSlot | LayoutSlot[])[]) {
let totalWidth = 0;
slots.forEach(slot => {
if (Array.isArray(slot)) {
totalWidth += this.calculateMinimum('x', slot);
} else {
const c = Object.keys(this.state.slottedElements).find(
comp => this.state.slottedElements[comp] === slot,
);
totalWidth += ELEMENT_MINS[c].x;
}
});

return totalWidth;
}

calculateMinimum(orientation: 'x' | 'y', slots: (LayoutSlot | LayoutSlot[])[]) {
const aggregateMins: number[] = [];
const components: ELayoutElement[] = [];
Expand Down