mirror of
https://github.com/discourse/discourse.git
synced 2025-03-25 01:05:35 +08:00
FEATURE: Don't show the draft checkmark when drafts are saved (#13292)
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:
parent
393dafce7d
commit
9e426d33c7
app/assets
javascripts/discourse
app
tests/acceptance
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user