FEATURE: improve blank page syndrome on the user activity pages (#14311)
This improves blank page syndrome on the next pages: * activity * activity/replies * activity/drafts * activity/likes-given
This commit is contained in:
parent
119bdc12ea
commit
477bbc372e
|
@ -60,10 +60,6 @@ export default RestModel.extend({
|
|||
return;
|
||||
}
|
||||
|
||||
if (result.no_results_help) {
|
||||
this.set("noContentHelp", result.no_results_help);
|
||||
}
|
||||
|
||||
if (!result.drafts) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -81,9 +81,6 @@ export default RestModel.extend({
|
|||
if (this.filterParam) {
|
||||
findUrl += `&filter=${this.filterParam}`;
|
||||
}
|
||||
if (this.noContentHelpKey) {
|
||||
findUrl += `&no_results_help_key=${this.noContentHelpKey}`;
|
||||
}
|
||||
|
||||
if (this.actingUsername) {
|
||||
findUrl += `&acting_username=${this.actingUsername}`;
|
||||
|
@ -102,9 +99,6 @@ export default RestModel.extend({
|
|||
this.set("loading", true);
|
||||
return ajax(findUrl)
|
||||
.then((result) => {
|
||||
if (result && result.no_results_help) {
|
||||
this.set("noContentHelp", result.no_results_help);
|
||||
}
|
||||
if (result && result.user_actions) {
|
||||
const copy = A();
|
||||
result.user_actions.forEach((action) => {
|
||||
|
|
|
@ -74,6 +74,14 @@ const DiscourseRoute = Route.extend({
|
|||
}
|
||||
},
|
||||
|
||||
isAnotherUsersPage(user) {
|
||||
if (!this.currentUser) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return user.username !== this.currentUser.username;
|
||||
},
|
||||
|
||||
isPoppedState(transition) {
|
||||
return !transition._discourse_intercepted && !!transition.intent.url;
|
||||
},
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default DiscourseRoute.extend({
|
||||
noContentHelpKey: "user_activity.no_bookmarks",
|
||||
|
||||
queryParams: {
|
||||
acting_username: { refreshModel: true },
|
||||
},
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
import I18n from "I18n";
|
||||
|
||||
export default DiscourseRoute.extend({
|
||||
model() {
|
||||
const model = this.modelFor("user").get("userDraftsStream");
|
||||
model.reset();
|
||||
return model.findItems(this.site).then(() => model);
|
||||
const user = this.modelFor("user");
|
||||
const draftsStream = user.get("userDraftsStream");
|
||||
draftsStream.reset();
|
||||
|
||||
return draftsStream.findItems(this.site).then(() => {
|
||||
return {
|
||||
stream: draftsStream,
|
||||
isAnotherUsersPage: this.isAnotherUsersPage(user),
|
||||
emptyState: this.emptyState(),
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
renderTemplate() {
|
||||
|
@ -15,6 +24,12 @@ export default DiscourseRoute.extend({
|
|||
controller.set("model", model);
|
||||
},
|
||||
|
||||
emptyState() {
|
||||
const title = I18n.t("user_activity.no_drafts_title");
|
||||
const body = I18n.t("user_activity.no_drafts_body");
|
||||
return { title, body };
|
||||
},
|
||||
|
||||
activate() {
|
||||
this.appEvents.on("draft:destroyed", this, this.refresh);
|
||||
},
|
||||
|
|
|
@ -1,5 +1,20 @@
|
|||
import UserActivityStreamRoute from "discourse/routes/user-activity-stream";
|
||||
import { iconHTML } from "discourse-common/lib/icon-library";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
import I18n from "I18n";
|
||||
|
||||
export default UserActivityStreamRoute.extend({
|
||||
userActionType: null,
|
||||
|
||||
emptyState() {
|
||||
const title = I18n.t("user_activity.no_activity_title");
|
||||
const body = I18n.t("user_activity.no_activity_body", {
|
||||
topUrl: getURL("/top"),
|
||||
categoriesUrl: getURL("/categories"),
|
||||
preferencesUrl: getURL("/my/preferences"),
|
||||
heartIcon: iconHTML("heart"),
|
||||
}).htmlSafe();
|
||||
|
||||
return { title, body };
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,9 +1,20 @@
|
|||
import UserAction from "discourse/models/user-action";
|
||||
import UserActivityStreamRoute from "discourse/routes/user-activity-stream";
|
||||
import { iconHTML } from "discourse-common/lib/icon-library";
|
||||
import I18n from "I18n";
|
||||
|
||||
export default UserActivityStreamRoute.extend({
|
||||
userActionType: UserAction.TYPES["likes_given"],
|
||||
noContentHelpKey: "user_activity.no_likes_given",
|
||||
emptyStateOthers: I18n.t("user_activity.no_likes_others"),
|
||||
|
||||
emptyState() {
|
||||
const title = I18n.t("user_activity.no_likes_title");
|
||||
const body = I18n.t("user_activity.no_likes_body", {
|
||||
heartIcon: iconHTML("heart"),
|
||||
}).htmlSafe();
|
||||
|
||||
return { title, body };
|
||||
},
|
||||
|
||||
actions: {
|
||||
didTransition() {
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
import UserAction from "discourse/models/user-action";
|
||||
import UserActivityStreamRoute from "discourse/routes/user-activity-stream";
|
||||
import I18n from "I18n";
|
||||
|
||||
export default UserActivityStreamRoute.extend({
|
||||
userActionType: UserAction.TYPES["posts"],
|
||||
noContentHelpKey: "user_activity.no_replies",
|
||||
emptyStateOthers: I18n.t("user_activity.no_replies_others"),
|
||||
|
||||
emptyState() {
|
||||
const title = I18n.t("user_activity.no_replies_title");
|
||||
const body = "";
|
||||
return { title, body };
|
||||
},
|
||||
|
||||
actions: {
|
||||
didTransition() {
|
||||
|
|
|
@ -1,19 +1,30 @@
|
|||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
import ViewingActionType from "discourse/mixins/viewing-action-type";
|
||||
import { action } from "@ember/object";
|
||||
import I18n from "I18n";
|
||||
|
||||
export default DiscourseRoute.extend(ViewingActionType, {
|
||||
queryParams: {
|
||||
acting_username: { refreshModel: true },
|
||||
},
|
||||
|
||||
emptyStateOthers: I18n.t("user_activity.no_activity_others"),
|
||||
|
||||
model() {
|
||||
return this.modelFor("user").get("stream");
|
||||
const user = this.modelFor("user");
|
||||
const stream = user.get("stream");
|
||||
|
||||
return {
|
||||
stream,
|
||||
isAnotherUsersPage: this.isAnotherUsersPage(user),
|
||||
emptyState: this.emptyState(),
|
||||
emptyStateOthers: this.emptyStateOthers,
|
||||
};
|
||||
},
|
||||
|
||||
afterModel(model, transition) {
|
||||
return model.filterBy({
|
||||
return model.stream.filterBy({
|
||||
filter: this.userActionType,
|
||||
noContentHelpKey: this.noContentHelpKey || "user_activity.no_default",
|
||||
actingUsername: transition.to.queryParams.acting_username,
|
||||
});
|
||||
},
|
||||
|
@ -27,10 +38,15 @@ export default DiscourseRoute.extend(ViewingActionType, {
|
|||
this.viewingActionType(this.userActionType);
|
||||
},
|
||||
|
||||
actions: {
|
||||
didTransition() {
|
||||
this.controllerFor("user-activity")._showFooter();
|
||||
return true;
|
||||
},
|
||||
emptyState() {
|
||||
const title = I18n.t("user_activity.no_activity_title");
|
||||
const body = "";
|
||||
return { title, body };
|
||||
},
|
||||
|
||||
@action
|
||||
didTransition() {
|
||||
this.controllerFor("user-activity")._showFooter();
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
{{#if model.noContent}}
|
||||
<div class="alert alert-info">{{html-safe model.noContentHelp}}</div>
|
||||
{{#if model.stream.noContent}}
|
||||
{{#if model.isAnotherUsersPage}}
|
||||
<div class="alert alert-info">{{model.emptyStateOthers}}</div>
|
||||
{{else}}
|
||||
<div class="empty-state">
|
||||
<span class="empty-state-title">{{model.emptyState.title}}</span>
|
||||
<div class="empty-state-body">
|
||||
<p>{{model.emptyState.body}}</p>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{user-stream stream=model}}
|
||||
{{user-stream stream=model.stream}}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
import { acceptance, exists, query } from "../helpers/qunit-helpers";
|
||||
import { test } from "qunit";
|
||||
import { visit } from "@ember/test-helpers";
|
||||
import I18n from "I18n";
|
||||
|
||||
acceptance("User Activity / All - empty state", function (needs) {
|
||||
needs.user();
|
||||
|
||||
needs.pretender((server, helper) => {
|
||||
const emptyResponse = { user_actions: [] };
|
||||
|
||||
server.get("/user_actions.json", () => {
|
||||
return helper.response(emptyResponse);
|
||||
});
|
||||
});
|
||||
|
||||
test("When looking at own activity it renders the empty state panel", async function (assert) {
|
||||
await visit("/u/eviltrout/activity");
|
||||
assert.ok(exists("div.empty-state"));
|
||||
});
|
||||
|
||||
test("When looking at another user activity it renders the 'No activity' message", async function (assert) {
|
||||
await visit("/u/charlie/activity");
|
||||
assert.ok(exists("div.alert-info"));
|
||||
assert.equal(
|
||||
query("div.alert-info").innerText.trim(),
|
||||
I18n.t("user_activity.no_activity_others")
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
import { acceptance, exists } from "../helpers/qunit-helpers";
|
||||
import { test } from "qunit";
|
||||
import { visit } from "@ember/test-helpers";
|
||||
|
||||
acceptance("User Activity / Drafts - empty state", function (needs) {
|
||||
needs.user();
|
||||
|
||||
needs.pretender((server, helper) => {
|
||||
const emptyResponse = { drafts: [] };
|
||||
|
||||
server.get("/drafts.json", () => {
|
||||
return helper.response(emptyResponse);
|
||||
});
|
||||
});
|
||||
|
||||
test("It renders the empty state panel", async function (assert) {
|
||||
await visit("/u/eviltrout/activity/drafts");
|
||||
assert.ok(exists("div.empty-state"));
|
||||
});
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
import { acceptance, exists, query } from "../helpers/qunit-helpers";
|
||||
import { test } from "qunit";
|
||||
import { visit } from "@ember/test-helpers";
|
||||
import I18n from "I18n";
|
||||
|
||||
acceptance("User Activity / Likes - empty state", function (needs) {
|
||||
needs.user();
|
||||
|
||||
needs.pretender((server, helper) => {
|
||||
const emptyResponse = { user_actions: [] };
|
||||
|
||||
server.get("/user_actions.json", () => {
|
||||
return helper.response(emptyResponse);
|
||||
});
|
||||
});
|
||||
|
||||
test("When looking at own activity it renders the empty state panel", async function (assert) {
|
||||
await visit("/u/eviltrout/activity/likes-given");
|
||||
assert.ok(exists("div.empty-state"));
|
||||
});
|
||||
|
||||
test("When looking at another user activity it renders the 'No activity' message", async function (assert) {
|
||||
await visit("/u/charlie/activity/likes-given");
|
||||
assert.ok(exists("div.alert-info"));
|
||||
assert.equal(
|
||||
query("div.alert-info").innerText.trim(),
|
||||
I18n.t("user_activity.no_likes_others")
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
import { acceptance, exists, query } from "../helpers/qunit-helpers";
|
||||
import { test } from "qunit";
|
||||
import { visit } from "@ember/test-helpers";
|
||||
import I18n from "I18n";
|
||||
|
||||
acceptance("User Activity / Replies - empty state", function (needs) {
|
||||
needs.user();
|
||||
|
||||
needs.pretender((server, helper) => {
|
||||
const emptyResponse = { user_actions: [] };
|
||||
|
||||
server.get("/user_actions.json", () => {
|
||||
return helper.response(emptyResponse);
|
||||
});
|
||||
});
|
||||
|
||||
test("When looking at own activity it renders the empty state panel", async function (assert) {
|
||||
await visit("/u/eviltrout/activity/replies");
|
||||
assert.ok(exists("div.empty-state"));
|
||||
});
|
||||
|
||||
test("When looking at another user activity it renders the 'No activity' message", async function (assert) {
|
||||
await visit("/u/charlie/activity/replies");
|
||||
assert.ok(exists("div.alert-info"));
|
||||
assert.equal(
|
||||
query("div.alert-info").innerText.trim(),
|
||||
I18n.t("user_activity.no_replies_others")
|
||||
);
|
||||
});
|
||||
});
|
|
@ -3855,6 +3855,18 @@ en:
|
|||
pick_files_button:
|
||||
unsupported_file_picked: "You have picked an unsupported file. Supported file types – %{types}."
|
||||
|
||||
user_activity:
|
||||
no_activity_title: "No activity yet"
|
||||
no_activity_body: "Welcome to our community! You are brand new here and have not yet contributed to discussions. As a first step, visit <a href='%{topUrl}'>Top</a> or <a href='%{categoriesUrl}'>Categories</a> and just start reading! Select %{heartIcon} on posts that you like or want to learn more about. If you have not already done so, help others get to know you by adding a picture and bio in your <a href='%{preferencesUrl}'>user preferences</a>."
|
||||
no_activity_others: "No activity."
|
||||
no_replies_title: "You have not replied to any topics yet"
|
||||
no_replies_others: "No replies."
|
||||
no_drafts_title: "You haven’t started any drafts"
|
||||
no_drafts_body: "Not quite ready to post? We’ll automatically save a new draft and list it here whenever you start composing a topic, reply, or personal message. Select the cancel button to discard or save your draft to continue later."
|
||||
no_likes_title: "You haven’t liked any topics yet"
|
||||
no_likes_body: "A great way to jump in and start contributing is to start reading conversations that have already taken place, and select the %{heartIcon} on posts that you like!"
|
||||
no_likes_others: "No liked posts."
|
||||
|
||||
# This section is exported to the javascript for i18n in the admin section
|
||||
admin_js:
|
||||
type_to_filter: "type to filter..."
|
||||
|
|
|
@ -958,19 +958,10 @@ en:
|
|||
pm_title: "Backup Drafts from ongoing topics"
|
||||
pm_body: "Topic containing backup drafts"
|
||||
user_activity:
|
||||
no_default:
|
||||
self: "You have no activity yet."
|
||||
others: "No activity."
|
||||
no_bookmarks:
|
||||
self: "You have no bookmarked posts; bookmarks allow you to quickly refer to specific posts."
|
||||
search: "No bookmarks found with the provided search query."
|
||||
others: "No bookmarks."
|
||||
no_likes_given:
|
||||
self: "You have not liked any posts."
|
||||
others: "No liked posts."
|
||||
no_replies:
|
||||
self: "You have not replied to any posts."
|
||||
others: "No replies."
|
||||
no_drafts:
|
||||
self: "You have no drafts; begin composing a reply in any topic and it will be auto-saved as a new draft."
|
||||
|
||||
|
|
Loading…
Reference in New Issue