'use strict'; oml.ui.peersPanel = function() { var ui = oml.user.ui, preferences = oml.user.preferences, buttons = [ {id: 'send', title: Ox._('Send')}, {id: 'cancel', title: Ox._('Cancel')}, {id: 'accept', title: Ox._('Accept')}, {id: 'reject', title: Ox._('Reject')}, {id: 'remove', title: Ox._('Remove...')} ], folders = [ { id: 'peers', title: Ox._('Your Peers'), itemTitle: Ox._('No peers'), text: Ox._('You don\'t have any peers yet.') }, { id: 'received', title: Ox._('Received Requests'), itemTitle: Ox._('No pending requests'), text: Ox._('You haven\'t received any peering requests.') }, { id: 'sent', title: Ox._('Sent Requests'), itemTitle: Ox._('No pending requests'), text: Ox._('You haven\'t sent any peering requests.') }, { id: 'others', title: Ox._('Other Users'), itemTitle: Ox._('No other users'), text: Ox._('There are no other users in your extended network.') } ], peerIds = [], users, // FIXME: UGLY $users = Ox.Element().css({ background: { oxlight: 'rgb(240, 240, 240)', oxmedium: 'rgb(144, 144, 145)', oxdark: 'rgb(16, 16, 16)' }[Ox.Theme()], overflowX: 'hidden' }), $lists = [ renderSectionList({id: 'invitations'}).appendTo($users) ], $folders = folders.map(function(folder) { return Ox.CollapsePanel({ collapsed: false, title: folder.title }) .css({width: '256px'}) .appendTo($users); }), $user = Ox.Element(), that = Ox.SplitPanel({ elements: [ {element: $users, size: 256}, {element: $user} ], orientation: 'horizontal' }) .bindEvent({ oml_page: function(data) { if (data.value == 'peers') { oml.bindEvent({peering: peering}); } else if (data.previousValue == 'peers') { oml.unbindEvent({peering: peering}); } } }); var peering = Ox.throttle(function() { updateUsers(); }, 1000); if (oml.user.ui.page == 'peers') { oml.bindEvent({peering: peering}); } function renderSectionList(folder) { var $list = Ox.TableList({ columns: [ { format: function() { return $('') .attr({ src: Ox.UI.getImageURL('symbolUser') }) .css({ width: '10px', height: '10px', margin: '2px -2px 2px 0', opacity: folder.id == 'invitations' ? 1 : 0.5 }) }, id: 'id', visible: true, width: 16 }, { format: function(value) { return folder.id == 'invitations' ? value : '' + value + '' }, id: 'title', visible: true, width: 240 - Ox.SCROLLBAR_SIZE } ], items: [ { id: folder.id, title: folder.id == 'invitations' ? Ox._('Invitations') : Ox.getObjectById(folders, folder.id).itemTitle }, ], sort: [{key: 'id', operator: '+'}], unique: 'id' }) .css({height: '16px'}) .bindEvent({ select: function(data) { if (data.ids.length) { selectItem($list); renderUser({section: data.ids[0]}); } else { renderUser(); } } }); $list.$body.css({ height: '16px', overflowX: 'hidden' }); // FIXME! return $list; } function renderUser(user) { var $user = Ox.Element(), $form = Ox.Element() .addClass('OxSelectable OxTextPage') .css({margin: '16px'}) .appendTo($user), $warning = Ox.Element() .css({margin: '32px 16px'}) // FIXME: WTF! .appendTo($user), $id, $buttons = [], $message, $nickname, folder; if (user && user.section) { folder = Ox.getObjectById(folders, user.section); } if (folder) { $('
') .html(folder.text) .appendTo($form); } else if (user) { if (user.section == 'invitations') { $('
') .html( 'To invite someone, just send her your public key – that\'s all she\'ll need to add you as a peer. ' + 'Along with that, you may want to send a download link for Open Media Library, in case she doesn\'t have it yet.' ) .appendTo($form); Ox.Input({ readonly: true, label: Ox._('Your Public Key'), labelWidth: 128, style: 'squared', value: oml.user.id, width: 480 }) .css({ marginTop: '8px' }) .appendTo($form); Ox.Input({ readonly: true, label: Ox._('Download Link'), labelWidth: 128, style: 'squared', value: 'https://openmedialibrary.com/#download', width: 480 }) .css({ marginTop: '8px' }) .appendTo($form); $('
') .html( 'If someone invites you, or if you know another user\'s public key, you can add her here.' ) .css({ margin: '32px 0 8px 0' }) .appendTo($form); } $nickname = Ox.Input({ label: Ox._('Nickname'), labelWidth: 128, style: 'squared', value: user.nickname, width: 480 }) .bindEvent({ change: function(data) { if (user.section != 'invitations') { oml.api.editUser({ id: user.id, nickname: data.value }, function(result) { oml.renameUser(result.data) // FIXME: ugly Ox.forEach($lists, function($list) { var selected = $list.options('selected'); if (selected.length) { $list.value(user.id, 'name', result.data.name); return false; } }); }); } } }) .appendTo($form); if (user.section == 'invitations') { $id = Ox.Input({ label: Ox._('Public Key'), labelWidth: 128, style: 'squared', width: 480 }) .bindEvent({ change: function(data) { var isOwn = data.value == oml.user.id, isPeer = Ox.contains(peerIds, data.value), isValid = oml.validatePublicKey(data.value), peer = Ox.getObjectById(users, data.value), readonly = isOwn || isPeer || !isValid; $buttons[0].options({ readonly: readonly }); if (data.value && readonly) { $warning.html( isOwn ? 'That\'s your own public key.' : isPeer ? 'That\'s ' + Ox.encodeHTMLEntities(peer.nickname || peer.username) + ' - you\'re already peered.' : 'That\'s not a valid key.' ) } else { $warning.empty(); if (data.value) { user.id = data.value; } } } }) .css({ marginTop: '8px' }) .appendTo($form); } else { Ox.Input({ readonly: true, label: Ox._('Username'), labelWidth: 128, style: 'squared', value: user.username, width: 480 }) .css({ marginTop: '8px' }) .appendTo($form); Ox.Input({ readonly: true, label: Ox._('Public Key'), labelWidth: 128, style: 'squared', value: user.id, width: 480 }) .css({ marginTop: '8px' }) .appendTo($form); Ox.Input({ readonly: true, label: Ox._('Contact'), labelWidth: 128, style: 'squared', value: user.contact || '', width: 480 }) .css({ marginTop: '8px' }) .appendTo($form); if (user.pending) { Ox.Input({ readonly: true, label: Ox._('Message'), labelWidth: 128, style: 'squared', value: user.message || '', width: 480 }) .css({ marginTop: '8px' }) .appendTo($form); } } Ox.Label({ textAlign: 'center', style: 'squared', title: user.peered ? Ox._('Remove Peer') : user.pending == 'received' ? Ox._('Accept Peering Request') : user.pending == 'sent' ? Ox._('Cancel Peering Request') : Ox._('Send Peering Request'), width: 480 }) .css({ marginTop: '32px' }) .appendTo($form); $message = Ox.Input({ label: Ox._('Message'), labelWidth: 128, placeholder: Ox._('none'), style: 'squared', width: 480 }) .css({ margin: '8px 0' }) .appendTo($form); $buttons = ( user.peered ? ['remove'] : user.pending == 'received' ? ['accept', 'reject'] : user.pending == 'sent' ? ['cancel'] : ['send'] ).map(function(id, index) { return Ox.Button({ style: 'squared', title: Ox.getObjectById(buttons, id).title }) .css({ float: 'right', marginRight: index ? '8px' : 0 }) .bindEvent({ click: function() { var data = { id: user.id, message: $message.value() }; if (id == 'send') { data.nickname = $nickname.value(); oml.api.requestPeering(data, function(result) { Ox.Request.clearCache(); updateUsers(function() { selectUser(user.id); }); }); } else if (id == 'cancel') { oml.api.cancelPeering(data, function(result) { Ox.Request.clearCache(); updateUsers(function() { selectUser(user.id); }); }); } else if (id == 'accept') { oml.api.acceptPeering(data, function(result) { Ox.Request.clearCache(); updateUsers(function() { selectUser(user.id); }); }); } else if (id == 'reject') { oml.api.rejectPeering(data, function(result) { Ox.Request.clearCache(); updateUsers(function() { selectUser(user.id); }); }); } else if (id == 'remove') { oml.ui.confirmDialog({ buttons: [ Ox.Button({ title: Ox._('No, Keep Peer') }), Ox.Button({ title: Ox._('Yes, Remove Peer') }) ], title: Ox._('Remove Peering'), content: Ox._('Are you sure you want to remove this peer?') }, function() { oml.api.removePeering(data, function(result) { Ox.Request.clearCache(); updateUsers(function() { selectUser(user.id); }); }); }); } } }) .appendTo($form); }); } that.replaceElement(1, $user); } function renderUserList(folder) { var $list = Ox.TableList({ columns: [ { format: function(value, data) { return oml.ui.statusIcon(data) .css({ margin: '2px 3px 3px 0' }); }, id: 'online', visible: true, width: 16 }, { format: function(value) { return Ox.encodeHTMLEntities(value); }, id: 'name', visible: true, width: 240 } ], items: folder.items, keys: ['local'], max: 1, sort: [{key: 'index', operator: '+'}], sortable: folder.id == 'peers', unique: 'id' }) .css({ height: folder.items.length * 16 + 'px' }) .bindEvent({ move: function(data) { oml.api.sortUsers({ ids: data.ids }, function(result) { oml.$ui.folders.updateElement(); }); }, select: function(data) { if (data.ids.length) { selectItem($list); renderUser(Ox.getObjectById(users, data.ids[0])); } else { renderUser(); } } }); return $list; } function selectUser(id) { $lists.forEach(function($list) { var item = $list.options('items').filter(function(item) { return item.id == id; })[0]; if (item) { selectItem($list, id); } }); } function selectItem($list, id) { $lists.forEach(function($element) { if ($element == $list) { $element.gainFocus(); } else { $element.options({selected: []}); } }); if (id) { $list.options({selected: [id]}); renderUser(Ox.getObjectById(users, id) || {section: id}); } } function updateUsers(callback) { Ox.Request.clearCache('getUsers'); oml.api.getUsers(function(result) { users = result.data.users; peerIds = users.filter(function(user) { return user.peered; }).map(function(user) { return user.id; }); folders.forEach(function(folder) { folder.items = []; }); users.forEach(function(user, index) { var id = user.peered ? 'peers' : (user.pending || 'others'); Ox.getObjectById(folders, id).items.push( Ox.extend({ index: index, nickname: '', username: '' }, user) ); }); $lists.splice(1).forEach(function(folder) { folder.remove(); }); folders.forEach(function(folder, index) { $lists.push( ( folder.items.length ? renderUserList(folder) : renderSectionList(folder) ) .appendTo($folders[index].$content) ); }); $lists.forEach(function($list, index) { $list.bindEvent({ selectnext: function() { var $list; if (index < $lists.length - 1) { $list = $lists[index + 1]; selectItem($list, $list.options('items')[0].id); } }, selectprevious: function() { var $list; if (index) { $list = $lists[index - 1]; selectItem($list, Ox.last($list.options('items')).id) } } }) }); callback && callback(); }); } that.updateElement = function() { updateUsers(function() { selectItem($lists[0], 'invitations'); renderUser({section: 'invitations'}); }); return that; }; return that.updateElement(); };