@blokkli/editor 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/module.mjs +1678 -41
- package/dist/runtime/adapter/drupal/graphql/base.graphql +14 -3
- package/dist/runtime/adapter/drupal/graphql/comments.graphql +6 -1
- package/dist/runtime/adapter/drupal/graphql/transform.graphql +10 -2
- package/dist/runtime/adapter/drupal/graphqlMiddleware.js +26 -18
- package/dist/runtime/adapter/index.d.ts +6 -2
- package/dist/runtime/blokkliPlugins/Sidebar/index.vue +4 -1
- package/dist/runtime/components/BlokkliField.vue +8 -2
- package/dist/runtime/components/Edit/Actions/index.vue +27 -6
- package/dist/runtime/components/Edit/AnimationCanvas/index.vue +1 -0
- package/dist/runtime/components/Edit/DragInteractions/index.vue +7 -0
- package/dist/runtime/components/Edit/EditProvider.vue +23 -5
- package/dist/runtime/components/Edit/Features/Artboard/index.vue +4 -0
- package/dist/runtime/components/Edit/Features/BlockAddList/index.vue +1 -0
- package/dist/runtime/components/Edit/Features/Clipboard/index.vue +3 -1
- package/dist/runtime/components/Edit/Features/CommandPalette/Palette/index.vue +14 -2
- package/dist/runtime/components/Edit/Features/Debug/index.vue +26 -4
- package/dist/runtime/components/Edit/Features/Diff/DiffView/index.vue +236 -0
- package/dist/runtime/components/Edit/Features/Diff/index.vue +37 -0
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +14 -4
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +3 -0
- package/dist/runtime/components/Edit/Features/EditForm/Frame/index.vue +8 -1
- package/dist/runtime/components/Edit/Features/EditableField/index.vue +11 -5
- package/dist/runtime/components/Edit/Features/EntityTitle/index.vue +1 -0
- package/dist/runtime/components/Edit/Features/History/index.vue +3 -1
- package/dist/runtime/components/Edit/Features/ImportExisting/index.vue +5 -2
- package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +10 -3
- package/dist/runtime/components/Edit/Features/MediaLibrary/Library/Item.vue +2 -0
- package/dist/runtime/components/Edit/Features/MultiSelect/index.vue +4 -1
- package/dist/runtime/components/Edit/Features/Options/Form/index.vue +14 -1
- package/dist/runtime/components/Edit/Features/Preview/index.vue +2 -1
- package/dist/runtime/components/Edit/Features/PreviewGrant/index.vue +2 -1
- package/dist/runtime/components/Edit/Features/Publish/index.vue +2 -0
- package/dist/runtime/components/Edit/Features/ResponsivePreview/index.vue +2 -1
- package/dist/runtime/components/Edit/Features/Selection/Overlay/fragment.glsl +78 -44
- package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue +8 -8
- package/dist/runtime/components/Edit/Features/Selection/Overlay/vertex.glsl +6 -1
- package/dist/runtime/components/Edit/Features/Settings/Dialog/FeatureSetting/index.vue +23 -2
- package/dist/runtime/components/Edit/Features/Settings/Dialog/index.vue +71 -38
- package/dist/runtime/components/Edit/Features/Settings/index.vue +4 -0
- package/dist/runtime/components/Edit/Features/Transform/index.vue +5 -1
- package/dist/runtime/components/Edit/Features/Translations/index.vue +24 -2
- package/dist/runtime/components/Edit/Features/index.vue +4 -0
- package/dist/runtime/components/Edit/InfoBox/index.vue +14 -0
- package/dist/runtime/components/Edit/Messages/index.vue +10 -12
- package/dist/runtime/components/Edit/PreviewProvider.vue +9 -2
- package/dist/runtime/components/Edit/index.d.ts +2 -1
- package/dist/runtime/components/Edit/index.js +3 -1
- package/dist/runtime/constants/index.d.ts +1 -1
- package/dist/runtime/constants/index.js +1 -0
- package/dist/runtime/css/output.css +1 -1
- package/dist/runtime/helpers/animationProvider.js +2 -1
- package/dist/runtime/helpers/featuresProvider.d.ts +7 -14
- package/dist/runtime/helpers/featuresProvider.js +29 -1
- package/dist/runtime/helpers/stateProvider.d.ts +1 -0
- package/dist/runtime/helpers/stateProvider.js +23 -4
- package/dist/runtime/helpers/uiProvider.d.ts +5 -1
- package/dist/runtime/helpers/uiProvider.js +10 -2
- package/dist/runtime/icons/diff.svg +1 -0
- package/dist/runtime/icons/info.svg +1 -0
- package/dist/runtime/types/index.d.ts +59 -1
- package/package.json +2 -1
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
precision mediump float;
|
|
2
|
-
|
|
3
2
|
varying vec4 v_quad;
|
|
4
3
|
varying vec3 v_color;
|
|
5
4
|
varying vec4 v_rect_radius;
|
|
6
5
|
varying float v_thickness;
|
|
6
|
+
varying float v_rect_id;
|
|
7
7
|
varying vec2 v_rect_size;
|
|
8
8
|
varying vec2 v_rect_center;
|
|
9
|
-
varying float
|
|
9
|
+
varying float v_rect_width;
|
|
10
10
|
|
|
11
|
+
varying float v_transition;
|
|
11
12
|
uniform float u_scale;
|
|
12
13
|
uniform float u_dpi;
|
|
14
|
+
uniform float u_time;
|
|
15
|
+
uniform float u_is_transforming;
|
|
13
16
|
uniform vec2 u_resolution;
|
|
14
17
|
|
|
18
|
+
#define PI (3.141592653589793)
|
|
19
|
+
|
|
15
20
|
int pseudoQuadrant(vec2 p) {
|
|
16
21
|
return int(floor(step(0.0, p.x) + 2.0 * step(0.0, -p.y)));
|
|
17
22
|
}
|
|
@@ -19,79 +24,108 @@ int pseudoQuadrant(vec2 p) {
|
|
|
19
24
|
float sdRoundBox(vec2 p, vec2 b, vec4 radii) {
|
|
20
25
|
int idx = pseudoQuadrant(p);
|
|
21
26
|
float cr;
|
|
22
|
-
|
|
23
|
-
// Use correct radius. Bottom left and bottom right are flipped.
|
|
24
27
|
if (idx == 0) cr = radii[0];
|
|
25
28
|
else if (idx == 1) cr = radii[1];
|
|
26
29
|
else if (idx == 2) cr = radii[3];
|
|
27
30
|
else cr = radii[2];
|
|
28
|
-
|
|
29
31
|
vec2 q = abs(p) - b + cr;
|
|
30
32
|
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - cr;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
float
|
|
35
|
-
float
|
|
36
|
-
|
|
37
|
-
vec2 size = v_rect_size + u_borderThickness * 2.0 * v_transition;
|
|
35
|
+
float bounceOut(float t) {
|
|
36
|
+
const float a = 4.0 / 11.0;
|
|
37
|
+
const float b = 8.0 / 11.0;
|
|
38
|
+
const float c = 9.0 / 10.0;
|
|
38
39
|
|
|
39
|
-
float
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
const float ca = 4356.0 / 361.0;
|
|
41
|
+
const float cb = 35442.0 / 1805.0;
|
|
42
|
+
const float cc = 16061.0 / 1805.0;
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
float u_borderSoftness = 1.0 + v_transition; // How soft the border should be (in pixels)
|
|
44
|
+
float t2 = t * t;
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
return t < a
|
|
47
|
+
? 7.5625 * t2
|
|
48
|
+
: t < b
|
|
49
|
+
? 9.075 * t2 - 9.9 * t + 3.4
|
|
50
|
+
: t < c
|
|
51
|
+
? ca * t2 - cb * t + cc
|
|
52
|
+
: 10.8 * t * t - 20.52 * t + 10.72;
|
|
53
|
+
}
|
|
47
54
|
|
|
48
|
-
|
|
55
|
+
float exponentialIn(float t) {
|
|
56
|
+
return t == 0.0
|
|
57
|
+
? t
|
|
58
|
+
: pow(2.0, 10.0 * (t - 1.0));
|
|
59
|
+
}
|
|
49
60
|
|
|
50
|
-
|
|
61
|
+
float getStripePattern(vec2 quadRelativePos, float time) {
|
|
62
|
+
float d = 300.0 * u_scale;
|
|
51
63
|
|
|
52
|
-
|
|
53
|
-
float distance =
|
|
54
|
-
sdRoundBox(gl_FragCoord.xy - v_rect_center, size / 2.0, r) +
|
|
55
|
-
u_borderThickness;
|
|
64
|
+
float t = mod(u_time + v_rect_id * 1000.0, 1200.0) / 1200.0;
|
|
56
65
|
|
|
57
|
-
|
|
58
|
-
float smoothedAlpha = 1.0 - smoothstep(0.0, u_edgeSoftness, distance);
|
|
66
|
+
float movement = t * 2.0 * PI;
|
|
59
67
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
smoothstep(
|
|
65
|
-
u_borderThickness - u_borderSoftness,
|
|
66
|
-
u_borderThickness,
|
|
67
|
-
abs(distance - u_borderThickness)
|
|
68
|
-
);
|
|
68
|
+
float normalizedSin =
|
|
69
|
+
(sin((quadRelativePos.y + quadRelativePos.x) / d + movement + v_rect_id) +
|
|
70
|
+
1.0) /
|
|
71
|
+
2.0;
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
return normalizedSin * 0.2 + 0.5;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
vec4 drawBox(float thickness, vec4 bg, vec4 fill, vec4 border, float offset) {
|
|
77
|
+
float borderThickness = max(thickness, 2.0);
|
|
78
|
+
|
|
79
|
+
float t = exponentialIn(
|
|
80
|
+
(sin(u_time / 270.0 - v_rect_id + offset) + 1.0) / 2.0
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
if (u_is_transforming >= 0.5) {
|
|
84
|
+
borderThickness = (t * 0.7 + 0.5) * borderThickness;
|
|
85
|
+
}
|
|
86
|
+
vec2 size = v_rect_size + borderThickness * 2.0 * v_transition;
|
|
87
|
+
float u_edgeSoftness = 1.0 + v_transition;
|
|
88
|
+
vec4 radius = v_rect_radius * u_scale + vec4(borderThickness);
|
|
89
|
+
vec4 u_cornerRadii = min(radius, min(size.x, size.y) / 2.0) * v_transition;
|
|
90
|
+
float u_borderSoftness = 1.0 + v_transition;
|
|
91
|
+
|
|
92
|
+
vec4 r = u_cornerRadii;
|
|
93
|
+
|
|
94
|
+
vec2 posRelativeToQuad = gl_FragCoord.xy - v_rect_center;
|
|
95
|
+
|
|
96
|
+
float mainDist = sdRoundBox(posRelativeToQuad, size / 2.0, r);
|
|
97
|
+
float innerDist = mainDist;
|
|
98
|
+
|
|
99
|
+
float fillAlpha = 1.0 - smoothstep(-u_edgeSoftness, 0.0, innerDist);
|
|
100
|
+
float borderAlpha =
|
|
101
|
+
1.0 - smoothstep(-u_borderSoftness, 0.0, abs(mainDist) - borderThickness);
|
|
72
102
|
|
|
73
|
-
|
|
74
|
-
|
|
103
|
+
vec4 stripedFill = vec4(1.0, 1.0, 1.0, 0.0);
|
|
104
|
+
if (u_is_transforming >= 0.5) {
|
|
105
|
+
stripedFill = fill;
|
|
106
|
+
stripedFill.a = getStripePattern(posRelativeToQuad, u_time);
|
|
107
|
+
borderAlpha *= t + 0.6;
|
|
108
|
+
}
|
|
75
109
|
|
|
76
|
-
|
|
77
|
-
return mix(
|
|
110
|
+
vec4 res_with_fill = mix(bg, stripedFill, fillAlpha * stripedFill.a);
|
|
111
|
+
return mix(res_with_fill, border, borderAlpha * border.a);
|
|
78
112
|
}
|
|
79
113
|
|
|
80
114
|
void main() {
|
|
81
|
-
// Red border that should be below the blue border.
|
|
82
115
|
vec4 borderBottom = drawBox(
|
|
83
116
|
v_transition * (v_thickness * 2.0),
|
|
84
117
|
vec4(v_color, 0.0),
|
|
85
|
-
vec4(v_color, 0.5
|
|
86
|
-
vec4(v_color, 0.4)
|
|
118
|
+
vec4(v_color, 0.5),
|
|
119
|
+
vec4(v_color, 0.4),
|
|
120
|
+
0.0
|
|
87
121
|
);
|
|
88
122
|
|
|
89
|
-
// Blue border that should be on top of the red border.
|
|
90
123
|
vec4 borderTop = drawBox(
|
|
91
124
|
v_thickness,
|
|
92
125
|
vec4(v_color, 0.0),
|
|
93
126
|
vec4(v_color, 0.0),
|
|
94
|
-
vec4(v_color, 1.0)
|
|
127
|
+
vec4(v_color, 1.0),
|
|
128
|
+
-0.2
|
|
95
129
|
);
|
|
96
130
|
|
|
97
131
|
vec4 finalColor = mix(borderBottom, borderTop, borderTop.a);
|
|
@@ -22,7 +22,7 @@ const props = defineProps<{
|
|
|
22
22
|
gl: WebGLRenderingContext
|
|
23
23
|
}>()
|
|
24
24
|
|
|
25
|
-
const { animation, theme, dom } = useBlokkli()
|
|
25
|
+
const { animation, theme, dom, ui } = useBlokkli()
|
|
26
26
|
|
|
27
27
|
const programInfo = animation.registerProgram('selection', props.gl, [vs, fs])
|
|
28
28
|
|
|
@@ -99,15 +99,15 @@ class SelectionRectangleBufferCollector extends RectangleBufferCollector<Selecti
|
|
|
99
99
|
|
|
100
100
|
const collector = new SelectionRectangleBufferCollector(props.gl)
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
u_color_default: toShaderColor(theme.accent.value[600]),
|
|
104
|
-
u_color_inverted: [255, 255, 255],
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
onBlokkliEvent('canvas:draw', () => {
|
|
102
|
+
onBlokkliEvent('canvas:draw', (e) => {
|
|
108
103
|
props.gl.useProgram(programInfo.program)
|
|
109
104
|
|
|
110
|
-
setUniforms(programInfo,
|
|
105
|
+
setUniforms(programInfo, {
|
|
106
|
+
u_color_default: toShaderColor(theme.accent.value[600]),
|
|
107
|
+
u_color_inverted: [255, 255, 255],
|
|
108
|
+
u_is_transforming: ui.isTransforming.value ? 1 : 0,
|
|
109
|
+
u_time: e.time,
|
|
110
|
+
})
|
|
111
111
|
animation.setSharedUniforms(props.gl, programInfo)
|
|
112
112
|
const { info, hasChanged } = collector.getBufferInfo()
|
|
113
113
|
|
|
@@ -27,11 +27,13 @@ varying float v_thickness;
|
|
|
27
27
|
varying vec2 v_rect_size;
|
|
28
28
|
varying vec2 v_rect_center;
|
|
29
29
|
varying float v_transition;
|
|
30
|
+
varying float v_rect_id;
|
|
31
|
+
varying float v_rect_width;
|
|
30
32
|
|
|
31
33
|
void main() {
|
|
32
34
|
// Define the increase size in viewport terms (not affected by u_scale)
|
|
33
35
|
float thickness = (0.5 + smoothstep(0.3, 1.0, u_scale) * 2.5) * u_dpi;
|
|
34
|
-
float increaseSize = max(thickness,
|
|
36
|
+
float increaseSize = max(thickness, 25.0);
|
|
35
37
|
|
|
36
38
|
// Calculate the new dimensions of the quad
|
|
37
39
|
vec4 adjusted_quad = a_quad;
|
|
@@ -75,10 +77,13 @@ void main() {
|
|
|
75
77
|
);
|
|
76
78
|
v_quad = transformed_quad;
|
|
77
79
|
|
|
80
|
+
v_rect_width = adjusted_quad.x;
|
|
81
|
+
|
|
78
82
|
// Set color and other varying variables
|
|
79
83
|
v_color = a_rect_type > 0.5 ? u_color_inverted : u_color_default;
|
|
80
84
|
v_rect_radius = a_rect_radius * u_dpi;
|
|
81
85
|
v_thickness = thickness;
|
|
86
|
+
v_rect_id = a_rect_id;
|
|
82
87
|
v_rect_size = vec2(v_quad.z, v_quad.w);
|
|
83
88
|
v_rect_center = vec2(v_quad.x + v_quad.z / 2.0, v_quad.y + v_quad.w / 2.0); // The pixel-space rectangle center location
|
|
84
89
|
v_transition = smoothstep(0.5, 0.8, u_scale);
|
|
@@ -7,8 +7,13 @@
|
|
|
7
7
|
class="peer"
|
|
8
8
|
@change="toggleCheckbox"
|
|
9
9
|
/>
|
|
10
|
-
<div />
|
|
11
|
-
<
|
|
10
|
+
<div class="bk-checkbox-toggle-toggle" />
|
|
11
|
+
<div class="bk-checkbox-toggle-label">
|
|
12
|
+
<div>{{ settingLabel }}</div>
|
|
13
|
+
<div v-if="settingDescription">
|
|
14
|
+
{{ settingDescription }}
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
12
17
|
</label>
|
|
13
18
|
<div v-else-if="setting.type === 'radios'">
|
|
14
19
|
<h3 class="bk-form-label">
|
|
@@ -80,6 +85,22 @@ const settingLabel = computed(() => {
|
|
|
80
85
|
)
|
|
81
86
|
})
|
|
82
87
|
|
|
88
|
+
const settingDescription = computed(() => {
|
|
89
|
+
const translated = textTranslation(
|
|
90
|
+
'feature_' +
|
|
91
|
+
props.featureId +
|
|
92
|
+
'_setting_' +
|
|
93
|
+
props.settingsKey +
|
|
94
|
+
'_description',
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
if (!translated && 'description' in props.setting) {
|
|
98
|
+
return props.setting.description
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return translated
|
|
102
|
+
})
|
|
103
|
+
|
|
83
104
|
const getOptionLabel = (key: string, defaultLabel: string) => {
|
|
84
105
|
return (
|
|
85
106
|
textTranslation(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<DialogModal
|
|
3
3
|
:title="$t('settingsDialogTitle', 'Change settings')"
|
|
4
|
-
:width="
|
|
4
|
+
:width="900"
|
|
5
5
|
hide-buttons
|
|
6
6
|
icon="cog"
|
|
7
7
|
@cancel="$emit('cancel')"
|
|
@@ -10,14 +10,17 @@
|
|
|
10
10
|
<div v-for="group in groups" :key="group.key" class="bk-form-section">
|
|
11
11
|
<h3 class="bk-settings-group-title">
|
|
12
12
|
<span>{{ group.label }}</span>
|
|
13
|
+
<span v-if="group.id === 'beta'" class="bk-beta-indicator">BETA</span>
|
|
13
14
|
</h3>
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
<div>
|
|
16
|
+
<FeatureSetting
|
|
17
|
+
v-for="setting in group.settings"
|
|
18
|
+
:key="group.key + setting.settingsKey"
|
|
19
|
+
:feature-id="setting.featureId"
|
|
20
|
+
:settings-key="setting.settingsKey"
|
|
21
|
+
:setting="setting.setting"
|
|
22
|
+
/>
|
|
23
|
+
</div>
|
|
21
24
|
</div>
|
|
22
25
|
</div>
|
|
23
26
|
</DialogModal>
|
|
@@ -35,6 +38,8 @@ import { settingsOverride } from '#blokkli/config'
|
|
|
35
38
|
|
|
36
39
|
const { $t, features, ui } = useBlokkli()
|
|
37
40
|
|
|
41
|
+
const getTranslation = $t
|
|
42
|
+
|
|
38
43
|
type FeatureSetting = {
|
|
39
44
|
featureId: ValidFeatureKey
|
|
40
45
|
settingsKey: string
|
|
@@ -58,6 +63,8 @@ const getGroupLabel = (key: SettingsGroup): string => {
|
|
|
58
63
|
return $t('settingsAdvanced', 'Advanced')
|
|
59
64
|
} else if (key === 'artboard') {
|
|
60
65
|
return $t('settingsArtboard', 'Artboard')
|
|
66
|
+
} else if (key === 'beta') {
|
|
67
|
+
return $t('settingsBeta', 'New Features')
|
|
61
68
|
}
|
|
62
69
|
return key
|
|
63
70
|
}
|
|
@@ -90,37 +97,63 @@ const shouldRenderSetting = (
|
|
|
90
97
|
const settingTypeOrder = ['checkbox', 'slider', 'method']
|
|
91
98
|
|
|
92
99
|
const groups = computed<GroupedSettings[]>(() => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
100
|
+
const settingGroups = features.features.value.reduce<
|
|
101
|
+
Partial<Record<SettingsGroup, GroupedSettings>>
|
|
102
|
+
>((acc, feature) => {
|
|
103
|
+
Object.entries(feature.settings || {}).forEach(([settingsKey, setting]) => {
|
|
104
|
+
const key: any = `feature:${feature.id}:${settingsKey}`
|
|
105
|
+
if (shouldRenderSetting(key, setting)) {
|
|
106
|
+
const group = setting.group || 'advanced'
|
|
107
|
+
if (!acc[group]) {
|
|
108
|
+
acc[group] = {
|
|
109
|
+
id: group as any,
|
|
110
|
+
key: group,
|
|
111
|
+
label: getGroupLabel(group),
|
|
112
|
+
icon: getGroupIcon(group),
|
|
113
|
+
settings: [],
|
|
114
|
+
}
|
|
115
|
+
}
|
|
110
116
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
)
|
|
123
|
-
|
|
117
|
+
acc[group].settings.push({
|
|
118
|
+
featureId: feature.id,
|
|
119
|
+
settingsKey,
|
|
120
|
+
setting,
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
return acc
|
|
125
|
+
}, {})
|
|
126
|
+
|
|
127
|
+
if (features.betaFeatures.value.length) {
|
|
128
|
+
if (!settingGroups.beta) {
|
|
129
|
+
settingGroups.beta = {
|
|
130
|
+
id: 'beta',
|
|
131
|
+
key: 'betaFeatures',
|
|
132
|
+
label: getGroupLabel('beta'),
|
|
133
|
+
icon: 'bug',
|
|
134
|
+
settings: [],
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
features.betaFeatures.value.forEach((v) => {
|
|
139
|
+
const label = getTranslation(`feature_${v.id}_label`) || v.label
|
|
140
|
+
const description =
|
|
141
|
+
getTranslation(`feature_${v.id}_description`) || v.description
|
|
142
|
+
settingGroups.beta!.settings.push({
|
|
143
|
+
featureId: 'settings',
|
|
144
|
+
settingsKey: 'beta:' + v.id,
|
|
145
|
+
setting: {
|
|
146
|
+
type: 'checkbox',
|
|
147
|
+
default: false,
|
|
148
|
+
label,
|
|
149
|
+
description,
|
|
150
|
+
group: 'beta',
|
|
151
|
+
},
|
|
152
|
+
})
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return Object.values(settingGroups)
|
|
124
157
|
.map((group) => {
|
|
125
158
|
group.settings
|
|
126
159
|
.sort((a, b) => b.settingsKey.localeCompare(a.settingsKey))
|
|
@@ -43,12 +43,16 @@ const { settings } = defineBlokkliFeature({
|
|
|
43
43
|
type: 'checkbox',
|
|
44
44
|
default: true,
|
|
45
45
|
label: 'Use animations',
|
|
46
|
+
description:
|
|
47
|
+
'Animates UI elements like dialogs or drawers or interactions like drag and drop or scroll changes.',
|
|
46
48
|
group: 'advanced',
|
|
47
49
|
},
|
|
48
50
|
lowPerformanceMode: {
|
|
49
51
|
type: 'checkbox',
|
|
50
52
|
default: false,
|
|
51
53
|
label: 'Enable low performance mode',
|
|
54
|
+
description:
|
|
55
|
+
'Reduces the animations and interactivity to a minimum for devices with low performance.',
|
|
52
56
|
group: 'advanced',
|
|
53
57
|
},
|
|
54
58
|
resetAllSettings: {
|
|
@@ -44,7 +44,7 @@ const { adapter } = defineBlokkliFeature({
|
|
|
44
44
|
screenshot: 'feature-transform.jpg',
|
|
45
45
|
})
|
|
46
46
|
|
|
47
|
-
const { types, selection, state, $t, dom } = useBlokkli()
|
|
47
|
+
const { types, selection, state, $t, dom, ui } = useBlokkli()
|
|
48
48
|
|
|
49
49
|
const {
|
|
50
50
|
data: plugins,
|
|
@@ -64,6 +64,8 @@ watch(selection.uuids, async () => {
|
|
|
64
64
|
})
|
|
65
65
|
|
|
66
66
|
async function onTransform(plugin: TransformPlugin, uuids: string[]) {
|
|
67
|
+
ui.setTransform(plugin.label)
|
|
68
|
+
|
|
67
69
|
await state.mutateWithLoadingState(
|
|
68
70
|
() =>
|
|
69
71
|
adapter.applyTransformPlugin({
|
|
@@ -75,6 +77,8 @@ async function onTransform(plugin: TransformPlugin, uuids: string[]) {
|
|
|
75
77
|
'The action "@name" could not be executed.',
|
|
76
78
|
).replace('@name', plugin.label),
|
|
77
79
|
)
|
|
80
|
+
|
|
81
|
+
ui.setTransform()
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
const itemBundleIds = computed(() =>
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
</PluginTourItem>
|
|
51
51
|
</Teleport>
|
|
52
52
|
|
|
53
|
-
<Teleport to="
|
|
53
|
+
<Teleport to="#bk-banner-container">
|
|
54
54
|
<Banner
|
|
55
55
|
v-if="state.editMode.value === 'translating'"
|
|
56
56
|
:active-language="activeLanguage"
|
|
@@ -116,7 +116,20 @@ const { translation, editMode } = state
|
|
|
116
116
|
|
|
117
117
|
const isOpen = ref(false)
|
|
118
118
|
|
|
119
|
-
const isDropdown = computed(() =>
|
|
119
|
+
const isDropdown = computed(() => {
|
|
120
|
+
// Always a dropdown on mobile.
|
|
121
|
+
if (ui.isMobile.value) {
|
|
122
|
+
return true
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// It is a dropdown if all langcodes combined is greater than 15.
|
|
126
|
+
// That way up to 7 languages with 2-char langcodes are displayed as radio buttons.
|
|
127
|
+
// This handles cases where langcodes are e.g. 'en-US', 'en-GB', 'de-CH', etc.
|
|
128
|
+
// In this case it switches to a dropdown. This is better than relying on the number
|
|
129
|
+
// languages.
|
|
130
|
+
const allCodes = items.value.map((v) => v.code).join('')
|
|
131
|
+
return allCodes.length > 15
|
|
132
|
+
})
|
|
120
133
|
const activeLangcode = computed(() => context.value.language)
|
|
121
134
|
const activeLanguage = computed<Language>(() => {
|
|
122
135
|
return (
|
|
@@ -212,6 +225,15 @@ onBlokkliEvent('item:doubleClick', function (block) {
|
|
|
212
225
|
}
|
|
213
226
|
})
|
|
214
227
|
|
|
228
|
+
onBlokkliEvent('entity:translated', (langcode) => {
|
|
229
|
+
const targetTranslation = translation.value.translations?.find(
|
|
230
|
+
(v) => v.id === langcode,
|
|
231
|
+
)
|
|
232
|
+
if (targetTranslation) {
|
|
233
|
+
adapter.changeLanguage(targetTranslation)
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
|
|
215
237
|
onMounted(() => {
|
|
216
238
|
// Make sure the user is not trying to edit a translation that does not exist.
|
|
217
239
|
const translationExists = !!translation.value.translations?.find(
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
</div>
|
|
13
|
-
</Teleport>
|
|
2
|
+
<div class="bk bk-messages">
|
|
3
|
+
<TransitionGroup name="bk-message">
|
|
4
|
+
<Item
|
|
5
|
+
v-for="(message, index) in messages"
|
|
6
|
+
v-bind="message"
|
|
7
|
+
:key="index"
|
|
8
|
+
@close="removeMessage(index)"
|
|
9
|
+
/>
|
|
10
|
+
</TransitionGroup>
|
|
11
|
+
</div>
|
|
14
12
|
</template>
|
|
15
13
|
|
|
16
14
|
<script lang="ts" setup>
|
|
@@ -62,7 +62,7 @@ const mutatedEntity = computed(
|
|
|
62
62
|
() => mutatedEntityFromState.value || props.entity,
|
|
63
63
|
)
|
|
64
64
|
|
|
65
|
-
const { data, refresh } = await useAsyncData(() =>
|
|
65
|
+
const { data, refresh, error } = await useAsyncData(() =>
|
|
66
66
|
adapter.loadState().then((v) => adapter.mapState(v)),
|
|
67
67
|
)
|
|
68
68
|
|
|
@@ -94,8 +94,10 @@ const updateState = () => {
|
|
|
94
94
|
|
|
95
95
|
updateState()
|
|
96
96
|
|
|
97
|
+
const isPreview = computed(() => !error.value)
|
|
98
|
+
|
|
97
99
|
provide(INJECT_MUTATED_FIELDS_MAP, mutatedFieldsMap)
|
|
98
|
-
provide(INJECT_IS_PREVIEW,
|
|
100
|
+
provide(INJECT_IS_PREVIEW, isPreview)
|
|
99
101
|
provide<ItemEditContext>(INJECT_EDIT_CONTEXT, {
|
|
100
102
|
mutatedOptions,
|
|
101
103
|
eventBus,
|
|
@@ -127,6 +129,11 @@ const onMouseDown = () => {
|
|
|
127
129
|
* update.
|
|
128
130
|
*/
|
|
129
131
|
function checkChangedDate() {
|
|
132
|
+
// State loading has failed, so we can return here; no need to poll.
|
|
133
|
+
if (!isPreview.value) {
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
|
|
130
137
|
clearTimeout(timeout)
|
|
131
138
|
|
|
132
139
|
const delay = adapter.getLastChanged ? 1000 : 5000
|
|
@@ -12,4 +12,5 @@ import Loading from './Loading/index.vue.js';
|
|
|
12
12
|
import Highlight from './Highlight/index.vue.js';
|
|
13
13
|
import ViewportBlockingRect from './ViewportBlockingRect/index.vue.js';
|
|
14
14
|
import ScrollBoundary from './ScrollBoundary/index.vue.js';
|
|
15
|
-
|
|
15
|
+
import InfoBox from './InfoBox/index.vue.js';
|
|
16
|
+
export { ItemIcon, ShortcutIndicator, RelativeTime, Icon, Resizable, DialogModal, ScaleToFit, Sortli, FormOverlay, AddListItem, Loading, Highlight, ViewportBlockingRect, ScrollBoundary, InfoBox, };
|
|
@@ -12,6 +12,7 @@ import Loading from "./Loading/index.vue";
|
|
|
12
12
|
import Highlight from "./Highlight/index.vue";
|
|
13
13
|
import ViewportBlockingRect from "./ViewportBlockingRect/index.vue";
|
|
14
14
|
import ScrollBoundary from "./ScrollBoundary/index.vue";
|
|
15
|
+
import InfoBox from "./InfoBox/index.vue";
|
|
15
16
|
export {
|
|
16
17
|
ItemIcon,
|
|
17
18
|
ShortcutIndicator,
|
|
@@ -26,5 +27,6 @@ export {
|
|
|
26
27
|
Loading,
|
|
27
28
|
Highlight,
|
|
28
29
|
ViewportBlockingRect,
|
|
29
|
-
ScrollBoundary
|
|
30
|
+
ScrollBoundary,
|
|
31
|
+
InfoBox
|
|
30
32
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const SETTINGS_GROUP: readonly ["appearance", "artboard", "behavior", "advanced"];
|
|
1
|
+
export declare const SETTINGS_GROUP: readonly ["appearance", "artboard", "behavior", "beta", "advanced"];
|
|
2
2
|
export declare const VIEWPORT: readonly ["mobile", "desktop"];
|
|
3
3
|
export type SettingsGroup = (typeof SETTINGS_GROUP)[number];
|
|
4
4
|
export type Viewport = (typeof VIEWPORT)[number];
|