',
className: 'marker-cluster' + c,
iconSize: new L.Point(40, 40)
});
};
};
var replay = L.markerClusterGroup({
showCoverageOnHover: false,
disableClusteringAtZoom: 16,
singleMarkerMode: true,
iconCreateFunction: iconCreate('replay')
}).addTo(map);
var live = L.markerClusterGroup({
showCoverageOnHover: false,
disableClusteringAtZoom: 16,
singleMarkerMode: true,
iconCreateFunction: iconCreate('live')
}).addTo(map);
var refreshMap = function () {
//if (e && e.hard === false) return; // zoom change case
var mapBounds = map.getBounds();
clearXHR();
if (mapBounds._northEast.lat == mapBounds._southWest.lat && mapBounds._northEast.lng == mapBounds._southWest.lng)
console.warn('Map is out of mind');
Api('mapGeoBroadcastFeed', {
"include_replay": true,
"p1_lat": mapBounds._northEast.lat,
"p1_lng": mapBounds._northEast.lng,
"p2_lat": mapBounds._southWest.lat,
"p2_lng": mapBounds._southWest.lng
}, function (r) {
var openLL; // for preventing of closing opened popup
live.eachLayer(function (layer) {
if (layer.getPopup()._isOpen)
openLL = layer.getLatLng();
else
live.removeLayer(layer);
});
replay.eachLayer(function (layer) {
if (layer.getPopup()._isOpen)
openLL = layer.getLatLng();
else
replay.removeLayer(layer);
});
// adding markers
for (var i = 0; i < r.length; i++) {
var stream = r[i];
var marker = L.marker(new L.LatLng(stream.ip_lat, stream.ip_lng), {title: stream.status || stream.user_display_name});
if (!marker.getLatLng().equals(openLL)) {
var description = getDescription(stream);
marker.bindPopup(description);
marker.on('popupopen', getM3U.bind(null, stream.id, $(description)));
marker.on('popupopen', Api.bind(null, 'getBroadcasts', {
broadcast_ids: [stream.id],
only_public_publish: true
}, function (info) {
$('.leaflet-popup-content .watching').text(info[0].n_watching + info[0].n_web_watching);
}));
marker.on('popupopen', function (e) {
var img = $(e.popup._content).find('img');
img.attr('src', img.attr('lazysrc'));
img.removeAttr('lazysrc');
});
(stream.state == 'RUNNING' ? live : replay).addLayer(marker);
}
}
if (splitPanelEnabled)
refreshList(mapList)(r);
});
var mapCenter = map.getCenter();
history.replaceState({
section: 'Map',
param: mapCenter.lat + ',' + mapCenter.lng
}, 'Map', '/Map/' + mapCenter.lat + ',' + mapCenter.lng);
};
if (!history.state.param) {
if (navigator.geolocation)
navigator.geolocation.getCurrentPosition(function (position) {
map.setView([position.coords.latitude, position.coords.longitude], 11);
refreshMap();
}, function(){
refreshMap();
});
}
map.on('moveend', refreshMap);
lazyLoad(mapList);
},
ApiTest: function () {
var submitButton = $('Submit');
submitButton.click(function () {
try {
$('#ApiTest form').submit();
var method = $('#method').val().trim();
if (method == '')
throw Error('Method is empty');
var params = $('#params').val().trim();
if (params == '') {
params = '{}';
$('#params').text(params);
}
Api(method, JSON.parse(params), function (response) {
$('#response').html(JSON.stringify(response, null, 4));
}, function (error) {
$('#response').text(error);
});
} catch (e) {
$('#response').text(e.toString());
}
});
$('#right').append(
$('').append(
'' +
'Some documentation can be found in docs by @cjhbtn' +
'
Method
' +
'
Parameters
'
, submitButton, '
Response is also displayed in the browser console, if [Debug mode] is checked')
);
},
Top: function () {
var featured = $('');
var ranked = $('');
var langDt = $(languageSelect);
langDt.find(":contains(" + (navigator.language || navigator.userLanguage || "en").substr(0, 2) + ")").attr("selected", "selected");
var button = $('Refresh').click(function () {
Api('rankedBroadcastFeed', {languages: [langDt.find('.lang').val()]}, refreshList(ranked, '
').click(function () {
Progress.start();
historyLoad('');
$(this).remove();
}));
if (broadcast.read_only)
switch (broadcast.type) {
case "StreamTypeOnlyFriends":
chat.append('
*** This chat is for friends only!
');
break;
default:
chat.append('
*** Chatroom is full! You in read only mode!
');
}
// Chat reading & posting
if (NODEJS) {
var openSocket = function (failures) {
ws = new WebSocket(broadcast.endpoint.replace('https:', 'wss:').replace('http:', 'ws:') + '/chatapi/v1/chatnow');
ws.on('open', function open() {
// AUTH
ws.send(JSON.stringify({
payload: JSON.stringify({access_token: broadcast.access_token}),
kind: MESSAGE_KIND.AUTH
}));
// JOIN
ws.send(JSON.stringify({
payload: JSON.stringify({
body: JSON.stringify({
room: broadcast.room_id
}),
kind: MESSAGE_KIND.CHAT
}),
kind: MESSAGE_KIND.CONTROL
}));
});
ws.on('ping', function (data) {
ws.pong(data, {masked: false, binary: true});
});
ws.on('message', function (data) {
processWSmessage(JSON.parse(data), chat);
});
ws.on('close', function (code) {
ws.close();
switch (code) {
case 403: // 403=forbidden
console.log('Forbidden');
break;
case 1006: // 1006=timeout
if (failures < 4) {
setTimeout(openSocket.bind(null, failures + 1), 100);
console.log('reconnect ' + failures);
}
break;
case 1000: // 1000=broadcast ended
break;
default:
console.log('websocket closed, code: ', code);
}
});
};
var sendMessage = function (customtype) {
var timestamp = Math.floor(Date.now() / 1000);
var ntpstamp = parseInt((timestamp + 2208988800).toString(16) + '00000000', 16); // timestamp in NTP format
var message = {
body: textBox.val(),
//display_name: 'OpenPeriscope',
//initials: '',
//"moderationReportType": 0,
//"moderationType": 0,
//v: 2
profileImageURL: loginTwitter.user.profile_image_urls[0].url,
timestamp: timestamp,
remoteID: loginTwitter.user.id,
username: loginTwitter.user.username,
uuid: "OpenPeriscope" + (Math.random()+'').replace('.',''),
signer_token: broadcast.signer_token,
participant_index: broadcast.participant_index,
type: customtype || 1, // "text message"
ntpForBroadcasterFrame: ntpstamp,
ntpForLiveFrame: ntpstamp
};
ws.send(JSON.stringify({
payload: JSON.stringify({
body: JSON.stringify(message),
room: broadcast.room_id,
timestamp: timestamp
//sender
}),
kind: MESSAGE_KIND.CHAT
}), function (error) {
textBox.val('');
if (error)
console.log('message not sent', error);
else
renderMessages(message, chat);
});
};
if (broadcast.endpoint)
openSocket(0);
} else {
if (broadcast.endpoint) {
var cursor = null;
clearInterval(chat_interval);
var prevMessages = [];
chat_interval = setInterval(function () {
GM_xmlhttpRequest({
method: 'POST',
url: broadcast.endpoint + '/chatapi/v1/history',
data: JSON.stringify({
access_token: broadcast.access_token,
cursor: cursor || (Date.now() - 30000) * 1000000 + '',
limit: 1000
}),
onload: function (history) {
if (history.status == 200) {
history = JSON.parse(history.responseText);
for (var i in history.messages) {
var contains = false;
for (var j = 0; j < prevMessages.length && !contains; j++) // if prevMessages contains meesage
if (prevMessages[j].signature == history.messages[i].signature)
contains = true;
if (!contains)
processWSmessage(history.messages[i], chat);
}
prevMessages = history.messages;
cursor = history.cursor;
}
}
});
}, 1000);
}
var sendMessage = function () {
alert('Sending messages available only in standalone version');
};
}
$('#sendMessage').off().click(sendMessage.bind(null, null));
$('#sendLike').off().click(sendMessage.bind(null, 2));
textBox.off().keypress(function (e) {
if (e.which == 13) {
sendMessage();
return false;
}
});
}, function (error) {
title.append('' + error + '');
});
});
$('#right').append(
$('').append(
broadcast_id, playButton, title, ' ', userlist, chat, $('
').append(
'',
'\u2665Send', $('').append(textBox)
)
)
);
},
User: function () {
var resultUser = $('');
var showButton = $('OK').click(function () {
resultUser.empty();
var id = $('#user_id').val().trim();
Api('user', {
user_id: id
}, function (response) {
resultUser.prepend(getUserDescription(response.user));
FollowersSpoiler.append(' (' + response.user.n_followers + ')');
FollowingSpoiler.append(' (' + response.user.n_following + ')');
});
Api('userBroadcasts', {
user_id: id,
all: true
}, function (broadcasts) {
refreshList($('#userBroadcasts'))(broadcasts);
BroadcastsSpoiler.append(' (' + broadcasts.length + ')').click();
});
var BroadcastsSpoiler = $('
Broadcasts
');
var FollowersSpoiler = $('
Followers
').on("jq-spoiler-visible", function() {
var followersDiv = $('#userFollowers');
if (!followersDiv.html())
Api('followers', {
user_id: id
}, function (followers) {
if (followers.length)
for (var i in followers)
followersDiv.append($('').append(getUserDescription(followers[i])));
else
followersDiv.html('No results');
});
});
var FollowingSpoiler = $('
Following
').on("jq-spoiler-visible", function() {
var followingDiv = $('#userFollowing');
if (!followingDiv.html())
Api('following', {
user_id: id
}, function (following) {
if (following.length)
for (var i in following)
followingDiv.append($('').append(getUserDescription(following[i])));
else
followingDiv.html('No results');
});
});
resultUser.append(BroadcastsSpoiler, '',
FollowersSpoiler, '',
FollowingSpoiler, '');
if (id == loginTwitter.user.id) { // Blocked list
var BlockedSpoiler = $('
Blocked
').on("jq-spoiler-visible", function() {
var blockedDiv = $('#userBlocked');
if (!blockedDiv.html())
Api('block/users', {}, function (blocked) {
if (blocked.length)
for (var i in blocked) {
blocked[i].is_blocked = true;
blockedDiv.append($('').append(getUserDescription(blocked[i])));
}
else
blockedDiv.html('No results');
});
});
resultUser.append(BlockedSpoiler, '');
}
$(".spoiler").spoiler({ triggerEvents: true });
});
$('#right').append($('
id:
').append(showButton, '
', resultUser));
},
People: function () {
var refreshButton = $('Refresh').click(function () {
Api('suggestedPeople', {
languages: [$('#People .lang').val()]
}, function (response) {
var result = $('#resultPeople');
result.empty();
if (response.featured && response.featured.length) {
result.append('
Featured
');
for (var i in response.featured)
result.append($('').append(getUserDescription(response.featured[i])));
}
result.append('
Popular
');
for (i in response.popular)
result.append($('').append(getUserDescription(response.popular[i])));
Api('suggestedPeople', {}, function (response) {
if (response.hearted && response.hearted.length) {
result.append('
Hearted
');
for (var i in response.hearted)
result.append($('').append(getUserDescription(response.hearted[i])));
}
});
});
});
var searchPeople = function () {
Api('userSearch', {
search: $('#search').val()
}, function (response) {
var result = $('#resultPeople');
result.html('
Search results
');
var found_exact = false;
for (var i in response) {
result.append($('').append(getUserDescription(response[i])));
if (!found_exact && response[i].username.toUpperCase() == $('#search').val().toUpperCase())
found_exact=true;
}
if (!found_exact)
Api('user', {
username: $('#search').val()
}, function (user) {
result.prepend($('').append(getUserDescription(user.user)));
});
});
};
var searchButton = $('Search').click(searchPeople);
$('#right').append($('').append(languageSelect, refreshButton, $('').keypress(function (e) {
if (e.which == 13) {
searchPeople();
return false;
}
}), searchButton, ''));
$("#People .lang").find(":contains(" + (navigator.language || navigator.userLanguage || "en").substr(0, 2) + ")").attr("selected", "selected");
refreshButton.click();
},
Edit: function () {
var button = $('Save').click(function () {
var uname = $('#uname').val();
if (uname != loginTwitter.user.username) {
Api('verifyUsername', {
username: uname,
display_name: loginTwitter.user.display_name
}, function () {
loginTwitter.user.username = uname;
localStorage.setItem('loginTwitter', JSON.stringify(loginTwitter));
});
}
var description = $('#description').val();
if (description != loginTwitter.user.description)
Api('updateDescription', {
description: description
}, function () {
loginTwitter.user.description = description;
localStorage.setItem('loginTwitter', JSON.stringify(loginTwitter));
});
var dname = $('#dname').val();
if (dname != loginTwitter.user.display_name) {
Api('updateDisplayName', {
display_name: dname
}, function () {
loginTwitter.user.display_name = dname;
localStorage.setItem('loginTwitter', JSON.stringify(loginTwitter));
});
}
if ($('input[name="image"]').val())
form.submit();
});
var form = $('');
var hiddenIframe = $('').on('load',refreshProfile);
var settingsContainer = $('');
var tempSettings;
Api('getSettings', {}, function (settingsResponse) {
loginTwitter.settings = settingsResponse;
localStorage.setItem('loginTwitter', JSON.stringify(loginTwitter));
tempSettings = settingsResponse;
for (var setting in loginTwitter.settings) {
settingsContainer.append($(' ').click(function (setting) {
return function (e) {
tempSettings[setting] = e.target.checked;
}
}(setting)));
}
});
var buttonSettings = $('Save').click(function () {
Api('setSettings', {
settings: tempSettings
}, function (r) {
if (r.success){
loginTwitter.settings = tempSettings;
localStorage.setItem('loginTwitter', JSON.stringify(loginTwitter));
} else
alert('Settings not saved!');
});
});
var notifications = $('').click(function (e) {
setSet('followingNotifications', e.target.checked);
if (e.target.checked)
Notifications.start();
else
Notifications.stop();
});
var notifications_interval = $('').change(function () {
setSet('followingInterval', this.value);
Notifications.stop();
Notifications.start();
});
if (NODEJS) {
var autoDownload = $('').click(function (e) {
setSet('automaticDownload', e.target.checked);
if (e.target.checked)
Notifications.start();
else
Notifications.stop();
});
var download_private = $('').click(function (e) {
setSet('privateDownload', e.target.checked);
});
var download_following = $('').click(function (e) {
setSet('followingDownload', e.target.checked);
});
var download_shared = $('').click(function (e) {
setSet('sharedDownload', e.target.checked);
});
var current_download_path = $('
' + settings.downloadPath + '
');
var download_path = $('').append($('').change(function () {
var path = this.files[0].path.replace(/[\\\/][^\\\/]+$/,'');
setSet('downloadPath', path);
current_download_path.text(path);
}));
var download_format = $('').append($('').change(function () {
setSet('downloadFormat', $(this).val());
}));
}
$('#right').append($('').append(
'