139 |
140 |
141 |
142 |

143 |
144 |
145 |
146 |
Username
147 |
1 hour ago
148 |
149 |
150 |
151 | Hello World!
152 |
153 |
154 |
155 | -
156 | 1
157 |
158 |
159 | -
160 |
161 |
162 |
163 | -
164 | 3
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
--------------------------------------------------------------------------------
/assets/stream.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function bindApiButtons() {
4 | getSingleElementByClassName('hs_showImagePreview').addEventListener('click', function () {
5 | hsp.showImagePreview(getSingleElementByClassName('hs_showImagePreviewInput').value, 'https://hootsuite.com');
6 | });
7 |
8 | getSingleElementByClassName('hs_showLightbox').addEventListener('click', function () {
9 | // similar to showImagePreview
10 | hsp.showLightbox(getSingleElementByClassName('hs_showLightboxInput').value);
11 | });
12 |
13 | getSingleElementByClassName('hs_showStatusMessage').addEventListener('click', function () {
14 | // type can be info, error, warning or success
15 | hsp.showStatusMessage(getSingleElementByClassName('hs_showStatusMessageInput').value, getSingleElementByClassName('hs_showStatusMessageTypeInput').value);
16 | });
17 |
18 | getSingleElementByClassName('hs_showUser').addEventListener('click', function () {
19 | // opens a modal with info about a twitter user
20 | hsp.showUser(getSingleElementByClassName('hs_showUserInput').value);
21 | });
22 |
23 | getSingleElementByClassName('hs_composeMessage').addEventListener('click', function () {
24 | hsp.composeMessage(getSingleElementByClassName('hs_composeMessageInput').value);
25 | });
26 |
27 | getSingleElementByClassName('hs_saveData').addEventListener('click', function () {
28 | hsp.saveData(getSingleElementByClassName('hs_saveDataInput').value, function(){});
29 | });
30 |
31 | getSingleElementByClassName('hs_getData').addEventListener('click', function () {
32 | hsp.getData(function (data){
33 | replaceTextInClass('hs_getDataOutput', data);
34 | });
35 | });
36 |
37 | getSingleElementByClassName('hs_assignItem').addEventListener('click', function () {
38 | // Generates a 16 character random string to use as the messageId
39 | // because the messageId must be unique or Hootsuite will return a 500 error.
40 | // This can be saved if you'd like to do something using the `sendassignmentupdates` event
41 | // or with the Assignment Event Request API Callback
42 | var randomString = '';
43 | var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
44 | for (var i = 0; i < 16; i++) {
45 | randomString += possible.charAt(Math.floor(Math.random() * possible.length));
46 | }
47 |
48 | hsp.assignItem({
49 | messageId: randomString,
50 | messageAuthor: getSingleElementByClassName('hs_assignMessageAuthor').value,
51 | messageAuthorAvatar: getSingleElementByClassName('hs_assignMessageAuthorAvatar').value,
52 | message: getSingleElementByClassName('hs_assignMessage').value
53 | });
54 | });
55 |
56 | getSingleElementByClassName('hs_attachFile').addEventListener('click', function () {
57 | hsp.getMemberInfo(function (data) {
58 | var timestamp = Math.floor(Date.now() / 1000);
59 | var url = getSingleElementByClassName('hs_attachFileInput').value;
60 | var extension = url.split('.');
61 | if (extension.length !== 0) {
62 | extension = extension[extension.length - 1];
63 | } else {
64 | extension = 'jpg';
65 | }
66 | var name = getSingleElementByClassName('hs_attachFileImageName').value;
67 | var httpRequest = new XMLHttpRequest();
68 | var once = false;
69 | // generates a token on the backend because secret must be kept on backend
70 | httpRequest.open( 'GET',
71 | window.location.origin +
72 | '/gen-token?userId=' + encodeURIComponent(data.userId) +
73 | '×tamp=' + encodeURIComponent(timestamp) +
74 | '&url=' + encodeURIComponent(url));
75 | httpRequest.send();
76 | httpRequest.onreadystatechange = function () {
77 | if (httpRequest.responseText !== '' && !once) {
78 | hsp.attachFileToMessage({
79 | url: url,
80 | name: name,
81 | extension: extension,
82 | timestamp: timestamp,
83 | token: httpRequest.responseText
84 | });
85 | once = true;
86 | }
87 | };
88 | });
89 | });
90 |
91 | getSingleElementByClassName('hs_updatePlacementSubtitle').addEventListener('click', function () {
92 | hsp.updatePlacementSubtitle(getSingleElementByClassName('hs_updatePlacementSubtitleInput').value);
93 | });
94 |
95 | getSingleElementByClassName('hs_getTwitterAccounts').addEventListener('click', function () {
96 | hsp.getTwitterAccounts(function (data) {
97 | var httpRequest = new XMLHttpRequest();
98 | httpRequest.open(
99 | 'GET',
100 | window.location.origin + '/twitterAccounts?accountIds=' + data.join()
101 | );
102 | httpRequest.setRequestHeader('secretKey', 'super_secret')
103 | httpRequest.send();
104 | httpRequest.onreadystatechange = function() {
105 | replaceTextInClass('hs_getTwitterAccountsOutput', httpRequest.responseText);
106 | }
107 | });
108 | });
109 |
110 | getSingleElementByClassName('hs_retweet').addEventListener('click', function () {
111 | hsp.getTwitterAccounts(function (data) {
112 | var splitURL = getSingleElementByClassName('hs_retweetInput').value.split('/');
113 | var id = splitURL[splitURL.length - 1];
114 | hsp.retweet(id, data[0]);
115 | });
116 | });
117 |
118 | getSingleElementByClassName('hs_showFollowDialog').addEventListener('click', function () {
119 | hsp.showFollowDialog(getSingleElementByClassName('hs_showFollowDialogName').value, true);
120 | });
121 |
122 | getSingleElementByClassName('hs_logout').addEventListener('click', signOut);
123 |
124 | getSingleElementByClassName('hs_showGeolocation').addEventListener('click', function () {
125 | getGeolocation();
126 | });
127 | }
128 |
129 | function loadTopBars() {
130 | var topBarControls = document.getElementsByClassName('hs_topBarControlsBtn');
131 |
132 | Array.prototype.forEach.call(topBarControls, function(topBarControl) {
133 | topBarControl.addEventListener('click', function (event) {
134 | var topBarDropdowns = document.getElementsByClassName('hs_topBarDropdown');
135 | for (var i = 0; i < topBarDropdowns.length; i++) {
136 | if (event.currentTarget.getAttribute('data-dropdown') === topBarDropdowns[i].getAttribute('data-dropdown')) {
137 | if (topBarDropdowns[i].style.display === 'none') {
138 | topBarDropdowns[i].style.display = 'block';
139 | event.currentTarget.classList.add('active');
140 | } else {
141 | topBarDropdowns[i].style.display = 'none';
142 | event.currentTarget.classList.remove('active');
143 | }
144 | } else {
145 | // remove active on all dropdown buttons except the one that was clicked
146 | var topBarBtns = document.getElementsByClassName('hs_topBarControlsBtn');
147 | for (var p = 0; p < topBarBtns.length; p++) {
148 | if (topBarBtns[p].getAttribute('data-dropdown') !== event.currentTarget.getAttribute('data-dropdown')) {
149 | topBarBtns[p].classList.remove('active');
150 | }
151 | }
152 | // close all dropdowns except the one that was clicked
153 | topBarDropdowns[i].style.display = 'none';
154 | }
155 | }
156 | });
157 | });
158 | }
159 |
160 | // for our purposes this is the same thing as jQuery's $(document).ready(...)
161 | document.addEventListener('DOMContentLoaded', function () {
162 | // intializes the Hootsuite JS SDK
163 | hsp.init({
164 | useTheme: true
165 | });
166 |
167 | loadTopBars();
168 | bindApiButtons();
169 | googleAuthInit();
170 |
171 | var socket = io();
172 |
173 | socket.on('stream update', function (msg) {
174 | // inserts incoming messages by copying previous messages and changing contents
175 | var parent = getSingleElementByClassName('hs_messages');
176 | var child = parent.insertBefore(getSingleElementByClassName('hs_message').cloneNode(true), parent.firstChild);
177 | child.getElementsByClassName('hs_postBody')[0].textContent = msg;
178 | });
179 |
180 | hsp.bind('refresh', function () {
181 | // You can do a complex refresh here,
182 | // for example only reload certain parts of your app.
183 | // In this example we'll resend the fake messages that get sent on connection
184 |
185 | var messages = document.getElementsByClassName('hs_message');
186 | // removes all messages except for one to use it as a template for adding more
187 | var initialLength = messages.length;
188 | for (var i = 0; i < initialLength-1; i++) {
189 | messages[0].remove();
190 | }
191 |
192 | // tells the server to re-serve the fake stream updates
193 | socket.emit('restart');
194 | });
195 | });
196 |
--------------------------------------------------------------------------------