Skip to content

Commit c4c7b9c

Browse files
authored
Merge pull request #29 from line/stp-fixed-args
Fix payload for ShareTargetPicker
2 parents 258e17a + 72a5063 commit c4c7b9c

File tree

5 files changed

+202
-68
lines changed

5 files changed

+202
-68
lines changed

src/App.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Snippet from './components/Snippet'
66
import Input from './components/Input'
77
import { FilterContext, FilterTypes } from './Context'
88
import qrCode from './qr-code.png'
9+
import { SHARE_TARGET_PICKER_FIXED_ARGUMENT_LIST } from './constants'
910

1011
const isMINI = new URLSearchParams(location.search).has('mini')
1112
const filter = isMINI ? FilterTypes.MINI : FilterTypes.LIFF
@@ -225,16 +226,8 @@ function App() {
225226
docUrl="https://developers.line.biz/en/reference/liff/#share-target-picker"
226227
needRequestPayload={true}
227228
hideResponse={true}
228-
defaultRequestPayload={JSON.stringify(
229-
[
230-
{
231-
type: 'text',
232-
text: 'Hello, World!',
233-
},
234-
],
235-
null,
236-
4
237-
)}
229+
defaultRequestPayload={SHARE_TARGET_PICKER_FIXED_ARGUMENT_LIST[0].value}
230+
pulldownOptions={SHARE_TARGET_PICKER_FIXED_ARGUMENT_LIST}
238231
skipAutoRun={true}
239232
runner={async (options) => {
240233
return await liff.shareTargetPicker(JSON.parse(options))

src/components/Pulldown.module.css

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
.label {
2+
font-size: 15px;
3+
font-weight: 700;
4+
margin-bottom: 8px;
5+
}
6+
7+
.frame {
8+
display: flex;
9+
width: 100%;
10+
}
11+
12+
.helpText {
13+
color: rgb(148, 148, 148);
14+
font-size: 13px;
15+
font-weight: 400;
16+
margin-top: 8px;
17+
margin-bottom: 8px;
18+
}
19+
20+
.select {
21+
padding: 4px 12px;
22+
line-height: 24px;
23+
font-size: 12px;
24+
font-weight: 400;
25+
border: solid 1px #ddd;
26+
border-radius: 5px;
27+
}

src/components/Pulldown.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from 'react'
2+
import styles from './Pulldown.module.css'
3+
4+
interface PulldownProps {
5+
label: string
6+
helpText?: string
7+
value: number|string
8+
onChange: (event: React.ChangeEvent<HTMLSelectElement>) => void
9+
options: { label: string; value: string | number }[]
10+
}
11+
12+
export default function Pulldown({
13+
label,
14+
helpText,
15+
value,
16+
onChange,
17+
options,
18+
}: PulldownProps) {
19+
return (
20+
<>
21+
<label>
22+
{label && <div className={styles.label}>{label}</div>}
23+
<div className={styles.frame}>
24+
<select className={styles.select} value={value} onChange={onChange}>
25+
{options.map((option, i) => (
26+
<option key={i} value={option.value}>
27+
{option.label}
28+
</option>
29+
))}
30+
</select>
31+
</div>
32+
</label>
33+
{helpText && <div className={styles.helpText}>{helpText}</div>}
34+
</>
35+
)
36+
}

src/components/Snippet.tsx

Lines changed: 81 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ import styles from './Snippet.module.css'
55
import Tag from './Tag'
66
import TextArea from './TextArea'
77
import { FilterContext, FilterTypes } from '../Context'
8+
import Pulldown from './Pulldown'
89

910
interface SippetProps {
1011
apiName: string
1112
version: string
1213
docUrl: string
1314
needRequestPayload?: boolean
1415
defaultRequestPayload?: string
16+
pulldownOptions?: { label: string; value: string }[]
1517
useTextareaForResponse?: boolean
1618
skipAutoRun?: boolean
1719
hideResponse?: boolean
@@ -26,9 +28,9 @@ interface RunnerError extends Error {
2628
message: string
2729
}
2830

29-
const primaryRed = '#eb4e3d';
30-
const primaryBlue = '#6fedd6';
31-
const primaryOrange = '#ff9551';
31+
const primaryRed = '#eb4e3d'
32+
const primaryBlue = '#6fedd6'
33+
const primaryOrange = '#ff9551'
3234

3335
export default function Snippet({
3436
apiName,
@@ -40,10 +42,11 @@ export default function Snippet({
4042
needRequestPayload,
4143
useTextareaForResponse,
4244
defaultRequestPayload,
45+
pulldownOptions,
4346
loginRequired,
4447
inClientOnly,
4548
isInLIFF = true,
46-
isInMINI = true
49+
isInMINI = true,
4750
}: SippetProps) {
4851
const [response, setResponse] = useState('')
4952
const [payload, setPayload] = useState(defaultRequestPayload || '')
@@ -71,64 +74,84 @@ export default function Snippet({
7174

7275
return (
7376
<FilterContext.Consumer>
74-
{
75-
(filter) =>
76-
((filter === FilterTypes.LIFF && isInLIFF) || (filter === FilterTypes.MINI && isInMINI))
77-
&& <div className={styles.snippet}>
78-
<div className={styles.head}>
79-
<h2 className={styles.title}>
80-
<span className={styles.text}>{apiName}</span>
81-
<Tag>{version}</Tag>
82-
{loginRequired && <Tag backgroundColor={primaryRed}>Login Required</Tag>} {inClientOnly && <Tag backgroundColor={primaryRed}>LINE Client only</Tag>}
83-
{isInLIFF && <Tag backgroundColor={primaryBlue}>LIFF</Tag>}
84-
{isInMINI && <Tag backgroundColor={primaryOrange}>MINI</Tag>}
85-
</h2>
86-
<div className={styles.action}>
87-
<Button
88-
appearance="outlined"
89-
variant="primary"
90-
size="S"
91-
aria-disabled="false"
92-
onClick={openDoc}>
93-
DOCUMENT
94-
</Button>{' '}
95-
<Button
96-
variant="primary"
97-
size="S"
98-
onClick={() => {
99-
callRunner()
100-
}}>
101-
RUN
102-
</Button>
77+
{(filter) =>
78+
((filter === FilterTypes.LIFF && isInLIFF) ||
79+
(filter === FilterTypes.MINI && isInMINI)) && (
80+
<div className={styles.snippet}>
81+
<div className={styles.head}>
82+
<h2 className={styles.title}>
83+
<span className={styles.text}>{apiName}</span>
84+
<Tag>{version}</Tag>
85+
{loginRequired && (
86+
<Tag backgroundColor={primaryRed}>Login Required</Tag>
87+
)}{' '}
88+
{inClientOnly && (
89+
<Tag backgroundColor={primaryRed}>LINE Client only</Tag>
90+
)}
91+
{isInLIFF && <Tag backgroundColor={primaryBlue}>LIFF</Tag>}
92+
{isInMINI && <Tag backgroundColor={primaryOrange}>MINI</Tag>}
93+
</h2>
94+
<div className={styles.action}>
95+
<Button
96+
appearance="outlined"
97+
variant="primary"
98+
size="S"
99+
aria-disabled="false"
100+
onClick={openDoc}>
101+
DOCUMENT
102+
</Button>{' '}
103+
<Button
104+
variant="primary"
105+
size="S"
106+
onClick={() => {
107+
callRunner()
108+
}}>
109+
RUN
110+
</Button>
111+
</div>
103112
</div>
104-
</div>
105-
{needRequestPayload && (
106-
<TextArea
107-
label="Arguments"
108-
helpText="Enter the request payload for API request"
109-
value={payload}
110-
onChange={(e) => setPayload(e?.currentTarget?.value)}
111-
rows={4}
112-
/>
113-
)}
114-
{!hideResponse &&
115-
(useTextareaForResponse ? (
113+
{needRequestPayload && pulldownOptions ? (
114+
<>
115+
<Pulldown
116+
label="Arguments"
117+
helpText="Choose the request payload for API request"
118+
value={payload}
119+
onChange={(e) => setPayload(e.currentTarget.value)}
120+
options={pulldownOptions.map(({ label, value }) => ({
121+
label,
122+
value,
123+
}))}
124+
/>
125+
<TextArea value={payload} readonly={true} rows={4} />
126+
</>
127+
) : (
116128
<TextArea
117-
label="Response"
118-
helpText="Run this API to get the response"
119-
value={response}
129+
label="Arguments"
130+
helpText="Enter the request payload for API request"
131+
value={payload}
132+
onChange={(e) => setPayload(e?.currentTarget?.value)}
120133
rows={4}
121-
readonly={true}
122134
/>
123-
) : (
124-
<Input
125-
label="Response"
126-
helpText="Run this API to get the response"
127-
readonly={true}
128-
value={response}
129-
/>
130-
))}
131-
</div>
135+
)}
136+
{!hideResponse &&
137+
(useTextareaForResponse ? (
138+
<TextArea
139+
label="Response"
140+
helpText="Run this API to get the response"
141+
value={response}
142+
rows={4}
143+
readonly={true}
144+
/>
145+
) : (
146+
<Input
147+
label="Response"
148+
helpText="Run this API to get the response"
149+
readonly={true}
150+
value={response}
151+
/>
152+
))}
153+
</div>
154+
)
132155
}
133156
</FilterContext.Consumer>
134157
)

src/constants.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
export const SHARE_TARGET_PICKER_FIXED_ARGUMENT_LIST = [
2+
{
3+
label: 'text',
4+
value: {
5+
type: 'text',
6+
text: 'Hello, World!',
7+
},
8+
},
9+
{
10+
label: 'sticker',
11+
value: {
12+
type: 'sticker',
13+
packageId: '446',
14+
stickerId: '1988',
15+
},
16+
},
17+
{
18+
label: 'image',
19+
value: {
20+
type: 'image',
21+
originalContentUrl: 'https://example.com/original.jpg',
22+
previewImageUrl: 'https://example.com/preview.jpg',
23+
},
24+
},
25+
{
26+
label: 'video',
27+
value: {
28+
type: 'video',
29+
originalContentUrl: 'https://example.com/original.mp4',
30+
previewImageUrl: 'https://example.com/preview.jpg',
31+
trackingId: 'track-id',
32+
},
33+
},
34+
{
35+
label: 'audio',
36+
value: {
37+
type: 'audio',
38+
originalContentUrl: 'https://example.com/original.m4a',
39+
duration: 60000,
40+
},
41+
},
42+
{
43+
label: 'location',
44+
value: {
45+
type: 'location',
46+
title: 'my location',
47+
address: '〒102-8282 東京都千代田区紀尾井町1番3号',
48+
latitude: 35.67966,
49+
longitude: 139.73669,
50+
},
51+
},
52+
].map(({ label, value }) => ({
53+
label,
54+
value: JSON.stringify(value, null, 4),
55+
}))

0 commit comments

Comments
 (0)