-
Notifications
You must be signed in to change notification settings - Fork 61
/
ShareController.js
119 lines (104 loc) · 3.62 KB
/
ShareController.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { bindActionCreators } from 'redux'
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { assoc, chain, compose, concat, head, last, join, map, split } from 'ramda'
import { Future as Task } from 'ramda-fantasy'
import { List } from 'immutable-ext'
import * as modalActions from 'actions/modal'
import IconButton from 'components/IconButton'
import * as Tracking from 'modules/tracking'
import { createPreset } from 'utils/presets'
import { logError } from 'utils/tools'
import { getGoogleShortURL } from 'utils/short-urls'
const getIDFromGoogleURL = compose(last, split('/'))
// combineShortURLs :: [url] -> url
const combineShortURLs = compose(
concat(`${window.location.host}/share/`),
join('-'),
map(getIDFromGoogleURL),
)
// compressShortMultiURL :: url -> Task Error url
const compressShortMultiURL = (url) => {
if (!url.includes('-')) return Task.of(url)
return getGoogleShortURL(url)
.map(shortURL => combineShortURLs([shortURL]))
}
// getShareableURL :: preset -> Task url
const getShareableURL = preset =>
Task((rej, res) => {
require.ensure(['lzutf8'], (require) => {
const compress = require('lzutf8').compress
const compressedPreset = compress(JSON.stringify(preset), { outputEncoding: 'Base64' })
const shareableURL = `djen.co/#share=${compressedPreset}`
if (shareableURL.length > 2048) logError('URL exceeds 2048 chars. May not succeed')
res(shareableURL)
}, 'lzutf8')
})
// getShortURL :: preset -> Task Error url
const getShortURL = preset => compose(
chain(getGoogleShortURL),
getShareableURL,
createPreset,
assoc('usePredefinedSettings', true),
)(preset)
class ShareController extends Component {
state = {
isEnabled: false,
isLoading: false,
shortURL: ''
}
onClick = () => {
this.setState({ isLoading: true })
Tracking.sendShareEvent('share')
List(this.props.audioPlaylist)
.traverse(Task.of, getShortURL)
.map(combineShortURLs)
.chain(compressShortMultiURL)
.fork(logError, (url) => {
this.launchModal(url)
this.setState({ isLoading: false })
})
}
launchModal = (url) => {
const content = (<ShareBox url={url} />)
this.props.actions.enableModal({ className: 'modal--small', content, title: 'Share URL', isCloseable: true })
}
render = () => {
const { googleAPIHasLoaded, audioPlaylist } = this.props
const isDisabled = !googleAPIHasLoaded || !audioPlaylist.length
return (
<IconButton
icon="share"
isDisabled={isDisabled}
isLoading={this.state.isLoading}
onClick={this.onClick}
theme="alpha-dark"
>
Share
</IconButton>
)
}
}
const ShareBox = props => (
<div className="u-flex-row u-flex-justify-center">
<input
className="input-container__input input-container__input--bare input-container__input--large input-container__input--long u-tac"
type="text"
value={props.url}
onFocus={e => e.target.select()}
readOnly={true}
/>
</div>
)
const mapStateToProps = state => ({
audioPlaylist : state.sound.audioPlaylist,
})
const actions = {
...modalActions
}
const mapDispatchToProps = dispatch => ({
actions: {
...bindActionCreators(actions, dispatch)
}
})
export default connect(mapStateToProps, mapDispatchToProps)(ShareController)