Commit 7fc5514f authored by leadream's avatar leadream

add webhook

parent 04d41f04
export const sendNotification = ({webhookUrl, data}, prUrl, version, message) => {
return fetch(`https://figma-handoff-cors.herokuapp.com/${webhookUrl}`, {
headers: {
'content-type': 'application/json'
},
body: data
.replace(/\$prUrl/g, prUrl)
.replace(/\$version/g, version)
.replace(/\$message/g, message),
method: 'POST'
})
.then(response => response.json())
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
figma.showUI(__html__, { width: 320, height: 320 })
figma.showUI(__html__, { width: 320, height: 436 })
// get github settings
function getGithubSettings () {
return figma.clientStorage.getAsync('githubData')
function getLocalData (key) {
return figma.clientStorage.getAsync(key)
}
// set github settings
function setGithubSettings (data) {
figma.clientStorage.setAsync('githubData', data)
function setLocalData (key, data) {
figma.clientStorage.setAsync(key, data)
}
// send github data to UI
function init () {
getGithubSettings()
getLocalData('githubData')
.then(githubData => {
figma.ui.postMessage({ type: 'githubDataGot', githubData })
})
getLocalData('webhookData')
.then(webhookData => {
figma.ui.postMessage({ type: 'webhookDataGot', webhookData })
})
}
figma.ui.onmessage = msg => {
switch (msg.type) {
case 'setGithubData':
setGithubSettings(msg.githubData)
setLocalData('githubData', msg.githubData)
break
case 'setWebhookData':
setLocalData('webhookData', msg.webhookData)
break
case 'cancel':
figma.closePlugin()
......
......@@ -49,7 +49,7 @@ export default class Settings extends React.Component<Props> {
}
}
render () {
const { visible } = this.props
const { visible, githubData } = this.props
const { githubRepo, githubToken, warning } = this.state
return (
<div className={!visible ? 'hide' : ''}>
......@@ -84,7 +84,9 @@ export default class Settings extends React.Component<Props> {
/>
</div>
<div className="form-item">
<button className='button button--primary button-block' onClick={this.handleSubmit}>Go</button>
<button className='button button--primary button-block' onClick={this.handleSubmit}>
{githubData ? 'Update' : 'Go'}
</button>
</div>
<div className="setting-footer form-item type type--pos-medium-normal">
developed by <a href="https://github.com/leadream" target="_blank">Leadream</a>
......
import * as React from 'react'
import Webhook from './Webhook'
import { getContent, getCommit, updatePackage, createPullRequest, createBranch } from '../../api/github'
import { sendNotification } from '../../api/webhook'
import { versionValue } from '../../utils/helper'
declare function require(path: string): any
export interface Props {
onSucceed: () => void;
githubData: {owner?: string, name?: string, githubToken?: string};
webhookData: {webhookUrl: string, data: string};
visible: boolean;
}
......@@ -23,7 +25,8 @@ export default class Settings extends React.Component<Props> {
currentVersion: '',
currentVersionTip: '',
resultTip: '',
prUrl: ''
prUrl: '',
webhookData: null
}
getVersion = async (githubData) => {
const { contents, sha } = await getContent('package.json', githubData)
......@@ -61,6 +64,12 @@ export default class Settings extends React.Component<Props> {
const { name, value } = e.target
this.setState({[name]: value})
}
handleWebhookFilled = (webhookUrl, data) => {
const noData = !webhookUrl && !data
this.setState({
webhookData: noData? null : {webhookUrl, data}
})
}
validate = (callback) => {
const { version, message, currentVersion } = this.state
// TODO: should validate async
......@@ -91,26 +100,24 @@ export default class Settings extends React.Component<Props> {
})
callback && callback()
}
handleSubmit = () => {
this.validate(() => {
handleSubmit = async () => {
this.validate(async () => {
this.setState({isPushing: true})
this.createBranch()
.then(({branchName}) => {
this.changeVersion(branchName)
.then(() => {
this.createCommitAndPR(branchName)
.then(({html_url}) => {
this.props.onSucceed()
this.setState({
version: '',
message: '',
isPushing: false,
resultTip: 'Pushing successfully! You can now go to Github and merge this PR. Then your icons will be published to NPM automatically.',
prUrl: html_url
})
})
})
})
const { branchName } = await this.createBranch()
await this.changeVersion(branchName)
const { html_url } = await this.createCommitAndPR(branchName)
const { version, message, webhookData } = this.state
webhookData && sendNotification(webhookData, html_url, version, message)
this.setState({
version: '',
message: '',
isPushing: false,
resultTip: 'Pushing successfully! You can now go to Github and merge this PR. Then your icons will be published to NPM automatically.',
prUrl: html_url
})
})
}
onCancel = () => {
......@@ -122,7 +129,7 @@ export default class Settings extends React.Component<Props> {
}
}
render () {
const { visible } = this.props
const { visible, webhookData } = this.props
const { isPushing, version, message, versionTip, messageTip, currentVersionTip, resultTip, prUrl } = this.state
return (
<div className={'updator ' + (!visible ? 'hide' : '')}>
......@@ -171,6 +178,11 @@ export default class Settings extends React.Component<Props> {
<div className="type type--pos-medium-normal help-tip">{messageTip}</div>
}
</div>
<Webhook
hidden={resultTip}
onFilled={this.handleWebhookFilled}
webhookData={webhookData}
/>
<div className={'form-item '+(resultTip ? 'hide' : '')}>
<button
onClick={this.handleSubmit}
......@@ -190,4 +202,4 @@ export default class Settings extends React.Component<Props> {
</div>
)
}
}
\ No newline at end of file
}
import * as React from 'react'
export interface Props {
hidden: boolean;
webhookData: {webhookUrl: string, data: string};
onFilled: (webhookUrl, data) => void;
}
export default ({hidden, onFilled, webhookData}) => {
const [visible, setVisible] = React.useState(false)
const [webhookUrl, setWebhookUrl] = React.useState('')
const [data, setData] = React.useState('')
const toggle = e => {
setVisible(e.target.checked)
}
const handleChange = e => {
const { value, name } = e.target
name==='webhookUrl' ? setWebhookUrl(value) : setData(value)
}
React.useEffect(() => {
if (!visible) {
onFilled()
parent.postMessage({ pluginMessage: { type: 'setWebhookData', webhookData: '' } }, '*')
}
if (visible && webhookUrl && data) {
onFilled(webhookUrl, data)
parent.postMessage({ pluginMessage: { type: 'setWebhookData', webhookData: {webhookUrl, data} } }, '*')
}
}, [visible, webhookUrl, data])
React.useEffect(() => {
const { webhookUrl: url, data: message } = webhookData || { webhookUrl: '', data: '' }
if (url && message) {
setVisible(true)
setWebhookUrl(url)
setData(message)
}
}, [webhookData])
return (
!hidden &&
<React.Fragment>
<div className="checkbox">
<input id="visible" type="checkbox" className="checkbox__box" onChange={toggle} checked={visible}/>
<label htmlFor="visible" className="checkbox__label">Send a message to Slack/Lark</label>
</div>
<div className={visible ? '' : 'hide'}>
<div className="form-item">
<input
name="webhookUrl"
className="input"
placeholder="Webhook link"
value={webhookUrl}
onChange={handleChange}
/>
</div>
<div className="form-item">
<textarea
rows={2}
name="data"
className="textarea"
placeholder="Message data (json)"
value={data}
onChange={handleChange}
/>
<div className="type type--pos-medium-normal">You can use variables $prUrl, $version, $message in the content.</div>
</div>
</div>
</React.Fragment>
)
}
......@@ -47,7 +47,7 @@ a{
color: #18a0fb
}
.container{
.container-with-tab{
padding-top: 20px;
}
......
......@@ -11,6 +11,7 @@ class App extends React.Component {
state = {
updatorVisible: false,
githubData: null,
webhookData: null,
settingSwitch: false,
isDone: false
}
......@@ -30,7 +31,7 @@ class App extends React.Component {
}
}
componentDidMount () {
// 所有的消息接收集中在这里
// receive messages here
window.onmessage = async (event) => {
const msg = event.data.pluginMessage
switch (msg.type) {
......@@ -42,14 +43,22 @@ class App extends React.Component {
})
}
break
case 'webhookDataGot':
if (msg.webhookData) {
this.setState({
webhookData: msg.webhookData
})
}
break
}
}
}
render() {
const { updatorVisible, githubData, settingSwitch, isDone } = this.state
const { updatorVisible, githubData, webhookData, settingSwitch, isDone } = this.state
const tabVisible = githubData&&!isDone
return (
<div className="container">
<div className={'bar-adjust '+ ((githubData&&!isDone) ? '' : 'hide')}>
<div className={'container '+ (!tabVisible ? '' : 'container-with-tab')}>
<div className={'bar-adjust '+ (tabVisible ? '' : 'hide')}>
<div
className={'adjust-item type type--pos-medium-bold '+(updatorVisible ? '' : 'active')}
onClick={e => this.toggleView()}
......@@ -72,7 +81,9 @@ class App extends React.Component {
<Updator
onSucceed={this.onSucceed}
visible={updatorVisible}
githubData={githubData}/>
githubData={githubData}
webhookData={webhookData}
/>
</div>
)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment