compose: Disable unneeded control buttons in preview mode.

Buttons which change the content in the compose textarea were so far
enabled even in preview mode, and would work, but those changes would
not be reflected in the visible preview. This is extremely confusing,
and can lead to the possibility of a user accidentally changing the
content of the compose textarea while previewing, and sending that.

Now we disable those buttons in preview mode, both when composing a new
message and when editing an existing one. We still show the tooltips,
but grey them out and make them unclickable.

Fixes: #20962
This commit is contained in:
yogesh sirsat 2022-01-30 20:30:45 +05:30 committed by Tim Abbott
parent aaf3369d39
commit 953f026487
7 changed files with 48 additions and 10 deletions

View File

@ -123,6 +123,11 @@ export function clear_preview_area() {
$("#compose .preview_content").empty();
$("#compose .markdown_preview").show();
autosize.update($("#compose-textarea"));
// While in preview mode we disable unneeded compose_control_buttons,
// so here we are re-enabling that compose_control_buttons
$("#compose").removeClass("preview_mode");
$("#compose .preview_mode_disabled .compose_control_button").attr("tabindex", 0);
}
export function abort_xhr() {
@ -719,6 +724,11 @@ export function initialize() {
e.preventDefault();
e.stopPropagation();
// Disable unneeded compose_control_buttons as we don't
// need them in preview mode.
$("#compose").addClass("preview_mode");
$("#compose .preview_mode_disabled .compose_control_button").attr("tabindex", -1);
const content = $("#compose-textarea").val();
$("#compose-textarea").hide();
$("#compose .markdown_preview").hide();

View File

@ -515,6 +515,7 @@ export function initialize() {
parse_html(
render_compose_control_buttons_popover({
giphy_enabled: giphy.is_giphy_enabled(),
preview_mode_on: $("#compose").hasClass("preview_mode"),
}),
),
);

View File

@ -943,3 +943,14 @@ input.recipient_box {
flex: 1;
}
}
.preview_mode {
.preview_mode_disabled {
cursor: not-allowed;
opacity: 0.3;
.compose_control_button {
pointer-events: none;
}
}
}

View File

@ -1,16 +1,22 @@
<div class="compose_control_buttons_container order-1">
<input type="file" class="file_input notvisible" multiple />
{{#if file_upload_enabled }}
<a role="button" class="compose_control_button compose_upload_file fa fa-paperclip notdisplayed" aria-label="{{t 'Upload files' }}" tabindex=0 data-tippy-content="{{t 'Upload files' }}"></a>
<div class="compose_control_button_container preview_mode_disabled" data-tippy-content="{{t 'Upload files' }}">
<a role="button" class="compose_control_button compose_upload_file fa fa-paperclip notdisplayed" aria-label="{{t 'Upload files' }}" tabindex=0></a>
</div>
{{/if}}
<a role="button" class="markdown_preview compose_control_button fa fa-eye" aria-label="{{t 'Preview' }}" tabindex=0 data-tippy-content="{{t 'Preview' }}"></a>
<a role="button" class="undo_markdown_preview compose_control_button fa fa-edit" aria-label="{{t 'Write' }}" tabindex=0 style="display:none;" data-tippy-content="{{t 'Write' }}"></a>
<a role="button" class="compose_control_button fa fa-video-camera video_link" aria-label="{{t 'Add video call' }}" tabindex=0 data-tippy-content="{{t 'Add video call' }}"></a>
<div class="compose_control_button_container" data-tippy-content="{{t 'Add emoji' }}">
<div class="compose_control_button_container preview_mode_disabled" data-tippy-content="{{t 'Add video call' }}">
<a role="button" class="compose_control_button fa fa-video-camera video_link" aria-label="{{t 'Add video call' }}" tabindex=0></a>
</div>
<div class="compose_control_button_container preview_mode_disabled" data-tippy-content="{{t 'Add emoji' }}">
<a role="button" class="compose_control_button fa fa-smile-o emoji_map" aria-label="{{t 'Add emoji' }}" tabindex=0></a>
</div>
<a role="button" class="compose_control_button fa fa-clock-o time_pick" aria-label="{{t 'Add global time' }}" tabindex=0 data-tooltip-template-id="add-global-time-tooltip" data-tippy-maxWidth="none"></a>
<div class="compose_control_button_container {{#unless giphy_enabled }}hide{{/unless}}" data-tippy-content="{{t 'Add GIF' }}">
<div class="compose_control_button_container preview_mode_disabled" data-tooltip-template-id="add-global-time-tooltip" data-tippy-maxWidth="none">
<a role="button" class="compose_control_button fa fa-clock-o time_pick" aria-label="{{t 'Add global time' }}" tabindex=0></a>
</div>
<div class="compose_control_button_container {{#unless giphy_enabled }}hide{{/unless}} preview_mode_disabled" data-tippy-content="{{t 'Add GIF' }}">
<a role="button" class="compose_control_button compose_gif_icon zulip-icon zulip-icon-gif" aria-label="{{t 'Add GIF' }}" tabindex=0></a>
</div>
<div class="divider hide-sm">|</div>

View File

@ -1,5 +1,7 @@
<a role="button" data-format-type="bold" class="compose_control_button fa fa-bold formatting_button" aria-label="{{t 'Bold' }}" tabindex=0 data-tippy-content="{{t 'Bold' }}"></a>
<a role="button" data-format-type="italic" class="compose_control_button fa fa-italic formatting_button" aria-label="{{t 'Italic' }}" tabindex=0 data-tippy-content="{{t 'Italic' }}"></a>
<a role="button" data-format-type="link" class="compose_control_button fa fa-link formatting_button" aria-label="{{t 'Link' }}" tabindex=0 data-tippy-content="{{t 'Link' }}"></a>
<div class="divider hide-sm">|</div>
<div class="compose_control_buttons_container preview_mode_disabled">
<a role="button" data-format-type="bold" class="compose_control_button fa fa-bold formatting_button" aria-label="{{t 'Bold' }}" {{#unless preview_mode_on}} tabindex=0 {{/unless}} data-tippy-content="{{t 'Bold' }}"></a>
<a role="button" data-format-type="italic" class="compose_control_button fa fa-italic formatting_button" aria-label="{{t 'Italic' }}" {{#unless preview_mode_on}} tabindex=0 {{/unless}} data-tippy-content="{{t 'Italic' }}"></a>
<a role="button" data-format-type="link" class="compose_control_button fa fa-link formatting_button" aria-label="{{t 'Link' }}" {{#unless preview_mode_on}} tabindex=0 {{/unless}} data-tippy-content="{{t 'Link' }}"></a>
<div class="divider hide-sm">|</div>
</div>
<a role="button" class="compose_control_button compose_help_button fa fa-question" tabindex=0 data-tippy-content="{{t 'Message formatting' }}" data-overlay-trigger="message-formatting"></a>

View File

@ -1,3 +1,3 @@
<div class="compose_control_buttons_container order-1">
<div class="compose_control_buttons_container order-1 {{#if preview_mode_on}} preview_mode {{/if}}">
{{> compose_control_buttons_in_popover}}
</div>

View File

@ -324,6 +324,7 @@ test_ui("enter_with_preview_open", ({override, override_rewire}) => {
$("#compose .undo_markdown_preview").show();
$("#compose .preview_message_area").show();
$("#compose .markdown_preview").hide();
$("#compose").addClass("preview_mode");
user_settings.enter_sends = true;
let send_message_called = false;
override_rewire(compose, "send_message", () => {
@ -334,6 +335,7 @@ test_ui("enter_with_preview_open", ({override, override_rewire}) => {
assert.ok(!$("#compose .undo_markdown_preview").visible());
assert.ok(!$("#compose .preview_message_area").visible());
assert.ok($("#compose .markdown_preview").visible());
assert.ok(!$("#compose").hasClass("preview_mode"));
assert.ok(send_message_called);
assert.ok(show_button_spinner_called);
@ -386,6 +388,7 @@ test_ui("finish", ({override, override_rewire}) => {
$("#compose .undo_markdown_preview").show();
$("#compose .preview_message_area").show();
$("#compose .markdown_preview").hide();
$("#compsoe").addClass("preview_mode");
$("#compose-textarea").val("foobarfoobar");
override_rewire(compose_ui, "compose_spinner_visible", false);
compose_state.set_message_type("private");
@ -405,6 +408,7 @@ test_ui("finish", ({override, override_rewire}) => {
assert.ok(!$("#compose .undo_markdown_preview").visible());
assert.ok(!$("#compose .preview_message_area").visible());
assert.ok($("#compose .markdown_preview").visible());
assert.ok(!$("#compose").hasClass("preview_mode"));
assert.ok(send_message_called);
assert.ok(compose_finished_event_checked);
})();
@ -579,6 +583,7 @@ test_ui("on_events", ({override, override_rewire}) => {
$("#compose .markdown_preview").show();
$("#compose .undo_markdown_preview").hide();
$("#compose .preview_message_area").hide();
$("#compose").removeClass("preview_mode");
}
function assert_visibilities() {
@ -586,6 +591,7 @@ test_ui("on_events", ({override, override_rewire}) => {
assert.ok(!$("#compose .markdown_preview").visible());
assert.ok($("#compose .undo_markdown_preview").visible());
assert.ok($("#compose .preview_message_area").visible());
assert.ok($("#compose").hasClass("preview_mode"));
}
function setup_mock_markdown_contains_backend_only_syntax(msg_content, return_val) {
@ -704,6 +710,7 @@ test_ui("on_events", ({override, override_rewire}) => {
$("#compose .undo_markdown_preview").show();
$("#compose .preview_message_area").show();
$("#compose .markdown_preview").hide();
$("#compose").removeClass("preview_mode");
const event = {
preventDefault: noop,
@ -718,6 +725,7 @@ test_ui("on_events", ({override, override_rewire}) => {
assert.ok(!$("#compose .undo_markdown_preview").visible());
assert.ok(!$("#compose .preview_message_area").visible());
assert.ok($("#compose .markdown_preview").visible());
assert.ok(!$("#compose").hasClass("preview_mode"));
})();
});