@monimesl/dot-cli 0.1.0-alpha.8 → 0.1.0-alpha.9
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 +17 -9
- package/dist/cli.js +156 -67
- package/dist/cli.js.map +1 -1
- package/dist/{server-DFOUQnLA.js → server-BfPAnsSf.js} +34 -81
- package/dist/{server-DFOUQnLA.js.map → server-BfPAnsSf.js.map} +1 -1
- package/dist/templates/showcase/.env +1 -1
- package/dist/templates/showcase/dot.ts +2 -0
- package/dist/templates/showcase/pages/cache/controller.ts +45 -0
- package/dist/templates/showcase/pages/cache/state.ts +17 -0
- package/dist/templates/showcase/pages/cache/view.dml +36 -0
- package/dist/templates/showcase/pages/carousel/controller.ts +33 -3
- package/dist/templates/showcase/pages/carousel/state.ts +61 -24
- package/dist/templates/showcase/pages/carousel/view.dml +18 -15
- package/dist/templates/showcase/pages/device/controller.ts +22 -12
- package/dist/templates/showcase/pages/device/state.ts +1 -1
- package/dist/templates/showcase/pages/device/view.dml +13 -8
- package/dist/templates/showcase/pages/feedback/controller.ts +6 -1
- package/dist/templates/showcase/pages/feedback/state.ts +1 -0
- package/dist/templates/showcase/pages/feedback/view.dml +23 -23
- package/dist/templates/showcase/pages/files/controller.ts +33 -14
- package/dist/templates/showcase/pages/files/state.ts +10 -2
- package/dist/templates/showcase/pages/files/view.dml +29 -14
- package/dist/templates/showcase/pages/filters/controller.ts +11 -12
- package/dist/templates/showcase/pages/filters/state.ts +107 -61
- package/dist/templates/showcase/pages/filters/view.dml +18 -17
- package/dist/templates/showcase/pages/forms/controller.ts +36 -12
- package/dist/templates/showcase/pages/forms/state.ts +25 -6
- package/dist/templates/showcase/pages/forms/view.dml +28 -18
- package/dist/templates/showcase/pages/images/controller.ts +26 -0
- package/dist/templates/showcase/pages/images/state.ts +3 -0
- package/dist/templates/showcase/pages/images/view.dml +18 -3
- package/dist/templates/showcase/pages/index/state.ts +26 -14
- package/dist/templates/showcase/pages/index/view.dml +2 -2
- package/dist/templates/showcase/pages/layout/controller.ts +36 -2
- package/dist/templates/showcase/pages/layout/state.ts +22 -2
- package/dist/templates/showcase/pages/layout/view.dml +45 -22
- package/dist/templates/showcase/pages/lists/controller.ts +12 -11
- package/dist/templates/showcase/pages/lists/state.ts +87 -66
- package/dist/templates/showcase/pages/lists/view.dml +15 -15
- package/dist/templates/showcase/pages/navigation/controller.ts +2 -1
- package/dist/templates/showcase/pages/navigation/view.dml +5 -5
- package/dist/templates/showcase/pages/network/controller.ts +68 -24
- package/dist/templates/showcase/pages/network/state.ts +13 -6
- package/dist/templates/showcase/pages/network/view.dml +29 -18
- package/dist/templates/showcase/pages/payments/controller.ts +16 -12
- package/dist/templates/showcase/pages/payments/state.ts +3 -0
- package/dist/templates/showcase/pages/payments/view.dml +22 -12
- package/dist/templates/showcase/pages/secrets/controller.ts +43 -0
- package/dist/templates/showcase/pages/secrets/state.ts +5 -0
- package/dist/templates/showcase/pages/secrets/view.dml +24 -0
- package/dist/templates/showcase/pages/state/state.ts +1 -1
- package/dist/templates/showcase/pages/state/view.dml +9 -9
- package/dist/templates/showcase/pages/text/controller.ts +3 -3
- package/dist/templates/showcase/pages/text/state.ts +6 -5
- package/dist/templates/showcase/pages/text/view.dml +22 -13
- package/dist/templates/showcase/statics/logo.png +0 -0
- package/package.json +6 -6
|
@@ -1,7 +1,33 @@
|
|
|
1
1
|
import state from './state';
|
|
2
2
|
|
|
3
|
+
// AUDACITY's id in Apple's catalog; its cover's address can change, so the page looks it up.
|
|
4
|
+
const AUDACITY = 6811765244;
|
|
5
|
+
|
|
6
|
+
interface Lookup {
|
|
7
|
+
results: { artworkUrl100: string }[];
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
export default definePage({
|
|
4
11
|
initialState: state,
|
|
12
|
+
hooks: {
|
|
13
|
+
async onLoad() {
|
|
14
|
+
try {
|
|
15
|
+
const { body } = await this.dash.network.http.request<Lookup>({
|
|
16
|
+
url: `https://itunes.apple.com/lookup?id=${AUDACITY}`,
|
|
17
|
+
as: 'json',
|
|
18
|
+
});
|
|
19
|
+
const artwork = body.results[0]?.artworkUrl100;
|
|
20
|
+
// The catalog's artwork comes in any size its address names.
|
|
21
|
+
this.setState(
|
|
22
|
+
artwork
|
|
23
|
+
? { cover: artwork.replace('100x100bb', '600x600bb') }
|
|
24
|
+
: { coverNote: "Apple's catalog has no cover for it" },
|
|
25
|
+
);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
this.setState({ coverNote: (error as Error).message });
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
},
|
|
5
31
|
mutations: {
|
|
6
32
|
grow: (state) => ({ size: Math.min(state.size + 16, 128) }),
|
|
7
33
|
shrink: (state) => ({ size: Math.max(state.size - 16, 16) }),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<View>
|
|
2
2
|
<Text variant="title">Images</Text>
|
|
3
|
-
<Text>Pictures in the
|
|
3
|
+
<Text>Pictures in the statics/ folder come with the dot, and the build checks each one. Pictures from the web load from their address.</Text>
|
|
4
4
|
|
|
5
5
|
<View variant="card" direction="row" align="end" gap="large">
|
|
6
6
|
<Image src="statics/logo.png" alt="Small logo" width="24" height="24" />
|
|
@@ -8,7 +8,22 @@
|
|
|
8
8
|
<Image src="statics/logo.png" alt="Large logo" width="96" height="96" />
|
|
9
9
|
</View>
|
|
10
10
|
|
|
11
|
-
<Text variant="caption" tone="muted">
|
|
11
|
+
<Text variant="caption" tone="muted">From the web: the cover of Drizilik's album AUDACITY. With aspect="1:1" and no width, it fills the card.</Text>
|
|
12
|
+
<View variant="card" gap="small">
|
|
13
|
+
<If condition="{{ cover }}">
|
|
14
|
+
<Image src="{{ cover }}" alt="The cover of AUDACITY, by Drizilik" aspect="1:1" />
|
|
15
|
+
<Text weight="medium">AUDACITY</Text>
|
|
16
|
+
<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>
|
|
17
|
+
</If>
|
|
18
|
+
<ElseIf condition="{{ coverNote }}">
|
|
19
|
+
<Text variant="caption" tone="muted">{{ coverNote }}</Text>
|
|
20
|
+
</ElseIf>
|
|
21
|
+
<Else>
|
|
22
|
+
<Skeleton shape="box" height="280" />
|
|
23
|
+
</Else>
|
|
24
|
+
</View>
|
|
25
|
+
|
|
26
|
+
<Text variant="caption" tone="muted">Shapes, and how a picture fills its space</Text>
|
|
12
27
|
<View variant="card" direction="row" align="center" gap="large">
|
|
13
28
|
<Image src="statics/logo.png" alt="Rounded" width="56" height="56" />
|
|
14
29
|
<Image src="statics/logo.png" alt="Square" width="56" height="56" shape="square" />
|
|
@@ -26,7 +41,7 @@
|
|
|
26
41
|
</View>
|
|
27
42
|
</View>
|
|
28
43
|
|
|
29
|
-
<Text variant="caption" tone="muted">
|
|
44
|
+
<Text variant="caption" tone="muted">A broken image shows why it failed</Text>
|
|
30
45
|
<View variant="card">
|
|
31
46
|
<If condition="{{ failure }}">
|
|
32
47
|
<Text>{{ failure }}</Text>
|
|
@@ -11,7 +11,7 @@ export interface Section {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export default {
|
|
14
|
-
title: '
|
|
14
|
+
title: 'Salone Sounds',
|
|
15
15
|
sections: [
|
|
16
16
|
{
|
|
17
17
|
title: 'Views',
|
|
@@ -19,55 +19,55 @@ export default {
|
|
|
19
19
|
{
|
|
20
20
|
page: 'layout',
|
|
21
21
|
title: 'Layout',
|
|
22
|
-
summary: 'Rows, columns,
|
|
22
|
+
summary: 'Rows, columns, cards, a shelf to scroll and a grid',
|
|
23
23
|
icon: 'grid',
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
26
|
page: 'text',
|
|
27
27
|
title: 'Text and bindings',
|
|
28
|
-
summary: 'Text styles
|
|
28
|
+
summary: 'Text styles, tones, links and bindings',
|
|
29
29
|
icon: 'edit',
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
page: 'images',
|
|
33
33
|
title: 'Images',
|
|
34
|
-
summary: 'Pictures from
|
|
34
|
+
summary: 'Pictures from the dot and from the web',
|
|
35
35
|
icon: 'image',
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
page: 'carousel',
|
|
39
39
|
title: 'Carousel',
|
|
40
|
-
summary: 'Slides
|
|
40
|
+
summary: 'Slides of Gen Z artists and Salone history',
|
|
41
41
|
icon: 'image',
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
44
|
page: 'lists',
|
|
45
45
|
title: 'Lists and icons',
|
|
46
|
-
summary: 'Rows to tap,
|
|
46
|
+
summary: 'Rows to tap, badges and icons',
|
|
47
47
|
icon: 'list',
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
page: 'filters',
|
|
51
51
|
title: 'Tabs and filters',
|
|
52
|
-
summary: 'Tabs, chips
|
|
52
|
+
summary: 'Tabs, chips and empty states',
|
|
53
53
|
icon: 'search',
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
page: 'forms',
|
|
57
57
|
title: 'Forms',
|
|
58
|
-
summary: 'Fields, choices
|
|
58
|
+
summary: 'Fields, choices and switches for buying tickets',
|
|
59
59
|
icon: 'check',
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
page: 'payments',
|
|
63
63
|
title: 'Payments',
|
|
64
|
-
summary: 'Amounts,
|
|
64
|
+
summary: 'Amounts, QR codes and one-time codes',
|
|
65
65
|
icon: 'cash',
|
|
66
66
|
},
|
|
67
67
|
{
|
|
68
68
|
page: 'feedback',
|
|
69
69
|
title: 'Feedback',
|
|
70
|
-
summary: '
|
|
70
|
+
summary: 'Loading, toasts, progress and notices',
|
|
71
71
|
icon: 'bell',
|
|
72
72
|
},
|
|
73
73
|
],
|
|
@@ -78,13 +78,13 @@ export default {
|
|
|
78
78
|
{
|
|
79
79
|
page: 'state',
|
|
80
80
|
title: 'State, mutations and actions',
|
|
81
|
-
summary: '
|
|
81
|
+
summary: 'State, conditions and lists',
|
|
82
82
|
icon: 'refresh',
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
85
|
page: 'navigation',
|
|
86
86
|
title: 'Navigation and hooks',
|
|
87
|
-
summary: '
|
|
87
|
+
summary: 'Opening pages, going back, and page hooks',
|
|
88
88
|
icon: 'arrow-right',
|
|
89
89
|
},
|
|
90
90
|
],
|
|
@@ -95,7 +95,7 @@ export default {
|
|
|
95
95
|
{
|
|
96
96
|
page: 'device',
|
|
97
97
|
title: 'Alerts and device',
|
|
98
|
-
summary: '
|
|
98
|
+
summary: 'Alerts, copy, share, links and the torch',
|
|
99
99
|
icon: 'mobile',
|
|
100
100
|
},
|
|
101
101
|
{
|
|
@@ -107,9 +107,21 @@ export default {
|
|
|
107
107
|
{
|
|
108
108
|
page: 'files',
|
|
109
109
|
title: 'Files',
|
|
110
|
-
summary: "
|
|
110
|
+
summary: "Saving files in the dot's own folder",
|
|
111
111
|
icon: 'file',
|
|
112
112
|
},
|
|
113
|
+
{
|
|
114
|
+
page: 'cache',
|
|
115
|
+
title: 'Cache',
|
|
116
|
+
summary: 'Values that expire after a while',
|
|
117
|
+
icon: 'refresh',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
page: 'secrets',
|
|
121
|
+
title: 'Secrets',
|
|
122
|
+
summary: 'Sign-in tokens kept encrypted',
|
|
123
|
+
icon: 'lock',
|
|
124
|
+
},
|
|
113
125
|
],
|
|
114
126
|
},
|
|
115
127
|
] as Section[],
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<View>
|
|
2
2
|
<View direction="row" align="center" gap="large">
|
|
3
|
-
<Image src="statics/logo.png" alt="
|
|
3
|
+
<Image src="statics/logo.png" alt="Salone Sounds logo" width="48" height="48" />
|
|
4
4
|
<View gap="none">
|
|
5
5
|
<Text variant="title">{{ title }}</Text>
|
|
6
|
-
<Text variant="caption" tone="muted">What a dot can do,
|
|
6
|
+
<Text variant="caption" tone="muted">What a dot can do, shown with Sierra Leone's music</Text>
|
|
7
7
|
</View>
|
|
8
8
|
</View>
|
|
9
9
|
|
|
@@ -6,17 +6,51 @@ const JUSTIFIES: Justify[] = ['start', 'center', 'end', 'between'];
|
|
|
6
6
|
const ALIGNS: Align[] = ['stretch', 'start', 'center', 'end'];
|
|
7
7
|
const SPACES: Space[] = ['none', 'small', 'medium', 'large'];
|
|
8
8
|
|
|
9
|
+
interface Lookup {
|
|
10
|
+
results: { collectionId: number; artworkUrl100: string }[];
|
|
11
|
+
}
|
|
12
|
+
|
|
9
13
|
export default definePage({
|
|
10
14
|
initialState: state,
|
|
15
|
+
hooks: {
|
|
16
|
+
// The shelf's covers come from Apple's catalog.
|
|
17
|
+
async onLoad() {
|
|
18
|
+
const ids = this.state.releases.map((release) => release.id).join(',');
|
|
19
|
+
try {
|
|
20
|
+
const { body } = await this.dash.network.http.request<Lookup>({
|
|
21
|
+
url: `https://itunes.apple.com/lookup?id=${ids}`,
|
|
22
|
+
as: 'json',
|
|
23
|
+
});
|
|
24
|
+
const covers = new Map(
|
|
25
|
+
body.results.map((result) => [
|
|
26
|
+
result.collectionId,
|
|
27
|
+
result.artworkUrl100.replace('100x100bb', '300x300bb'),
|
|
28
|
+
]),
|
|
29
|
+
);
|
|
30
|
+
this.setState((current) => ({
|
|
31
|
+
releases: current.releases.map((release) => ({
|
|
32
|
+
...release,
|
|
33
|
+
cover: covers.get(release.id) ?? '',
|
|
34
|
+
})),
|
|
35
|
+
}));
|
|
36
|
+
} catch {
|
|
37
|
+
// Without the catalog, the shelf shows its titles alone.
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
},
|
|
11
41
|
mutations: {
|
|
12
42
|
nextDirection: (state) => ({ direction: after(DIRECTIONS, state.direction) }),
|
|
13
43
|
nextJustify: (state) => ({ justify: after(JUSTIFIES, state.justify) }),
|
|
14
44
|
nextAlign: (state) => ({ align: after(ALIGNS, state.align) }),
|
|
15
45
|
nextGap: (state) => ({ gap: after(SPACES, state.gap) }),
|
|
16
46
|
toggleWrap: (state) => ({ wrap: !state.wrap }),
|
|
17
|
-
|
|
18
|
-
|
|
47
|
+
openSection: (_state, event: DotEvent<unknown, { name: string }>) => ({
|
|
48
|
+
section: event.data.name,
|
|
19
49
|
}),
|
|
50
|
+
showFirst: (_state, event: DotEvent<{ index: number }>) => ({ first: event.detail.index }),
|
|
51
|
+
shelfStart: () => ({ first: 0 }),
|
|
52
|
+
shelfEnd: (state) => ({ first: state.releases.length - 1 }),
|
|
53
|
+
playSong: (state) => ({ playing: !state.playing }),
|
|
20
54
|
},
|
|
21
55
|
});
|
|
22
56
|
|
|
@@ -3,12 +3,32 @@ export type Justify = 'start' | 'center' | 'end' | 'between';
|
|
|
3
3
|
export type Align = 'stretch' | 'start' | 'center' | 'end';
|
|
4
4
|
export type Space = 'none' | 'small' | 'medium' | 'large';
|
|
5
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
|
+
|
|
6
14
|
export default {
|
|
7
15
|
direction: 'row' as Direction,
|
|
8
16
|
justify: 'start' as Justify,
|
|
9
17
|
align: 'center' as Align,
|
|
10
18
|
gap: 'small' as Space,
|
|
11
19
|
wrap: true,
|
|
12
|
-
// The
|
|
13
|
-
|
|
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,
|
|
14
34
|
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<View>
|
|
2
2
|
<Text variant="title">Layout</Text>
|
|
3
|
-
<Text>A View
|
|
3
|
+
<Text>A View puts its items in a column or a row. Change the one below.</Text>
|
|
4
4
|
|
|
5
5
|
<View variant="card" direction="{{ direction }}" justify="{{ justify }}" align="{{ align }}" gap="{{ gap }}" wrap="{{ wrap }}">
|
|
6
|
-
<Button variant="secondary">
|
|
7
|
-
<Button variant="secondary">
|
|
8
|
-
<Text variant="title">
|
|
9
|
-
<Button variant="secondary">
|
|
10
|
-
<Text variant="caption" tone="muted">
|
|
6
|
+
<Button variant="secondary">Palm-wine</Button>
|
|
7
|
+
<Button variant="secondary">Gumbe</Button>
|
|
8
|
+
<Text variant="title">Afropop</Text>
|
|
9
|
+
<Button variant="secondary">Bubu</Button>
|
|
10
|
+
<Text variant="caption" tone="muted">Milo jazz</Text>
|
|
11
11
|
</View>
|
|
12
12
|
|
|
13
13
|
<View gap="small">
|
|
@@ -38,17 +38,38 @@
|
|
|
38
38
|
</View>
|
|
39
39
|
</View>
|
|
40
40
|
|
|
41
|
-
<Text variant="caption" tone="muted">grow
|
|
41
|
+
<Text variant="caption" tone="muted">grow fills the space left over: the song grows, the year does not. Tap the song: a View can be tapped.</Text>
|
|
42
42
|
<View direction="row" gap="small">
|
|
43
|
-
<View variant="card" grow>
|
|
44
|
-
<Text>
|
|
43
|
+
<View variant="card" grow onTap="playSong">
|
|
44
|
+
<Text>{{ playing ? 'Playing Exodus, by Drizilik' : 'Exodus, by Drizilik' }}</Text>
|
|
45
45
|
</View>
|
|
46
46
|
<View variant="card">
|
|
47
|
-
<Text>
|
|
47
|
+
<Text>2021</Text>
|
|
48
48
|
</View>
|
|
49
49
|
</View>
|
|
50
50
|
|
|
51
|
-
<Text variant="caption" tone="muted">
|
|
51
|
+
<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>
|
|
52
|
+
<Scroll gap="medium" snap="start" index="{{ first }}" onChange="showFirst">
|
|
53
|
+
<For each="{{ releases }}" item="release" key="id">
|
|
54
|
+
<View gap="small">
|
|
55
|
+
<If condition="{{ release.cover }}">
|
|
56
|
+
<Image src="{{ release.cover }}" alt="{{ release.title }}" width="128" height="128" />
|
|
57
|
+
</If>
|
|
58
|
+
<Else>
|
|
59
|
+
<Skeleton shape="box" height="128" />
|
|
60
|
+
</Else>
|
|
61
|
+
<Text weight="medium" maxLines="2">{{ release.title }}</Text>
|
|
62
|
+
<Text variant="caption" tone="muted">{{ release.year }}</Text>
|
|
63
|
+
</View>
|
|
64
|
+
</For>
|
|
65
|
+
</Scroll>
|
|
66
|
+
<Text tone="muted">First on the shelf: {{ releases[first].title }}</Text>
|
|
67
|
+
<View direction="row" gap="small">
|
|
68
|
+
<Button variant="secondary" onClick="shelfStart" disabled="{{ first === 0 }}">To the start</Button>
|
|
69
|
+
<Button variant="secondary" onClick="shelfEnd" disabled="{{ first === releases.length - 1 }}">To the end</Button>
|
|
70
|
+
</View>
|
|
71
|
+
|
|
72
|
+
<Text variant="caption" tone="muted">padding, on every side or on one side</Text>
|
|
52
73
|
<View direction="row" gap="small">
|
|
53
74
|
<View variant="card" padding="small">
|
|
54
75
|
<Text>small</Text>
|
|
@@ -60,21 +81,23 @@
|
|
|
60
81
|
<Text>start</Text>
|
|
61
82
|
</View>
|
|
62
83
|
</View>
|
|
84
|
+
<Text variant="caption" tone="muted">Text, List, Notice and Grid take padding too</Text>
|
|
85
|
+
<Notice title="Heads up" paddingTop="large" paddingBottom="large">This notice has large padding above and below.</Notice>
|
|
63
86
|
|
|
64
|
-
<Text variant="caption" tone="muted">A Grid keeps
|
|
87
|
+
<Text variant="caption" tone="muted">A Grid keeps its columns the same width</Text>
|
|
65
88
|
<View variant="card" gap="medium">
|
|
66
89
|
<Grid columns="4">
|
|
67
|
-
<GridItem icon="
|
|
68
|
-
<GridItem icon="
|
|
69
|
-
<GridItem icon="
|
|
70
|
-
<GridItem icon="
|
|
71
|
-
<GridItem icon="
|
|
72
|
-
<GridItem icon="
|
|
73
|
-
<GridItem icon="
|
|
74
|
-
<GridItem
|
|
90
|
+
<GridItem icon="microphone" label="Artists" data-name="Artists" onTap="openSection" />
|
|
91
|
+
<GridItem icon="music" label="Albums" data-name="Albums" onTap="openSection" />
|
|
92
|
+
<GridItem icon="playlist" label="Playlists" data-name="Playlists" onTap="openSection" />
|
|
93
|
+
<GridItem icon="star" label="Charts" badge="New" data-name="Charts" onTap="openSection" />
|
|
94
|
+
<GridItem icon="calendar" label="Shows" data-name="Shows" onTap="openSection" />
|
|
95
|
+
<GridItem icon="ticket" label="Tickets" data-name="Tickets" onTap="openSection" />
|
|
96
|
+
<GridItem icon="headphones" label="Library" data-name="Library" onTap="openSection" />
|
|
97
|
+
<GridItem image="statics/logo.png" label="Salone" data-name="Salone" onTap="openSection" />
|
|
75
98
|
</Grid>
|
|
76
|
-
<If condition="{{
|
|
77
|
-
<Text tone="muted">You tapped {{
|
|
99
|
+
<If condition="{{ section }}">
|
|
100
|
+
<Text tone="muted">You tapped {{ section }}</Text>
|
|
78
101
|
</If>
|
|
79
102
|
</View>
|
|
80
103
|
</View>
|
|
@@ -4,32 +4,33 @@ export default definePage({
|
|
|
4
4
|
initialState: state,
|
|
5
5
|
mutations: {
|
|
6
6
|
choose: (state, event: DotEvent<unknown, { id: string }>) => {
|
|
7
|
-
const
|
|
8
|
-
return { chosen:
|
|
7
|
+
const artist = state.artists.find((candidate) => candidate.id === event.data.id);
|
|
8
|
+
return { chosen: artist?.name ?? '' };
|
|
9
9
|
},
|
|
10
|
-
|
|
11
|
-
selected: state.
|
|
10
|
+
openRelease: (state, event: DotEvent<unknown, { id: string }>) => ({
|
|
11
|
+
selected: state.releases.find((release) => release.id === event.data.id) ?? null,
|
|
12
12
|
}),
|
|
13
13
|
closeSheet: () => ({ selected: null }),
|
|
14
14
|
clearToast: () => ({ toast: '' }),
|
|
15
15
|
},
|
|
16
16
|
actions: {
|
|
17
|
-
async
|
|
17
|
+
async copyTitle(state) {
|
|
18
18
|
if (!state.selected) {
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
|
-
|
|
22
|
-
this.
|
|
21
|
+
const { title, artist } = state.selected;
|
|
22
|
+
await this.dash.system.copyText(`${title}, by ${artist}`);
|
|
23
|
+
this.setState({ selected: null, toast: 'Title copied' });
|
|
23
24
|
},
|
|
24
|
-
async
|
|
25
|
+
async shareRelease(state) {
|
|
25
26
|
if (!state.selected) {
|
|
26
27
|
return;
|
|
27
28
|
}
|
|
28
|
-
const { title,
|
|
29
|
+
const { title, artist, year, note } = state.selected;
|
|
29
30
|
this.setState({ selected: null });
|
|
30
31
|
await this.dash.system.share({
|
|
31
|
-
title
|
|
32
|
-
text: `${title}
|
|
32
|
+
title,
|
|
33
|
+
text: `${title}, by ${artist} (${year}): ${note.toLowerCase()}.`,
|
|
33
34
|
});
|
|
34
35
|
},
|
|
35
36
|
},
|
|
@@ -1,96 +1,117 @@
|
|
|
1
|
-
export interface
|
|
1
|
+
export interface Artist {
|
|
2
2
|
id: string;
|
|
3
3
|
name: string;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
song: string;
|
|
5
|
+
genre: string;
|
|
6
6
|
icon: string;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export interface
|
|
9
|
+
export interface Release {
|
|
10
10
|
id: string;
|
|
11
11
|
title: string;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
artist: string;
|
|
13
|
+
year: number;
|
|
14
|
+
note: string;
|
|
15
15
|
tone: string;
|
|
16
|
-
reference: string;
|
|
17
16
|
}
|
|
18
17
|
|
|
19
18
|
export default {
|
|
20
|
-
|
|
19
|
+
artists: [
|
|
21
20
|
{
|
|
22
|
-
id: '
|
|
23
|
-
name: '
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
icon: '
|
|
21
|
+
id: 'drizilik',
|
|
22
|
+
name: 'Drizilik',
|
|
23
|
+
song: 'Lemonade, with The Therapist',
|
|
24
|
+
genre: 'Kriofusion',
|
|
25
|
+
icon: 'microphone',
|
|
27
26
|
},
|
|
27
|
+
{ id: 'boii', name: 'Boii', song: 'Love Na Scam', genre: 'Afrobeats', icon: 'microphone' },
|
|
28
|
+
{ id: 'apreel', name: 'ApreeL', song: 'Control', genre: 'Afropop', icon: 'microphone' },
|
|
29
|
+
{ id: 'donii-major', name: 'Donii Major', song: 'Hannah', genre: 'R&B', icon: 'microphone' },
|
|
28
30
|
{
|
|
29
|
-
id: '
|
|
30
|
-
name: '
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
icon: '
|
|
31
|
+
id: 'star-zee',
|
|
32
|
+
name: 'Star Zee',
|
|
33
|
+
song: 'Leader, with Stonebwoy',
|
|
34
|
+
genre: 'Hip hop',
|
|
35
|
+
icon: 'microphone',
|
|
34
36
|
},
|
|
35
|
-
{ id: 'card', name: 'Debit card', number: '•••• 7730', balance: 'Le 310,000', icon: 'card' },
|
|
36
|
-
] as Account[],
|
|
37
|
-
payments: [
|
|
38
37
|
{
|
|
39
|
-
id: '
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
id: 'kao-denero',
|
|
39
|
+
name: 'Kao Denero',
|
|
40
|
+
song: 'Kenyatta',
|
|
41
|
+
genre: 'Hip hop',
|
|
42
|
+
icon: 'microphone',
|
|
43
|
+
},
|
|
44
|
+
{ id: 'laj', name: 'LAJ', song: 'Shock, with Cassidy', genre: 'Hip hop', icon: 'microphone' },
|
|
45
|
+
{
|
|
46
|
+
id: 'k-man',
|
|
47
|
+
name: 'K-Man',
|
|
48
|
+
song: 'Leh Wi Make Salone',
|
|
49
|
+
genre: 'Hip hop',
|
|
50
|
+
icon: 'microphone',
|
|
51
|
+
},
|
|
52
|
+
] as Artist[],
|
|
53
|
+
releases: [
|
|
54
|
+
{
|
|
55
|
+
id: 'rise-and-shine',
|
|
56
|
+
title: 'Rise & Shine',
|
|
57
|
+
artist: "Sierra Leone's Refugee All Stars",
|
|
58
|
+
year: 2010,
|
|
59
|
+
note: 'Album of the year',
|
|
44
60
|
tone: 'success',
|
|
45
|
-
reference: 'EDSA-58213',
|
|
46
61
|
},
|
|
47
62
|
{
|
|
48
|
-
id: '
|
|
49
|
-
title: '
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
63
|
+
id: 'kormot-bi-en-me',
|
|
64
|
+
title: 'Kormot Bi En Me',
|
|
65
|
+
artist: 'Steady Bongo',
|
|
66
|
+
year: 1996,
|
|
67
|
+
note: 'Best album',
|
|
68
|
+
tone: 'success',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'salone',
|
|
72
|
+
title: 'Salone',
|
|
73
|
+
artist: 'Bai Kamara Jr.',
|
|
74
|
+
year: 2020,
|
|
75
|
+
note: 'Nominated',
|
|
53
76
|
tone: 'warning',
|
|
54
|
-
reference: 'AIR-11907',
|
|
55
77
|
},
|
|
56
78
|
{
|
|
57
|
-
id: '
|
|
58
|
-
title: '
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
tone: '
|
|
63
|
-
|
|
79
|
+
id: 'red-album',
|
|
80
|
+
title: 'Red Album',
|
|
81
|
+
artist: 'LAJ',
|
|
82
|
+
year: 2013,
|
|
83
|
+
note: 'Launched at the stadium',
|
|
84
|
+
tone: 'info',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: 'let-me-love-you',
|
|
88
|
+
title: 'Let Me Love You',
|
|
89
|
+
artist: 'Bunny Mack',
|
|
90
|
+
year: 1981,
|
|
91
|
+
note: 'Gold disc',
|
|
92
|
+
tone: 'info',
|
|
64
93
|
},
|
|
65
|
-
] as
|
|
94
|
+
] as Release[],
|
|
66
95
|
chosen: '',
|
|
67
|
-
// The
|
|
68
|
-
selected: null as
|
|
96
|
+
// The record whose actions the sheet shows.
|
|
97
|
+
selected: null as Release | null,
|
|
69
98
|
toast: '',
|
|
70
99
|
icons: [
|
|
71
|
-
'
|
|
72
|
-
'
|
|
73
|
-
'
|
|
74
|
-
'
|
|
75
|
-
'
|
|
76
|
-
'
|
|
77
|
-
'
|
|
78
|
-
'
|
|
79
|
-
'
|
|
80
|
-
'
|
|
81
|
-
'
|
|
82
|
-
'qr-code',
|
|
83
|
-
'bolt',
|
|
84
|
-
'water',
|
|
85
|
-
'phone',
|
|
86
|
-
'mail',
|
|
87
|
-
'calendar',
|
|
88
|
-
'clock',
|
|
89
|
-
'location',
|
|
90
|
-
'lock',
|
|
100
|
+
'music',
|
|
101
|
+
'playlist',
|
|
102
|
+
'microphone',
|
|
103
|
+
'headphones',
|
|
104
|
+
'ticket',
|
|
105
|
+
'video',
|
|
106
|
+
'globe',
|
|
107
|
+
'link',
|
|
108
|
+
'external-link',
|
|
109
|
+
'heart',
|
|
110
|
+
'star',
|
|
91
111
|
'share',
|
|
92
|
-
'copy',
|
|
93
112
|
'download',
|
|
94
|
-
'
|
|
113
|
+
'calendar',
|
|
114
|
+
'location',
|
|
115
|
+
'search',
|
|
95
116
|
],
|
|
96
117
|
};
|