FEATURE: Rename onboarding popups to user tips (#18826)
This commit also hides the new user tips for existing users.
This commit is contained in:
parent
3d376c71b6
commit
4dad7816b2
|
@ -238,7 +238,7 @@ const SiteHeaderComponent = MountWidget.extend(
|
||||||
this.currentUser.on("status-changed", this, "queueRerender");
|
this.currentUser.on("status-changed", this, "queueRerender");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.siteSettings.enable_onboarding_popups) {
|
if (!this.siteSettings.enable_user_tips) {
|
||||||
if (
|
if (
|
||||||
this.currentUser &&
|
this.currentUser &&
|
||||||
!this.get("currentUser.read_first_notification")
|
!this.get("currentUser.read_first_notification")
|
||||||
|
|
|
@ -420,7 +420,7 @@ export default Controller.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
resetSeenPopups() {
|
resetSeenUserTips() {
|
||||||
this.model.set("skip_new_user_tips", false);
|
this.model.set("skip_new_user_tips", false);
|
||||||
this.model.set("seen_popups", null);
|
this.model.set("seen_popups", null);
|
||||||
this.model.set("user_option.skip_new_user_tips", false);
|
this.model.set("user_option.skip_new_user_tips", false);
|
||||||
|
|
|
@ -6,8 +6,8 @@ import tippy from "tippy.js";
|
||||||
const instances = {};
|
const instances = {};
|
||||||
const queue = [];
|
const queue = [];
|
||||||
|
|
||||||
export function showPopup(options) {
|
export function showUserTip(options) {
|
||||||
hidePopup(options.id);
|
hideUserTip(options.id);
|
||||||
|
|
||||||
if (!options.reference) {
|
if (!options.reference) {
|
||||||
return;
|
return;
|
||||||
|
@ -23,7 +23,7 @@ export function showPopup(options) {
|
||||||
showOnCreate: true,
|
showOnCreate: true,
|
||||||
hideOnClick: false,
|
hideOnClick: false,
|
||||||
trigger: "manual",
|
trigger: "manual",
|
||||||
theme: "d-onboarding",
|
theme: "user-tips",
|
||||||
|
|
||||||
// It must be interactive to make buttons work.
|
// It must be interactive to make buttons work.
|
||||||
interactive: true,
|
interactive: true,
|
||||||
|
@ -40,17 +40,15 @@ export function showPopup(options) {
|
||||||
allowHTML: true,
|
allowHTML: true,
|
||||||
|
|
||||||
content: `
|
content: `
|
||||||
<div class='onboarding-popup-container'>
|
<div class='user-tip-container'>
|
||||||
<div class='onboarding-popup-title'>${escape(options.titleText)}</div>
|
<div class='user-tip-title'>${escape(options.titleText)}</div>
|
||||||
<div class='onboarding-popup-content'>${escape(
|
<div class='user-tip-content'>${escape(options.contentText)}</div>
|
||||||
options.contentText
|
<div class='user-tip-buttons'>
|
||||||
)}</div>
|
|
||||||
<div class='onboarding-popup-buttons'>
|
|
||||||
<button class="btn btn-primary btn-dismiss">${escape(
|
<button class="btn btn-primary btn-dismiss">${escape(
|
||||||
options.primaryBtnText || I18n.t("popup.primary")
|
options.primaryBtnText || I18n.t("user_tips.primary")
|
||||||
)}</button>
|
)}</button>
|
||||||
<button class="btn btn-flat btn-text btn-dismiss-all">${escape(
|
<button class="btn btn-flat btn-text btn-dismiss-all">${escape(
|
||||||
options.secondaryBtnText || I18n.t("popup.secondary")
|
options.secondaryBtnText || I18n.t("user_tips.secondary")
|
||||||
)}</button>
|
)}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>`,
|
</div>`,
|
||||||
|
@ -73,12 +71,12 @@ export function showPopup(options) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hidePopup(popupId) {
|
export function hideUserTip(userTipId) {
|
||||||
const instance = instances[popupId];
|
const instance = instances[userTipId];
|
||||||
if (instance && !instance.state.isDestroyed) {
|
if (instance && !instance.state.isDestroyed) {
|
||||||
instance.destroy();
|
instance.destroy();
|
||||||
}
|
}
|
||||||
delete instances[popupId];
|
delete instances[userTipId];
|
||||||
}
|
}
|
||||||
|
|
||||||
function addToQueue(options) {
|
function addToQueue(options) {
|
||||||
|
@ -92,9 +90,9 @@ function addToQueue(options) {
|
||||||
queue.push(options);
|
queue.push(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showNextPopup() {
|
export function showNextUserTip() {
|
||||||
const options = queue.shift();
|
const options = queue.shift();
|
||||||
if (options) {
|
if (options) {
|
||||||
showPopup(options);
|
showUserTip(options);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -43,7 +43,11 @@ import Evented from "@ember/object/evented";
|
||||||
import { cancel } from "@ember/runloop";
|
import { cancel } from "@ember/runloop";
|
||||||
import discourseLater from "discourse-common/lib/later";
|
import discourseLater from "discourse-common/lib/later";
|
||||||
import { isTesting } from "discourse-common/config/environment";
|
import { isTesting } from "discourse-common/config/environment";
|
||||||
import { hidePopup, showNextPopup, showPopup } from "discourse/lib/popup";
|
import {
|
||||||
|
hideUserTip,
|
||||||
|
showNextUserTip,
|
||||||
|
showUserTip,
|
||||||
|
} from "discourse/lib/user-tips";
|
||||||
|
|
||||||
export const SECOND_FACTOR_METHODS = {
|
export const SECOND_FACTOR_METHODS = {
|
||||||
TOTP: 1,
|
TOTP: 1,
|
||||||
|
@ -1090,57 +1094,68 @@ const User = RestModel.extend({
|
||||||
return [...trackedTags, ...watchedTags, ...watchingFirstPostTags];
|
return [...trackedTags, ...watchedTags, ...watchingFirstPostTags];
|
||||||
},
|
},
|
||||||
|
|
||||||
showPopup(options) {
|
showUserTip(options) {
|
||||||
const popupTypes = Site.currentProp("onboarding_popup_types");
|
const userTips = Site.currentProp("user_tips");
|
||||||
if (!popupTypes[options.id]) {
|
if (!userTips || this.skip_new_user_tips) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userTips[options.id]) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.warn("Cannot display popup with type =", options.id);
|
console.warn("Cannot show user tip with type =", options.id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const seenPopups = this.seen_popups || [];
|
const seenUserTips = this.seen_popups || [];
|
||||||
if (seenPopups.includes(popupTypes[options.id])) {
|
if (
|
||||||
|
seenUserTips.includes(-1) ||
|
||||||
|
seenUserTips.includes(userTips[options.id])
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
showPopup({
|
showUserTip({
|
||||||
...options,
|
...options,
|
||||||
onDismiss: () => this.hidePopupForever(options.id),
|
onDismiss: () => this.hideUserTipForever(options.id),
|
||||||
onDismissAll: () => this.hidePopupForever(),
|
onDismissAll: () => this.hideUserTipForever(),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
hidePopupForever(popupId) {
|
hideUserTipForever(userTipId) {
|
||||||
// Empty popupId means all popups.
|
const userTips = Site.currentProp("user_tips");
|
||||||
const popupTypes = Site.currentProp("onboarding_popup_types");
|
if (!userTips || this.skip_new_user_tips) {
|
||||||
if (popupId && !popupTypes[popupId]) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.warn("Cannot hide popup with type =", popupId);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide any shown popups.
|
// Empty userTipId means all user tips.
|
||||||
let seenPopups = this.seen_popups || [];
|
if (userTipId && !userTips[userTipId]) {
|
||||||
if (popupId) {
|
// eslint-disable-next-line no-console
|
||||||
hidePopup(popupId);
|
console.warn("Cannot hide user tip with type =", userTipId);
|
||||||
if (!seenPopups.includes(popupTypes[popupId])) {
|
return;
|
||||||
seenPopups.push(popupTypes[popupId]);
|
}
|
||||||
|
|
||||||
|
// Hide any shown user tips.
|
||||||
|
let seenUserTips = this.seen_popups || [];
|
||||||
|
if (userTipId) {
|
||||||
|
hideUserTip(userTipId);
|
||||||
|
if (!seenUserTips.includes(userTips[userTipId])) {
|
||||||
|
seenUserTips.push(userTips[userTipId]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Object.keys(popupTypes).forEach(hidePopup);
|
Object.keys(userTips).forEach(hideUserTip);
|
||||||
seenPopups = Object.values(popupTypes);
|
seenUserTips = [-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show next popup in queue.
|
// Show next user tip in queue.
|
||||||
showNextPopup();
|
showNextUserTip();
|
||||||
|
|
||||||
// Save seen popups on the server.
|
// Save seen user tips on the server.
|
||||||
if (!this.user_option) {
|
if (!this.user_option) {
|
||||||
this.set("user_option", {});
|
this.set("user_option", {});
|
||||||
}
|
}
|
||||||
this.set("seen_popups", seenPopups);
|
this.set("seen_popups", seenUserTips);
|
||||||
this.set("user_option.seen_popups", seenPopups);
|
this.set("user_option.seen_popups", seenUserTips);
|
||||||
if (popupId) {
|
if (userTipId) {
|
||||||
return this.save(["seen_popups"]);
|
return this.save(["seen_popups"]);
|
||||||
} else {
|
} else {
|
||||||
this.set("skip_new_user_tips", true);
|
this.set("skip_new_user_tips", true);
|
||||||
|
|
|
@ -117,8 +117,8 @@
|
||||||
<ComboBox @valueProperty="value" @content={{this.titleCountModes}} @value={{this.model.user_option.title_count_mode}} @id="user-title-count-mode" @onChange={{action (mut this.model.user_option.title_count_mode)}} />
|
<ComboBox @valueProperty="value" @content={{this.titleCountModes}} @value={{this.model.user_option.title_count_mode}} @id="user-title-count-mode" @onChange={{action (mut this.model.user_option.title_count_mode)}} />
|
||||||
</div>
|
</div>
|
||||||
<PreferenceCheckbox @labelKey="user.skip_new_user_tips.description" @checked={{this.model.user_option.skip_new_user_tips}} @class="pref-new-user-tips" />
|
<PreferenceCheckbox @labelKey="user.skip_new_user_tips.description" @checked={{this.model.user_option.skip_new_user_tips}} @class="pref-new-user-tips" />
|
||||||
{{#if this.site.onboarding_popup_types}}
|
{{#if this.site.user_tips}}
|
||||||
<DButton @class="pref-reset-seen-popups" @action={{action "resetSeenPopups"}}>{{i18n "user.reset_seen_popups"}}</DButton>
|
<DButton @class="pref-reset-seen-user-tips" @action={{action "resetSeenUserTips"}}>{{i18n "user.reset_seen_user_tips"}}</DButton>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { wantsNewWindow } from "discourse/lib/intercept-click";
|
||||||
import { logSearchLinkClick } from "discourse/lib/search";
|
import { logSearchLinkClick } from "discourse/lib/search";
|
||||||
import RenderGlimmer from "discourse/widgets/render-glimmer";
|
import RenderGlimmer from "discourse/widgets/render-glimmer";
|
||||||
import { hbs } from "ember-cli-htmlbars";
|
import { hbs } from "ember-cli-htmlbars";
|
||||||
import { hidePopup } from "discourse/lib/popup";
|
import { hideUserTip } from "discourse/lib/user-tips";
|
||||||
|
|
||||||
let _extraHeaderIcons = [];
|
let _extraHeaderIcons = [];
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ createWidget("header-notifications", {
|
||||||
const count = unread + reviewables;
|
const count = unread + reviewables;
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
if (this._shouldHighlightAvatar()) {
|
if (this._shouldHighlightAvatar()) {
|
||||||
if (this.siteSettings.enable_onboarding_popups) {
|
if (this.siteSettings.enable_user_tips) {
|
||||||
contents.push(h("span.ring"));
|
contents.push(h("span.ring"));
|
||||||
} else {
|
} else {
|
||||||
this._addAvatarHighlight(contents);
|
this._addAvatarHighlight(contents);
|
||||||
|
@ -124,7 +124,7 @@ createWidget("header-notifications", {
|
||||||
const unreadHighPriority = user.unread_high_priority_notifications;
|
const unreadHighPriority = user.unread_high_priority_notifications;
|
||||||
if (!!unreadHighPriority) {
|
if (!!unreadHighPriority) {
|
||||||
if (this._shouldHighlightAvatar()) {
|
if (this._shouldHighlightAvatar()) {
|
||||||
if (this.siteSettings.enable_onboarding_popups) {
|
if (this.siteSettings.enable_user_tips) {
|
||||||
contents.push(h("span.ring"));
|
contents.push(h("span.ring"));
|
||||||
} else {
|
} else {
|
||||||
this._addAvatarHighlight(contents);
|
this._addAvatarHighlight(contents);
|
||||||
|
@ -198,17 +198,17 @@ createWidget("header-notifications", {
|
||||||
didRenderWidget() {
|
didRenderWidget() {
|
||||||
if (
|
if (
|
||||||
!this.currentUser ||
|
!this.currentUser ||
|
||||||
!this.siteSettings.enable_onboarding_popups ||
|
!this.siteSettings.enable_user_tips ||
|
||||||
!this._shouldHighlightAvatar()
|
!this._shouldHighlightAvatar()
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentUser.showPopup({
|
this.currentUser.showUserTip({
|
||||||
id: "first_notification",
|
id: "first_notification",
|
||||||
|
|
||||||
titleText: I18n.t("popup.first_notification.title"),
|
titleText: I18n.t("user_tips.first_notification.title"),
|
||||||
contentText: I18n.t("popup.first_notification.content"),
|
contentText: I18n.t("user_tips.first_notification.content"),
|
||||||
|
|
||||||
reference: document
|
reference: document
|
||||||
.querySelector(".badge-notification")
|
.querySelector(".badge-notification")
|
||||||
|
@ -219,11 +219,11 @@ createWidget("header-notifications", {
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
hidePopup("first_notification");
|
hideUserTip("first_notification");
|
||||||
},
|
},
|
||||||
|
|
||||||
willRerenderWidget() {
|
willRerenderWidget() {
|
||||||
hidePopup("first_notification");
|
hideUserTip("first_notification");
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import discourseLater from "discourse-common/lib/later";
|
||||||
import { relativeAge } from "discourse/lib/formatter";
|
import { relativeAge } from "discourse/lib/formatter";
|
||||||
import renderTags from "discourse/lib/render-tags";
|
import renderTags from "discourse/lib/render-tags";
|
||||||
import renderTopicFeaturedLink from "discourse/lib/render-topic-featured-link";
|
import renderTopicFeaturedLink from "discourse/lib/render-topic-featured-link";
|
||||||
import { hidePopup } from "discourse/lib/popup";
|
import { hideUserTip } from "discourse/lib/user-tips";
|
||||||
|
|
||||||
const SCROLLER_HEIGHT = 50;
|
const SCROLLER_HEIGHT = 50;
|
||||||
const LAST_READ_HEIGHT = 20;
|
const LAST_READ_HEIGHT = 20;
|
||||||
|
@ -601,15 +601,15 @@ export default createWidget("topic-timeline", {
|
||||||
},
|
},
|
||||||
|
|
||||||
didRenderWidget() {
|
didRenderWidget() {
|
||||||
if (!this.currentUser || !this.siteSettings.enable_onboarding_popups) {
|
if (!this.currentUser || !this.siteSettings.enable_user_tips) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentUser.showPopup({
|
this.currentUser.showUserTip({
|
||||||
id: "topic_timeline",
|
id: "topic_timeline",
|
||||||
|
|
||||||
titleText: I18n.t("popup.topic_timeline.title"),
|
titleText: I18n.t("user_tips.topic_timeline.title"),
|
||||||
contentText: I18n.t("popup.topic_timeline.content"),
|
contentText: I18n.t("user_tips.topic_timeline.content"),
|
||||||
|
|
||||||
reference: document.querySelector("div.timeline-scrollarea-wrapper"),
|
reference: document.querySelector("div.timeline-scrollarea-wrapper"),
|
||||||
|
|
||||||
|
@ -618,10 +618,10 @@ export default createWidget("topic-timeline", {
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
hidePopup("topic_timeline");
|
hideUserTip("topic_timeline");
|
||||||
},
|
},
|
||||||
|
|
||||||
willRerenderWidget() {
|
willRerenderWidget() {
|
||||||
hidePopup("topic_timeline");
|
hideUserTip("topic_timeline");
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -144,18 +144,18 @@ acceptance("User Preferences - Interface", function (needs) {
|
||||||
document.querySelector("meta[name='discourse_theme_id']").remove();
|
document.querySelector("meta[name='discourse_theme_id']").remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("shows reset seen onboarding popups button", async function (assert) {
|
test("shows reset seen user tips popups button", async function (assert) {
|
||||||
let site = Site.current();
|
let site = Site.current();
|
||||||
site.set("onboarding_popup_types", { first_notification: 1 });
|
site.set("user_tips", { first_notification: 1 });
|
||||||
|
|
||||||
await visit("/u/eviltrout/preferences/interface");
|
await visit("/u/eviltrout/preferences/interface");
|
||||||
|
|
||||||
assert.ok(
|
assert.ok(
|
||||||
exists(".pref-reset-seen-popups"),
|
exists(".pref-reset-seen-user-tips"),
|
||||||
"has reset seen popups button"
|
"has reset seen user tips button"
|
||||||
);
|
);
|
||||||
|
|
||||||
await click(".pref-reset-seen-popups");
|
await click(".pref-reset-seen-user-tips");
|
||||||
|
|
||||||
assert.deepEqual(lastUserData, {
|
assert.deepEqual(lastUserData, {
|
||||||
seen_popups: "",
|
seen_popups: "",
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
@import "crawler_layout";
|
@import "crawler_layout";
|
||||||
@import "d-icon";
|
@import "d-icon";
|
||||||
@import "d-popover";
|
@import "d-popover";
|
||||||
@import "d-onboarding";
|
|
||||||
@import "dialog";
|
@import "dialog";
|
||||||
@import "directory";
|
@import "directory";
|
||||||
@import "discourse";
|
@import "discourse";
|
||||||
|
@ -59,4 +58,5 @@
|
||||||
@import "topic";
|
@import "topic";
|
||||||
@import "upload";
|
@import "upload";
|
||||||
@import "user-badges";
|
@import "user-badges";
|
||||||
|
@import "user-tips";
|
||||||
@import "user";
|
@import "user";
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
.onboarding-popup-container {
|
|
||||||
min-width: 300px;
|
|
||||||
padding: 0.5em;
|
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
.onboarding-popup-title {
|
|
||||||
font-size: $font-up-2;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.onboarding-popup-content {
|
|
||||||
margin-top: 0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.onboarding-popup-buttons {
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tippy-box[data-theme~="d-onboarding"][data-placement^="left"]
|
|
||||||
> .tippy-svg-arrow
|
|
||||||
> svg {
|
|
||||||
left: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tippy-box[data-theme~="d-onboarding"][data-placement^="bottom"]
|
|
||||||
> .tippy-svg-arrow
|
|
||||||
> svg {
|
|
||||||
top: -13px;
|
|
||||||
left: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tippy-box[data-theme~="d-onboarding"] > .tippy-svg-arrow:after,
|
|
||||||
.tippy-box[data-theme~="d-onboarding"] > .tippy-svg-arrow > svg {
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
.user-tip-container {
|
||||||
|
min-width: 300px;
|
||||||
|
padding: 0.5em;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
.user-tip-title {
|
||||||
|
font-size: $font-up-2;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-tip-content {
|
||||||
|
margin-top: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-tip-buttons {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tippy-box[data-theme~="user-tips"][data-placement^="left"]
|
||||||
|
> .tippy-svg-arrow
|
||||||
|
> svg {
|
||||||
|
left: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tippy-box[data-theme~="user-tips"][data-placement^="bottom"]
|
||||||
|
> .tippy-svg-arrow
|
||||||
|
> svg {
|
||||||
|
top: -13px;
|
||||||
|
left: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tippy-box[data-theme~="user-tips"] > .tippy-svg-arrow:after,
|
||||||
|
.tippy-box[data-theme~="user-tips"] > .tippy-svg-arrow > svg {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class OnboardingPopup
|
|
||||||
def self.types
|
|
||||||
@types ||= Enum.new(
|
|
||||||
first_notification: 1,
|
|
||||||
topic_timeline: 2,
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -284,6 +284,13 @@ class User < ActiveRecord::Base
|
||||||
|
|
||||||
MAX_STAFF_DELETE_POST_COUNT ||= 5
|
MAX_STAFF_DELETE_POST_COUNT ||= 5
|
||||||
|
|
||||||
|
def self.user_tips
|
||||||
|
@user_tips ||= Enum.new(
|
||||||
|
first_notification: 1,
|
||||||
|
topic_timeline: 2,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def visible_sidebar_tags(user_guardian = nil)
|
def visible_sidebar_tags(user_guardian = nil)
|
||||||
user_guardian ||= guardian
|
user_guardian ||= guardian
|
||||||
DiscourseTagging.filter_visible(custom_sidebar_tags, user_guardian)
|
DiscourseTagging.filter_visible(custom_sidebar_tags, user_guardian)
|
||||||
|
|
|
@ -293,7 +293,7 @@ class CurrentUserSerializer < BasicUserSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_seen_popups?
|
def include_seen_popups?
|
||||||
SiteSetting.enable_onboarding_popups
|
SiteSetting.enable_user_tips
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_primary_group_id?
|
def include_primary_group_id?
|
||||||
|
|
|
@ -6,7 +6,7 @@ class SiteSerializer < ApplicationSerializer
|
||||||
:default_archetype,
|
:default_archetype,
|
||||||
:notification_types,
|
:notification_types,
|
||||||
:post_types,
|
:post_types,
|
||||||
:onboarding_popup_types,
|
:user_tips,
|
||||||
:trust_levels,
|
:trust_levels,
|
||||||
:groups,
|
:groups,
|
||||||
:filters,
|
:filters,
|
||||||
|
@ -104,12 +104,12 @@ class SiteSerializer < ApplicationSerializer
|
||||||
Post.types
|
Post.types
|
||||||
end
|
end
|
||||||
|
|
||||||
def onboarding_popup_types
|
def user_tips
|
||||||
OnboardingPopup.types
|
User.user_tips
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_onboarding_popup_types?
|
def include_user_tips?
|
||||||
SiteSetting.enable_onboarding_popups
|
SiteSetting.enable_user_tips
|
||||||
end
|
end
|
||||||
|
|
||||||
def filters
|
def filters
|
||||||
|
|
|
@ -181,11 +181,7 @@ class UserUpdater
|
||||||
end
|
end
|
||||||
|
|
||||||
if attributes.key?(:skip_new_user_tips)
|
if attributes.key?(:skip_new_user_tips)
|
||||||
user.user_option.seen_popups = if user.user_option.skip_new_user_tips
|
user.user_option.seen_popups = user.user_option.skip_new_user_tips ? [-1] : nil
|
||||||
OnboardingPopup.types.values
|
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# automatically disable digests when mailing_list_mode is enabled
|
# automatically disable digests when mailing_list_mode is enabled
|
||||||
|
|
|
@ -1161,7 +1161,7 @@ en:
|
||||||
not_first_time: "Not your first time?"
|
not_first_time: "Not your first time?"
|
||||||
skip_link: "Skip these tips"
|
skip_link: "Skip these tips"
|
||||||
read_later: "I'll read it later."
|
read_later: "I'll read it later."
|
||||||
reset_seen_popups: "Show onboarding tips again"
|
reset_seen_user_tips: "Show user tips again"
|
||||||
theme_default_on_all_devices: "Make this the default theme on all my devices"
|
theme_default_on_all_devices: "Make this the default theme on all my devices"
|
||||||
color_scheme_default_on_all_devices: "Set default color scheme(s) on all my devices"
|
color_scheme_default_on_all_devices: "Set default color scheme(s) on all my devices"
|
||||||
color_scheme: "Color Scheme"
|
color_scheme: "Color Scheme"
|
||||||
|
@ -1827,7 +1827,7 @@ en:
|
||||||
what_are_you_doing: "What are you doing?"
|
what_are_you_doing: "What are you doing?"
|
||||||
remove_status: "Remove status"
|
remove_status: "Remove status"
|
||||||
|
|
||||||
popup:
|
user_tips:
|
||||||
primary: "Got it!"
|
primary: "Got it!"
|
||||||
secondary: "don't show me these tips"
|
secondary: "don't show me these tips"
|
||||||
|
|
||||||
|
|
|
@ -2354,7 +2354,7 @@ en:
|
||||||
sitemap_page_size: "Number of URLs to include in each sitemap page. Max 50.000"
|
sitemap_page_size: "Number of URLs to include in each sitemap page. Max 50.000"
|
||||||
|
|
||||||
enable_user_status: "(experimental) Allow users to set custom status message (emoji + description)."
|
enable_user_status: "(experimental) Allow users to set custom status message (emoji + description)."
|
||||||
enable_onboarding_popups: "(experimental) Enable educational popups that describe key features to users"
|
enable_user_tips: "(experimental) Enable new user tips that describe key features to users"
|
||||||
|
|
||||||
short_title: "The short title will be used on the user's home screen, launcher, or other places where space may be limited. It should be limited to 12 characters."
|
short_title: "The short title will be used on the user's home screen, launcher, or other places where space may be limited. It should be limited to 12 characters."
|
||||||
|
|
||||||
|
|
|
@ -379,7 +379,7 @@ basic:
|
||||||
enable_user_status:
|
enable_user_status:
|
||||||
client: true
|
client: true
|
||||||
default: false
|
default: false
|
||||||
enable_onboarding_popups:
|
enable_user_tips:
|
||||||
client: true
|
client: true
|
||||||
default: false
|
default: false
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class RenameOnboardingPopupsSiteSetting < ActiveRecord::Migration[7.0]
|
||||||
|
def up
|
||||||
|
execute "UPDATE site_settings SET name = 'enable_user_tips' WHERE name = 'enable_onboarding_popups'"
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
execute "UPDATE site_settings SET name = 'enable_onboarding_popups' WHERE name = 'enable_user_tips'"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class HideAllUserTipsForExistentUsers < ActiveRecord::Migration[7.0]
|
||||||
|
def up
|
||||||
|
execute "UPDATE user_options SET seen_popups = '{1, 2}'"
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
execute "UPDATE user_options SET seen_popups = '{}'"
|
||||||
|
end
|
||||||
|
end
|
|
@ -8,17 +8,17 @@ RSpec.describe SiteSerializer do
|
||||||
Site.clear_cache
|
Site.clear_cache
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#onboarding_popup_types' do
|
describe '#user_tips' do
|
||||||
it 'is included if enable_onboarding_popups' do
|
it 'is included if enable_user_tips' do
|
||||||
SiteSetting.enable_onboarding_popups = true
|
SiteSetting.enable_user_tips = true
|
||||||
|
|
||||||
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
||||||
expect(serialized[:onboarding_popup_types]).to eq(OnboardingPopup.types)
|
expect(serialized[:user_tips]).to eq(User.user_tips)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'is not included if enable_onboarding_popups is disabled' do
|
it 'is not included if enable_user_tips is disabled' do
|
||||||
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
||||||
expect(serialized[:onboarding_popup_types]).to eq(nil)
|
expect(serialized[:user_tips]).to eq(nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -530,7 +530,7 @@ RSpec.describe UserUpdater do
|
||||||
UserUpdater.new(Discourse.system_user, user).update(skip_new_user_tips: true)
|
UserUpdater.new(Discourse.system_user, user).update(skip_new_user_tips: true)
|
||||||
|
|
||||||
expect(user.user_option.skip_new_user_tips).to eq(true)
|
expect(user.user_option.skip_new_user_tips).to eq(true)
|
||||||
expect(user.user_option.seen_popups).to eq(OnboardingPopup.types.values)
|
expect(user.user_option.seen_popups).to eq([-1])
|
||||||
|
|
||||||
UserUpdater.new(Discourse.system_user, user).update(skip_new_user_tips: false)
|
UserUpdater.new(Discourse.system_user, user).update(skip_new_user_tips: false)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue