FEATURE: Don't show the draft checkmark when drafts are saved ()

We don't want to show the draft checkmark in the composer when drafts are saved, as it’s a little bit distracting to see it keeps appearing and disappearing. Only in the case of error does it need to show anything, we will be showing a "drafts offline" warning as we did it before.

An important detail is that the warning was appearing and disappearing all the time too. Now, the warning won’t be flashing while a user is typing, it’ll be disappearing only when the draft was eventually saved.
This commit is contained in:
Andrei Prigorshnev 2021-06-08 13:22:49 +04:00 committed by GitHub
parent 393dafce7d
commit 9e426d33c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 56 additions and 36 deletions
app/assets
javascripts/discourse
stylesheets/common/base

@ -1,6 +1,6 @@
import EmberObject, { set } from "@ember/object"; import EmberObject, { set } from "@ember/object";
import { and, equal, not, or, reads } from "@ember/object/computed"; import { and, equal, not, or, reads } from "@ember/object/computed";
import { cancel, later, next, throttle } from "@ember/runloop"; import { next, throttle } from "@ember/runloop";
import discourseComputed, { import discourseComputed, {
observes, observes,
on, on,
@ -113,7 +113,6 @@ const Composer = RestModel.extend({
unlistTopic: false, unlistTopic: false,
noBump: false, noBump: false,
draftSaving: false, draftSaving: false,
draftSaved: false,
draftForceSave: false, draftForceSave: false,
archetypes: reads("site.archetypes"), archetypes: reads("site.archetypes"),
@ -1190,16 +1189,10 @@ const Composer = RestModel.extend({
} }
this.setProperties({ this.setProperties({
draftSaved: false,
draftSaving: true, draftSaving: true,
draftConflictUser: null, draftConflictUser: null,
}); });
if (this._clearingStatus) {
cancel(this._clearingStatus);
this._clearingStatus = null;
}
let data = this.serialize(_draft_serializer); let data = this.serialize(_draft_serializer);
if (data.postId && !isEmpty(this.originalText)) { if (data.postId && !isEmpty(this.originalText)) {
@ -1224,7 +1217,7 @@ const Composer = RestModel.extend({
}); });
} else { } else {
this.setProperties({ this.setProperties({
draftSaved: true, draftStatus: null,
draftConflictUser: null, draftConflictUser: null,
draftForceSave: false, draftForceSave: false,
}); });
@ -1276,23 +1269,6 @@ const Composer = RestModel.extend({
this.set("draftSaving", false); this.set("draftSaving", false);
}); });
}, },
@observes("title", "reply")
dataChanged() {
const draftStatus = this.draftStatus;
if (draftStatus && !this._clearingStatus) {
this._clearingStatus = later(
this,
() => {
this.setProperties({ draftStatus: null, draftConflictUser: null });
this._clearingStatus = null;
this.setProperties({ draftSaving: false, draftSaved: false });
},
Ember.Test ? 0 : 1000
);
}
},
}); });
Composer.reopenClass({ Composer.reopenClass({

@ -175,14 +175,12 @@
</div> </div>
{{/if}} {{/if}}
<div class={{if isUploading "hidden"}} id="draft-status"> <div class={{if isUploading "hidden"}} id="draft-status">
{{#if model.draftSaving}}<div class="spinner small"></div>{{/if}}
{{#if model.draftSaved}}{{d-icon "check" class="save-animation"}}{{/if}}
{{#if model.draftStatus}} {{#if model.draftStatus}}
<span title={{model.draftStatus}}> <span title={{model.draftStatus}}>
{{#if model.draftConflictUser}} {{#if model.draftConflictUser}}
{{avatar model.draftConflictUser imageSize="small"}} {{d-icon "user-edit"}} {{avatar model.draftConflictUser imageSize="small"}} {{d-icon "user-edit"}}
{{else}} {{else}}
{{d-icon "sync-alt"}} {{d-icon "exclamation-triangle"}}
{{/if}} {{/if}}
{{#unless site.mobileView}} {{#unless site.mobileView}}
{{model.draftStatus}} {{model.draftStatus}}

@ -0,0 +1,53 @@
import {
acceptance,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import { click, fillIn, visit } from "@ember/test-helpers";
import { test } from "qunit";
import I18n from "I18n";
acceptance("Composer - Draft saving", function (needs) {
needs.user();
const draftThatWillBeSaved = "This_will_be_saved_successfully";
needs.pretender((server, helper) => {
server.post("/draft.json", (request) => {
const success = request.requestBody.includes(draftThatWillBeSaved);
return success
? helper.response({ success: true })
: helper.response(500, {});
});
});
test("Shows a warning if a draft wasn't saved", async function (assert) {
await visit("/t/internationalization-localization/280");
await click(".topic-post:nth-of-type(1) button.show-more-actions");
await click(".topic-post:nth-of-type(1) button.edit");
await fillIn(".d-editor-input", draftThatWillBeSaved);
assert.notOk(
exists("div#draft-status span"),
"the draft was saved, there's no warning"
);
await fillIn(".d-editor-input", "This won't be saved because of error");
assert.equal(
query("div#draft-status span").innerText.trim(),
I18n.t("composer.drafts_offline"),
"the draft wasn't saved, a warning is rendered"
);
assert.ok(
exists("div#draft-status svg.d-icon-exclamation-triangle"),
"an exclamation icon is rendered"
);
await fillIn(".d-editor-input", draftThatWillBeSaved);
assert.notOk(
exists("div#draft-status span"),
"the draft was saved again, the warning has disappeared"
);
});
});

@ -698,8 +698,6 @@ acceptance("Composer", function (needs) {
), ),
"mode should have changed" "mode should have changed"
); );
assert.ok(queryAll(".save-animation"), "save animation should show");
} finally { } finally {
toggleCheckDraftPopup(false); toggleCheckDraftPopup(false);
} }

@ -482,11 +482,6 @@ div.ac-wrap {
} }
} }
.save-animation {
-webkit-animation: transformer 5s forwards;
animation: transformer 5s forwards;
}
@-webkit-keyframes transformer { @-webkit-keyframes transformer {
90% { 90% {
-webkit-filter: opacity(1); -webkit-filter: opacity(1);