mirror of
https://github.com/zulip/zulip.git
synced 2025-11-02 04:53:36 +00:00
redesign: Convert subscriptions page to overlay.
This is a major change to the /#subscriptions page, converting it to by a side-by-side list of streams and their settings in an overlay. There are no new features added/removed, but it's a huge changeset, because it replaces the old navigation logic and moves the stream creation modal to appear in the right side of this overlay.
This commit is contained in:
committed by
Tim Abbott
parent
67f28fe62d
commit
1886f0a015
@@ -14,29 +14,27 @@ casper.then(function () {
|
||||
casper.test.assertUrlMatch(
|
||||
/^http:\/\/[^/]+\/#subscriptions/,
|
||||
'URL suggests we are on subscriptions page');
|
||||
casper.test.assertExists('#subscriptions.tab-pane.active', 'Subscriptions page is active');
|
||||
casper.waitUntilVisible('#subscription_overlay.new-style', function () {
|
||||
casper.test.assertExists('#subscription_overlay.new-style', 'Subscriptions page is active');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
casper.waitForSelector('.sub_unsub_button.checked', function () {
|
||||
casper.test.assertExists('.sub_unsub_button.checked', 'Initial subscriptions loaded');
|
||||
casper.click('form#add_new_subscription input.btn');
|
||||
});
|
||||
casper.waitForSelector('#create_stream_button', function () {
|
||||
casper.test.assertTextExists('Create stream', 'Modal for specifying new stream users');
|
||||
casper.fill('form#stream_creation_form', {stream_name: 'Waseemio', stream_description: 'Oimeesaw'});
|
||||
casper.click('form#stream_creation_form button.btn.btn-primary');
|
||||
casper.click('#create_stream_button');
|
||||
});
|
||||
|
||||
casper.then(function () {
|
||||
casper.test.assertExists('#user-checkboxes [data-name="cordelia@zulip.com"]', 'Original user list contains Cordelia');
|
||||
casper.test.assertExists('#user-checkboxes [data-name="hamlet@zulip.com"]', 'Original user list contains King Hamlet');
|
||||
});
|
||||
casper.then(function () {
|
||||
casper.waitForSelector("form#stream_creation_form", function () {
|
||||
casper.test.info("Filtering user list with keyword 'cor'");
|
||||
casper.fill('form#stream_creation_form', {user_list_filter: 'cor'});
|
||||
});
|
||||
casper.then(function () {
|
||||
casper.waitForSelector(".subscriber-list", function () {
|
||||
casper.test.assertEquals(casper.visible('#user-checkboxes [data-name="cordelia@zulip.com"]'),
|
||||
true,
|
||||
"Cordelia is visible"
|
||||
@@ -60,6 +58,12 @@ casper.then(function () {
|
||||
"King Hamlet is visible again"
|
||||
);
|
||||
});
|
||||
casper.waitForSelector('#stream_creation_form', function () {
|
||||
casper.test.assertTextExists('Add New Stream', 'New stream creation panel');
|
||||
casper.fill('form#stream_creation_form', {stream_name: 'Waseemio', stream_description: 'Oimeesaw'});
|
||||
casper.click('form#stream_creation_form button.btn.btn-primary');
|
||||
});
|
||||
|
||||
casper.waitFor(function () {
|
||||
return casper.evaluate(function () {
|
||||
return $('.stream-name').is(':contains("Waseemio")');
|
||||
@@ -70,12 +74,10 @@ casper.then(function () {
|
||||
casper.test.assertSelectorHasText('.stream-name', 'Waseemio');
|
||||
casper.test.assertSelectorHasText('.description', 'Oimeesaw');
|
||||
casper.fill('form#add_new_subscription', {stream_name: 'WASeemio'});
|
||||
casper.click('form#add_new_subscription input.btn');
|
||||
casper.click('#create_stream_button');
|
||||
});
|
||||
casper.waitForText('Already subscribed', function () {
|
||||
casper.test.assertTextExists('Already subscribed', "Can't subscribe twice to a stream");
|
||||
casper.fill('form#add_new_subscription', {stream_name: ' '});
|
||||
casper.click('form#add_new_subscription input.btn');
|
||||
casper.then(function () {
|
||||
casper.click('#create_stream_button');
|
||||
casper.fill('form#stream_creation_form', {stream_name: ' '});
|
||||
casper.click('form#stream_creation_form button.btn.btn-primary');
|
||||
});
|
||||
@@ -83,7 +85,7 @@ casper.waitForText('A stream needs to have a name', function () {
|
||||
casper.test.assertTextExists('A stream needs to have a name', "Can't create a stream with an empty name");
|
||||
casper.click('form#stream_creation_form button.btn.btn-default');
|
||||
casper.fill('form#add_new_subscription', {stream_name: ' '});
|
||||
casper.click('form#add_new_subscription input.btn');
|
||||
casper.click('#create_stream_button');
|
||||
casper.fill('form#stream_creation_form', {stream_name: 'Waseemio'});
|
||||
casper.click('form#stream_creation_form button.btn.btn-primary');
|
||||
});
|
||||
@@ -92,7 +94,7 @@ casper.waitForText('A stream with this name already exists', function () {
|
||||
casper.test.info('Streams should be filtered when typing in the create box');
|
||||
casper.click('form#stream_creation_form button.btn.btn-default');
|
||||
});
|
||||
casper.waitForText('Filter by stream name', function () {
|
||||
casper.waitForText('Filter Streams', function () {
|
||||
casper.test.assertSelectorHasText('.stream-row[data-stream-name="Verona"] .stream-name', 'Verona', 'Verona stream exists before filtering');
|
||||
casper.test.assertSelectorDoesntHaveText('.stream-row.notdisplayed .stream-name', 'Verona', 'Verona stream shown before filtering');
|
||||
});
|
||||
|
||||
@@ -43,9 +43,9 @@ function then_navigate_to_subscriptions() {
|
||||
var menu_selector = '#settings-dropdown';
|
||||
casper.waitUntilVisible(menu_selector, function () {
|
||||
casper.click(menu_selector);
|
||||
casper.then(function () {
|
||||
casper.click('a[href^="#subscriptions"]');
|
||||
wait_for_tab('subscriptions');
|
||||
casper.click('a[href^="#subscriptions"]');
|
||||
casper.waitForSelector(".subscriptions", function () {
|
||||
casper.test.assertExists('#subscriptions_table', "#subscriptions page is active");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -101,7 +101,7 @@ casper.then(function () {
|
||||
casper.then(function () {
|
||||
// Leave the page and return
|
||||
casper.click('#settings-dropdown');
|
||||
casper.click('a[href^="#subscriptions"]');
|
||||
casper.click('a[href^="#"]');
|
||||
casper.click('#settings-dropdown');
|
||||
casper.click('a[href^="#administration"]');
|
||||
|
||||
|
||||
@@ -361,8 +361,8 @@ var people = global.people;
|
||||
stream_data.add_sub(blue.name, blue);
|
||||
|
||||
var sub_rows = stream_data.get_streams_for_settings_page();
|
||||
assert.equal(sub_rows[0].color, 'amber');
|
||||
assert.equal(sub_rows[1].color, 'cinnamon');
|
||||
assert.equal(sub_rows[2].color, 'blue');
|
||||
assert.equal(sub_rows[0].color, 'blue');
|
||||
assert.equal(sub_rows[1].color, 'amber');
|
||||
assert.equal(sub_rows[2].color, 'cinnamon');
|
||||
|
||||
}());
|
||||
|
||||
BIN
static/images/preview-loading.png
Normal file
BIN
static/images/preview-loading.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 808 B |
@@ -11,6 +11,8 @@ $(function () {
|
||||
var clicking = false;
|
||||
var mouse_moved = false;
|
||||
|
||||
var meta = {};
|
||||
|
||||
function mousedown() {
|
||||
mouse_moved = false;
|
||||
clicking = true;
|
||||
@@ -127,6 +129,10 @@ $(function () {
|
||||
popovers.hide_all();
|
||||
});
|
||||
|
||||
$(window).on("focus", function (e) {
|
||||
meta.focusing = true;
|
||||
});
|
||||
|
||||
// RECIPIENT BARS
|
||||
|
||||
function get_row_id_for_narrowing(narrow_link_elem) {
|
||||
@@ -212,7 +218,19 @@ $(function () {
|
||||
popovers.hide_all();
|
||||
});
|
||||
|
||||
$("#subscriptions_table").on("click", ".exit, #subscription_overlay", function (e) {
|
||||
if (meta.focusing) {
|
||||
meta.focusing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($(e.target).is(".exit, .exit-sign, #subscription_overlay, #subscription_overlay > .flex")) {
|
||||
$("#subscription_overlay").fadeOut(500);
|
||||
subs.remove_miscategorized_streams();
|
||||
|
||||
hashchange.exit_settings();
|
||||
}
|
||||
});
|
||||
// HOME
|
||||
|
||||
// Capture both the left-sidebar Home click and the tab breadcrumb Home
|
||||
@@ -238,12 +256,6 @@ $(function () {
|
||||
|
||||
// MISC
|
||||
|
||||
$('#streams_inline_cog').click(function (e) {
|
||||
ui.change_tab_to('#subscriptions');
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
(function () {
|
||||
var sel = ["#group-pm-list", "#stream_filters", "#global_filters", "#user_presences"].join(", ");
|
||||
|
||||
|
||||
@@ -46,19 +46,6 @@ exports.initialize = function () {
|
||||
}
|
||||
});
|
||||
|
||||
var subs_link = $('#gear-menu a[href="#subscriptions"]');
|
||||
|
||||
// If the streams page is shown by clicking directly on the "Streams"
|
||||
// link (in the gear menu), then focus the new stream textbox.
|
||||
subs_link.on('click', function (e) {
|
||||
$(document).one('subs_page_loaded.zulip', function (e) {
|
||||
$('#create_or_filter_stream_row input[type="text"]').focus().select();
|
||||
});
|
||||
});
|
||||
|
||||
// Whenever the streams page comes up (from anywhere), populate it.
|
||||
subs_link.on('shown', subs.setup_page);
|
||||
|
||||
// The admin and settings pages are generated client-side through
|
||||
// templates.
|
||||
|
||||
|
||||
@@ -196,12 +196,16 @@ function get_main_hash(hash) {
|
||||
|
||||
function should_ignore(hash) {
|
||||
// an array of hashes to ignore (eg. ["subscriptions", "settings", "administration"]).
|
||||
var ignore_list = [];
|
||||
var ignore_list = ["subscriptions"];
|
||||
var main_hash = get_main_hash(hash);
|
||||
|
||||
return (ignore_list.indexOf(main_hash) > -1);
|
||||
}
|
||||
|
||||
function hide_overlays() {
|
||||
$("#subscription_overlay").fadeOut(500);
|
||||
}
|
||||
|
||||
function hashchanged(from_reload, e) {
|
||||
var old_hash;
|
||||
if (e) {
|
||||
@@ -212,9 +216,14 @@ function hashchanged(from_reload, e) {
|
||||
var base = get_main_hash(window.location.hash);
|
||||
if (should_ignore(window.location.hash)) {
|
||||
if (!should_ignore(old_hash || "#")) {
|
||||
if (base === "subscriptions") {
|
||||
subs.launch();
|
||||
}
|
||||
|
||||
ignore.prev = old_hash;
|
||||
}
|
||||
} else if (!should_ignore(window.location.hash) && !ignore.flag) {
|
||||
hide_overlays();
|
||||
changing_hash = true;
|
||||
var ret = do_hashchange(from_reload);
|
||||
changing_hash = false;
|
||||
|
||||
@@ -190,9 +190,14 @@ function process_hotkey(e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (event_name === "escape" && $("#overlay").hasClass("show")) {
|
||||
ui.exit_lightbox_photo();
|
||||
return true;
|
||||
if (event_name === "escape") {
|
||||
if ($("#overlay").hasClass("show")) {
|
||||
ui.exit_lightbox_photo();
|
||||
return true;
|
||||
} else if ($("#subscription_overlay").css("display") === "block") {
|
||||
$("#subscription_overlay").click();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Process hotkeys specially when in an input, select, textarea, or send button
|
||||
|
||||
@@ -685,17 +685,13 @@ exports.register_click_handlers = function () {
|
||||
$('body').on('click', '.open_stream_settings', function (e) {
|
||||
var stream = $(e.currentTarget).parents('ul').attr('data-name');
|
||||
popovers.hide_stream_sidebar_popover();
|
||||
if (! $('#subscriptions').hasClass('active')) {
|
||||
// Go to streams page and once it loads, expand the relevant
|
||||
// stream's settings.
|
||||
$(document).one('subs_page_loaded.zulip', function (event) {
|
||||
subs.show_settings_for(stream);
|
||||
});
|
||||
ui.change_tab_to('#subscriptions');
|
||||
} else {
|
||||
// Already on streams page, so just expand the relevant stream.
|
||||
subs.show_settings_for(stream);
|
||||
}
|
||||
|
||||
window.location.hash = "#subscriptions";
|
||||
// the template for subs needs to render.
|
||||
|
||||
subs.onlaunch("narrow_to_row", function () {
|
||||
$(".stream-row[data-stream-name='" + stream + "']").click();
|
||||
}, true);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
@@ -329,7 +329,7 @@ exports.get_streams_for_settings_page = function () {
|
||||
}
|
||||
subscribed_rows.sort(by_name);
|
||||
unsubscribed_rows.sort(by_name);
|
||||
var all_subs = subscribed_rows.concat(unsubscribed_rows);
|
||||
var all_subs = unsubscribed_rows.concat(subscribed_rows);
|
||||
|
||||
// Add in admin options and stream counts.
|
||||
var sub_rows = [];
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
var subs = (function () {
|
||||
|
||||
var meta = {
|
||||
callbacks: {},
|
||||
stream_created: false
|
||||
};
|
||||
var exports = {};
|
||||
|
||||
function settings_for_sub(sub) {
|
||||
@@ -240,7 +244,7 @@ exports.set_color = function (stream_id, color) {
|
||||
exports.rerender_subscribers_count = function (sub) {
|
||||
var id = parseInt(sub.stream_id, 10);
|
||||
stream_data.update_subscribers_count(sub);
|
||||
$(".stream-row[data-stream-id='" + id + "'] .subscriber-count").text(sub.subscriber_count);
|
||||
$(".stream-row[data-stream-id='" + id + "'] .subscriber-count-text").text(sub.subscriber_count);
|
||||
};
|
||||
|
||||
function add_email_hint(row, email_address_hint_content) {
|
||||
@@ -266,10 +270,17 @@ function add_sub_to_table(sub) {
|
||||
sub = stream_data.add_admin_options(sub);
|
||||
stream_data.update_subscribers_count(sub);
|
||||
var html = templates.render('subscription', sub);
|
||||
$('#create_or_filter_stream_row').after(html);
|
||||
settings_for_sub(sub).collapse('show');
|
||||
var settings_html = templates.render('subscription_settings', sub);
|
||||
$(".streams-list").append(html);
|
||||
$(".subscriptions .settings").append($(settings_html));
|
||||
|
||||
var email_address_hint_content = templates.render('email_address_hint', { page_params: page_params });
|
||||
add_email_hint(sub, email_address_hint_content);
|
||||
|
||||
if (meta.stream_created) {
|
||||
$(".stream-row[data-stream-name='" + meta.stream_created + "']").click();
|
||||
meta.stream_created = false;
|
||||
}
|
||||
}
|
||||
|
||||
function format_member_list_elem(email) {
|
||||
@@ -374,7 +385,6 @@ exports.show_settings_for = function (stream_name) {
|
||||
var stream = $(".subscription_settings[data-stream-name='" + stream_name + "']");
|
||||
$(".subscription_settings[data-stream].show").removeClass("show");
|
||||
|
||||
$("#subscription_overlay").fadeIn(300);
|
||||
$("#subscription_overlay .subscription_settings.show").removeClass("show");
|
||||
sub_settings.addClass("show");
|
||||
|
||||
@@ -399,11 +409,11 @@ exports.mark_subscribed = function (stream_name, attrs) {
|
||||
}
|
||||
var settings = settings_for_sub(sub);
|
||||
var button = button_for_sub(sub);
|
||||
|
||||
if (button.length !== 0) {
|
||||
exports.rerender_subscribers_count(sub);
|
||||
|
||||
button.toggleClass("checked");
|
||||
button.parent().children(".preview-stream").text(i18n.t("Narrow"));
|
||||
// Add the user to the member list if they're currently
|
||||
// viewing the members of this stream
|
||||
if (sub.render_subscribers && settings.hasClass('in')) {
|
||||
@@ -448,7 +458,6 @@ exports.mark_sub_unsubscribed = function (sub) {
|
||||
|
||||
var button = button_for_sub(sub);
|
||||
button.toggleClass("checked");
|
||||
button.parent().children(".preview-stream").text(i18n.t("Preview"));
|
||||
|
||||
var settings = settings_for_sub(sub);
|
||||
if (settings.hasClass('in')) {
|
||||
@@ -477,8 +486,19 @@ exports.mark_sub_unsubscribed = function (sub) {
|
||||
}
|
||||
|
||||
$(document).trigger($.Event('subscription_remove_done.zulip', {sub: sub}));
|
||||
|
||||
$(".stream-row[data-stream-id='" + sub.stream_id + "']").attr("data-temp-view", true);
|
||||
};
|
||||
|
||||
// these streams are miscategorized so they don't jump off the page when being
|
||||
// unsubscribed from, but should be cleared and sorted when you apply an actual
|
||||
// filter.
|
||||
function remove_temporarily_miscategorized_streams() {
|
||||
$("[data-temp-view]").removeAttr("data-temp-view", "false");
|
||||
}
|
||||
|
||||
exports.remove_miscategorized_streams = remove_temporarily_miscategorized_streams;
|
||||
|
||||
// query is now an object rather than a string.
|
||||
// Query { input: String, subscribed_only: Boolean }
|
||||
exports.filter_table = function (query) {
|
||||
@@ -494,9 +514,11 @@ exports.filter_table = function (query) {
|
||||
var sub_name = sub.name.toLowerCase();
|
||||
var matches_list = search_terms.indexOf(sub_name) > -1;
|
||||
var matches_last_val = sub_name.match(search_terms[search_terms.length - 1]);
|
||||
|
||||
return matches_list || matches_last_val;
|
||||
}());
|
||||
flag = flag && (sub.subscribed || !query.subscribed_only);
|
||||
flag = flag && ((sub.subscribed || !query.subscribed_only) ||
|
||||
$(row).attr("data-temp-view") === "true");
|
||||
|
||||
if (flag) {
|
||||
$(row).removeClass("notdisplayed");
|
||||
@@ -504,17 +526,50 @@ exports.filter_table = function (query) {
|
||||
$(row).addClass("notdisplayed");
|
||||
}
|
||||
});
|
||||
|
||||
if ($(".stream-row.active").hasClass("notdisplayed")) {
|
||||
$(".right .settings").hide();
|
||||
$(".nothing-selected").show();
|
||||
$(".stream-row.active").removeClass("active");
|
||||
}
|
||||
};
|
||||
|
||||
function actually_filter_streams() {
|
||||
var search_box = $("#create_or_filter_stream_row input[type='text']");
|
||||
var search_box = $("#add_new_subscription input[type='text']");
|
||||
var query = search_box.expectOne().val().trim();
|
||||
exports.filter_table({input: query});
|
||||
var subscribed_only;
|
||||
if (components.toggle.lookup("stream-filter-toggle")) {
|
||||
subscribed_only = components.toggle.lookup("stream-filter-toggle").value() === "Subscribed";
|
||||
} else {
|
||||
subscribed_only = false;
|
||||
}
|
||||
exports.filter_table({ input: query, subscribed_only: subscribed_only });
|
||||
}
|
||||
|
||||
var filter_streams = _.throttle(actually_filter_streams, 50);
|
||||
|
||||
exports.setup_page = function () {
|
||||
exports.setup_page = function (callback) {
|
||||
function initialize_components() {
|
||||
var stream_filter_toggle = components.toggle({
|
||||
name: "stream-filter-toggle",
|
||||
selected: 0,
|
||||
values: [
|
||||
{ label: "Subscribed" },
|
||||
{ label: "All Streams" },
|
||||
],
|
||||
callback: function (name) {
|
||||
actually_filter_streams();
|
||||
remove_temporarily_miscategorized_streams();
|
||||
}
|
||||
}).get();
|
||||
|
||||
if (should_list_all_streams()) {
|
||||
$("#subscriptions_table .search-container").prepend(stream_filter_toggle);
|
||||
}
|
||||
|
||||
// show the "Stream Settings" header by default.
|
||||
$(".display-type #stream_settings_title").show();
|
||||
}
|
||||
|
||||
function _populate_and_fill() {
|
||||
var sub_rows = stream_data.get_streams_for_settings_page();
|
||||
@@ -528,14 +583,24 @@ exports.setup_page = function () {
|
||||
};
|
||||
var rendered = templates.render('subscription_table_body', template_data);
|
||||
$('#subscriptions_table').append(rendered);
|
||||
|
||||
initialize_components();
|
||||
actually_filter_streams();
|
||||
var email_address_hint_content = templates.render('email_address_hint', { page_params: page_params });
|
||||
_.each(sub_rows, function (row) {
|
||||
add_email_hint(row, email_address_hint_content);
|
||||
});
|
||||
|
||||
$("#create_or_filter_stream_row input[type='text']").on("input", filter_streams);
|
||||
$("#add_new_subscription input[type='text']").on("input", function () {
|
||||
remove_temporarily_miscategorized_streams();
|
||||
actually_filter_streams();
|
||||
});
|
||||
|
||||
$(document).trigger($.Event('subs_page_loaded.zulip'));
|
||||
|
||||
if (callback) {
|
||||
callback();
|
||||
exports.onlaunchtrigger();
|
||||
}
|
||||
}
|
||||
|
||||
function populate_and_fill() {
|
||||
@@ -551,6 +616,34 @@ exports.setup_page = function () {
|
||||
}
|
||||
};
|
||||
|
||||
// add a function to run on subscription page launch by name,
|
||||
// and specify whether it should be kept or just run once (boolean).
|
||||
exports.onlaunch = function (name, callback, keep) {
|
||||
meta.callbacks[name] = {
|
||||
func: callback,
|
||||
keep: keep
|
||||
};
|
||||
};
|
||||
|
||||
exports.onlaunchtrigger = function () {
|
||||
for (var x in meta.callbacks) {
|
||||
if (typeof meta.callbacks[x].func === "function") {
|
||||
meta.callbacks[x].func();
|
||||
|
||||
// delete if it should not be kept.
|
||||
if (!meta.callbacks[x].keep) {
|
||||
delete meta.callbacks[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.launch = function () {
|
||||
exports.setup_page(function () {
|
||||
$("#subscription_overlay").fadeIn(300);
|
||||
});
|
||||
};
|
||||
|
||||
exports.update_subscription_properties = function (stream_name, property, value) {
|
||||
var sub = stream_data.get_sub(stream_name);
|
||||
if (sub === undefined) {
|
||||
@@ -601,7 +694,8 @@ function ajaxSubscribe(stream) {
|
||||
data: {subscriptions: JSON.stringify([{name: stream}]) },
|
||||
success: function (resp, statusText, xhr, form) {
|
||||
$("#create_stream_name").val("");
|
||||
exports.filter_table({input: ""});
|
||||
|
||||
actually_filter_streams();
|
||||
|
||||
var res = JSON.parse(xhr.responseText);
|
||||
if (!$.isEmptyObject(res.already_subscribed)) {
|
||||
@@ -636,10 +730,6 @@ function ajaxUnsubscribe(stream) {
|
||||
});
|
||||
}
|
||||
|
||||
function hide_new_stream_modal() {
|
||||
$('#stream-creation').modal("hide");
|
||||
}
|
||||
|
||||
function ajaxSubscribeForCreation(stream, description, principals, invite_only, announce) {
|
||||
// Subscribe yourself and possible other people to a new stream.
|
||||
return channel.post({
|
||||
@@ -653,13 +743,11 @@ function ajaxSubscribeForCreation(stream, description, principals, invite_only,
|
||||
$("#create_stream_name").val("");
|
||||
$("#create_stream_description").val("");
|
||||
$("#subscriptions-status").hide();
|
||||
hide_new_stream_modal();
|
||||
// The rest of the work is done via the subscribe event we will get
|
||||
},
|
||||
error: function (xhr) {
|
||||
ui.report_error(i18n.t("Error creating stream"), xhr,
|
||||
$("#subscriptions-status"), 'subscriptions-status');
|
||||
hide_new_stream_modal();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -684,6 +772,8 @@ function update_announce_stream_state() {
|
||||
}
|
||||
|
||||
function show_new_stream_modal() {
|
||||
$("#stream-creation").removeClass("hide");
|
||||
$(".right .settings").hide();
|
||||
$('#people_to_add').html(templates.render('new_stream_users', {
|
||||
users: people.get_rest_of_realm()
|
||||
}));
|
||||
@@ -695,8 +785,6 @@ function show_new_stream_modal() {
|
||||
$('#announce-new-stream input').prop('checked', true);
|
||||
|
||||
$("#stream_name_error").hide();
|
||||
|
||||
$('#stream-creation').modal("show");
|
||||
}
|
||||
|
||||
exports.invite_user_to_stream = function (user_email, stream_name, success, failure) {
|
||||
@@ -729,8 +817,31 @@ $(function () {
|
||||
// when new messages come in, but it's fairly quick.
|
||||
stream_list.build_stream_list();
|
||||
|
||||
$("#subscriptions_table").on("submit", "#add_new_subscription", function (e) {
|
||||
var show_subs_pane = {
|
||||
nothing_selected: function () {
|
||||
$(".nothing-selected, #stream_settings_title").show();
|
||||
$("#add_new_stream_title, .settings, #stream-creation").hide();
|
||||
},
|
||||
stream_creation: function () {
|
||||
$("#stream-creation, #add_new_stream_title").show();
|
||||
$("#stream_settings_title, .settings, .nothing-selected").hide();
|
||||
},
|
||||
settings: function () {
|
||||
$(".settings, #stream_settings_title").show();
|
||||
$("#add_new_stream_title, #stream-creation, .nothing-selected").hide();
|
||||
},
|
||||
};
|
||||
|
||||
$("#subscriptions_table").on("click", "#create_stream_button", function (e) {
|
||||
e.preventDefault();
|
||||
// this changes the tab switcher (settings/preview) which isn't necessary
|
||||
// to a add new stream title.
|
||||
$(".display-type #add_new_stream_title").show();
|
||||
$(".display-type #stream_settings_title").hide();
|
||||
|
||||
$(".stream-row.active").removeClass("active");
|
||||
|
||||
show_subs_pane.stream_creation();
|
||||
|
||||
if (!should_list_all_streams()) {
|
||||
ajaxSubscribe($("#search_stream_name").val());
|
||||
@@ -738,19 +849,18 @@ $(function () {
|
||||
}
|
||||
|
||||
var stream = $.trim($("#search_stream_name").val());
|
||||
var stream_status = compose.check_stream_existence(stream);
|
||||
if (stream_status === "does-not-exist" || !stream) {
|
||||
$('#create_stream_name').val(stream);
|
||||
show_new_stream_modal();
|
||||
$('#create_stream_name').focus();
|
||||
} else {
|
||||
ajaxSubscribe(stream);
|
||||
}
|
||||
$('#create_stream_name').val(stream);
|
||||
show_new_stream_modal();
|
||||
$('#create_stream_name').focus();
|
||||
});
|
||||
|
||||
$('#stream_creation_form').on('change',
|
||||
'#user-checkboxes input, #make-invite-only input',
|
||||
update_announce_stream_state);
|
||||
$('body').on('change', '#user-checkboxes input, #make-invite-only input', update_announce_stream_state);
|
||||
|
||||
|
||||
$(".subscriptions").on("click", "[data-dismiss]", function (e) {
|
||||
e.preventDefault();
|
||||
show_subs_pane.nothing_selected();
|
||||
});
|
||||
|
||||
// 'Check all' and 'Uncheck all' links
|
||||
$(document).on('click', '.subs_set_all_users', function (e) {
|
||||
@@ -786,35 +896,38 @@ $(function () {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
var announce_stream_docs = $("#announce-stream-docs");
|
||||
announce_stream_docs.popover({placement: "right",
|
||||
content: templates.render('announce_stream_docs'),
|
||||
trigger: "manual"});
|
||||
$("body").on("mouseover", "#announce-stream-docs", function (e) {
|
||||
var announce_stream_docs = $("#announce-stream-docs");
|
||||
announce_stream_docs.popover({placement: "right",
|
||||
content: templates.render('announce_stream_docs'),
|
||||
trigger: "manual"});
|
||||
announce_stream_docs.popover('show');
|
||||
announce_stream_docs.data('popover').tip().css('z-index', 2000);
|
||||
e.stopPropagation();
|
||||
});
|
||||
$("body").on("mouseout", "#announce-stream-docs", function (e) {
|
||||
announce_stream_docs.popover('hide');
|
||||
$("#announce-stream-docs").popover('hide');
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
$("#create_stream_name").on("focusout", function () {
|
||||
$(".subscriptions").on("focusout", "#create_stream_name", function () {
|
||||
var stream = $.trim($("#create_stream_name").val());
|
||||
var stream_status = compose.check_stream_existence(stream);
|
||||
if (stream.length < 1) {
|
||||
if (stream.length !== 0) {
|
||||
var stream_status = compose.check_stream_existence(stream);
|
||||
|
||||
if (stream_status !== "does-not-exist") {
|
||||
$("#stream_name_error").text(i18n.t("A stream with this name already exists"));
|
||||
$("#stream_name_error").show();
|
||||
} else {
|
||||
$("#stream_name_error").hide();
|
||||
}
|
||||
} else {
|
||||
$("#stream_name_error").text(i18n.t("A stream needs to have a name"));
|
||||
$("#stream_name_error").show();
|
||||
} else if (stream_status !== "does-not-exist") {
|
||||
$("#stream_name_error").text(i18n.t("A stream with this name already exists"));
|
||||
$("#stream_name_error").show();
|
||||
} else {
|
||||
$("#stream_name_error").hide();
|
||||
}
|
||||
});
|
||||
|
||||
$("#stream_creation_form").on("submit", function (e) {
|
||||
$(".subscriptions").on("submit", "#stream_creation_form", function (e) {
|
||||
e.preventDefault();
|
||||
var stream = $.trim($("#create_stream_name").val());
|
||||
var description = $.trim($("#create_stream_description").val());
|
||||
@@ -827,6 +940,9 @@ $(function () {
|
||||
);
|
||||
// You are always subscribed to streams you create.
|
||||
principals.push(page_params.email);
|
||||
|
||||
meta.stream_created = stream;
|
||||
|
||||
ajaxSubscribeForCreation(stream,
|
||||
description,
|
||||
principals,
|
||||
@@ -842,7 +958,7 @@ $(function () {
|
||||
$(e.target).removeClass("btn-danger").text(i18n.t("Subscribed"));
|
||||
});
|
||||
|
||||
$("#subscriptions-status").on("click", "#close-subscriptions-status", function (e) {
|
||||
$(".subscriptions").on("click", "#close-subscriptions-status", function (e) {
|
||||
$("#subscriptions-status").hide();
|
||||
});
|
||||
|
||||
@@ -964,12 +1080,36 @@ $(function () {
|
||||
exports.invite_user_to_stream(principal, stream, invite_success, invite_failure);
|
||||
});
|
||||
|
||||
function show_stream_row(node, e) {
|
||||
$(".display-type #add_new_stream_title").hide();
|
||||
$(".display-type #stream_settings_title, .right .settings").show();
|
||||
$(".stream-row.active").removeClass("active");
|
||||
if (e) {
|
||||
show_subs_pane.settings();
|
||||
|
||||
$(node).addClass("active");
|
||||
exports.show_settings_for(get_stream_name(node));
|
||||
} else {
|
||||
show_subs_pane.nothing_selected();
|
||||
}
|
||||
}
|
||||
|
||||
$("#subscriptions_table").on("click", ".stream-row", function (e) {
|
||||
if ($(e.target).closest(".check, .subscription_settings").length === 0) {
|
||||
exports.show_settings_for(get_stream_name($(e.target)));
|
||||
show_stream_row(this, e);
|
||||
}
|
||||
});
|
||||
|
||||
(function defocus_sub_settings() {
|
||||
var sel = ".search-container, .streams-list, .subscriptions-header";
|
||||
|
||||
$("#subscriptions_table").on("click", sel, function (e) {
|
||||
if ($(e.target).is(sel)) {
|
||||
show_stream_row(this);
|
||||
}
|
||||
});
|
||||
}());
|
||||
|
||||
$("#subscriptions_table").on("submit", ".subscriber_list_remove form", function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -1062,12 +1202,6 @@ $(function () {
|
||||
});
|
||||
});
|
||||
|
||||
$("body").on("click", "#subscription_overlay", function (e) {
|
||||
if ($(e.target).is(".flex, #subscription_overlay")) {
|
||||
$("#subscription_overlay").fadeOut(300);
|
||||
}
|
||||
});
|
||||
|
||||
function redraw_privacy_related_stuff(sub_row, sub) {
|
||||
var stream_settings = settings_for_sub(sub);
|
||||
var html;
|
||||
@@ -1080,6 +1214,16 @@ $(function () {
|
||||
html = templates.render('subscription_type', sub);
|
||||
stream_settings.find('.subscription-type').expectOne().html(html);
|
||||
|
||||
if (sub.invite_only) {
|
||||
stream_settings.find(".large-icon")
|
||||
.removeClass("hash").addClass("lock")
|
||||
.html("<i class='icon-vector-lock'></i>");
|
||||
} else {
|
||||
stream_settings.find(".large-icon")
|
||||
.addClass("hash").removeClass("lock")
|
||||
.html("");
|
||||
}
|
||||
|
||||
html = templates.render('change_stream_privacy', sub);
|
||||
stream_settings.find('.change-stream-privacy').expectOne().html(html);
|
||||
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
.clear-float {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* -- base button styling -- */
|
||||
.new-style .button {
|
||||
padding: 8px 15px;
|
||||
@@ -215,6 +219,10 @@
|
||||
-webkit-filter: grayscale(1);
|
||||
}
|
||||
|
||||
.new-style label.checkbox input[type=checkbox]:disabled ~ span {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.new-style a.no-style {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
@@ -16,12 +16,6 @@
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.subscription_settings,
|
||||
.subscription_header,
|
||||
.subscription_header.active {
|
||||
background-color: #fefefe;
|
||||
}
|
||||
|
||||
.color_swatch {
|
||||
display: inline-block;
|
||||
height: 18px;
|
||||
@@ -234,16 +228,34 @@
|
||||
}
|
||||
|
||||
form#add_new_subscription {
|
||||
display: inline;
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#create_stream_button {
|
||||
min-width: 140px;
|
||||
float: right;
|
||||
margin-top: 9px;
|
||||
/* margin-right: 38px will align with .sub_unsub_button
|
||||
10px will align with the right edge of #subscriptions_table */
|
||||
margin-right: 38px;
|
||||
margin: 0px 0px 0px 5px;
|
||||
|
||||
border: none;
|
||||
outline: none;
|
||||
background-color: transparent;
|
||||
|
||||
font-size: 2.2em;
|
||||
font-weight: 300;
|
||||
line-height: 1;
|
||||
color: #aaa;
|
||||
|
||||
display: inline-block;
|
||||
transition: all 0.2s ease;
|
||||
padding-bottom: 0px;
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
#create_stream_button:hover {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
#create_stream_description {
|
||||
width: calc(100% - 15px);
|
||||
}
|
||||
|
||||
#stream_name_error {
|
||||
@@ -357,12 +369,14 @@ form#add_new_subscription {
|
||||
|
||||
.subscriptions-container {
|
||||
position: relative;
|
||||
height: 80%;
|
||||
height: 95%;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
padding: 0px;
|
||||
width: 900px;
|
||||
width: 97%;
|
||||
overflow: hidden;
|
||||
max-width: 1200px;
|
||||
max-height: 1000px;
|
||||
}
|
||||
|
||||
.subscriptions-header {
|
||||
@@ -376,7 +390,7 @@ form#add_new_subscription {
|
||||
.subscriptions-container .exit {
|
||||
font-weight: 400;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
color: #AAA;
|
||||
cursor: pointer;
|
||||
@@ -384,19 +398,31 @@ form#add_new_subscription {
|
||||
|
||||
.subscriptions-container .exit-sign {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
top: 3px;
|
||||
margin-left: 3px;
|
||||
font-size: 1.7em;
|
||||
font-weight: 300;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.subscriptions-container .left,
|
||||
.subscriptions-container .right {
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 50%;
|
||||
height: calc(100% - 39px);
|
||||
margin: 0px -2px;
|
||||
height: calc(100% - 45px);
|
||||
margin: 0px -1px;
|
||||
}
|
||||
|
||||
.subscriptions-container .right .nothing-selected {
|
||||
display: block;
|
||||
margin-top: calc(45vh - 30px - 1em);
|
||||
text-align: center;
|
||||
font-size: 1em;
|
||||
color: #aaa;
|
||||
pointer-events: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.subscriptions-container .left {
|
||||
@@ -423,10 +449,26 @@ form#add_new_subscription {
|
||||
content: "Preferences";
|
||||
}
|
||||
|
||||
.subscriptions-container .right iframe {
|
||||
.subscriptions-container .display-type .stream-info-title {
|
||||
display: none;
|
||||
font-size: 1em;
|
||||
line-height: 1;
|
||||
margin: 9px 0px;
|
||||
font-weight: 400;
|
||||
font-weight: 600;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.subscriptions-container .right #preview_iframe {
|
||||
width: 100%;
|
||||
height: calc(100% - 41px);
|
||||
height: calc(100% - 45px);
|
||||
border: none;
|
||||
background-color: #FAFAFA;
|
||||
box-shadow: inset 0px 0px 50px rgba(0,0,0,0.5);
|
||||
background-image: url(../images/preview-loading.png);
|
||||
background-size: 150px auto;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.subscriptions-container input[type=text].small {
|
||||
@@ -446,28 +488,54 @@ form#add_new_subscription {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#find_streams {
|
||||
width: 194px;
|
||||
#search_stream_name {
|
||||
width: 190px;
|
||||
padding: 3px 5px;
|
||||
margin: 2px 0px;
|
||||
display: inline-block;
|
||||
border-radius: 5px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.create-stream-title {
|
||||
font-size: 1.5em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.stream-creation-body section.block {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stream-creation-body #make-invite-only label span.icon-vector-globe {
|
||||
margin-left: 14px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
.stream-creation-body #make-invite-only label span.icon-vector-lock {
|
||||
margin-left: 15px;
|
||||
margin-right: 11px;
|
||||
}
|
||||
|
||||
.stream-creation-body #announce-new-stream div[class^="icon"] {
|
||||
margin-left: 3px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.streams-list {
|
||||
overflow: auto;
|
||||
height: calc(100% - 41px);
|
||||
height: calc(100% - 45px);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stream-row {
|
||||
padding: 15px 10px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-bottom: 1px solid #eee;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.stream-row.active {
|
||||
background-color: #eee;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.stream-row.no-border {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.stream-row > div {
|
||||
@@ -534,11 +602,16 @@ form#add_new_subscription {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.stream-row .sub-info-box .top-bar .subscriber-count-text {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.stream-row .sub-info-box .description {
|
||||
margin-top: 5px;
|
||||
margin-top: 2px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
#subscription_overlay .stream-description:empty:after,
|
||||
@@ -548,12 +621,36 @@ form#add_new_subscription {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
#subscription_overlay #stream-creation {
|
||||
max-height: calc(100% - 102px);
|
||||
overflow: auto;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#subscription_overlay #stream-creation .modal-footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: calc(100% - 30px);
|
||||
}
|
||||
|
||||
#stream-creation .stream-creation-body {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.stream-row .settings-dropdown-trigger {
|
||||
float: right;
|
||||
margin-left: 10px;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.add-user-label {
|
||||
margin: 8px 0px;
|
||||
}
|
||||
|
||||
#stream_creation_form {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
#subscription_overlay .inner-box {
|
||||
margin: 20px;
|
||||
}
|
||||
@@ -613,15 +710,19 @@ form#add_new_subscription {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#subscription_overlay .settings {
|
||||
position: relative;
|
||||
height: calc(100% - 45px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#subscription_overlay .subscription_settings {
|
||||
display: none;
|
||||
position: relative;
|
||||
width: 600px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
border-radius: 4px;
|
||||
top: -1px;
|
||||
max-height: 85vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#subscription_overlay .subscription_settings.show {
|
||||
@@ -652,3 +753,71 @@ form#add_new_subscription {
|
||||
#subscription_overlay .subscription_settings ul li .sp-replacer {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@media (max-width: 1130px) {
|
||||
.subscriptions-container {
|
||||
max-width: 95%;
|
||||
}
|
||||
|
||||
#subscription_overlay .left {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
#subscription_overlay .right {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
#search_stream_name {
|
||||
width: 100px;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
#search_stream_name {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.search-container {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
#subscription_overlay .left,
|
||||
#subscription_overlay .right {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#subscription_overlay .left {
|
||||
overflow: auto;
|
||||
height: 30%;
|
||||
}
|
||||
|
||||
#subscription_overlay .right {
|
||||
overflow: auto;
|
||||
height: calc(70% - 45px);
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
#subscription_overlay .display-type {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#subscription_overlay .subscriptions-container {
|
||||
height: 95%;
|
||||
}
|
||||
|
||||
#subscription_overlay .subscription_settings {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
#subscription_overlay .settings {
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
<input class="add-user-list-filter" name="user_list_filter" type="text" placeholder="{{t "Filter users" }}" />
|
||||
<div id="user-checkboxes">
|
||||
{{#each users}}
|
||||
<label class="checkbox" data-name="{{this.email}}">
|
||||
<input type="checkbox" name="user" value="{{this.email}}" /> {{this.full_name}} ({{this.email}})
|
||||
<label class="checkbox add-user-label" data-name="{{this.email}}">
|
||||
<input type="checkbox" name="user" value="{{this.email}}" />
|
||||
<span></span>
|
||||
{{this.full_name}} ({{this.email}})
|
||||
</label>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
@@ -10,12 +10,9 @@
|
||||
<div class="sub-info-box">
|
||||
<div class="top-bar">
|
||||
<div class="stream-name">{{name}}</div>
|
||||
<div class="settings-dropdown-trigger">
|
||||
<i class="icon-vector-chevron-down"></i>
|
||||
</div>
|
||||
<div class="subscriber-count">
|
||||
<span class="subscriber-count-text">{{subscriber_count}}</span>
|
||||
<i class="icon-vector-user"></i>
|
||||
{{subscriber_count}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="description" data-no-description="{{t 'No description.'}}">{{description}}</div>
|
||||
|
||||
54
static/templates/subscription_creation_form.handlebars
Normal file
54
static/templates/subscription_creation_form.handlebars
Normal file
@@ -0,0 +1,54 @@
|
||||
<div class="hide" id="stream-creation" tabindex="-1" role="dialog"
|
||||
aria-labelledby="stream-creation-label" aria-hidden="true">
|
||||
<form id="stream_creation_form" class="form-inline">
|
||||
<div class="stream-creation-body">
|
||||
<section class="block">
|
||||
<div class="create-stream-title">
|
||||
{{t "Stream name" }}
|
||||
</div>
|
||||
<input type="text" name="stream_name" id="create_stream_name"
|
||||
placeholder="{{t 'Stream name' }}" value="" autocomplete="off" />
|
||||
<div id="stream_name_error"></div>
|
||||
</section>
|
||||
<section class="block">
|
||||
<b>{{t "Stream description (optional)"}}</b><br />
|
||||
<textarea name="stream_description" id="create_stream_description"
|
||||
placeholder="{{t 'Stream description' }}" value="" autocomplete="off"></textarea>
|
||||
</section>
|
||||
<section class="block" id="make-invite-only">
|
||||
<div class="create-stream-title">
|
||||
{{t "Stream accessibility" }}
|
||||
</div>
|
||||
<label class="radio">
|
||||
<input type="radio" name="privacy" value="public" checked />
|
||||
<span class="icon-vector-globe"></span>
|
||||
{{t "Anyone can join" }}
|
||||
</label><br />
|
||||
<label class="radio">
|
||||
<input type="radio" name="privacy" value="invite-only" />
|
||||
<span class="icon-vector-lock"></span>
|
||||
{{t "People must be invited" }}
|
||||
</label>
|
||||
<div id="announce-new-stream">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="announce" value="announce" checked />
|
||||
<span></span>
|
||||
<div class="icon-vector-bullhorn"></div>
|
||||
{{t "Announce stream" }}
|
||||
</label>
|
||||
<span class="icon-vector-question-sign" id="announce-stream-docs"></span>
|
||||
</div>
|
||||
</section>
|
||||
<section class="block">
|
||||
<label class="control-label" for="people_to_add">
|
||||
{{t "People to add" }}
|
||||
</label>
|
||||
<div class="controls" id="people_to_add"></div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">{{t "Cancel" }}</button>
|
||||
<button class="btn btn-primary" type="submit">{{t "Create" }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -1,24 +1,46 @@
|
||||
<div id="create_or_filter_stream_row">
|
||||
<div class="subscription_table_elem">
|
||||
<form id="add_new_subscription" class="form-inline" action="">
|
||||
<input type="text" name="stream_name" id="search_stream_name"
|
||||
placeholder="{{t 'Filter by stream name' }}" value="" autocomplete="off" />
|
||||
{{#if can_create_streams}}
|
||||
<input type="submit" class="btn btn-primary"
|
||||
id="create_stream_button" value="{{t 'Create new stream' }}" />
|
||||
{{/if}}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#each subscriptions}}
|
||||
{{partial "subscription"}}
|
||||
{{/each}}
|
||||
|
||||
<div id="subscription_overlay">
|
||||
<div id="subscription_overlay" class="new-style">
|
||||
<div class="flex">
|
||||
{{#each subscriptions}}
|
||||
{{ partial "subscription_settings" }}
|
||||
{{/each}}
|
||||
<div class="subscriptions-container">
|
||||
<div class="subscriptions-header">
|
||||
Subscriptions
|
||||
<div class="exit">
|
||||
<span class="exit-sign">×</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="left">
|
||||
<div class="search-container">
|
||||
<form id="add_new_subscription" class="form-inline" action="">
|
||||
<input type="text" name="stream_name" id="search_stream_name"
|
||||
placeholder="{{t 'Filter Streams' }}" value="" autocomplete="off" />
|
||||
{{#if can_create_streams}}
|
||||
<input type="submit" class=""
|
||||
id="create_stream_button" value="{{t '+' }}" />
|
||||
{{/if}}
|
||||
<div class="float-clear"></div>
|
||||
</form>
|
||||
<div class="clear-float"></div>
|
||||
</div>
|
||||
<div class="streams-list">
|
||||
{{#each subscriptions}}
|
||||
{{partial "subscription"}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="display-type">
|
||||
<div id="add_new_stream_title" class="stream-info-title">Add New Stream</div>
|
||||
<div id="stream_settings_title" class="stream-info-title">Stream Settings</div>
|
||||
</div>
|
||||
<div class="nothing-selected">
|
||||
Nothing selected.
|
||||
</div>
|
||||
<div class="settings">
|
||||
{{#each subscriptions}}
|
||||
{{ partial "subscription_settings" }}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{ partial "subscription_creation_form" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -102,9 +102,6 @@ var page_params = {{ page_params }};
|
||||
</div>
|
||||
{% include "zerver/home.html" %}
|
||||
</div>
|
||||
<div class="tab-pane" id="subscriptions">
|
||||
{% include "zerver/subscriptions.html" %}
|
||||
</div>
|
||||
<div class="tab-pane new-style" id="administration">
|
||||
</div>
|
||||
<div class="tab-pane new-style" id="settings">
|
||||
@@ -121,6 +118,7 @@ var page_params = {{ page_params }};
|
||||
{% include "zerver/right-sidebar.html" %}
|
||||
</div><!--/right sidebar-->
|
||||
{% include "zerver/image-overlay.html" %}
|
||||
{% include "zerver/subscriptions.html" %}
|
||||
</div><!--/row-->
|
||||
{% include "zerver/keyboard_shortcuts.html" %}
|
||||
{% include "zerver/search_operators.html" %}
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
</ul>
|
||||
<div id="streams_list" class="zoom-out">
|
||||
<div id="streams_header" class="zoom-in-hide"><h4 class="sidebar-title" data-toggle="tooltip" title="Subscribed streams"><a href="">{{ _('STREAMS') }}</a></h4>
|
||||
<a href=""><i id="streams_inline_cog" class='icon-vector-cog' data-toggle="tooltip" title="Subscribe, add, or configure streams"></i></a>
|
||||
<a href="#subscriptions">
|
||||
<i id="streams_inline_cog" class='icon-vector-cog' data-toggle="tooltip" title="Subscribe, add, or configure streams"></i>
|
||||
</a>
|
||||
<a href=""><i id='streams_filter_icon' class='icon-vector-search' data-toggle="tooltip" title="Filter streams list"></i></a>
|
||||
</div>
|
||||
<div id="topics_header">
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#}
|
||||
<li style="display:none;"><a href="#home" data-toggle="tab"></a></li>
|
||||
<li title="Manage Streams">
|
||||
<a href="#subscriptions" data-toggle="tab">
|
||||
<a href="#subscriptions">
|
||||
<i class="icon-vector-exchange"></i> {{ _('Manage Streams') }}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
<div class="modal hide" id="stream-creation" tabindex="-1" role="dialog"
|
||||
aria-labelledby="stream-creation-label" aria-hidden="true">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3 id="stream-creation-label">{% trans %}Create stream{% endtrans %}</h3>
|
||||
</div>
|
||||
<form id="stream_creation_form" class="form-inline">
|
||||
<div class="modal-body">
|
||||
<div>
|
||||
<b>{% trans %}Stream name{% endtrans %}</b><br />
|
||||
<input type="text" name="stream_name" id="create_stream_name"
|
||||
placeholder="{{ _('Stream name') }}" value="" autocomplete="off" />
|
||||
<div id="stream_name_error"></div>
|
||||
</div>
|
||||
<div>
|
||||
<b>{% trans %}Stream description (optional){% endtrans %}</b><br />
|
||||
<input type="text" name="stream_description" id="create_stream_description"
|
||||
placeholder="{{_('Stream description') }}" value="" autocomplete="off" />
|
||||
</div>
|
||||
<div id="make-invite-only">
|
||||
<b>{% trans %}Stream accessibility{% endtrans %}</b><br />
|
||||
<label class="radio">
|
||||
<input type="radio" name="privacy" value="public" checked />
|
||||
<span class="icon-vector-globe"></span>
|
||||
{% trans %}Anyone can join{% endtrans %}
|
||||
</label><br />
|
||||
<label class="radio">
|
||||
<input type="radio" name="privacy" value="invite-only" />
|
||||
<span class="icon-vector-lock"></span>
|
||||
{% trans %}People must be invited{% endtrans %}
|
||||
</label>
|
||||
</div>
|
||||
<div id="announce-new-stream">
|
||||
<br />
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="announce" value="announce" checked />
|
||||
{% trans %}Announce stream{% endtrans %}
|
||||
</label>
|
||||
<span class="icon-vector-question-sign" id="announce-stream-docs"></span>
|
||||
</div>
|
||||
<br />
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="people_to_add"><b>{% trans %}People to add{% endtrans %}</b></label><br />
|
||||
<div class="controls" id="people_to_add"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">{{ _("Cancel") }}</button>
|
||||
<button class="btn btn-primary" type="submit">{{ _("Create") }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -1,14 +1,5 @@
|
||||
{# Subscriptions management tab of the app. #}
|
||||
|
||||
<div class="subscriptions">
|
||||
<h1><i class="icon-vector-exchange streams-icon"></i>{{ _("Streams") }}</h1>
|
||||
<div class="alert" id="subscriptions-status">
|
||||
<span id="response"></span>
|
||||
<span id="close-subscriptions-status"><i class="icon-vector-remove"></i></span>
|
||||
</div>
|
||||
<div id="subs_page_loading_indicator"></div>
|
||||
<div id="subscriptions_table">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include "zerver/stream_creation_prompt.html" %}
|
||||
<div class="subscriptions">
|
||||
<div id="subscriptions_table">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -23,6 +23,8 @@ GENERIC_KEYWORDS = [
|
||||
'warning',
|
||||
'zoom-in', # TODO: clean these up, they are confusing
|
||||
'zoom-out',
|
||||
'first',
|
||||
'second',
|
||||
]
|
||||
|
||||
def raise_error(fn, i, line):
|
||||
|
||||
Reference in New Issue
Block a user