FEATURE: Let staff add custom post notices. (#7377)
This commit is contained in:
parent
ba6369edc5
commit
57d1dea8a2
|
@ -0,0 +1,59 @@
|
||||||
|
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||||
|
import computed from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
|
export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
|
post: null,
|
||||||
|
resolve: null,
|
||||||
|
reject: null,
|
||||||
|
|
||||||
|
notice: null,
|
||||||
|
saving: false,
|
||||||
|
|
||||||
|
@computed("saving", "notice")
|
||||||
|
disabled(saving, notice) {
|
||||||
|
return saving || Ember.isEmpty(notice);
|
||||||
|
},
|
||||||
|
|
||||||
|
onShow() {
|
||||||
|
this.setProperties({
|
||||||
|
notice: "",
|
||||||
|
saving: false
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onClose() {
|
||||||
|
const reject = this.get("reject");
|
||||||
|
if (reject) {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
setNotice() {
|
||||||
|
this.set("saving", true);
|
||||||
|
|
||||||
|
const post = this.get("post");
|
||||||
|
const resolve = this.get("resolve");
|
||||||
|
const reject = this.get("reject");
|
||||||
|
const notice = this.get("notice");
|
||||||
|
|
||||||
|
// Let `updatePostField` handle state.
|
||||||
|
this.setProperties({ resolve: null, reject: null });
|
||||||
|
|
||||||
|
post
|
||||||
|
.updatePostField("notice", notice)
|
||||||
|
.then(() => {
|
||||||
|
post.setProperties({
|
||||||
|
notice_type: "custom",
|
||||||
|
notice_args: notice
|
||||||
|
});
|
||||||
|
resolve();
|
||||||
|
this.send("closeModal");
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
reject();
|
||||||
|
this.send("closeModal");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -750,6 +750,22 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
|
||||||
this.send("showGrantBadgeModal");
|
this.send("showGrantBadgeModal");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addNotice(post) {
|
||||||
|
return new Ember.RSVP.Promise(function(resolve, reject) {
|
||||||
|
const controller = showModal("add-post-notice");
|
||||||
|
controller.setProperties({ post, resolve, reject });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
removeNotice(post) {
|
||||||
|
return post.updatePostField("notice", null).then(() =>
|
||||||
|
post.setProperties({
|
||||||
|
notice_type: null,
|
||||||
|
notice_args: null
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
toggleParticipant(user) {
|
toggleParticipant(user) {
|
||||||
this.get("model.postStream")
|
this.get("model.postStream")
|
||||||
.toggleParticipant(user.get("username"))
|
.toggleParticipant(user.get("username"))
|
||||||
|
|
|
@ -133,10 +133,12 @@ export default function transformPost(
|
||||||
postAtts.topicUrl = topic.get("url");
|
postAtts.topicUrl = topic.get("url");
|
||||||
postAtts.isSaving = post.isSaving;
|
postAtts.isSaving = post.isSaving;
|
||||||
|
|
||||||
if (post.post_notice_type) {
|
if (post.notice_type) {
|
||||||
postAtts.postNoticeType = post.post_notice_type;
|
postAtts.noticeType = post.notice_type;
|
||||||
if (postAtts.postNoticeType === "returning") {
|
if (postAtts.noticeType === "custom") {
|
||||||
postAtts.postNoticeTime = new Date(post.post_notice_time);
|
postAtts.noticeMessage = post.notice_args;
|
||||||
|
} else if (postAtts.noticeType === "returning_user") {
|
||||||
|
postAtts.noticeTime = new Date(post.notice_args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
{{#d-modal-body title="post.controls.add_post_notice"}}
|
||||||
|
<form>{{textarea value=notice}}</form>
|
||||||
|
{{/d-modal-body}}
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
{{d-button
|
||||||
|
class="btn-primary"
|
||||||
|
action=(action "setNotice")
|
||||||
|
disabled=disabled
|
||||||
|
label=(if saving "saving" "save")}}
|
||||||
|
{{d-modal-cancel close=(route-action "closeModal")}}
|
||||||
|
</div>
|
|
@ -184,6 +184,8 @@
|
||||||
rebakePost=(action "rebakePost")
|
rebakePost=(action "rebakePost")
|
||||||
changePostOwner=(action "changePostOwner")
|
changePostOwner=(action "changePostOwner")
|
||||||
grantBadge=(action "grantBadge")
|
grantBadge=(action "grantBadge")
|
||||||
|
addNotice=(action "addNotice")
|
||||||
|
removeNotice=(action "removeNotice")
|
||||||
lockPost=(action "lockPost")
|
lockPost=(action "lockPost")
|
||||||
unlockPost=(action "unlockPost")
|
unlockPost=(action "unlockPost")
|
||||||
unhidePost=(action "unhidePost")
|
unhidePost=(action "unhidePost")
|
||||||
|
|
|
@ -74,14 +74,23 @@ export function buildManageButtons(attrs, currentUser, siteSettings) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const action = attrs.locked ? "unlock" : "lock";
|
if (attrs.locked) {
|
||||||
contents.push({
|
contents.push({
|
||||||
icon: action,
|
icon: "unlock",
|
||||||
label: `post.controls.${action}_post`,
|
label: "post.controls.unlock_post",
|
||||||
action: `${action}Post`,
|
action: "unlockPost",
|
||||||
title: `post.controls.${action}_post_description`,
|
title: "post.controls.unlock_post_description",
|
||||||
className: `btn-default ${action}-post`
|
className: "btn-default unlock-post"
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
contents.push({
|
||||||
|
icon: "lock",
|
||||||
|
label: "post.controls.lock_post",
|
||||||
|
action: "lockPost",
|
||||||
|
title: "post.controls.lock_post_description",
|
||||||
|
className: "btn-default lock-post"
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrs.canManage || attrs.canWiki) {
|
if (attrs.canManage || attrs.canWiki) {
|
||||||
|
@ -102,6 +111,24 @@ export function buildManageButtons(attrs, currentUser, siteSettings) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentUser.staff) {
|
||||||
|
if (attrs.noticeType) {
|
||||||
|
contents.push({
|
||||||
|
icon: "asterisk",
|
||||||
|
label: "post.controls.remove_post_notice",
|
||||||
|
action: "removeNotice",
|
||||||
|
className: "btn-default remove-notice"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
contents.push({
|
||||||
|
icon: "asterisk",
|
||||||
|
label: "post.controls.add_post_notice",
|
||||||
|
action: "addNotice",
|
||||||
|
className: "btn-default add-notice"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return contents;
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -434,13 +434,7 @@ createWidget("post-notice", {
|
||||||
tagName: "div.post-notice",
|
tagName: "div.post-notice",
|
||||||
|
|
||||||
buildClasses(attrs) {
|
buildClasses(attrs) {
|
||||||
const classes = [];
|
const classes = [attrs.noticeType.replace(/_/g, "-")];
|
||||||
|
|
||||||
if (attrs.postNoticeType === "first") {
|
|
||||||
classes.push("new-user");
|
|
||||||
} else if (attrs.postNoticeType === "returning") {
|
|
||||||
classes.push("returning-user");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
new Date() - new Date(attrs.created_at) >
|
new Date() - new Date(attrs.created_at) >
|
||||||
|
@ -458,13 +452,16 @@ createWidget("post-notice", {
|
||||||
? attrs.username
|
? attrs.username
|
||||||
: attrs.name;
|
: attrs.name;
|
||||||
let text, icon;
|
let text, icon;
|
||||||
if (attrs.postNoticeType === "first") {
|
if (attrs.noticeType === "custom") {
|
||||||
|
icon = "asterisk";
|
||||||
|
text = attrs.noticeMessage;
|
||||||
|
} else if (attrs.noticeType === "new_user") {
|
||||||
icon = "hands-helping";
|
icon = "hands-helping";
|
||||||
text = I18n.t("post.notice.first", { user });
|
text = I18n.t("post.notice.new_user", { user });
|
||||||
} else if (attrs.postNoticeType === "returning") {
|
} else if (attrs.noticeType === "returning_user") {
|
||||||
icon = "far-smile";
|
icon = "far-smile";
|
||||||
const distance = (new Date() - new Date(attrs.postNoticeTime)) / 1000;
|
const distance = (new Date() - new Date(attrs.noticeTime)) / 1000;
|
||||||
text = I18n.t("post.notice.return", {
|
text = I18n.t("post.notice.returning_user", {
|
||||||
user,
|
user,
|
||||||
time: durationTiny(distance, { addAgo: true })
|
time: durationTiny(distance, { addAgo: true })
|
||||||
});
|
});
|
||||||
|
@ -552,7 +549,7 @@ createWidget("post-article", {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrs.postNoticeType) {
|
if (attrs.noticeType) {
|
||||||
rows.push(h("div.row", [this.attach("post-notice", attrs)]));
|
rows.push(h("div.row", [this.attach("post-notice", attrs)]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -476,6 +476,22 @@ class PostsController < ApplicationController
|
||||||
render_json_dump(locked: post.locked?)
|
render_json_dump(locked: post.locked?)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def notice
|
||||||
|
raise Discourse::NotFound unless guardian.is_staff?
|
||||||
|
|
||||||
|
post = find_post_from_params
|
||||||
|
|
||||||
|
if params[:notice].present?
|
||||||
|
post.custom_fields["notice_type"] = Post.notices[:custom]
|
||||||
|
post.custom_fields["notice_args"] = params[:notice]
|
||||||
|
post.save_custom_fields
|
||||||
|
else
|
||||||
|
post.delete_post_notices
|
||||||
|
end
|
||||||
|
|
||||||
|
render body: nil
|
||||||
|
end
|
||||||
|
|
||||||
def bookmark
|
def bookmark
|
||||||
if params[:bookmarked] == "true"
|
if params[:bookmarked] == "true"
|
||||||
post = find_post_from_params
|
post = find_post_from_params
|
||||||
|
|
|
@ -142,6 +142,12 @@ class Post < ActiveRecord::Base
|
||||||
email: 3)
|
email: 3)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.notices
|
||||||
|
@notices ||= Enum.new(custom: "custom",
|
||||||
|
new_user: "new_user",
|
||||||
|
returning_user: "returning_user")
|
||||||
|
end
|
||||||
|
|
||||||
def self.find_by_detail(key, value)
|
def self.find_by_detail(key, value)
|
||||||
includes(:post_details).find_by(post_details: { key: key, value: value })
|
includes(:post_details).find_by(post_details: { key: key, value: value })
|
||||||
end
|
end
|
||||||
|
@ -389,8 +395,8 @@ class Post < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_post_notices
|
def delete_post_notices
|
||||||
self.custom_fields.delete("post_notice_type")
|
self.custom_fields.delete("notice_type")
|
||||||
self.custom_fields.delete("post_notice_time")
|
self.custom_fields.delete("notice_args")
|
||||||
self.save_custom_fields
|
self.save_custom_fields
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -70,8 +70,8 @@ class PostSerializer < BasicPostSerializer
|
||||||
:is_auto_generated,
|
:is_auto_generated,
|
||||||
:action_code,
|
:action_code,
|
||||||
:action_code_who,
|
:action_code_who,
|
||||||
:post_notice_type,
|
:notice_type,
|
||||||
:post_notice_time,
|
:notice_args,
|
||||||
:last_wiki_edit,
|
:last_wiki_edit,
|
||||||
:locked,
|
:locked,
|
||||||
:excerpt
|
:excerpt
|
||||||
|
@ -365,24 +365,33 @@ class PostSerializer < BasicPostSerializer
|
||||||
include_action_code? && action_code_who.present?
|
include_action_code? && action_code_who.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def post_notice_type
|
def notice_type
|
||||||
post_custom_fields["post_notice_type"]
|
post_custom_fields["notice_type"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_post_notice_type?
|
def include_notice_type?
|
||||||
return false if !scope.user || !scope.user.id || scope.user.id == object.user_id ||
|
case notice_type
|
||||||
!object.user || object.user.anonymous? || object.user.bot? || object.user.staged ||
|
when Post.notices[:custom]
|
||||||
!scope.user.has_trust_level?(SiteSetting.min_post_notice_tl)
|
return true
|
||||||
|
when Post.notices[:new_user]
|
||||||
|
min_trust_level = SiteSetting.new_user_notice_tl
|
||||||
|
when Post.notices[:returning_user]
|
||||||
|
min_trust_level = SiteSetting.returning_user_notice_tl
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
post_notice_type.present?
|
scope.user && scope.user.id && object.user &&
|
||||||
|
scope.user.id != object.user_id &&
|
||||||
|
scope.user.has_trust_level?(min_trust_level)
|
||||||
end
|
end
|
||||||
|
|
||||||
def post_notice_time
|
def notice_args
|
||||||
post_custom_fields["post_notice_time"]
|
post_custom_fields["notice_args"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_post_notice_time?
|
def include_notice_args?
|
||||||
include_post_notice_type? && post_notice_time.present?
|
notice_args.present? && include_notice_type?
|
||||||
end
|
end
|
||||||
|
|
||||||
def locked
|
def locked
|
||||||
|
|
|
@ -18,8 +18,8 @@ class WebHookPostSerializer < PostSerializer
|
||||||
primary_group_flair_url
|
primary_group_flair_url
|
||||||
primary_group_flair_bg_color
|
primary_group_flair_bg_color
|
||||||
primary_group_flair_color
|
primary_group_flair_color
|
||||||
post_notice_time
|
notice_args
|
||||||
post_notice_type
|
notice_type
|
||||||
}.each do |attr|
|
}.each do |attr|
|
||||||
define_method("include_#{attr}?") do
|
define_method("include_#{attr}?") do
|
||||||
false
|
false
|
||||||
|
|
|
@ -2274,8 +2274,8 @@ en:
|
||||||
other: "view {{count}} hidden replies"
|
other: "view {{count}} hidden replies"
|
||||||
|
|
||||||
notice:
|
notice:
|
||||||
first: "This is the first time {{user}} has posted — let’s welcome them to our community!"
|
new_user: "This is the first time {{user}} has posted — let’s welcome them to our community!"
|
||||||
return: "It’s been a while since we’ve seen {{user}} — their last post was {{time}}."
|
returning_user: "It’s been a while since we’ve seen {{user}} — their last post was {{time}}."
|
||||||
|
|
||||||
unread: "Post is unread"
|
unread: "Post is unread"
|
||||||
has_replies:
|
has_replies:
|
||||||
|
@ -2358,6 +2358,8 @@ en:
|
||||||
delete_topic_disallowed_modal: "You don't have permission to delete this topic. If you really want it to be deleted, submit a flag for moderator attention together with reasoning."
|
delete_topic_disallowed_modal: "You don't have permission to delete this topic. If you really want it to be deleted, submit a flag for moderator attention together with reasoning."
|
||||||
delete_topic_disallowed: "you don't have permission to delete this topic"
|
delete_topic_disallowed: "you don't have permission to delete this topic"
|
||||||
delete_topic: "delete topic"
|
delete_topic: "delete topic"
|
||||||
|
add_post_notice: "Add post notice"
|
||||||
|
remove_post_notice: "Remove post notice"
|
||||||
|
|
||||||
actions:
|
actions:
|
||||||
flag: "Flag"
|
flag: "Flag"
|
||||||
|
|
|
@ -1948,8 +1948,9 @@ en:
|
||||||
max_allowed_message_recipients: "Maximum recipients allowed in a message."
|
max_allowed_message_recipients: "Maximum recipients allowed in a message."
|
||||||
watched_words_regular_expressions: "Watched words are regular expressions."
|
watched_words_regular_expressions: "Watched words are regular expressions."
|
||||||
|
|
||||||
min_post_notice_tl: "Minimum trust level required to see post notices."
|
|
||||||
old_post_notice_days: "Days before post notice becomes old"
|
old_post_notice_days: "Days before post notice becomes old"
|
||||||
|
new_user_notice_tl: "Minimum trust level required to see new user post notices."
|
||||||
|
returning_user_notice_tl: "Minimum trust level required to see returning user post notices."
|
||||||
returning_users_days: "How many days should pass before a user is considered to be returning."
|
returning_users_days: "How many days should pass before a user is considered to be returning."
|
||||||
|
|
||||||
default_email_digest_frequency: "How often users receive summary emails by default."
|
default_email_digest_frequency: "How often users receive summary emails by default."
|
||||||
|
|
|
@ -553,6 +553,7 @@ Discourse::Application.routes.draw do
|
||||||
put "rebake"
|
put "rebake"
|
||||||
put "unhide"
|
put "unhide"
|
||||||
put "locked"
|
put "locked"
|
||||||
|
put "notice"
|
||||||
get "replies"
|
get "replies"
|
||||||
get "revisions/latest" => "posts#latest_revision"
|
get "revisions/latest" => "posts#latest_revision"
|
||||||
get "revisions/:revision" => "posts#revisions", constraints: { revision: /\d+/ }
|
get "revisions/:revision" => "posts#revisions", constraints: { revision: /\d+/ }
|
||||||
|
|
|
@ -825,12 +825,15 @@ posting:
|
||||||
default: false
|
default: false
|
||||||
client: true
|
client: true
|
||||||
shadowed_by_global: true
|
shadowed_by_global: true
|
||||||
min_post_notice_tl:
|
|
||||||
default: 2
|
|
||||||
enum: "TrustLevelSetting"
|
|
||||||
old_post_notice_days:
|
old_post_notice_days:
|
||||||
default: 14
|
default: 14
|
||||||
client: true
|
client: true
|
||||||
|
new_user_notice_tl:
|
||||||
|
default: 2
|
||||||
|
enum: "TrustLevelSetting"
|
||||||
|
returning_user_notice_tl:
|
||||||
|
default: 2
|
||||||
|
enum: "TrustLevelSetting"
|
||||||
returning_users_days:
|
returning_users_days:
|
||||||
default: 120
|
default: 120
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
class RenamePostNotices < ActiveRecord::Migration[5.2]
|
||||||
|
def up
|
||||||
|
add_index :post_custom_fields, :post_id, unique: true, name: "index_post_custom_fields_on_notice_type", where: "name = 'notice_type'"
|
||||||
|
add_index :post_custom_fields, :post_id, unique: true, name: "index_post_custom_fields_on_notice_args", where: "name = 'notice_args'"
|
||||||
|
|
||||||
|
# Split site setting `min_post_notice_tl` into `new_user_notice_tl` and `returning_user_notice_tl`.
|
||||||
|
execute <<~SQL
|
||||||
|
INSERT INTO site_settings(name, data_type, value, created_at, updated_at)
|
||||||
|
SELECT 'new_user_notice_tl', data_type, value, created_at, updated_at
|
||||||
|
FROM site_settings WHERE name = 'min_post_notice_tl'
|
||||||
|
UNION
|
||||||
|
SELECT 'returning_user_notice_tl', data_type, value, created_at, updated_at
|
||||||
|
FROM site_settings WHERE name = 'min_post_notice_tl'
|
||||||
|
SQL
|
||||||
|
execute "DELETE FROM site_settings WHERE name = 'min_post_notice_tl'"
|
||||||
|
|
||||||
|
# Rename custom fields to match new naming scheme.
|
||||||
|
execute "UPDATE post_custom_fields SET name = 'notice_type', value = 'new_user' WHERE name = 'post_notice_type' AND value = 'first'"
|
||||||
|
execute "UPDATE post_custom_fields SET name = 'notice_type', value = 'returning_user' WHERE name = 'post_notice_type' AND value = 'returning'"
|
||||||
|
execute "UPDATE post_custom_fields SET name = 'notice_args' WHERE name = 'post_notice_time'"
|
||||||
|
|
||||||
|
# Delete all notices for bots, staged and anonymous users.
|
||||||
|
execute <<~SQL
|
||||||
|
DELETE FROM user_custom_fields
|
||||||
|
WHERE (name = 'notice_type' OR name = 'notice_args')
|
||||||
|
AND user_id IN (SELECT id FROM users WHERE id <= 0 OR staged = true
|
||||||
|
UNION
|
||||||
|
SELECT user_id FROM user_custom_fields ucf WHERE name = 'master_id')
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
raise ActiveRecord::IrreversibleMigration
|
||||||
|
end
|
||||||
|
end
|
|
@ -519,7 +519,7 @@ class PostCreator
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_post_notice
|
def create_post_notice
|
||||||
return if @opts[:import_mode] || @user.bot? || @user.staged
|
return if @opts[:import_mode] || @user.anonymous? || @user.bot? || @user.staged
|
||||||
|
|
||||||
last_post_time = Post.where(user_id: @user.id)
|
last_post_time = Post.where(user_id: @user.id)
|
||||||
.order(created_at: :desc)
|
.order(created_at: :desc)
|
||||||
|
@ -528,10 +528,10 @@ class PostCreator
|
||||||
.first
|
.first
|
||||||
|
|
||||||
if !last_post_time
|
if !last_post_time
|
||||||
@post.custom_fields["post_notice_type"] = "first"
|
@post.custom_fields["notice_type"] = Post.notices[:new_user]
|
||||||
elsif SiteSetting.returning_users_days > 0 && last_post_time < SiteSetting.returning_users_days.days.ago
|
elsif SiteSetting.returning_users_days > 0 && last_post_time < SiteSetting.returning_users_days.days.ago
|
||||||
@post.custom_fields["post_notice_type"] = "returning"
|
@post.custom_fields["notice_type"] = Post.notices[:returning_user]
|
||||||
@post.custom_fields["post_notice_time"] = last_post_time.iso8601
|
@post.custom_fields["notice_args"] = last_post_time.iso8601
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ module SvgSprite
|
||||||
"arrow-up",
|
"arrow-up",
|
||||||
"arrows-alt-h",
|
"arrows-alt-h",
|
||||||
"arrows-alt-v",
|
"arrows-alt-v",
|
||||||
|
"asterisk",
|
||||||
"at",
|
"at",
|
||||||
"backward",
|
"backward",
|
||||||
"ban",
|
"ban",
|
||||||
|
|
|
@ -36,7 +36,7 @@ class TopicView
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.default_post_custom_fields
|
def self.default_post_custom_fields
|
||||||
@default_post_custom_fields ||= ["action_code_who", "post_notice_type", "post_notice_time"]
|
@default_post_custom_fields ||= ["action_code_who", "notice_type", "notice_args"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.post_custom_fields_whitelisters
|
def self.post_custom_fields_whitelisters
|
||||||
|
|
|
@ -1331,33 +1331,37 @@ describe PostCreator do
|
||||||
context "#create_post_notice" do
|
context "#create_post_notice" do
|
||||||
let(:user) { Fabricate(:user) }
|
let(:user) { Fabricate(:user) }
|
||||||
let(:staged) { Fabricate(:staged) }
|
let(:staged) { Fabricate(:staged) }
|
||||||
|
let(:anonymous) { Fabricate(:anonymous) }
|
||||||
|
|
||||||
it "generates post notices for new users" do
|
it "generates post notices for new users" do
|
||||||
post = PostCreator.create(user, title: "one of my first topics", raw: "one of my first posts")
|
post = PostCreator.create!(user, title: "one of my first topics", raw: "one of my first posts")
|
||||||
expect(post.custom_fields["post_notice_type"]).to eq("first")
|
expect(post.custom_fields["notice_type"]).to eq("new_user")
|
||||||
post = PostCreator.create(user, title: "another one of my first topics", raw: "another one of my first posts")
|
|
||||||
expect(post.custom_fields["post_notice_type"]).to eq(nil)
|
post = PostCreator.create!(user, title: "another one of my first topics", raw: "another one of my first posts")
|
||||||
|
expect(post.custom_fields["notice_type"]).to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "generates post notices for returning users" do
|
it "generates post notices for returning users" do
|
||||||
SiteSetting.returning_users_days = 30
|
SiteSetting.returning_users_days = 30
|
||||||
old_post = Fabricate(:post, user: user, created_at: 31.days.ago)
|
old_post = Fabricate(:post, user: user, created_at: 31.days.ago)
|
||||||
|
|
||||||
post = PostCreator.create(user, title: "this is a returning topic", raw: "this is a post")
|
post = PostCreator.create!(user, title: "this is a returning topic", raw: "this is a post")
|
||||||
expect(post.custom_fields["post_notice_type"]).to eq("returning")
|
expect(post.custom_fields["notice_type"]).to eq(Post.notices[:returning_user])
|
||||||
expect(post.custom_fields["post_notice_time"]).to eq(old_post.created_at.iso8601)
|
expect(post.custom_fields["notice_args"]).to eq(old_post.created_at.iso8601)
|
||||||
|
|
||||||
post = PostCreator.create(user, title: "this is another topic", raw: "this is my another post")
|
post = PostCreator.create!(user, title: "this is another topic", raw: "this is my another post")
|
||||||
expect(post.custom_fields["post_notice_type"]).to eq(nil)
|
expect(post.custom_fields["notice_type"]).to eq(nil)
|
||||||
expect(post.custom_fields["post_notice_time"]).to eq(nil)
|
expect(post.custom_fields["notice_args"]).to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not generate for non-human or staged users" do
|
it "does not generate for non-human, staged or anonymous users" do
|
||||||
[Discourse.system_user, staged].each do |user|
|
SiteSetting.allow_anonymous_posting = true
|
||||||
|
|
||||||
|
[anonymous, Discourse.system_user, staged].each do |user|
|
||||||
expect(user.posts.size).to eq(0)
|
expect(user.posts.size).to eq(0)
|
||||||
post = PostCreator.create(user, title: "#{user.name}'s first topic", raw: "#{user.name}'s first post")
|
post = PostCreator.create!(user, title: "#{user.username}'s first topic", raw: "#{user.name}'s first post")
|
||||||
expect(post.custom_fields["post_notice_type"]).to eq(nil)
|
expect(post.custom_fields["notice_type"]).to eq(nil)
|
||||||
expect(post.custom_fields["post_notice_time"]).to eq(nil)
|
expect(post.custom_fields["notice_args"]).to eq(nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -136,8 +136,8 @@ describe Post do
|
||||||
context 'a post with notices' do
|
context 'a post with notices' do
|
||||||
let(:post) {
|
let(:post) {
|
||||||
post = Fabricate(:post, post_args)
|
post = Fabricate(:post, post_args)
|
||||||
post.custom_fields["post_notice_type"] = "returning"
|
post.custom_fields["notice_type"] = Post.notices[:returning_user]
|
||||||
post.custom_fields["post_notice_time"] = 1.day.ago
|
post.custom_fields["notice_args"] = 1.day.ago
|
||||||
post.save_custom_fields
|
post.save_custom_fields
|
||||||
post
|
post
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,8 +181,8 @@ describe PostSerializer do
|
||||||
|
|
||||||
let(:post) {
|
let(:post) {
|
||||||
post = Fabricate(:post, user: user)
|
post = Fabricate(:post, user: user)
|
||||||
post.custom_fields["post_notice_type"] = "returning"
|
post.custom_fields["notice_type"] = Post.notices[:returning_user]
|
||||||
post.custom_fields["post_notice_time"] = 1.day.ago
|
post.custom_fields["notice_args"] = 1.day.ago
|
||||||
post.save_custom_fields
|
post.save_custom_fields
|
||||||
post
|
post
|
||||||
}
|
}
|
||||||
|
@ -192,32 +192,16 @@ describe PostSerializer do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "is visible for TL2+ users (except poster)" do
|
it "is visible for TL2+ users (except poster)" do
|
||||||
expect(json_for_user(nil)[:post_notice_type]).to eq(nil)
|
expect(json_for_user(nil)[:notice_type]).to eq(nil)
|
||||||
expect(json_for_user(user)[:post_notice_type]).to eq(nil)
|
expect(json_for_user(user)[:notice_type]).to eq(nil)
|
||||||
|
|
||||||
SiteSetting.min_post_notice_tl = 2
|
SiteSetting.returning_user_notice_tl = 2
|
||||||
expect(json_for_user(user_tl1)[:post_notice_type]).to eq(nil)
|
expect(json_for_user(user_tl1)[:notice_type]).to eq(nil)
|
||||||
expect(json_for_user(user_tl2)[:post_notice_type]).to eq("returning")
|
expect(json_for_user(user_tl2)[:notice_type]).to eq(Post.notices[:returning_user])
|
||||||
|
|
||||||
SiteSetting.min_post_notice_tl = 1
|
SiteSetting.returning_user_notice_tl = 1
|
||||||
expect(json_for_user(user_tl1)[:post_notice_type]).to eq("returning")
|
expect(json_for_user(user_tl1)[:notice_type]).to eq(Post.notices[:returning_user])
|
||||||
expect(json_for_user(user_tl2)[:post_notice_type]).to eq("returning")
|
expect(json_for_user(user_tl2)[:notice_type]).to eq(Post.notices[:returning_user])
|
||||||
end
|
|
||||||
|
|
||||||
it "is visible when created by anonymous, bots and staged users" do
|
|
||||||
expect(json_for_user(user_tl2)[:post_notice_type]).to eq("returning")
|
|
||||||
|
|
||||||
post.user = nil
|
|
||||||
expect(json_for_user(user_tl2)[:post_notice_type]).to eq(nil)
|
|
||||||
|
|
||||||
post.user = AnonymousShadowCreator.get(user)
|
|
||||||
expect(json_for_user(user_tl2)[:post_notice_type]).to eq(nil)
|
|
||||||
|
|
||||||
post.user = Discourse.system_user
|
|
||||||
expect(json_for_user(user_tl2)[:post_notice_type]).to eq(nil)
|
|
||||||
|
|
||||||
post.user = Fabricate(:staged)
|
|
||||||
expect(json_for_user(user_tl2)[:post_notice_type]).to eq(nil)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4999,7 +4999,7 @@ export default {
|
||||||
edit_reason: null,
|
edit_reason: null,
|
||||||
can_view_edit_history: true,
|
can_view_edit_history: true,
|
||||||
wiki: false,
|
wiki: false,
|
||||||
post_notice_type: "first"
|
notice_type: "new-user"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
stream: [25, 26, 27]
|
stream: [25, 26, 27]
|
||||||
|
|
|
@ -879,8 +879,8 @@ widgetTest("post notice - with username", {
|
||||||
this.siteSettings.prioritize_username_in_ux = true;
|
this.siteSettings.prioritize_username_in_ux = true;
|
||||||
this.siteSettings.old_post_notice_days = 14;
|
this.siteSettings.old_post_notice_days = 14;
|
||||||
this.set("args", {
|
this.set("args", {
|
||||||
postNoticeType: "returning",
|
noticeType: "returning_user",
|
||||||
postNoticeTime: twoDaysAgo,
|
noticeTime: twoDaysAgo,
|
||||||
username: "codinghorror",
|
username: "codinghorror",
|
||||||
name: "Jeff",
|
name: "Jeff",
|
||||||
created_at: new Date()
|
created_at: new Date()
|
||||||
|
@ -891,7 +891,10 @@ widgetTest("post notice - with username", {
|
||||||
find(".post-notice.returning-user:not(.old)")
|
find(".post-notice.returning-user:not(.old)")
|
||||||
.text()
|
.text()
|
||||||
.trim(),
|
.trim(),
|
||||||
I18n.t("post.notice.return", { user: "codinghorror", time: "2d ago" })
|
I18n.t("post.notice.returning_user", {
|
||||||
|
user: "codinghorror",
|
||||||
|
time: "2d ago"
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -902,7 +905,7 @@ widgetTest("post notice - with name", {
|
||||||
this.siteSettings.prioritize_username_in_ux = false;
|
this.siteSettings.prioritize_username_in_ux = false;
|
||||||
this.siteSettings.old_post_notice_days = 14;
|
this.siteSettings.old_post_notice_days = 14;
|
||||||
this.set("args", {
|
this.set("args", {
|
||||||
postNoticeType: "first",
|
noticeType: "new_user",
|
||||||
username: "codinghorror",
|
username: "codinghorror",
|
||||||
name: "Jeff",
|
name: "Jeff",
|
||||||
created_at: new Date(2019, 0, 1)
|
created_at: new Date(2019, 0, 1)
|
||||||
|
@ -913,7 +916,7 @@ widgetTest("post notice - with name", {
|
||||||
find(".post-notice.old.new-user")
|
find(".post-notice.old.new-user")
|
||||||
.text()
|
.text()
|
||||||
.trim(),
|
.trim(),
|
||||||
I18n.t("post.notice.first", { user: "Jeff", time: "Jan '10" })
|
I18n.t("post.notice.new_user", { user: "Jeff", time: "Jan '10" })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue