@monimesl/dot-cli 0.1.0-alpha.14 → 0.1.0-alpha.16
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/cli.js +1 -1
- package/dist/{server-Dbrgkelo.js → server-uIyYmYnp.js} +7 -2
- package/dist/{server-Dbrgkelo.js.map → server-uIyYmYnp.js.map} +1 -1
- package/dist/templates/showcase/dot.ts +11 -0
- package/dist/templates/showcase/pages/device/controller.ts +25 -0
- package/dist/templates/showcase/pages/device/state.ts +9 -0
- package/dist/templates/showcase/pages/device/view.dml +20 -0
- package/dist/templates/showcase/pages/files/controller.ts +23 -1
- package/dist/templates/showcase/pages/files/state.ts +8 -0
- package/dist/templates/showcase/pages/files/view.dml +14 -0
- package/dist/templates/showcase/pages/index/state.ts +8 -2
- package/dist/templates/showcase/pages/navigation/state.ts +1 -1
- package/dist/templates/showcase/pages/styles/controller.ts +5 -0
- package/dist/templates/showcase/pages/styles/state.ts +3 -0
- package/dist/templates/showcase/pages/styles/view.dml +61 -0
- package/package.json +6 -6
|
@@ -5,6 +5,7 @@ export default defineDot({
|
|
|
5
5
|
'index',
|
|
6
6
|
'layout',
|
|
7
7
|
'text',
|
|
8
|
+
'styles',
|
|
8
9
|
'images',
|
|
9
10
|
'carousel',
|
|
10
11
|
'lists',
|
|
@@ -20,5 +21,15 @@ export default defineDot({
|
|
|
20
21
|
'cache',
|
|
21
22
|
'secrets',
|
|
22
23
|
],
|
|
24
|
+
// The showcase's own colours, used by name on the Styles page.
|
|
25
|
+
theme: {
|
|
26
|
+
colors: {
|
|
27
|
+
custom: {
|
|
28
|
+
gold: { light: '#f5c542', dark: '#d4a72c' },
|
|
29
|
+
// Dark text that reads on gold in both light and dark.
|
|
30
|
+
ink: { light: '#1c1c1e', dark: '#1c1c1e' },
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
23
34
|
plugins: [logger()],
|
|
24
35
|
});
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
import { HostError } from '@monimesl/dot-runtime';
|
|
2
|
+
|
|
1
3
|
import state from './state';
|
|
2
4
|
|
|
5
|
+
// Closing a picker or scanner isn't a problem to show.
|
|
6
|
+
function problemToShow(error: unknown): string {
|
|
7
|
+
const closedByPerson = error instanceof HostError && error.code === 'cancelled';
|
|
8
|
+
return closedByPerson ? '' : (error as Error).message;
|
|
9
|
+
}
|
|
10
|
+
|
|
3
11
|
export default definePage({
|
|
4
12
|
initialState: state,
|
|
5
13
|
mutations: {
|
|
@@ -67,6 +75,23 @@ export default definePage({
|
|
|
67
75
|
}
|
|
68
76
|
this.setState({ showIn: 0, toast: "It's showtime" });
|
|
69
77
|
},
|
|
78
|
+
async pickPhoto(_state, event: DotEvent<unknown, { source: 'library' | 'camera' }>) {
|
|
79
|
+
try {
|
|
80
|
+
const photo = await this.dash.media.pickPhoto({ source: event.data.source });
|
|
81
|
+
const details = `${photo.name}, ${Math.round(photo.size / 1024)} KB as a JPEG`;
|
|
82
|
+
this.setState({ photo, photoDetails: details, note: '' });
|
|
83
|
+
} catch (error) {
|
|
84
|
+
this.setState({ note: problemToShow(error) });
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
async scanTicket() {
|
|
88
|
+
try {
|
|
89
|
+
const { text } = await this.dash.media.scanCode();
|
|
90
|
+
this.setState({ scanned: text, note: '' });
|
|
91
|
+
} catch (error) {
|
|
92
|
+
this.setState({ note: problemToShow(error) });
|
|
93
|
+
}
|
|
94
|
+
},
|
|
70
95
|
async toggleTorch(state) {
|
|
71
96
|
const next = state.torch === 'on' ? 'off' : 'on';
|
|
72
97
|
try {
|
|
@@ -37,6 +37,26 @@
|
|
|
37
37
|
<Button variant="secondary" onClick="countDown" disabled="{{ showIn > 0 }}">{{ showIn > 0 ? 'Showtime in ' + showIn + 's' : 'Count down to showtime' }}</Button>
|
|
38
38
|
</View>
|
|
39
39
|
|
|
40
|
+
<Text variant="caption" tone="muted">dash.media.pickPhoto, with the photoLibrary and camera permissions</Text>
|
|
41
|
+
<View variant="card" gap="small">
|
|
42
|
+
<View direction="row" wrap gap="small">
|
|
43
|
+
<Button variant="secondary" data-source="library" onClick="pickPhoto">Choose a photo</Button>
|
|
44
|
+
<Button variant="secondary" data-source="camera" onClick="pickPhoto">Take a photo</Button>
|
|
45
|
+
</View>
|
|
46
|
+
<If condition="{{ photo }}">
|
|
47
|
+
<Image src="{{ photo.url }}" alt="The photo you picked" aspect="4:3" fit="contain" />
|
|
48
|
+
<Text variant="caption" tone="muted">{{ photoDetails }}. It goes when the dot closes, unless the dot saves it.</Text>
|
|
49
|
+
</If>
|
|
50
|
+
</View>
|
|
51
|
+
|
|
52
|
+
<Text variant="caption" tone="muted">dash.media.scanCode, with Dash's own scanner and the camera permission</Text>
|
|
53
|
+
<View variant="card" gap="small">
|
|
54
|
+
<Button variant="secondary" onClick="scanTicket">Scan a ticket's QR code</Button>
|
|
55
|
+
<If condition="{{ scanned }}">
|
|
56
|
+
<Text>{{ scanned }}</Text>
|
|
57
|
+
</If>
|
|
58
|
+
</View>
|
|
59
|
+
|
|
40
60
|
<Text variant="caption" tone="muted">dash.system.torch</Text>
|
|
41
61
|
<View variant="card" gap="small">
|
|
42
62
|
<Button variant="secondary" onClick="toggleTorch">{{ torch === 'on' ? 'Turn the torch off' : 'Lights up for the slow song' }}</Button>
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { HostError } from '@monimesl/dot-runtime';
|
|
2
|
+
|
|
3
|
+
import type { Archive, Document, Song } from './state';
|
|
2
4
|
import state from './state';
|
|
3
5
|
|
|
4
6
|
const PICTURE = 'pictures/artwork.jpg';
|
|
@@ -29,11 +31,15 @@ export default definePage({
|
|
|
29
31
|
time: new Date(Number(entry.name)).toLocaleTimeString('en-GB'),
|
|
30
32
|
}))
|
|
31
33
|
.reverse();
|
|
34
|
+
const documents: Document[] = entries
|
|
35
|
+
.filter((entry) => entry.kind === 'file' && entry.path.startsWith('documents/'))
|
|
36
|
+
.map((entry) => ({ path: entry.path, name: entry.name }));
|
|
32
37
|
const { used, quota } = await this.dash.storage.file.usage();
|
|
33
38
|
const kept = await this.dash.storage.file.stat(PICTURE);
|
|
34
39
|
this.setState({
|
|
35
40
|
songs,
|
|
36
41
|
archives,
|
|
42
|
+
documents,
|
|
37
43
|
usage: `${used} bytes used of ${quota / 1024 / 1024} MB`,
|
|
38
44
|
picture: kept ? (await this.dash.storage.file.open(PICTURE)).url : '',
|
|
39
45
|
});
|
|
@@ -58,6 +64,22 @@ export default definePage({
|
|
|
58
64
|
await this.dash.storage.file.remove('setlist', { recursive: true });
|
|
59
65
|
await this.actions.refresh();
|
|
60
66
|
},
|
|
67
|
+
// A picked file goes when the dot closes, so it's saved into the dot's own folder.
|
|
68
|
+
async attach() {
|
|
69
|
+
try {
|
|
70
|
+
const file = await this.dash.storage.file.pick({ types: ['application/pdf', 'image/*'] });
|
|
71
|
+
await this.dash.storage.file.createFolder('documents');
|
|
72
|
+
await this.dash.storage.file.save(file, `documents/${file.name}`, { overwrite: true });
|
|
73
|
+
this.setState({ attachNote: '' });
|
|
74
|
+
await this.actions.refresh();
|
|
75
|
+
} catch (error) {
|
|
76
|
+
// Closing the picker or scanner isn't a problem to show.
|
|
77
|
+
const closedByPerson = error instanceof HostError && error.code === 'cancelled';
|
|
78
|
+
if (!closedByPerson) {
|
|
79
|
+
this.setState({ attachNote: (error as Error).message });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
61
83
|
async forgetPicture() {
|
|
62
84
|
await this.dash.storage.file.remove(PICTURE);
|
|
63
85
|
await this.actions.refresh();
|
|
@@ -4,6 +4,11 @@ export interface Archive {
|
|
|
4
4
|
time: string;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
export interface Document {
|
|
8
|
+
path: string;
|
|
9
|
+
name: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
7
12
|
export interface Song {
|
|
8
13
|
path: string;
|
|
9
14
|
text: string;
|
|
@@ -16,4 +21,7 @@ export default {
|
|
|
16
21
|
archives: [] as Archive[],
|
|
17
22
|
usage: '',
|
|
18
23
|
picture: '',
|
|
24
|
+
// Files the person attached, kept in the dot's documents folder.
|
|
25
|
+
documents: [] as Document[],
|
|
26
|
+
attachNote: '',
|
|
19
27
|
};
|
|
@@ -35,6 +35,20 @@
|
|
|
35
35
|
</Else>
|
|
36
36
|
</View>
|
|
37
37
|
|
|
38
|
+
<Text variant="caption" tone="muted">dash.storage.file.pick, with the files permission, then save to keep it</Text>
|
|
39
|
+
<View variant="card" gap="small">
|
|
40
|
+
<Button variant="secondary" onClick="attach">Attach your concert ticket</Button>
|
|
41
|
+
<For each="{{ documents }}" item="document" key="path">
|
|
42
|
+
<View gap="none">
|
|
43
|
+
<Text>{{ document.name }}</Text>
|
|
44
|
+
<Text variant="caption" tone="muted">{{ document.path }}</Text>
|
|
45
|
+
</View>
|
|
46
|
+
</For>
|
|
47
|
+
<If condition="{{ attachNote }}">
|
|
48
|
+
<Text variant="caption" tone="muted">{{ attachNote }}</Text>
|
|
49
|
+
</If>
|
|
50
|
+
</View>
|
|
51
|
+
|
|
38
52
|
<Text variant="caption" tone="muted">Artwork saved from the Network page</Text>
|
|
39
53
|
<View variant="card" gap="small">
|
|
40
54
|
<If condition="{{ picture }}">
|
|
@@ -28,6 +28,12 @@ export default {
|
|
|
28
28
|
summary: 'Text styles, tones, links and bindings',
|
|
29
29
|
icon: 'edit',
|
|
30
30
|
},
|
|
31
|
+
{
|
|
32
|
+
page: 'styles',
|
|
33
|
+
title: 'Styles',
|
|
34
|
+
summary: 'Colours, outlines, corners, sizes and layers',
|
|
35
|
+
icon: 'star',
|
|
36
|
+
},
|
|
31
37
|
{
|
|
32
38
|
page: 'images',
|
|
33
39
|
title: 'Images',
|
|
@@ -95,7 +101,7 @@ export default {
|
|
|
95
101
|
{
|
|
96
102
|
page: 'device',
|
|
97
103
|
title: 'Alerts and device',
|
|
98
|
-
summary: 'Alerts,
|
|
104
|
+
summary: 'Alerts, sharing, links, photos, QR codes and the torch',
|
|
99
105
|
icon: 'mobile',
|
|
100
106
|
},
|
|
101
107
|
{
|
|
@@ -107,7 +113,7 @@ export default {
|
|
|
107
113
|
{
|
|
108
114
|
page: 'files',
|
|
109
115
|
title: 'Files',
|
|
110
|
-
summary: "Saving files in the dot's own folder",
|
|
116
|
+
summary: "Saving files in the dot's own folder, and picking them",
|
|
111
117
|
icon: 'file',
|
|
112
118
|
},
|
|
113
119
|
{
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<View>
|
|
2
|
+
<Text variant="title">Styles</Text>
|
|
3
|
+
<Text>Colours, outlines, corners and sizes come from the theme, so a dot looks right in light and dark.</Text>
|
|
4
|
+
|
|
5
|
+
<Text variant="caption" tone="muted">background="primary", with text tone="onPrimary"</Text>
|
|
6
|
+
<View background="primary" radius="large" padding="large" gap="small">
|
|
7
|
+
<Text variant="caption" tone="onPrimary">Your balance</Text>
|
|
8
|
+
<Text variant="display" tone="onPrimary" numeric>{{ balance }}</Text>
|
|
9
|
+
</View>
|
|
10
|
+
|
|
11
|
+
<Text variant="caption" tone="muted">A tone as a background is a soft tint</Text>
|
|
12
|
+
<View direction="row" gap="small" wrap>
|
|
13
|
+
<View background="success" radius="medium" padding="small">
|
|
14
|
+
<Text tone="success" weight="medium">Paid</Text>
|
|
15
|
+
</View>
|
|
16
|
+
<View background="warning" radius="medium" padding="small">
|
|
17
|
+
<Text tone="warning" weight="medium">Due Friday</Text>
|
|
18
|
+
</View>
|
|
19
|
+
<View background="danger" radius="medium" padding="small">
|
|
20
|
+
<Text tone="danger" weight="medium">Failed</Text>
|
|
21
|
+
</View>
|
|
22
|
+
</View>
|
|
23
|
+
|
|
24
|
+
<Text variant="caption" tone="muted">The dot's own colours, named in dot.ts</Text>
|
|
25
|
+
<View direction="row" gap="small" align="center">
|
|
26
|
+
<View background="gold" radius="full" paddingTop="small" paddingBottom="small" paddingStart="medium" paddingEnd="medium">
|
|
27
|
+
<Text weight="medium" tone="ink">Gold member</Text>
|
|
28
|
+
</View>
|
|
29
|
+
<Text tone="gold" weight="bold">Since 2024</Text>
|
|
30
|
+
</View>
|
|
31
|
+
|
|
32
|
+
<Text variant="caption" tone="muted">Outlines, corners and sizes in points</Text>
|
|
33
|
+
<View direction="row" gap="medium" align="end">
|
|
34
|
+
<View width="56" height="56" background="muted" radius="small" />
|
|
35
|
+
<View width="56" height="56" background="muted" radius="medium" />
|
|
36
|
+
<View width="56" height="56" background="muted" radius="full" />
|
|
37
|
+
<View width="56" height="56" border="strong" radius="medium" />
|
|
38
|
+
</View>
|
|
39
|
+
|
|
40
|
+
<Text variant="caption" tone="muted">Prices with even digits, and the old one crossed out</Text>
|
|
41
|
+
<View variant="card" direction="row" align="center" gap="small">
|
|
42
|
+
<Text variant="subtitle">Freetown Jazz Night</Text>
|
|
43
|
+
<View grow />
|
|
44
|
+
<Text tone="muted" decoration="strikethrough" numeric>SLE 150</Text>
|
|
45
|
+
<Text weight="bold" numeric>SLE 120</Text>
|
|
46
|
+
</View>
|
|
47
|
+
|
|
48
|
+
<Text variant="caption" tone="muted">A Stack lays its children on top of each other</Text>
|
|
49
|
+
<Stack radius="large" aspect="16:9">
|
|
50
|
+
<View background="gold" />
|
|
51
|
+
<View justify="end" padding="large">
|
|
52
|
+
<Text variant="subtitle" tone="ink">Bo market day</Text>
|
|
53
|
+
<Text tone="ink">Every Saturday, from 7 am</Text>
|
|
54
|
+
</View>
|
|
55
|
+
<View align="end" padding="medium">
|
|
56
|
+
<View background="primary" radius="full" paddingStart="small" paddingEnd="small">
|
|
57
|
+
<Text variant="caption" tone="onPrimary" weight="bold">New</Text>
|
|
58
|
+
</View>
|
|
59
|
+
</View>
|
|
60
|
+
</Stack>
|
|
61
|
+
</View>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monimesl/dot-cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.16",
|
|
4
4
|
"description": "The dotctl command: build mini apps and run them in the simulator",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"typescript": "^5.9.3",
|
|
26
26
|
"uqr": "^0.1.3",
|
|
27
|
-
"@monimesl/dot-compiler": "0.1.0-alpha.
|
|
28
|
-
"@monimesl/dot-
|
|
29
|
-
"@monimesl/dot-
|
|
30
|
-
"@monimesl/dot-
|
|
31
|
-
"@monimesl/dot-
|
|
27
|
+
"@monimesl/dot-compiler": "0.1.0-alpha.16",
|
|
28
|
+
"@monimesl/dot-dml-parser": "0.1.0-alpha.16",
|
|
29
|
+
"@monimesl/dot-simulator": "0.1.0-alpha.16",
|
|
30
|
+
"@monimesl/dot-script-parser": "0.1.0-alpha.16",
|
|
31
|
+
"@monimesl/dot-core": "0.1.0-alpha.16"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/node": "^22.20.4",
|