1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-20 09:18:48 +02:00
phorge-phorge/webroot/rsrc/js/application/conpherence/behavior-menu.js
Bob Trahan 42c1e39ae6 Conpherence - mobilized
Summary:
makes conpherence switch to a liquid layout once we go from desktop -> less than that. When we make the switch conpherence updates to show a few more "Widgets" -- the list of conpherences and the current conversation -- and the switcher starts working. As you transition from device to device you are automagically forced to have the "conversation" widget toggled on initial change to smaller than desktop and then file widget once you get back to desktop.

Generally looks good when I make my browser small. Does not look as good on iOS simulator - in particular there seems to be a weird visual artifact on the "add people" widget that is present in all tokenizers, and the pontificate UI on mobile could use some work. ref T2399.

Test Plan: played in Safari, FF, Chrome and iOS Simulator. The first 3 were all pretty spiffy, and otherwise iOS add people widget was a bit ugly.

Reviewers: epriestley, chad

Reviewed By: epriestley

CC: aran, Korvin, AnhNhan

Maniphest Tasks: T2399

Differential Revision: https://secure.phabricator.com/D5674
2013-04-15 16:27:41 -07:00

314 lines
8.3 KiB
JavaScript

/**
* @provides javelin-behavior-conpherence-menu
* @requires javelin-behavior
* javelin-dom
* javelin-util
* javelin-request
* javelin-stratcom
* javelin-workflow
* javelin-behavior-device
* javelin-history
*/
JX.behavior('conpherence-menu', function(config) {
var thread = {
selected: null,
node: null,
visible: null
};
function selectthreadid(id, updatePageData) {
var threads = JX.DOM.scry(document.body, 'a', 'conpherence-menu-click');
for (var ii = 0; ii < threads.length; ii++) {
var data = JX.Stratcom.getData(threads[ii]);
if (data.id == id) {
selectthread(threads[ii], updatePageData);
return;
}
}
}
function selectthread(node, updatePageData) {
if (thread.node) {
JX.DOM.alterClass(thread.node, 'conpherence-selected', false);
// keep the unread-count hidden still. big TODO once we ajax in updates
// to threads to make this work right and move threads between read /
// unread
}
JX.DOM.alterClass(node, 'conpherence-selected', true);
JX.DOM.alterClass(node, 'hide-unread-count', true);
thread.node = node;
var data = JX.Stratcom.getData(node);
thread.selected = data.id;
if (updatePageData) {
updatepagedata(data);
}
redrawthread();
}
function updatepagedata(data) {
var uri_suffix = thread.selected + '/';
if (data.use_base_uri) {
uri_suffix = '';
}
JX.History.replace(config.base_uri + uri_suffix);
if (data.title) {
document.title = data.title;
}
}
JX.Stratcom.listen(
'conpherence-update-page-data',
null,
function (e) {
updatepagedata(e.getData());
}
);
JX.Stratcom.listen(
'conpherence-selectthread',
null,
function (e) {
var node = JX.$(e.getData().id);
selectthread(node);
}
);
function redrawthread() {
if (!thread.node) {
return;
}
if (thread.visible == thread.selected) {
return;
}
var data = JX.Stratcom.getData(thread.node);
if (thread.visible !== null || !config.hasThread) {
var uri = config.base_uri + data.id + '/';
new JX.Workflow(uri, {})
.setHandler(onresponse)
.start();
} else {
didredrawthread();
}
if (thread.visible !== null || !config.hasWidgets) {
var widget_uri = config.base_uri + 'widget/' + data.id + '/';
new JX.Workflow(widget_uri, {})
.setHandler(onwidgetresponse)
.start();
} else {
updatetoggledwidget();
}
thread.visible = thread.selected;
}
function onwidgetresponse(response) {
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
var widgetsRoot = JX.DOM.find(root, 'div', 'conpherence-widget-pane');
JX.DOM.setContent(widgetsRoot, JX.$H(response.widgets));
updatetoggledwidget();
}
function updatetoggledwidget() {
var device = JX.Device.getDevice();
if (device != 'desktop') {
if (config.role == 'list') {
JX.Stratcom.invoke(
'conpherence-toggle-widget',
null,
{
widget : 'conpherence-menu-pane'
}
);
} else {
JX.Stratcom.invoke(
'conpherence-toggle-widget',
null,
{
widget : 'conpherence-message-pane'
}
);
}
} else {
JX.Stratcom.invoke(
'conpherence-toggle-widget',
null,
{
widget : 'widgets-files'
}
);
}
}
function onresponse(response) {
var header = JX.$H(response.header);
var messages = JX.$H(response.messages);
var form = JX.$H(response.form);
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
var headerRoot = JX.DOM.find(root, 'div', 'conpherence-header-pane');
var messagesRoot = JX.DOM.find(root, 'div', 'conpherence-messages');
var formRoot = JX.DOM.find(root, 'div', 'conpherence-form');
JX.DOM.setContent(headerRoot, header);
JX.DOM.setContent(messagesRoot, messages);
JX.DOM.setContent(formRoot, form);
didredrawthread();
}
function didredrawthread() {
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
var messagesRoot = JX.DOM.find(root, 'div', 'conpherence-messages');
messagesRoot.scrollTop = messagesRoot.scrollHeight;
}
JX.Stratcom.listen(
null,
'conpherence-redraw-thread',
function (e) {
didredrawthread();
}
);
JX.Stratcom.listen(
'click',
'conpherence-menu-click',
function(e) {
if (!e.isNormalClick()) {
return;
}
// On devices, just follow the link normally.
if (JX.Device.getDevice() != 'desktop') {
return;
}
e.kill();
selectthread(e.getNode('conpherence-menu-click'), true);
});
JX.Stratcom.listen('click', 'conpherence-edit-metadata', function (e) {
e.kill();
var root = e.getNode('conpherence-layout');
var form = JX.DOM.find(root, 'form', 'conpherence-pontificate');
var data = e.getNodeData('conpherence-edit-metadata');
var header = JX.DOM.find(root, 'div', 'conpherence-header-pane');
var messages = JX.DOM.find(root, 'div', 'conpherence-messages');
new JX.Workflow.newFromForm(form, data)
.setHandler(JX.bind(this, function(r) {
JX.DOM.appendContent(messages, JX.$H(r.transactions));
messages.scrollTop = messages.scrollHeight;
JX.DOM.setContent(
header,
JX.$H(r.header)
);
try {
// update the menu entry
JX.DOM.replace(
JX.$(r.conpherence_phid + '-nav-item'),
JX.$H(r.nav_item)
);
JX.Stratcom.invoke(
'conpherence-selectthread',
null,
{ id : r.conpherence_phid + '-nav-item' }
);
} catch (ex) {
// Ignore; this view may not have a menu.
}
}))
.start();
});
JX.Stratcom.listen('click', 'show-older-messages', function(e) {
e.kill();
var last_offset = e.getNodeData('show-older-messages').offset;
var conf_id = e.getNodeData('show-older-messages').ID;
JX.DOM.remove(e.getNode('show-older-messages'));
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
var messages_root = JX.DOM.find(root, 'div', 'conpherence-messages');
new JX.Request(config.base_uri + conf_id + '/', function(r) {
var messages = JX.$H(r.messages);
JX.DOM.prependContent(messages_root,
JX.$H(messages));
}).setData({ offset: last_offset+1 }).send();
});
// On mobile, we just show a thread list, so we don't want to automatically
// select or load any threads. On Desktop, we automatically select the first
// thread.
var old_device = null;
function ondevicechange() {
var new_device = JX.Device.getDevice();
if (new_device === old_device) {
return;
}
var update_toggled_widget =
new_device == 'desktop' || old_device == 'desktop';
old_device = new_device;
if (thread.visible !== null && update_toggled_widget) {
updatetoggledwidget();
}
if (!config.hasThreadList) {
loadthreads();
} else {
didloadthreads();
}
}
JX.Stratcom.listen('phabricator-device-change', null, ondevicechange);
ondevicechange();
function loadthreads() {
var uri = config.base_uri + 'thread/' + config.selectedID + '/';
new JX.Workflow(uri)
.setHandler(onthreadresponse)
.start();
}
function onthreadresponse(r) {
var layout = JX.$(config.layoutID);
var menu = JX.DOM.find(layout, 'div', 'conpherence-menu-pane');
JX.DOM.setContent(menu, JX.$H(r));
config.selectedID && selectthreadid(config.selectedID);
}
function didloadthreads() {
// If there's no thread selected yet, select the current thread or the
// first thread.
if (!thread.selected) {
if (config.selectedID) {
selectthreadid(config.selectedID, true);
} else {
var layout = JX.$(config.layoutID);
var threads = JX.DOM.scry(layout, 'a', 'conpherence-menu-click');
if (threads.length) {
selectthread(threads[0]);
} else {
var nothreads = JX.DOM.find(layout, 'div', 'conpherence-no-threads');
nothreads.style.display = 'block';
}
}
}
redrawthread();
}
});