-
Notifications
You must be signed in to change notification settings - Fork 0
/
sticker.js
302 lines (269 loc) · 7.78 KB
/
sticker.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
const payloads = require("./payloads");
const store = require("./store");
/**
main sticker view modal
depending on mode, it will add actions for that mode and user
- set:view view only stickers
- set:choose stickers with action button to choose & send via submit
- set:edit edit and delete sticker for set owner
**/
const viewStickers = async (app, context, body, action, mode) => {
const set = await store.findSet(action.value);
const stickers = await store.findStickersBySet(action.value);
// get response_url from /commands to store in view metadata
// if interaction is started from a modal, pass on response_url
// for stacked modal
let metadata = {};
// pass on metadata to new view if applicable
if (body.view && body.view.private_metadata) {
try {
metadata = JSON.parse(body.view.private_metadata);
} catch (e) {}
}
// add response_url to metadata if applicable
if (body.response_url) {
metadata.response_url = body.response_url;
}
const modal = await renderViewModal(
body.user && body.user.id || body.user_id,
action.value,
set,
stickers,
mode,
metadata
);
switch (mode) {
case "set:choose":
// user has an open modal with list of sets to choose from
return app.client.views.push({
token: context.botToken,
trigger_id: body.trigger_id,
view: modal
});
case "set:choose:command":
// set is chosen from command directly already, so open view with stickers
return app.client.views.open({
token: context.botToken,
trigger_id: body.trigger_id,
view: modal
});
default:
// this is the view sticker mode from e.g. app home or messages
return app.client.views.open({
token: context.botToken,
trigger_id: body.trigger_id,
view: modal
});
}
};
const viewSets = async (app, context, body, metadata) => {
metadata = metadata || {}
// response_url doesn't exist for shortcuts
// only add it if it exists
if(body.response_url) metadata.response_url = body.response_url
const sets = await store.findSetsByUserId(body.user && body.user.id || body.user_id);
// add message_ts in case of message action
if(body.message_ts) metadata.message_ts = body.message_ts
const modal = payloads.modals.setsView({metadata});
if (sets.length) {
sets.forEach(set => {
modal.blocks = modal.blocks.concat(
payloads.modals.setChoose({
setId: set.id,
set: set.data()
})
);
});
} else {
modal.blocks = modal.blocks.concat(
payloads.utils.text(
"You currently don't have any sticker sets ‾\\_(ツ)_/‾"
)
);
}
return app.client.views.open({
token: context.botToken,
trigger_id: body.trigger_id,
view: modal
});
};
const updateStickers = async (
app,
context,
body,
viewId,
setId,
mode,
newMetadata
) => {
const set = await store.findSet(setId);
const stickers = await store.findStickersBySet(setId);
let metadata =
(body.view &&
body.view.private_metadata &&
JSON.parse(body.view.private_metadata)) ||
{};
metadata = Object.assign(metadata, newMetadata || {});
const modal = await renderViewModal(
body.user.id,
setId,
set,
stickers,
mode,
metadata
);
return app.client.views.update({
token: context.botToken,
view_id: viewId,
view: modal
});
};
const editName = async (app, context, body, action) => {
const setId = action.value.split(":")[0];
const id = action.value.split(":")[1];
const sticker = await store.findSticker(setId, id);
const modal = payloads.modals.stickerEdit({
name: sticker.name,
url: sticker.url,
id: id,
setId: setId
});
return app.client.views.push({
token: context.botToken,
trigger_id: body.trigger_id,
view: modal
});
};
/**
default home view
depending on ownership and team, it will show
- own sticker sets with edit buttons
- sticker sets available in the team and public to view and add
**/
const homeView = async (user, userId, teamId) => {
let home = payloads.home.home();
let sets = [];
let setIds = [];
// add existing sticker sets if user is stored
if (user) {
sets = await store.findSetIdsByUserId(userId);
setIds = sets.map(data => data.set_id);
let promises = sets.map(async data => {
let set = await store.findSet(data.set_id);
return {
id: data.set_id,
set: set
};
});
sets = await Promise.all(promises);
if (sets.length) {
home.blocks = home.blocks.concat(
payloads.home.stickerHeader({ text: "Your stickers" })
);
sets.forEach(doc => {
home.blocks = home.blocks.concat(
payloads.home.stickerSet({ setId: doc.id, set: doc.set })
);
// if user is owner, show edit buttons
if (doc.set.user_id === userId) {
home.blocks.push(
payloads.home.setEditButtons({ setId: doc.id, set: doc.set })
);
} else {
// otherwise just show remove button
home.blocks.push(
payloads.home.setRemoveButtons({ setId: doc.id, set: doc.set })
);
}
});
}
}
// load available sets to view and add
// either public or team privacy settings
const availableSets = await store.findAvailableSets(teamId, setIds);
if (availableSets.length) {
// only add spacer if user has own sets as well
if (sets.length) home.blocks.push(payloads.utils.spacer);
home.blocks = home.blocks.concat(
payloads.home.stickerHeader({ text: "Add stickers" })
);
availableSets.forEach(set => {
home.blocks = home.blocks.concat(
payloads.home.stickerSet({ setId: set.id, set: set.data() })
);
home.blocks.push(
payloads.home.setAddButtons({ setId: set.id, set: set.data() })
);
});
}
return home;
};
const renderViewModal = (userId, setId, set, stickers, mode, metadata) => {
const modal = payloads.modals.setView({ name: set.name, metadata: metadata });
if (!stickers.length) {
modal.blocks.push(
payloads.utils.text(
"There are currently no stickers in this set ‾\\_(ツ)_/‾"
)
);
}
if (mode.indexOf("set:choose") >= 0) {
modal.submit = payloads.utils.submit("Send");
}
// add sticker component for each sticker
stickers.forEach(sticker => {
let data = sticker.data();
// display the sticker
modal.blocks.push(
payloads.modals.stickerView({
name: data.name,
url: data.url
})
);
// if user is owner and we are in edit mode, add edit & delete buttons
if (set.user_id === userId && mode === "set:edit") {
modal.blocks.push(
payloads.modals.stickerEditButtons({
setId: setId,
id: sticker.id,
name: data.name
})
);
}
// if in sending mode, add send buttons
if (mode.indexOf("set:choose") >= 0) {
// if sticker has been selected, show different button style & text
if (metadata.setId === setId && metadata.stickerId === sticker.id) {
modal.blocks.push(
payloads.modals.stickerSelectedButtons({
setId: setId,
id: sticker.id,
name: data.name
})
);
} else {
// show default button style & text for others
modal.blocks.push(
payloads.modals.stickerSendButtons({
setId: setId,
id: sticker.id,
name: data.name
})
);
}
}
modal.blocks.push(payloads.utils.divider);
});
// if launched from a shortcut, add a conversation select
if(metadata.shortcut) {
modal.blocks.push(payloads.modals.conversationsSelect)
}
return modal;
};
module.exports = {
homeView,
viewStickers,
updateStickers,
editName,
viewSets
};