@monimesl/dot-cli 0.1.0-alpha.8 → 1.0.0-beta.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/README.md +75 -54
- package/dist/cli.js +628 -348
- package/dist/cli.js.map +1 -1
- package/dist/{server-DFOUQnLA.js → server-DMnWDdJ6.js} +582 -537
- package/dist/server-DMnWDdJ6.js.map +1 -0
- package/dist/templates/showcase/.env +1 -1
- package/dist/templates/showcase/dot.ts +53 -14
- package/dist/templates/showcase/pages/basics/bars/controller.ts +47 -0
- package/dist/templates/showcase/pages/basics/bars/state.ts +7 -0
- package/dist/templates/showcase/pages/basics/bars/view.dml +36 -0
- package/dist/templates/showcase/pages/basics/bindings/controller.ts +15 -0
- package/dist/templates/showcase/pages/basics/bindings/state.ts +14 -0
- package/dist/templates/showcase/pages/basics/bindings/view.dml +41 -0
- package/dist/templates/showcase/pages/basics/colors/controller.ts +112 -0
- package/dist/templates/showcase/pages/basics/colors/palette.ts +52 -0
- package/dist/templates/showcase/pages/basics/colors/state.ts +17 -0
- package/dist/templates/showcase/pages/basics/colors/view.dml +142 -0
- package/dist/templates/showcase/pages/basics/concert/controller.ts +16 -0
- package/dist/templates/showcase/pages/basics/concert/state.ts +7 -0
- package/dist/templates/showcase/pages/basics/concert/view.dml +20 -0
- package/dist/templates/showcase/pages/basics/control-flow/controller.ts +18 -0
- package/dist/templates/showcase/pages/basics/control-flow/state.ts +16 -0
- package/dist/templates/showcase/pages/basics/control-flow/view.dml +55 -0
- package/dist/templates/showcase/pages/basics/events/controller.ts +43 -0
- package/dist/templates/showcase/pages/basics/events/state.ts +11 -0
- package/dist/templates/showcase/pages/basics/events/view.dml +51 -0
- package/dist/templates/showcase/pages/basics/hooks/controller.ts +43 -0
- package/dist/templates/showcase/pages/basics/hooks/state.ts +10 -0
- package/dist/templates/showcase/pages/basics/hooks/view.dml +37 -0
- package/dist/templates/showcase/pages/basics/navigation/controller.ts +41 -0
- package/dist/templates/showcase/pages/basics/navigation/state.ts +11 -0
- package/dist/templates/showcase/pages/basics/navigation/view.dml +48 -0
- package/dist/templates/showcase/pages/basics/pick-genre/controller.ts +18 -0
- package/dist/templates/showcase/pages/basics/pick-genre/state.ts +3 -0
- package/dist/templates/showcase/pages/basics/pick-genre/view.dml +10 -0
- package/dist/templates/showcase/pages/basics/share/concerts.ts +31 -0
- package/dist/templates/showcase/pages/basics/share/controller.ts +12 -0
- package/dist/templates/showcase/pages/basics/share/state.ts +5 -0
- package/dist/templates/showcase/pages/basics/share/view.dml +21 -0
- package/dist/templates/showcase/pages/{state → basics/state}/controller.ts +1 -0
- package/dist/templates/showcase/pages/{state → basics/state}/state.ts +1 -1
- package/dist/templates/showcase/pages/basics/state/view.dml +46 -0
- package/dist/templates/showcase/pages/components/carousel/controller.ts +41 -0
- package/dist/templates/showcase/pages/components/carousel/state.ts +77 -0
- package/dist/templates/showcase/pages/components/carousel/view.dml +42 -0
- package/dist/templates/showcase/pages/components/feedback/controller.ts +32 -0
- package/dist/templates/showcase/pages/components/feedback/state.ts +41 -0
- package/dist/templates/showcase/pages/components/feedback/view.dml +116 -0
- package/dist/templates/showcase/pages/components/forms/controller.ts +72 -0
- package/dist/templates/showcase/pages/components/forms/state.ts +37 -0
- package/dist/templates/showcase/pages/components/forms/view.dml +97 -0
- package/dist/templates/showcase/pages/components/icons/controller.ts +15 -0
- package/dist/templates/showcase/pages/components/icons/state.ts +75 -0
- package/dist/templates/showcase/pages/components/icons/view.dml +36 -0
- package/dist/templates/showcase/pages/components/images/controller.ts +44 -0
- package/dist/templates/showcase/pages/{images → components/images}/state.ts +3 -0
- package/dist/templates/showcase/pages/components/images/view.dml +83 -0
- package/dist/templates/showcase/pages/components/layout/controller.ts +61 -0
- package/dist/templates/showcase/pages/components/layout/state.ts +34 -0
- package/dist/templates/showcase/pages/components/layout/view.dml +143 -0
- package/dist/templates/showcase/pages/components/lists/controller.ts +18 -0
- package/dist/templates/showcase/pages/components/lists/state.ts +130 -0
- package/dist/templates/showcase/pages/components/lists/view.dml +88 -0
- package/dist/templates/showcase/pages/components/money/controller.ts +45 -0
- package/dist/templates/showcase/pages/{payments → components/money}/state.ts +3 -0
- package/dist/templates/showcase/pages/components/money/view.dml +54 -0
- package/dist/templates/showcase/pages/components/reading/controller.ts +6 -0
- package/dist/templates/showcase/pages/components/reading/state.ts +23 -0
- package/dist/templates/showcase/pages/components/reading/view.dml +42 -0
- package/dist/templates/showcase/pages/components/sheets/controller.ts +36 -0
- package/dist/templates/showcase/pages/components/sheets/state.ts +26 -0
- package/dist/templates/showcase/pages/components/sheets/view.dml +38 -0
- package/dist/templates/showcase/pages/components/styles/controller.ts +6 -0
- package/dist/templates/showcase/pages/components/styles/state.ts +3 -0
- package/dist/templates/showcase/pages/components/styles/view.dml +101 -0
- package/dist/templates/showcase/pages/components/tabs/controller.ts +41 -0
- package/dist/templates/showcase/pages/components/tabs/state.ts +127 -0
- package/dist/templates/showcase/pages/components/tabs/view.dml +57 -0
- package/dist/templates/showcase/pages/components/text/controller.ts +10 -0
- package/dist/templates/showcase/pages/components/text/state.ts +3 -0
- package/dist/templates/showcase/pages/components/text/view.dml +95 -0
- package/dist/templates/showcase/pages/dash/account/controller.ts +32 -0
- package/dist/templates/showcase/pages/dash/account/state.ts +9 -0
- package/dist/templates/showcase/pages/dash/account/view.dml +33 -0
- package/dist/templates/showcase/pages/dash/cache/controller.ts +50 -0
- package/dist/templates/showcase/pages/dash/cache/state.ts +17 -0
- package/dist/templates/showcase/pages/dash/cache/view.dml +48 -0
- package/dist/templates/showcase/pages/dash/calls/controller.ts +67 -0
- package/dist/templates/showcase/pages/dash/calls/state.ts +9 -0
- package/dist/templates/showcase/pages/dash/calls/view.dml +69 -0
- package/dist/templates/showcase/pages/dash/contacts/controller.ts +30 -0
- package/dist/templates/showcase/pages/dash/contacts/state.ts +6 -0
- package/dist/templates/showcase/pages/dash/contacts/view.dml +33 -0
- package/dist/templates/showcase/pages/dash/crypto/controller.ts +38 -0
- package/dist/templates/showcase/pages/dash/crypto/state.ts +10 -0
- package/dist/templates/showcase/pages/dash/crypto/view.dml +48 -0
- package/dist/templates/showcase/pages/dash/files/controller.ts +71 -0
- package/dist/templates/showcase/pages/dash/files/state.ts +23 -0
- package/dist/templates/showcase/pages/dash/files/view.dml +78 -0
- package/dist/templates/showcase/pages/dash/media/controller.ts +65 -0
- package/dist/templates/showcase/pages/dash/media/state.ts +12 -0
- package/dist/templates/showcase/pages/dash/media/view.dml +53 -0
- package/dist/templates/showcase/pages/dash/network/controller.ts +215 -0
- package/dist/templates/showcase/pages/dash/network/state.ts +35 -0
- package/dist/templates/showcase/pages/dash/network/view.dml +108 -0
- package/dist/templates/showcase/pages/dash/payments/cases.ts +445 -0
- package/dist/templates/showcase/pages/dash/payments/controller.ts +149 -0
- package/dist/templates/showcase/pages/dash/payments/state.ts +33 -0
- package/dist/templates/showcase/pages/dash/payments/view.dml +71 -0
- package/dist/templates/showcase/pages/dash/secrets/controller.ts +44 -0
- package/dist/templates/showcase/pages/dash/secrets/state.ts +5 -0
- package/dist/templates/showcase/pages/dash/secrets/view.dml +26 -0
- package/dist/templates/showcase/pages/dash/system/controller.ts +89 -0
- package/dist/templates/showcase/pages/dash/system/state.ts +13 -0
- package/dist/templates/showcase/pages/dash/system/view.dml +96 -0
- package/dist/templates/showcase/pages/dash/ui/controller.ts +70 -0
- package/dist/templates/showcase/pages/dash/ui/state.ts +8 -0
- package/dist/templates/showcase/pages/dash/ui/view.dml +31 -0
- package/dist/templates/showcase/pages/index/controller.ts +1 -1
- package/dist/templates/showcase/pages/index/state.ts +181 -54
- package/dist/templates/showcase/pages/index/view.dml +8 -5
- package/dist/templates/showcase/statics/logo.png +0 -0
- package/package.json +6 -6
- package/dist/server-DFOUQnLA.js.map +0 -1
- package/dist/templates/showcase/pages/carousel/controller.ts +0 -10
- package/dist/templates/showcase/pages/carousel/state.ts +0 -40
- package/dist/templates/showcase/pages/carousel/view.dml +0 -37
- package/dist/templates/showcase/pages/device/controller.ts +0 -70
- package/dist/templates/showcase/pages/device/state.ts +0 -7
- package/dist/templates/showcase/pages/device/view.dml +0 -44
- package/dist/templates/showcase/pages/feedback/controller.ts +0 -16
- package/dist/templates/showcase/pages/feedback/state.ts +0 -7
- package/dist/templates/showcase/pages/feedback/view.dml +0 -87
- package/dist/templates/showcase/pages/files/controller.ts +0 -47
- package/dist/templates/showcase/pages/files/state.ts +0 -11
- package/dist/templates/showcase/pages/files/view.dml +0 -35
- package/dist/templates/showcase/pages/filters/controller.ts +0 -28
- package/dist/templates/showcase/pages/filters/state.ts +0 -72
- package/dist/templates/showcase/pages/filters/view.dml +0 -43
- package/dist/templates/showcase/pages/forms/controller.ts +0 -44
- package/dist/templates/showcase/pages/forms/state.ts +0 -15
- package/dist/templates/showcase/pages/forms/view.dml +0 -39
- package/dist/templates/showcase/pages/images/controller.ts +0 -15
- package/dist/templates/showcase/pages/images/view.dml +0 -38
- package/dist/templates/showcase/pages/layout/controller.ts +0 -26
- package/dist/templates/showcase/pages/layout/state.ts +0 -14
- package/dist/templates/showcase/pages/layout/view.dml +0 -80
- package/dist/templates/showcase/pages/lists/controller.ts +0 -36
- package/dist/templates/showcase/pages/lists/state.ts +0 -96
- package/dist/templates/showcase/pages/lists/view.dml +0 -59
- package/dist/templates/showcase/pages/navigation/controller.ts +0 -64
- package/dist/templates/showcase/pages/navigation/state.ts +0 -17
- package/dist/templates/showcase/pages/navigation/view.dml +0 -34
- package/dist/templates/showcase/pages/network/controller.ts +0 -107
- package/dist/templates/showcase/pages/network/state.ts +0 -15
- package/dist/templates/showcase/pages/network/view.dml +0 -56
- package/dist/templates/showcase/pages/payments/controller.ts +0 -42
- package/dist/templates/showcase/pages/payments/view.dml +0 -35
- package/dist/templates/showcase/pages/state/view.dml +0 -33
- package/dist/templates/showcase/pages/text/controller.ts +0 -10
- package/dist/templates/showcase/pages/text/state.ts +0 -7
- package/dist/templates/showcase/pages/text/view.dml +0 -49
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { errorMessage } from '@monimesl/dot-runtime';
|
|
2
|
+
|
|
3
|
+
import state from './state';
|
|
4
|
+
|
|
5
|
+
// AUDACITY's id in Apple's catalog; its cover's address can change, so the page looks it up.
|
|
6
|
+
const AUDACITY = 6811765244;
|
|
7
|
+
|
|
8
|
+
interface Lookup {
|
|
9
|
+
results: { artworkUrl100: string }[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default definePage({
|
|
13
|
+
initialState: state,
|
|
14
|
+
configs: { navigationBar: { title: 'Images' } },
|
|
15
|
+
hooks: {
|
|
16
|
+
async onLoad() {
|
|
17
|
+
try {
|
|
18
|
+
const { body } = await this.dash.network.http.request<Lookup>({
|
|
19
|
+
url: `https://itunes.apple.com/lookup?id=${AUDACITY}`,
|
|
20
|
+
as: 'json',
|
|
21
|
+
});
|
|
22
|
+
const artwork = body.results[0]?.artworkUrl100;
|
|
23
|
+
// The catalog's artwork comes in any size its address names.
|
|
24
|
+
this.setState(
|
|
25
|
+
artwork
|
|
26
|
+
? { cover: artwork.replace('100x100bb', '600x600bb') }
|
|
27
|
+
: { coverNote: "Apple's catalog has no cover for it" },
|
|
28
|
+
);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
this.setState({ coverNote: errorMessage(error) });
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
mutations: {
|
|
35
|
+
grow: (state) => ({ size: Math.min(state.size + 16, 128) }),
|
|
36
|
+
shrink: (state) => ({ size: Math.max(state.size - 16, 16) }),
|
|
37
|
+
logoLoaded: (_state, event: DotEvent<{ width: number; height: number }>) => ({
|
|
38
|
+
loaded: `${event.detail.width} × ${event.detail.height}`,
|
|
39
|
+
}),
|
|
40
|
+
missingFailed: (_state, event: DotEvent<{ message: string }>) => ({
|
|
41
|
+
failure: event.detail.message,
|
|
42
|
+
}),
|
|
43
|
+
},
|
|
44
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<View>
|
|
2
|
+
<Text variant="title">Images</Text>
|
|
3
|
+
<Text>Image shows a picture from the dot's statics/ folder or from the web. Give it alt text, which screen readers say aloud.</Text>
|
|
4
|
+
|
|
5
|
+
<View gap="small">
|
|
6
|
+
<Text variant="subtitle">From statics/</Text>
|
|
7
|
+
<Text variant="caption" tone="muted">These pictures come with the dot, and the build checks each one exists.</Text>
|
|
8
|
+
<View variant="card" direction="row" align="end" gap="large">
|
|
9
|
+
<Image src="statics/logo.png" alt="Small logo" width="24" height="24" />
|
|
10
|
+
<Image src="statics/logo.png" alt="Medium logo" width="48" height="48" />
|
|
11
|
+
<Image src="statics/logo.png" alt="Large logo" width="96" height="96" />
|
|
12
|
+
</View>
|
|
13
|
+
</View>
|
|
14
|
+
|
|
15
|
+
<View gap="small">
|
|
16
|
+
<Text variant="subtitle">From the web</Text>
|
|
17
|
+
<Text variant="caption" tone="muted">The cover of Drizilik's album AUDACITY. With aspect="1:1" and no width, it fills the card.</Text>
|
|
18
|
+
<View variant="card" gap="small">
|
|
19
|
+
<If condition="{{ cover }}">
|
|
20
|
+
<Image src="{{ cover }}" alt="The cover of AUDACITY, by Drizilik" aspect="1:1" />
|
|
21
|
+
<Text weight="medium">AUDACITY</Text>
|
|
22
|
+
<Text variant="caption" tone="muted">Drizilik raps mostly in Krio, in a style called Kriofusion. He won Best Male Artist at the 2026 SLeDU awards.</Text>
|
|
23
|
+
</If>
|
|
24
|
+
<ElseIf condition="{{ coverNote }}">
|
|
25
|
+
<Text variant="caption" tone="muted">{{ coverNote }}</Text>
|
|
26
|
+
</ElseIf>
|
|
27
|
+
<Else>
|
|
28
|
+
<Skeleton shape="box" height="280" />
|
|
29
|
+
</Else>
|
|
30
|
+
</View>
|
|
31
|
+
</View>
|
|
32
|
+
|
|
33
|
+
<View gap="small">
|
|
34
|
+
<Text variant="subtitle">shape and fit</Text>
|
|
35
|
+
<Text variant="caption" tone="muted">Rounded, square or circle. fit="contain" shows the whole picture; cover, the default, fills the box.</Text>
|
|
36
|
+
<View variant="card" direction="row" align="center" gap="large">
|
|
37
|
+
<Image src="statics/logo.png" alt="Rounded" width="56" height="56" shape="rounded" />
|
|
38
|
+
<Image src="statics/logo.png" alt="Square" width="56" height="56" shape="square" />
|
|
39
|
+
<Image src="statics/logo.png" alt="Circle" width="56" height="56" shape="circle" />
|
|
40
|
+
<Image src="statics/logo.png" alt="Contained" width="96" height="56" fit="contain" />
|
|
41
|
+
<Image src="statics/logo.png" alt="Covered" width="96" height="56" fit="cover" />
|
|
42
|
+
</View>
|
|
43
|
+
</View>
|
|
44
|
+
|
|
45
|
+
<View gap="small">
|
|
46
|
+
<Text variant="subtitle">onLoad</Text>
|
|
47
|
+
<Text variant="caption" tone="muted">Tells the page the picture's own size once it loads. The size on screen comes from state here.</Text>
|
|
48
|
+
<View variant="card" gap="small">
|
|
49
|
+
<Image src="statics/logo.png" alt="Logo" width="{{ size }}" height="{{ size }}" onLoad="logoLoaded" />
|
|
50
|
+
<Text>{{ size }} × {{ size }} on screen, {{ loaded }} in the file</Text>
|
|
51
|
+
<View direction="row" gap="small">
|
|
52
|
+
<Button variant="secondary" onClick="shrink" disabled="{{ size <= 16 }}">Smaller</Button>
|
|
53
|
+
<Button variant="secondary" onClick="grow" disabled="{{ size >= 128 }}">Bigger</Button>
|
|
54
|
+
</View>
|
|
55
|
+
</View>
|
|
56
|
+
</View>
|
|
57
|
+
|
|
58
|
+
<View gap="small">
|
|
59
|
+
<Text variant="subtitle">onError</Text>
|
|
60
|
+
<Text variant="caption" tone="muted">Tells the page why a picture didn't load.</Text>
|
|
61
|
+
<View variant="card">
|
|
62
|
+
<If condition="{{ failure }}">
|
|
63
|
+
<Text>{{ failure }}</Text>
|
|
64
|
+
</If>
|
|
65
|
+
<Else>
|
|
66
|
+
<Image src="{{ missing }}" alt="" width="48" height="48" onError="missingFailed" />
|
|
67
|
+
</Else>
|
|
68
|
+
</View>
|
|
69
|
+
</View>
|
|
70
|
+
|
|
71
|
+
<View gap="small">
|
|
72
|
+
<Text variant="subtitle">Avatar</Text>
|
|
73
|
+
<Text variant="caption" tone="muted">A person's photo, round. Without one, or when it fails to load, their initials show.</Text>
|
|
74
|
+
<View variant="card" direction="row" align="center" gap="large">
|
|
75
|
+
<Avatar name="Salone Sounds" image="statics/logo.png" size="large" />
|
|
76
|
+
<Avatar name="Mariama Kamara" size="large" />
|
|
77
|
+
<Avatar name="Fatmata Conteh" />
|
|
78
|
+
<Avatar name="Boii" size="small" />
|
|
79
|
+
<Avatar name="Kao Denero" image="{{ missing }}" />
|
|
80
|
+
</View>
|
|
81
|
+
<Text variant="caption" tone="muted">The last one's picture is missing, so it shows KD.</Text>
|
|
82
|
+
</View>
|
|
83
|
+
</View>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Align, Direction, Justify, Space } from './state';
|
|
2
|
+
import state from './state';
|
|
3
|
+
|
|
4
|
+
const DIRECTIONS: Direction[] = ['row', 'column'];
|
|
5
|
+
const JUSTIFIES: Justify[] = ['start', 'center', 'end', 'between'];
|
|
6
|
+
const ALIGNS: Align[] = ['stretch', 'start', 'center', 'end'];
|
|
7
|
+
const SPACES: Space[] = ['none', 'small', 'medium', 'large'];
|
|
8
|
+
|
|
9
|
+
interface Lookup {
|
|
10
|
+
results: { collectionId: number; artworkUrl100: string }[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default definePage({
|
|
14
|
+
initialState: state,
|
|
15
|
+
configs: { navigationBar: { title: 'Layout' } },
|
|
16
|
+
hooks: {
|
|
17
|
+
// The shelf's covers come from Apple's catalog.
|
|
18
|
+
async onLoad() {
|
|
19
|
+
const ids = this.state.releases.map((release) => release.id).join(',');
|
|
20
|
+
try {
|
|
21
|
+
const { body } = await this.dash.network.http.request<Lookup>({
|
|
22
|
+
url: `https://itunes.apple.com/lookup?id=${ids}`,
|
|
23
|
+
as: 'json',
|
|
24
|
+
});
|
|
25
|
+
const covers = new Map(
|
|
26
|
+
body.results.map((result) => [
|
|
27
|
+
result.collectionId,
|
|
28
|
+
result.artworkUrl100.replace('100x100bb', '300x300bb'),
|
|
29
|
+
]),
|
|
30
|
+
);
|
|
31
|
+
this.setState((current) => ({
|
|
32
|
+
releases: current.releases.map((release) => ({
|
|
33
|
+
...release,
|
|
34
|
+
cover: covers.get(release.id) ?? '',
|
|
35
|
+
})),
|
|
36
|
+
}));
|
|
37
|
+
} catch {
|
|
38
|
+
// Without the catalog, the shelf shows its titles alone.
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
mutations: {
|
|
43
|
+
nextDirection: (state) => ({ direction: after(DIRECTIONS, state.direction) }),
|
|
44
|
+
nextJustify: (state) => ({ justify: after(JUSTIFIES, state.justify) }),
|
|
45
|
+
nextAlign: (state) => ({ align: after(ALIGNS, state.align) }),
|
|
46
|
+
nextGap: (state) => ({ gap: after(SPACES, state.gap) }),
|
|
47
|
+
toggleWrap: (state) => ({ wrap: !state.wrap }),
|
|
48
|
+
openSection: (_state, event: DataEvent<{ name: string }>) => ({
|
|
49
|
+
section: event.data.name,
|
|
50
|
+
}),
|
|
51
|
+
showFirst: (_state, event: IndexEvent) => ({ first: event.detail.index }),
|
|
52
|
+
shelfStart: () => ({ first: 0 }),
|
|
53
|
+
shelfEnd: (state) => ({ first: state.releases.length - 1 }),
|
|
54
|
+
playSong: (state) => ({ playing: !state.playing }),
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
function after<Value>(values: Value[], current: Value): Value {
|
|
59
|
+
const next = (values.indexOf(current) + 1) % values.length;
|
|
60
|
+
return values[next]!;
|
|
61
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type Direction = 'row' | 'column';
|
|
2
|
+
export type Justify = 'start' | 'center' | 'end' | 'between';
|
|
3
|
+
export type Align = 'stretch' | 'start' | 'center' | 'end';
|
|
4
|
+
export type Space = 'none' | 'small' | 'medium' | 'large';
|
|
5
|
+
|
|
6
|
+
export interface Release {
|
|
7
|
+
// Its id in Apple's catalog, which has its cover.
|
|
8
|
+
id: number;
|
|
9
|
+
title: string;
|
|
10
|
+
year: number;
|
|
11
|
+
cover: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default {
|
|
15
|
+
direction: 'row' as Direction,
|
|
16
|
+
justify: 'start' as Justify,
|
|
17
|
+
align: 'center' as Align,
|
|
18
|
+
gap: 'small' as Space,
|
|
19
|
+
wrap: true,
|
|
20
|
+
// The section tapped in the grid.
|
|
21
|
+
section: '',
|
|
22
|
+
// Whether the tapped song card is playing.
|
|
23
|
+
playing: false,
|
|
24
|
+
// Drizilik's releases, newest first, for the shelf.
|
|
25
|
+
releases: [
|
|
26
|
+
{ id: 6811765244, title: 'AUDACITY', year: 2026, cover: '' },
|
|
27
|
+
{ id: 1788321371, title: 'Wait and See', year: 2025, cover: '' },
|
|
28
|
+
{ id: 1745452762, title: 'Send Money', year: 2024, cover: '' },
|
|
29
|
+
{ id: 1638724918, title: 'Ashobi', year: 2022, cover: '' },
|
|
30
|
+
{ id: 1590578915, title: 'Exodus', year: 2021, cover: '' },
|
|
31
|
+
] as Release[],
|
|
32
|
+
// The release at the start of the shelf.
|
|
33
|
+
first: 0,
|
|
34
|
+
};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
<View>
|
|
2
|
+
<Text variant="title">Layout</Text>
|
|
3
|
+
<Text>Views hold other components and lay them out. Every page starts with one.</Text>
|
|
4
|
+
|
|
5
|
+
<View gap="small">
|
|
6
|
+
<Text variant="subtitle">View</Text>
|
|
7
|
+
<Text variant="caption" tone="muted">A View puts its items in a column or a row. variant="card" gives it a card's look. Change the one below.</Text>
|
|
8
|
+
<View variant="card" direction="{{ direction }}" justify="{{ justify }}" align="{{ align }}" gap="{{ gap }}" wrap="{{ wrap }}">
|
|
9
|
+
<Button variant="secondary">Palm-wine</Button>
|
|
10
|
+
<Button variant="secondary">Gumbe</Button>
|
|
11
|
+
<Text variant="title">Afropop</Text>
|
|
12
|
+
<Button variant="secondary">Bubu</Button>
|
|
13
|
+
<Text variant="caption" tone="muted">Milo jazz</Text>
|
|
14
|
+
</View>
|
|
15
|
+
<View gap="small">
|
|
16
|
+
<View direction="row" align="center">
|
|
17
|
+
<Text>direction="{{ direction }}"</Text>
|
|
18
|
+
<View grow />
|
|
19
|
+
<Button variant="secondary" onClick="nextDirection">Change</Button>
|
|
20
|
+
</View>
|
|
21
|
+
<View direction="row" align="center">
|
|
22
|
+
<Text>justify="{{ justify }}"</Text>
|
|
23
|
+
<View grow />
|
|
24
|
+
<Button variant="secondary" onClick="nextJustify">Change</Button>
|
|
25
|
+
</View>
|
|
26
|
+
<View direction="row" align="center">
|
|
27
|
+
<Text>align="{{ align }}"</Text>
|
|
28
|
+
<View grow />
|
|
29
|
+
<Button variant="secondary" onClick="nextAlign">Change</Button>
|
|
30
|
+
</View>
|
|
31
|
+
<View direction="row" align="center">
|
|
32
|
+
<Text>gap="{{ gap }}"</Text>
|
|
33
|
+
<View grow />
|
|
34
|
+
<Button variant="secondary" onClick="nextGap">Change</Button>
|
|
35
|
+
</View>
|
|
36
|
+
<View direction="row" align="center">
|
|
37
|
+
<Text>wrap="{{ wrap }}"</Text>
|
|
38
|
+
<View grow />
|
|
39
|
+
<Button variant="secondary" onClick="toggleWrap">Change</Button>
|
|
40
|
+
</View>
|
|
41
|
+
</View>
|
|
42
|
+
</View>
|
|
43
|
+
|
|
44
|
+
<View gap="small">
|
|
45
|
+
<Text variant="subtitle">grow and onTap</Text>
|
|
46
|
+
<Text variant="caption" tone="muted">grow fills the space left over: the song grows, the year does not. A View can be tapped: tap the song.</Text>
|
|
47
|
+
<View direction="row" gap="small">
|
|
48
|
+
<View variant="card" grow onTap="playSong">
|
|
49
|
+
<Text>{{ playing ? 'Playing Exodus, by Drizilik' : 'Exodus, by Drizilik' }}</Text>
|
|
50
|
+
</View>
|
|
51
|
+
<View variant="card">
|
|
52
|
+
<Text>2021</Text>
|
|
53
|
+
</View>
|
|
54
|
+
</View>
|
|
55
|
+
</View>
|
|
56
|
+
|
|
57
|
+
<View gap="small">
|
|
58
|
+
<Text variant="subtitle">padding</Text>
|
|
59
|
+
<Text variant="caption" tone="muted">The space inside the edges, on every side or on one side. Most components take it.</Text>
|
|
60
|
+
<View direction="row" gap="small">
|
|
61
|
+
<View variant="card" padding="small">
|
|
62
|
+
<Text>small</Text>
|
|
63
|
+
</View>
|
|
64
|
+
<View variant="card" padding="large">
|
|
65
|
+
<Text>large</Text>
|
|
66
|
+
</View>
|
|
67
|
+
<View variant="card" padding="small" paddingStart="large">
|
|
68
|
+
<Text>start</Text>
|
|
69
|
+
</View>
|
|
70
|
+
</View>
|
|
71
|
+
</View>
|
|
72
|
+
|
|
73
|
+
<View gap="small">
|
|
74
|
+
<Text variant="subtitle">Stack</Text>
|
|
75
|
+
<Text variant="caption" tone="muted">A Stack lays its children on top of each other, such as words over a picture.</Text>
|
|
76
|
+
<Stack radius="large" aspect="16:9">
|
|
77
|
+
<View background="gold" />
|
|
78
|
+
<View justify="end" padding="large">
|
|
79
|
+
<Text variant="subtitle" tone="ink">Bo market day</Text>
|
|
80
|
+
<Text tone="ink">Every Saturday, from 7 am</Text>
|
|
81
|
+
</View>
|
|
82
|
+
<View align="end" padding="medium">
|
|
83
|
+
<View background="primary" radius="full" paddingStart="small" paddingEnd="small">
|
|
84
|
+
<Text variant="caption" tone="onPrimary" weight="bold">New</Text>
|
|
85
|
+
</View>
|
|
86
|
+
</View>
|
|
87
|
+
</Stack>
|
|
88
|
+
</View>
|
|
89
|
+
|
|
90
|
+
<View gap="small">
|
|
91
|
+
<Text variant="subtitle">Scroll</Text>
|
|
92
|
+
<Text variant="caption" tone="muted">A Scroll moves a row sideways. It stops at the start of each release. The buttons scroll it too.</Text>
|
|
93
|
+
<Scroll gap="medium" snap="start" index="{{ first }}" onChange="showFirst">
|
|
94
|
+
<For each="{{ releases }}" item="release" key="id">
|
|
95
|
+
<View gap="small">
|
|
96
|
+
<If condition="{{ release.cover }}">
|
|
97
|
+
<Image src="{{ release.cover }}" alt="{{ release.title }}" width="128" height="128" />
|
|
98
|
+
</If>
|
|
99
|
+
<Else>
|
|
100
|
+
<Skeleton shape="box" height="128" />
|
|
101
|
+
</Else>
|
|
102
|
+
<Text weight="medium" maxLines="2">{{ release.title }}</Text>
|
|
103
|
+
<Text variant="caption" tone="muted">{{ release.year }}</Text>
|
|
104
|
+
</View>
|
|
105
|
+
</For>
|
|
106
|
+
</Scroll>
|
|
107
|
+
<Text tone="muted">First on the shelf: {{ releases[first].title }}</Text>
|
|
108
|
+
<View direction="row" gap="small">
|
|
109
|
+
<Button variant="secondary" onClick="shelfStart" disabled="{{ first === 0 }}">To the start</Button>
|
|
110
|
+
<Button variant="secondary" onClick="shelfEnd" disabled="{{ first === releases.length - 1 }}">To the end</Button>
|
|
111
|
+
</View>
|
|
112
|
+
</View>
|
|
113
|
+
|
|
114
|
+
<View gap="small">
|
|
115
|
+
<Text variant="subtitle">Grid</Text>
|
|
116
|
+
<Text variant="caption" tone="muted">A Grid keeps its columns the same width. A GridItem shows an icon or a picture, with a label.</Text>
|
|
117
|
+
<View variant="card" gap="medium">
|
|
118
|
+
<Grid columns="4" gap="small">
|
|
119
|
+
<GridItem icon="microphone" label="Artists" data-name="Artists" onTap="openSection" />
|
|
120
|
+
<GridItem icon="music" label="Albums" data-name="Albums" onTap="openSection" />
|
|
121
|
+
<GridItem icon="playlist" label="Playlists" data-name="Playlists" onTap="openSection" />
|
|
122
|
+
<GridItem icon="star" label="Charts" badge="New" data-name="Charts" onTap="openSection" />
|
|
123
|
+
<GridItem icon="calendar" label="Shows" data-name="Shows" onTap="openSection" />
|
|
124
|
+
<GridItem icon="ticket" label="Tickets" data-name="Tickets" onTap="openSection" />
|
|
125
|
+
<GridItem icon="headphones" label="Library" data-name="Library" onTap="openSection" />
|
|
126
|
+
<GridItem image="statics/logo.png" label="Salone" data-name="Salone" onTap="openSection" />
|
|
127
|
+
</Grid>
|
|
128
|
+
<If condition="{{ section }}">
|
|
129
|
+
<Text tone="muted">You tapped {{ section }}</Text>
|
|
130
|
+
</If>
|
|
131
|
+
</View>
|
|
132
|
+
</View>
|
|
133
|
+
|
|
134
|
+
<View gap="small">
|
|
135
|
+
<Text variant="subtitle">Divider</Text>
|
|
136
|
+
<Text variant="caption" tone="muted">A line between parts.</Text>
|
|
137
|
+
<View variant="card">
|
|
138
|
+
<Text>Side A</Text>
|
|
139
|
+
<Divider />
|
|
140
|
+
<Text>Side B</Text>
|
|
141
|
+
</View>
|
|
142
|
+
</View>
|
|
143
|
+
</View>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import state, { CHART } from './state';
|
|
2
|
+
|
|
3
|
+
// Rows to add each time the list's end comes into view.
|
|
4
|
+
const MORE = 5;
|
|
5
|
+
|
|
6
|
+
export default definePage({
|
|
7
|
+
initialState: state,
|
|
8
|
+
configs: { navigationBar: { title: 'Lists' } },
|
|
9
|
+
mutations: {
|
|
10
|
+
choose: (state, event: DataEvent<{ id: string }>) => {
|
|
11
|
+
const artist = state.artists.find((candidate) => candidate.id === event.data.id);
|
|
12
|
+
return { chosen: artist?.name ?? '' };
|
|
13
|
+
},
|
|
14
|
+
showMore: (state) => ({ chart: CHART.slice(0, state.chart.length + MORE) }),
|
|
15
|
+
saveSome: () => ({ saved: ['Exodus, by Drizilik', 'Control, by ApreeL'] }),
|
|
16
|
+
clearSaved: () => ({ saved: [] }),
|
|
17
|
+
},
|
|
18
|
+
});
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
export interface Artist {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
song: string;
|
|
5
|
+
genre: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface Release {
|
|
9
|
+
id: string;
|
|
10
|
+
title: string;
|
|
11
|
+
artist: string;
|
|
12
|
+
year: number;
|
|
13
|
+
note: string;
|
|
14
|
+
tone: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ChartSong {
|
|
18
|
+
id: number;
|
|
19
|
+
title: string;
|
|
20
|
+
plays: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const TITLES = [
|
|
24
|
+
'Lemonade',
|
|
25
|
+
'Control',
|
|
26
|
+
'Love Na Scam',
|
|
27
|
+
'Hannah',
|
|
28
|
+
'Nack',
|
|
29
|
+
'Exodus',
|
|
30
|
+
'Ashobi',
|
|
31
|
+
'Send Money',
|
|
32
|
+
'Blunt',
|
|
33
|
+
"O'way",
|
|
34
|
+
'Shadow',
|
|
35
|
+
'Leader',
|
|
36
|
+
'Kenyatta',
|
|
37
|
+
'Shock',
|
|
38
|
+
'Leh Wi Make Salone',
|
|
39
|
+
'Borbor Bele',
|
|
40
|
+
'Let Me Love You',
|
|
41
|
+
'Cry Africa',
|
|
42
|
+
'Corruption',
|
|
43
|
+
'Ghetto Struggle',
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
// This week's chart. The list shows the first few, and more as you scroll.
|
|
47
|
+
export const CHART: ChartSong[] = TITLES.map((title, index) => ({
|
|
48
|
+
id: index + 1,
|
|
49
|
+
title,
|
|
50
|
+
plays: `${(20 - index) * 1000} plays`,
|
|
51
|
+
}));
|
|
52
|
+
|
|
53
|
+
export default {
|
|
54
|
+
artists: [
|
|
55
|
+
{
|
|
56
|
+
id: 'drizilik',
|
|
57
|
+
name: 'Drizilik',
|
|
58
|
+
song: 'Lemonade, with The Therapist',
|
|
59
|
+
genre: 'Kriofusion',
|
|
60
|
+
},
|
|
61
|
+
{ id: 'boii', name: 'Boii', song: 'Love Na Scam', genre: 'Afrobeats' },
|
|
62
|
+
{ id: 'apreel', name: 'ApreeL', song: 'Control', genre: 'Afropop' },
|
|
63
|
+
{ id: 'donii-major', name: 'Donii Major', song: 'Hannah', genre: 'R&B' },
|
|
64
|
+
{
|
|
65
|
+
id: 'star-zee',
|
|
66
|
+
name: 'Star Zee',
|
|
67
|
+
song: 'Leader, with Stonebwoy',
|
|
68
|
+
genre: 'Hip hop',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'kao-denero',
|
|
72
|
+
name: 'Kao Denero',
|
|
73
|
+
song: 'Kenyatta',
|
|
74
|
+
genre: 'Hip hop',
|
|
75
|
+
},
|
|
76
|
+
{ id: 'laj', name: 'LAJ', song: 'Shock, with Cassidy', genre: 'Hip hop' },
|
|
77
|
+
{
|
|
78
|
+
id: 'k-man',
|
|
79
|
+
name: 'K-Man',
|
|
80
|
+
song: 'Leh Wi Make Salone',
|
|
81
|
+
genre: 'Hip hop',
|
|
82
|
+
},
|
|
83
|
+
] as Artist[],
|
|
84
|
+
releases: [
|
|
85
|
+
{
|
|
86
|
+
id: 'rise-and-shine',
|
|
87
|
+
title: 'Rise & Shine',
|
|
88
|
+
artist: "Sierra Leone's Refugee All Stars",
|
|
89
|
+
year: 2010,
|
|
90
|
+
note: 'Album of the year',
|
|
91
|
+
tone: 'success',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: 'kormot-bi-en-me',
|
|
95
|
+
title: 'Kormot Bi En Me',
|
|
96
|
+
artist: 'Steady Bongo',
|
|
97
|
+
year: 1996,
|
|
98
|
+
note: 'Best album',
|
|
99
|
+
tone: 'success',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: 'salone',
|
|
103
|
+
title: 'Salone',
|
|
104
|
+
artist: 'Bai Kamara Jr.',
|
|
105
|
+
year: 2020,
|
|
106
|
+
note: 'Nominated',
|
|
107
|
+
tone: 'warning',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: 'red-album',
|
|
111
|
+
title: 'Red Album',
|
|
112
|
+
artist: 'LAJ',
|
|
113
|
+
year: 2013,
|
|
114
|
+
note: 'Launched at the stadium',
|
|
115
|
+
tone: 'info',
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
id: 'let-me-love-you',
|
|
119
|
+
title: 'Let Me Love You',
|
|
120
|
+
artist: 'Bunny Mack',
|
|
121
|
+
year: 1981,
|
|
122
|
+
note: 'Gold disc',
|
|
123
|
+
tone: 'info',
|
|
124
|
+
},
|
|
125
|
+
] as Release[],
|
|
126
|
+
chosen: '',
|
|
127
|
+
chart: CHART.slice(0, 8),
|
|
128
|
+
chartSize: CHART.length,
|
|
129
|
+
saved: [] as string[],
|
|
130
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<View>
|
|
2
|
+
<Text variant="title">Lists</Text>
|
|
3
|
+
<Text>A List shows rows in a card. A ListItem can show an icon or a picture, a subtitle, and a value or a badge at its end. A row you can tap shows an arrow.</Text>
|
|
4
|
+
|
|
5
|
+
<View gap="small">
|
|
6
|
+
<Text variant="subtitle">List and ListItem</Text>
|
|
7
|
+
<Text variant="caption" tone="muted">Artists in a small list. Tap one: its data-id tells the page which one.</Text>
|
|
8
|
+
<List>
|
|
9
|
+
<For each="{{ artists }}" item="artist" key="id">
|
|
10
|
+
<ListItem icon="microphone" title="{{ artist.name }}" subtitle="{{ artist.song }}" value="{{ artist.genre }}" data-id="{{ artist.id }}" onTap="choose" />
|
|
11
|
+
</For>
|
|
12
|
+
</List>
|
|
13
|
+
<If condition="{{ chosen }}">
|
|
14
|
+
<Text>You chose {{ chosen }}</Text>
|
|
15
|
+
</If>
|
|
16
|
+
</View>
|
|
17
|
+
|
|
18
|
+
<View gap="small">
|
|
19
|
+
<Text variant="subtitle">size="md", with a picture and a badge</Text>
|
|
20
|
+
<Text variant="caption" tone="muted">Medium lists have more room. A ListItem's children show at its end, in place of value.</Text>
|
|
21
|
+
<List size="md">
|
|
22
|
+
<For each="{{ releases }}" item="release" key="id">
|
|
23
|
+
<ListItem image="statics/logo.png" title="{{ release.title }}" subtitle="{{ release.artist }} · {{ release.year }}">
|
|
24
|
+
<Badge tone="{{ release.tone }}">{{ release.note }}</Badge>
|
|
25
|
+
</ListItem>
|
|
26
|
+
</For>
|
|
27
|
+
</List>
|
|
28
|
+
</View>
|
|
29
|
+
|
|
30
|
+
<View gap="small">
|
|
31
|
+
<Text variant="subtitle">onEndReached</Text>
|
|
32
|
+
<Text variant="caption" tone="muted">Comes when the last row scrolls into view, so the page can add more. {{ chart.length }} of {{ chartSize }} songs so far.</Text>
|
|
33
|
+
<List onEndReached="showMore">
|
|
34
|
+
<For each="{{ chart }}" item="song" key="id">
|
|
35
|
+
<ListItem title="{{ song.id }}. {{ song.title }}" value="{{ song.plays }}" />
|
|
36
|
+
</For>
|
|
37
|
+
</List>
|
|
38
|
+
</View>
|
|
39
|
+
|
|
40
|
+
<View gap="small">
|
|
41
|
+
<Text variant="subtitle">DetailRow</Text>
|
|
42
|
+
<Text variant="caption" tone="muted">A label with its value, such as on a receipt. tone and weight change the value.</Text>
|
|
43
|
+
<View variant="card" gap="none">
|
|
44
|
+
<DetailRow label="Show" value="Salone Sounds Live" />
|
|
45
|
+
<DetailRow label="Seats" value="2, near the stage" tone="muted" />
|
|
46
|
+
<DetailRow label="Doors open" value="18:00" tone="info" />
|
|
47
|
+
<DetailRow label="Status" value="Paid" tone="success" />
|
|
48
|
+
<DetailRow label="Refunds" value="Not after Friday" tone="warning" />
|
|
49
|
+
<DetailRow label="Total" value="SLE 800" weight="bold" />
|
|
50
|
+
</View>
|
|
51
|
+
</View>
|
|
52
|
+
|
|
53
|
+
<View gap="small">
|
|
54
|
+
<Text variant="subtitle">Disclosure</Text>
|
|
55
|
+
<Text variant="caption" tone="muted">A row that opens to show more, such as an answer. The person opens and closes it, and open sets how it starts.</Text>
|
|
56
|
+
<View variant="card" gap="none">
|
|
57
|
+
<Disclosure title="Can I get a refund?" subtitle="Tickets and refunds" open>
|
|
58
|
+
<Text>Yes, until the Friday before the show. After that, you can give your ticket to someone else.</Text>
|
|
59
|
+
</Disclosure>
|
|
60
|
+
<Divider />
|
|
61
|
+
<Disclosure title="When do doors open?">
|
|
62
|
+
<Text>At 6 pm. The music starts at 7.</Text>
|
|
63
|
+
</Disclosure>
|
|
64
|
+
<Divider />
|
|
65
|
+
<Disclosure title="Is there parking?">
|
|
66
|
+
<Text>Yes, at the Lumley junction car park, a short walk away.</Text>
|
|
67
|
+
</Disclosure>
|
|
68
|
+
</View>
|
|
69
|
+
</View>
|
|
70
|
+
|
|
71
|
+
<View gap="small">
|
|
72
|
+
<Text variant="subtitle">EmptyState</Text>
|
|
73
|
+
<Text variant="caption" tone="muted">Shows when a list has nothing in it, with a way forward.</Text>
|
|
74
|
+
<View variant="card">
|
|
75
|
+
<If condition="{{ saved.length > 0 }}">
|
|
76
|
+
<For each="{{ saved }}" item="title" key="*this">
|
|
77
|
+
<Text>{{ title }}</Text>
|
|
78
|
+
</For>
|
|
79
|
+
<Button variant="secondary" onClick="clearSaved">Clear</Button>
|
|
80
|
+
</If>
|
|
81
|
+
<Else>
|
|
82
|
+
<EmptyState icon="heart" title="No saved songs" text="Save a song to find it here later.">
|
|
83
|
+
<Button variant="secondary" onClick="saveSome">Save two songs</Button>
|
|
84
|
+
</EmptyState>
|
|
85
|
+
</Else>
|
|
86
|
+
</View>
|
|
87
|
+
</View>
|
|
88
|
+
</View>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import state from './state';
|
|
2
|
+
|
|
3
|
+
// The code this page accepts; a real dot checks it with its server.
|
|
4
|
+
const RIGHT_CODE = '123456';
|
|
5
|
+
|
|
6
|
+
// In dollars, as the pledge field sends them.
|
|
7
|
+
const MAX_PLEDGE = 1000;
|
|
8
|
+
|
|
9
|
+
export default definePage({
|
|
10
|
+
initialState: state,
|
|
11
|
+
configs: { navigationBar: { title: 'Money and codes' } },
|
|
12
|
+
mutations: {
|
|
13
|
+
setAmount: (_state, event: ValueEvent<number | null>) => {
|
|
14
|
+
const amount = event.detail.value;
|
|
15
|
+
if (!amount) {
|
|
16
|
+
return { amount, amountText: '', request: '' };
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
amount,
|
|
20
|
+
amountText: (amount / 100).toLocaleString('en-US', { minimumFractionDigits: 2 }),
|
|
21
|
+
request: `https://pay.example.com/tip?amount=${amount}¤cy=SLE&in=cents`,
|
|
22
|
+
};
|
|
23
|
+
},
|
|
24
|
+
setCode: (_state, event: ValueEvent) => ({ code: event.detail.value, codeError: '' }),
|
|
25
|
+
checkCode: (_state, event: ValueEvent) => {
|
|
26
|
+
if (event.detail.value === RIGHT_CODE) {
|
|
27
|
+
return { verified: true };
|
|
28
|
+
}
|
|
29
|
+
return { code: '', codeError: 'That code is wrong. Try again.' };
|
|
30
|
+
},
|
|
31
|
+
startAgain: () => ({ verified: false, code: '' }),
|
|
32
|
+
setPin: (_state, event: ValueEvent) => ({ pin: event.detail.value }),
|
|
33
|
+
clearPin: () => ({ pin: '' }),
|
|
34
|
+
setLocked: (_state, event: CheckedEvent) => ({
|
|
35
|
+
locked: event.detail.checked,
|
|
36
|
+
}),
|
|
37
|
+
setPledge: (_state, event: ValueEvent<number | null>) => {
|
|
38
|
+
const pledge = event.detail.value;
|
|
39
|
+
return {
|
|
40
|
+
pledge,
|
|
41
|
+
pledgeError: pledge !== null && pledge > MAX_PLEDGE ? 'Pledge up to USD 1,000' : '',
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
});
|