diff --git a/.eslintrc.json b/.eslintrc.json index bb7a7062b7..98dd9980fc 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -204,6 +204,7 @@ "user_pill": false, "user_search": false, "user_status": false, + "user_status_ui": false, "util": false, "poll_widget": false, "widgetize": false, diff --git a/frontend_tests/node_tests/ui_init.js b/frontend_tests/node_tests/ui_init.js index 04218aec73..07661fb686 100644 --- a/frontend_tests/node_tests/ui_init.js +++ b/frontend_tests/node_tests/ui_init.js @@ -118,6 +118,7 @@ zrequire('typing'); zrequire('top_left_corner'); zrequire('starred_messages'); zrequire('user_status'); +zrequire('user_status_ui'); zrequire('ui_init'); set_global('$', global.make_zjquery()); diff --git a/frontend_tests/node_tests/user_status.js b/frontend_tests/node_tests/user_status.js index d73307431e..304fdba260 100644 --- a/frontend_tests/node_tests/user_status.js +++ b/frontend_tests/node_tests/user_status.js @@ -42,10 +42,12 @@ run_test('server', () => { initialize(); var sent_data; + var success; channel.post = (opts) => { sent_data = opts.data; assert.equal(opts.url, '/json/users/me/status'); + success = opts.success; }; assert.equal(sent_data, undefined); @@ -55,4 +57,16 @@ run_test('server', () => { user_status.server_revoke_away(); assert.deepEqual(sent_data, {away: false, status_text: undefined}); + + var called; + + user_status.server_update({ + status_text: 'out to lunch', + success: () => { + called = true; + }, + }); + + success(); + assert(called); }); diff --git a/static/js/bundles/app.js b/static/js/bundles/app.js index e39429dce4..d7274718b9 100644 --- a/static/js/bundles/app.js +++ b/static/js/bundles/app.js @@ -154,6 +154,7 @@ import "js/zulip.js"; import "js/presence.js"; import "js/user_search.js"; import "js/user_status.js"; +import "js/user_status_ui.js"; import "js/buddy_data.js"; import "js/padded_widget.js"; import "js/buddy_list.js"; @@ -229,4 +230,5 @@ import "styles/media.scss"; import "styles/typing_notifications.scss"; import "styles/hotspots.scss"; import "styles/night_mode.scss"; +import "styles/user_status.scss"; import "styles/widgets.scss"; diff --git a/static/js/popovers.js b/static/js/popovers.js index 14749ec1d5..e97e82727f 100644 --- a/static/js/popovers.js +++ b/static/js/popovers.js @@ -792,6 +792,15 @@ exports.register_click_handlers = function () { e.preventDefault(); }); + $('body').on('click', '.update_status_text', function (e) { + popovers.hide_all(); + + user_status_ui.open_overlay(); + + e.stopPropagation(); + e.preventDefault(); + }); + $('#user_presences').on('click', 'span.arrow', function (e) { e.stopPropagation(); diff --git a/static/js/ui_init.js b/static/js/ui_init.js index 6d42a4a3da..cd28d6a763 100644 --- a/static/js/ui_init.js +++ b/static/js/ui_init.js @@ -335,6 +335,7 @@ exports.initialize_everything = function () { panels.initialize(); typing.initialize(); starred_messages.initialize(); + user_status_ui.initialize(); }; $(function () { diff --git a/static/js/user_status.js b/static/js/user_status.js index 34de4b9ecd..2d59551ad6 100644 --- a/static/js/user_status.js +++ b/static/js/user_status.js @@ -13,6 +13,11 @@ exports.server_update = function (opts) { status_text: opts.status_text, }, idempotent: true, + success: function () { + if (opts.success) { + opts.success(); + } + }, }); }; diff --git a/static/js/user_status_ui.js b/static/js/user_status_ui.js new file mode 100644 index 0000000000..be8ca44758 --- /dev/null +++ b/static/js/user_status_ui.js @@ -0,0 +1,91 @@ +var user_status_ui = (function () { + +var exports = {}; + +exports.input_field = function () { + return $('.user_status_overlay input.user_status'); +}; + +exports.submit_button = function () { + return $('.user_status_overlay .set_user_status'); +}; + +exports.open_overlay = function () { + var overlay = $(".user_status_overlay"); + overlays.open_overlay({ + name: 'user_status_overlay', + overlay: overlay, + on_close: function () {}, + }); + + var user_id = people.my_current_user_id(); + var old_status_text = user_status.get_status_text(user_id); + var field = exports.input_field(); + field.val(old_status_text); + field.select(); + field.focus(); + + var button = exports.submit_button(); + button.attr('disabled', true); +}; + +exports.close_overlay = function () { + overlays.close_overlay('user_status_overlay'); +}; + +exports.submit_new_status = function () { + var user_id = people.my_current_user_id(); + var old_status_text = user_status.get_status_text(user_id) || ''; + old_status_text = old_status_text.trim(); + var new_status_text = exports.input_field().val().trim(); + + if (old_status_text === new_status_text) { + exports.close_overlay(); + return; + } + + user_status.server_update({ + status_text: new_status_text, + success: function () { + exports.close_overlay(); + }, + }); +}; + +exports.update_button = function () { + var user_id = people.my_current_user_id(); + var old_status_text = user_status.get_status_text(user_id) || ''; + old_status_text = old_status_text.trim(); + var new_status_text = exports.input_field().val().trim(); + var button = exports.submit_button(); + + if (old_status_text === new_status_text) { + button.attr('disabled', true); + } else { + button.attr('disabled', false); + } + + if (new_status_text === '') { + button.text(i18n.t('Clear')); + } else { + button.text(i18n.t('Change')); + } +}; + +exports.initialize = function () { + $('body').on('click', '.user_status_overlay .set_user_status', function () { + exports.submit_new_status(); + }); + + $('body').on('keyup', '.user_status_overlay input.user_status', function () { + exports.update_button(); + }); +}; + +return exports; + +}()); +if (typeof module !== 'undefined') { + module.exports = user_status_ui; +} +window.user_status_ui = user_status_ui; diff --git a/static/styles/user_status.scss b/static/styles/user_status.scss new file mode 100644 index 0000000000..b6f355997b --- /dev/null +++ b/static/styles/user_status.scss @@ -0,0 +1,28 @@ +.user_status_overlay .overlay-content { + width: 320px; + margin: 0 auto; + padding-left: 30px; + padding-right: 30px; + padding-bottom: 30px; + padding-top: 10px; + position: relative; + top: calc((30vh - 50px) / 2); + border-radius: 4px; + overflow: hidden; + + background-color: hsl(0, 0%, 100%); +} + +.user_status_overlay .user_status_change_title { + font-size: 130%; + font-weight: 600; + padding: 5px; +} + +.user_status_overlay input.user_status { + width: 170px; +}; + +.user_status_overlay button:focus { + font-weight: 650; +}; diff --git a/static/templates/user_info_popover_content.handlebars b/static/templates/user_info_popover_content.handlebars index 378bbf9b3d..c3a677cc95 100644 --- a/static/templates/user_info_popover_content.handlebars +++ b/static/templates/user_info_popover_content.handlebars @@ -95,4 +95,11 @@ {{/if}} + {{#if is_me}} +