@monimesl/dot-cli 0.1.0-alpha.9 → 1.0.0-beta.1
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 +72 -59
- package/dist/cli.js +539 -341
- package/dist/cli.js.map +1 -1
- package/dist/{server-BfPAnsSf.js → server-DMnWDdJ6.js} +570 -478
- package/dist/server-DMnWDdJ6.js.map +1 -0
- package/dist/templates/showcase/dot.ts +53 -16
- 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/{text → basics/bindings}/controller.ts +5 -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/basics/state/view.dml +46 -0
- package/dist/templates/showcase/pages/{carousel → components/carousel}/controller.ts +2 -1
- package/dist/templates/showcase/pages/{carousel → components/carousel}/state.ts +5 -5
- package/dist/templates/showcase/pages/{carousel → components/carousel}/view.dml +7 -5
- package/dist/templates/showcase/pages/{feedback → components/feedback}/controller.ts +13 -2
- package/dist/templates/showcase/pages/components/feedback/state.ts +41 -0
- package/dist/templates/showcase/pages/{feedback → components/feedback}/view.dml +38 -9
- package/dist/templates/showcase/pages/{forms → components/forms}/controller.ts +23 -19
- package/dist/templates/showcase/pages/{forms → components/forms}/state.ts +6 -3
- 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/{images → components/images}/controller.ts +4 -1
- package/dist/templates/showcase/pages/components/images/view.dml +83 -0
- package/dist/templates/showcase/pages/{layout → components/layout}/controller.ts +3 -2
- 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/{lists → components/lists}/state.ts +43 -30
- package/dist/templates/showcase/pages/components/lists/view.dml +88 -0
- package/dist/templates/showcase/pages/{payments → components/money}/controller.ts +7 -8
- 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/{lists → components/sheets}/controller.ts +10 -11
- 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/{filters → components/tabs}/state.ts +32 -23
- 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/{cache → dash/cache}/controller.ts +9 -4
- 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/{files → dash/files}/controller.ts +7 -2
- package/dist/templates/showcase/pages/{files → dash/files}/state.ts +4 -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/{network → dash/network}/controller.ts +84 -20
- package/dist/templates/showcase/pages/{network → dash/network}/state.ts +14 -1
- 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/{secrets → dash/secrets}/controller.ts +2 -1
- 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 +175 -60
- package/dist/templates/showcase/pages/index/view.dml +6 -3
- package/package.json +6 -6
- package/dist/server-BfPAnsSf.js.map +0 -1
- package/dist/templates/showcase/pages/cache/view.dml +0 -36
- package/dist/templates/showcase/pages/device/controller.ts +0 -80
- package/dist/templates/showcase/pages/device/state.ts +0 -7
- package/dist/templates/showcase/pages/device/view.dml +0 -49
- package/dist/templates/showcase/pages/feedback/state.ts +0 -8
- package/dist/templates/showcase/pages/files/view.dml +0 -50
- package/dist/templates/showcase/pages/filters/controller.ts +0 -27
- package/dist/templates/showcase/pages/filters/view.dml +0 -44
- package/dist/templates/showcase/pages/forms/view.dml +0 -49
- package/dist/templates/showcase/pages/images/view.dml +0 -53
- package/dist/templates/showcase/pages/layout/view.dml +0 -103
- package/dist/templates/showcase/pages/lists/view.dml +0 -59
- package/dist/templates/showcase/pages/navigation/controller.ts +0 -65
- 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/view.dml +0 -67
- package/dist/templates/showcase/pages/payments/view.dml +0 -45
- package/dist/templates/showcase/pages/secrets/view.dml +0 -24
- package/dist/templates/showcase/pages/state/view.dml +0 -33
- package/dist/templates/showcase/pages/text/state.ts +0 -8
- package/dist/templates/showcase/pages/text/view.dml +0 -58
- /package/dist/templates/showcase/pages/{state → basics/state}/state.ts +0 -0
- /package/dist/templates/showcase/pages/{images → components/images}/state.ts +0 -0
- /package/dist/templates/showcase/pages/{layout → components/layout}/state.ts +0 -0
- /package/dist/templates/showcase/pages/{payments → components/money}/state.ts +0 -0
- /package/dist/templates/showcase/pages/{cache → dash/cache}/state.ts +0 -0
- /package/dist/templates/showcase/pages/{secrets → dash/secrets}/state.ts +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { debounce, errorMessage, latest, unlessCancelled } from '@monimesl/dot-runtime';
|
|
2
|
+
|
|
1
3
|
import type { Release } from './state';
|
|
2
4
|
import state from './state';
|
|
3
5
|
|
|
@@ -14,6 +16,10 @@ interface CatalogAnswer {
|
|
|
14
16
|
}[];
|
|
15
17
|
}
|
|
16
18
|
|
|
19
|
+
interface ArtistAnswer {
|
|
20
|
+
results: { artistId: number; artistName: string; primaryGenreName?: string }[];
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
interface Echo {
|
|
18
24
|
json: unknown;
|
|
19
25
|
files: Record<string, string>;
|
|
@@ -23,27 +29,76 @@ interface Echo {
|
|
|
23
29
|
const PAGE = 10;
|
|
24
30
|
const MOST = 50;
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return `https://itunes.apple.com/search?entity
|
|
32
|
+
// Songs or artists whose names match `term`, at most `limit` of them.
|
|
33
|
+
function catalogUrl(entity: 'song' | 'musicArtist', term: string, limit: number): string {
|
|
34
|
+
return `https://itunes.apple.com/search?entity=${entity}&limit=${limit}&term=${encodeURIComponent(term)}`;
|
|
29
35
|
}
|
|
30
36
|
|
|
37
|
+
// For searching as the person types: a pause in typing, and only the newest search's answer.
|
|
38
|
+
const typingPause = debounce(400);
|
|
39
|
+
const artistSearch = latest();
|
|
40
|
+
|
|
31
41
|
export default definePage({
|
|
32
42
|
initialState: state,
|
|
43
|
+
configs: { navigationBar: { title: 'Network' } },
|
|
33
44
|
mutations: {
|
|
34
|
-
setArtist: (_state, event:
|
|
45
|
+
setArtist: (_state, event: ValueEvent) => ({ artist: event.detail.value }),
|
|
35
46
|
},
|
|
36
47
|
actions: {
|
|
48
|
+
async suggest(_state, event: ValueEvent) {
|
|
49
|
+
const typed = event.detail.value;
|
|
50
|
+
this.setState({ typed });
|
|
51
|
+
if (!typed.trim()) {
|
|
52
|
+
this.setState({ suggestions: [] });
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// False while the person is still typing: a later keystroke runs this again.
|
|
56
|
+
if (!(await typingPause(this.dash))) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const answer = await unlessCancelled(
|
|
61
|
+
artistSearch(
|
|
62
|
+
this.dash.network.http.request<ArtistAnswer>({
|
|
63
|
+
url: catalogUrl('musicArtist', typed, 5),
|
|
64
|
+
as: 'json',
|
|
65
|
+
}),
|
|
66
|
+
),
|
|
67
|
+
);
|
|
68
|
+
// Undefined when a newer search took its place.
|
|
69
|
+
if (answer) {
|
|
70
|
+
this.setState({
|
|
71
|
+
suggestions: answer.body.results.map((artist) => ({
|
|
72
|
+
id: artist.artistId,
|
|
73
|
+
name: artist.artistName,
|
|
74
|
+
genre: artist.primaryGenreName ?? '',
|
|
75
|
+
})),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
} catch (error) {
|
|
79
|
+
this.setState({ note: errorMessage(error) });
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
async checkStatus() {
|
|
83
|
+
try {
|
|
84
|
+
const { online, type } = await this.dash.network.status();
|
|
85
|
+
this.setState({ connection: online ? `Online, by ${type}` : 'Offline' });
|
|
86
|
+
} catch (error) {
|
|
87
|
+
this.setState({ connection: errorMessage(error) });
|
|
88
|
+
}
|
|
89
|
+
},
|
|
37
90
|
async searchAsText(state) {
|
|
38
91
|
try {
|
|
39
|
-
const response = await this.dash.network.http.request({
|
|
92
|
+
const response = await this.dash.network.http.request({
|
|
93
|
+
url: catalogUrl('song', state.artist, PAGE),
|
|
94
|
+
});
|
|
40
95
|
this.setState({
|
|
41
96
|
raw: response.ok
|
|
42
97
|
? `${response.body.trim().slice(0, 90)}…`
|
|
43
98
|
: `Apple answered ${response.status}`,
|
|
44
99
|
});
|
|
45
100
|
} catch (error) {
|
|
46
|
-
this.setState({ note: (error
|
|
101
|
+
this.setState({ note: errorMessage(error) });
|
|
47
102
|
}
|
|
48
103
|
},
|
|
49
104
|
async search() {
|
|
@@ -62,7 +117,7 @@ export default definePage({
|
|
|
62
117
|
this.setState({ searching: true, note: '' });
|
|
63
118
|
try {
|
|
64
119
|
const { body } = await this.dash.network.http.request<CatalogAnswer>(
|
|
65
|
-
{ url:
|
|
120
|
+
{ url: catalogUrl('song', state.artist, state.limit), as: 'json' },
|
|
66
121
|
{ timeout: 10_000 },
|
|
67
122
|
);
|
|
68
123
|
const releases: Release[] = body.results.map((result) => ({
|
|
@@ -74,9 +129,10 @@ export default definePage({
|
|
|
74
129
|
}));
|
|
75
130
|
this.setState({ releases });
|
|
76
131
|
} catch (error) {
|
|
77
|
-
this.setState({ note: (error
|
|
132
|
+
this.setState({ note: errorMessage(error) });
|
|
133
|
+
} finally {
|
|
134
|
+
this.setState({ searching: false });
|
|
78
135
|
}
|
|
79
|
-
this.setState({ searching: false });
|
|
80
136
|
},
|
|
81
137
|
async sendJson(state) {
|
|
82
138
|
try {
|
|
@@ -88,7 +144,7 @@ export default definePage({
|
|
|
88
144
|
});
|
|
89
145
|
this.setState({ echo: JSON.stringify(body.json) });
|
|
90
146
|
} catch (error) {
|
|
91
|
-
this.setState({ note: (error
|
|
147
|
+
this.setState({ note: errorMessage(error) });
|
|
92
148
|
}
|
|
93
149
|
},
|
|
94
150
|
async download(state) {
|
|
@@ -103,48 +159,56 @@ export default definePage({
|
|
|
103
159
|
name: 'artwork.jpg',
|
|
104
160
|
});
|
|
105
161
|
if (response.ok) {
|
|
106
|
-
|
|
107
|
-
this.setState({ picture: { id, url, size }, kept: false });
|
|
162
|
+
this.setState({ picture: response.file, kept: false });
|
|
108
163
|
} else {
|
|
109
164
|
this.setState({ note: `Apple answered ${response.status}` });
|
|
110
165
|
}
|
|
111
166
|
} catch (error) {
|
|
112
|
-
this.setState({ note: (error
|
|
167
|
+
this.setState({ note: errorMessage(error) });
|
|
113
168
|
}
|
|
114
169
|
},
|
|
115
170
|
async upload(state) {
|
|
171
|
+
if (!state.picture) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
116
174
|
try {
|
|
117
175
|
const { body } = await this.dash.network.http.upload<Echo>({
|
|
118
176
|
url: 'https://httpbin.org/post',
|
|
119
177
|
fields: { artist: state.artist },
|
|
120
|
-
files: [{ field: 'artwork', file: state.picture
|
|
178
|
+
files: [{ field: 'artwork', file: state.picture }],
|
|
121
179
|
as: 'json',
|
|
122
180
|
});
|
|
123
181
|
this.setState({ uploaded: Object.keys(body.files).join(', ') });
|
|
124
182
|
} catch (error) {
|
|
125
|
-
this.setState({ note: (error
|
|
183
|
+
this.setState({ note: errorMessage(error) });
|
|
126
184
|
}
|
|
127
185
|
},
|
|
128
186
|
async sharePicture(state) {
|
|
187
|
+
if (!state.picture) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
129
190
|
try {
|
|
130
|
-
await this.dash.system.share({ file: state.picture
|
|
191
|
+
await this.dash.system.share({ file: state.picture });
|
|
131
192
|
} catch (error) {
|
|
132
|
-
this.setState({ note: (error
|
|
193
|
+
this.setState({ note: errorMessage(error) });
|
|
133
194
|
}
|
|
134
195
|
},
|
|
135
196
|
async keep(state) {
|
|
197
|
+
if (!state.picture) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
136
200
|
try {
|
|
137
|
-
await this.dash.storage.file.save(state.picture
|
|
201
|
+
await this.dash.storage.file.save(state.picture, PICTURE, { overwrite: true });
|
|
138
202
|
this.setState({ kept: true });
|
|
139
203
|
} catch (error) {
|
|
140
|
-
this.setState({ note: (error
|
|
204
|
+
this.setState({ note: errorMessage(error) });
|
|
141
205
|
}
|
|
142
206
|
},
|
|
143
207
|
async tryUnlistedHost() {
|
|
144
208
|
try {
|
|
145
209
|
await this.dash.network.http.request({ url: 'https://example.com' });
|
|
146
210
|
} catch (error) {
|
|
147
|
-
this.setState({ note: (error
|
|
211
|
+
this.setState({ note: errorMessage(error) });
|
|
148
212
|
}
|
|
149
213
|
},
|
|
150
214
|
},
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
import type { DotFile } from '@monimesl/dot-runtime';
|
|
2
|
+
|
|
3
|
+
export interface Suggestion {
|
|
4
|
+
id: number;
|
|
5
|
+
name: string;
|
|
6
|
+
genre: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
1
9
|
export interface Release {
|
|
2
10
|
id: number;
|
|
3
11
|
title: string;
|
|
@@ -7,6 +15,10 @@ export interface Release {
|
|
|
7
15
|
}
|
|
8
16
|
|
|
9
17
|
export default {
|
|
18
|
+
connection: 'Not checked yet',
|
|
19
|
+
// What the person typed to search as they type, and the artists found.
|
|
20
|
+
typed: '',
|
|
21
|
+
suggestions: [] as Suggestion[],
|
|
10
22
|
artist: 'Drizilik',
|
|
11
23
|
// The start of Apple's answer, as the text it came as.
|
|
12
24
|
raw: '',
|
|
@@ -15,7 +27,8 @@ export default {
|
|
|
15
27
|
limit: 10,
|
|
16
28
|
searching: false,
|
|
17
29
|
echo: '',
|
|
18
|
-
|
|
30
|
+
// The downloaded artwork, in a temporary file until the dot closes.
|
|
31
|
+
picture: null as DotFile | null,
|
|
19
32
|
uploaded: '',
|
|
20
33
|
kept: false,
|
|
21
34
|
note: '',
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<View>
|
|
2
|
+
<Text variant="title">dash.network</Text>
|
|
3
|
+
<Text>Whether the phone is online, and the dot's requests, which Dash sends only to the hosts listed in dot.json. This page searches Apple's music catalog.</Text>
|
|
4
|
+
|
|
5
|
+
<View gap="small">
|
|
6
|
+
<Text variant="subtitle">status</Text>
|
|
7
|
+
<Text variant="caption" tone="muted">Whether the phone is online now, and how: wifi, cellular, other or none. Online doesn't promise a server answers.</Text>
|
|
8
|
+
<View variant="card" direction="row" align="center" gap="medium">
|
|
9
|
+
<View grow>
|
|
10
|
+
<Text>{{ connection }}</Text>
|
|
11
|
+
</View>
|
|
12
|
+
<Button variant="secondary" onClick="checkStatus">Check</Button>
|
|
13
|
+
</View>
|
|
14
|
+
</View>
|
|
15
|
+
|
|
16
|
+
<View gap="small">
|
|
17
|
+
<Text variant="subtitle">http.request</Text>
|
|
18
|
+
<Text variant="caption" tone="muted">The answer comes as text, or as JSON with as: 'json'. timeout gives up after a while.</Text>
|
|
19
|
+
<View variant="card" gap="small">
|
|
20
|
+
<Input label="Artist" placeholder="Drizilik" value="{{ artist }}" maxLength="40" onChange="setArtist" onSubmit="search" />
|
|
21
|
+
<View direction="row" wrap gap="small">
|
|
22
|
+
<Button onClick="search" loading="{{ searching }}" disabled="{{ !artist }}">Search</Button>
|
|
23
|
+
<Button variant="secondary" onClick="searchAsText" disabled="{{ !artist }}">Read as text</Button>
|
|
24
|
+
</View>
|
|
25
|
+
<If condition="{{ raw }}">
|
|
26
|
+
<Text variant="caption" tone="muted">The answer as text starts with: {{ raw }}</Text>
|
|
27
|
+
</If>
|
|
28
|
+
</View>
|
|
29
|
+
|
|
30
|
+
<Text variant="caption" tone="muted">The same answer read as JSON, with artwork. Near the end, the list loads 10 more, up to 50. {{ releases.length }} so far.</Text>
|
|
31
|
+
<If condition="{{ releases.length > 0 }}">
|
|
32
|
+
<List onEndReached="loadMore">
|
|
33
|
+
<For each="{{ releases }}" item="release" key="id">
|
|
34
|
+
<ListItem image="{{ release.artwork }}" title="{{ release.title }}" subtitle="{{ release.album }} · {{ release.year }}" />
|
|
35
|
+
</For>
|
|
36
|
+
</List>
|
|
37
|
+
</If>
|
|
38
|
+
<Else>
|
|
39
|
+
<View variant="card">
|
|
40
|
+
<EmptyState icon="search" title="No songs yet" text="Search for an artist, such as Drizilik, Kao Denero or Emmerson." />
|
|
41
|
+
</View>
|
|
42
|
+
</Else>
|
|
43
|
+
</View>
|
|
44
|
+
|
|
45
|
+
<View gap="small">
|
|
46
|
+
<Text variant="subtitle">Searching as you type: debounce and latest</Text>
|
|
47
|
+
<Text variant="caption" tone="muted">debounce waits for a pause in typing before searching, and latest cancels a search still running when a newer one starts, so an older answer can't replace a newer one.</Text>
|
|
48
|
+
<View variant="card" gap="small">
|
|
49
|
+
<Input type="search" placeholder="Type an artist, such as Emmerson" clearable value="{{ typed }}" onChange="suggest" />
|
|
50
|
+
<For each="{{ suggestions }}" item="artist" key="id">
|
|
51
|
+
<View direction="row" align="center" gap="medium">
|
|
52
|
+
<Avatar name="{{ artist.name }}" size="small" />
|
|
53
|
+
<View gap="none">
|
|
54
|
+
<Text>{{ artist.name }}</Text>
|
|
55
|
+
<Text variant="caption" tone="muted">{{ artist.genre }}</Text>
|
|
56
|
+
</View>
|
|
57
|
+
</View>
|
|
58
|
+
</For>
|
|
59
|
+
</View>
|
|
60
|
+
</View>
|
|
61
|
+
|
|
62
|
+
<View gap="small">
|
|
63
|
+
<Text variant="subtitle">Sending JSON</Text>
|
|
64
|
+
<Text variant="caption" tone="muted">method: 'POST' with a body. httpbin sends back what it got.</Text>
|
|
65
|
+
<View variant="card" gap="small">
|
|
66
|
+
<Button variant="secondary" onClick="sendJson">Send the first song as JSON</Button>
|
|
67
|
+
<If condition="{{ echo }}">
|
|
68
|
+
<Text>httpbin got {{ echo }}</Text>
|
|
69
|
+
</If>
|
|
70
|
+
</View>
|
|
71
|
+
</View>
|
|
72
|
+
|
|
73
|
+
<View gap="small">
|
|
74
|
+
<Text variant="subtitle">http.download and http.upload</Text>
|
|
75
|
+
<Text variant="caption" tone="muted">download saves the answer as a file. upload sends files with form fields. Then share the file, or keep it in the dot's folder.</Text>
|
|
76
|
+
<View variant="card" gap="small">
|
|
77
|
+
<View direction="row" wrap gap="small">
|
|
78
|
+
<Button variant="secondary" onClick="download" disabled="{{ releases.length === 0 }}">Download</Button>
|
|
79
|
+
<Button variant="secondary" onClick="upload" disabled="{{ !picture }}">Upload</Button>
|
|
80
|
+
<Button variant="secondary" onClick="sharePicture" disabled="{{ !picture }}">Share</Button>
|
|
81
|
+
<Button variant="secondary" onClick="keep" disabled="{{ !picture || kept }}">Keep</Button>
|
|
82
|
+
</View>
|
|
83
|
+
<If condition="{{ picture }}">
|
|
84
|
+
<View direction="row" align="center" gap="medium">
|
|
85
|
+
<Image src="{{ picture.url }}" alt="Artwork" width="64" height="64" />
|
|
86
|
+
<Text variant="caption" tone="muted">{{ picture.size }} bytes, in a temporary file until the dot closes</Text>
|
|
87
|
+
</View>
|
|
88
|
+
</If>
|
|
89
|
+
<If condition="{{ uploaded }}">
|
|
90
|
+
<Text>httpbin got the file field "{{ uploaded }}"</Text>
|
|
91
|
+
</If>
|
|
92
|
+
<If condition="{{ kept }}">
|
|
93
|
+
<Text>Saved in the dot's folder. See the dash.storage.file page.</Text>
|
|
94
|
+
</If>
|
|
95
|
+
</View>
|
|
96
|
+
</View>
|
|
97
|
+
|
|
98
|
+
<View gap="small">
|
|
99
|
+
<Text variant="subtitle">Hosts dot.json doesn't list</Text>
|
|
100
|
+
<Text variant="caption" tone="muted">Dash turns the request down.</Text>
|
|
101
|
+
<View variant="card" gap="small">
|
|
102
|
+
<Button variant="secondary" onClick="tryUnlistedHost">Reach example.com</Button>
|
|
103
|
+
<If condition="{{ note }}">
|
|
104
|
+
<Text variant="caption" tone="muted">{{ note }}</Text>
|
|
105
|
+
</If>
|
|
106
|
+
</View>
|
|
107
|
+
</View>
|
|
108
|
+
</View>
|