UNPKG

3.33 kBtext/coffeescriptView Raw
1Promise = window.Promise or require 'promiz'
2portal = require 'portal-gun'
3
4TRUSTED_DOMAIN = (process.env.TRUSTED_DOMAIN or 'clay.io')
5TWEET_LENGTH = 140
6VERSION = 'v1.1.1'
7
8deferredFactory = ->
9 resolve = null
10 reject = null
11 promise = new Promise (_resolve, _reject) ->
12 resolve = _resolve
13 reject = _reject
14 promise.resolve = resolve
15 promise.reject = reject
16
17 return promise
18
19config = deferredFactory()
20initHasBeenCalled = false
21windowOpeningMethods = ['share.any']
22
23Clay = (method, params, cb = -> null) ->
24 if typeof params is 'function'
25 cb = params
26 params = []
27
28 # Normalize params to an array if passed an object
29 if params? and Object::toString.call(params) is '[object Object]'
30 params = [params]
31
32 if params? and Object::toString.call(params) isnt '[object Array]'
33 return cb new Error 'Params must be an array'
34
35 methodRoot = method.split('.')[0]
36 method = method.slice method.indexOf('.') + 1
37
38 unless methods[methodRoot]
39 return cb new Error 'Method not found'
40
41 methods[methodRoot].apply 0, [method, params, cb]
42
43methods = {
44 version: (_, __, cb) ->
45 cb null, VERSION
46
47 init: (method, [options], cb) ->
48 (do ->
49 gameId = options.gameId
50 debug = Boolean options.debug
51
52 if debug
53 portal.up()
54 else
55 portal.up trusted: TRUSTED_DOMAIN, subdomains: true
56
57 unless typeof gameId is 'string' and /^[0-9]+$/.test gameId
58 return cb new Error 'Missing or invalid gameId'
59
60 initHasBeenCalled = true
61
62 portal.get 'auth.getStatus', {gameId}
63 .then (status) ->
64 # TODO: Token may be invalid
65 config.resolve
66 gameId: gameId
67 accessToken: status?.accessToken
68 return config
69 .catch ->
70 config.resolve
71 gameId: gameId
72 accessToken: null
73 return config
74 )
75 .then (x) ->
76 cb null, x
77 .catch cb
78
79 client: (method, params, cb) ->
80 if method is 'client'
81 return cb new Error 'Missing or invalid method'
82
83 (do ->
84 unless initHasBeenCalled
85 return Promise.reject new Error 'Must call Clay(\'init\') first'
86
87 # must occur before any async code
88 if method in windowOpeningMethods
89 portal.beforeWindowOpen()
90
91 config.then (config) ->
92 unless Object::toString.call(params) is '[object Array]'
93 params = [params]
94
95 # inject gameId and accessToken into request parameters
96 if typeof params[0] is 'object'
97 params[0].gameId = config.gameId
98 params[0].accessToken = config.accessToken
99
100 return portal.get method, params
101 )
102 .then (x) -> cb null, x
103 .catch cb
104
105 register: (_, [{method, fn}]) ->
106 methods[method] = fn(config)
107
108}
109
110portal.register 'share.any', ({text} = {}) ->
111 unless typeof text is 'string'
112 throw new Error 'text parameter is missing or invalid'
113
114 if text.length > TWEET_LENGTH
115 throw new Error 'No valid share method available'
116
117 tweet = (text) ->
118 text = encodeURIComponent text.substr 0, TWEET_LENGTH
119 portal.windowOpen "https://twitter.com/intent/tweet?text=#{text}", '_system'
120
121 return tweet(text)
122
123module.exports = Clay
124
125# Initialize, allowing time for synchronous registration of services
126window.setTimeout ->
127 q = window.Clay?.q or []
128
129 window.Clay = Clay
130 for call in q
131 Clay.apply 0, call