Skip to content

Commit

Permalink
feat: announce when removing post
Browse files Browse the repository at this point in the history
  • Loading branch information
pangbo13 committed Nov 9, 2024
1 parent ee44386 commit 151ae2b
Show file tree
Hide file tree
Showing 9 changed files with 285 additions and 18 deletions.
52 changes: 52 additions & 0 deletions assets/javascripts/discourse/components/modal/remove-post.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<DModal
class="remove-post-modal"
@title="同意举报并删除"
{{!-- @title={{i18n this.modalTitle}} --}}
{{!-- @closeModal={{this.warnBeforeClosing}}
@flash={{this.flash}} --}}
>
<:body>
{{#unless this.submitted}}
<h2>为什么删除此内容?</h2>
<form>
{{#each this.reasonOptions as |reason|}}
<label>
<input
type="radio"
name="reason"
value={{reason.id}}
checked={{eq this.reason.id reason.id}}
{{on "change" (fn this.setReason reason.id)}}
/>
{{reason.name}}
</label>
{{/each}}
</form>
{{#unless this.reason.hideReason}}
<Textarea
name="message"
class="announcement-message"
placeholder={{this.customPlaceholder}}
@disabled={{this.isSaving}}
@value={{this.announcementContent}}
/>
{{/unless}}
{{/unless}}
</:body>
<:footer>
{{!-- <div class="penalty-history">{{html-safe this.penaltyHistory}}</div> --}}
<DButton
class="btn-danger confirm-delete"
@action={{this.confirmDelete}}
@disabled={{this.isSaving}}
@icon="trash-alt"
@label={{this.confirmButtonLabel}}
/>
<DButton
class="btn-flat d-modal-cancel"
@action={{@closeModal}}
@disabled={{this.isSaving}}
@label="cancel"
/>
</:footer>
</DModal>
168 changes: 168 additions & 0 deletions assets/javascripts/discourse/components/modal/remove-post.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import { service } from "@ember/service";

const REMOVE_REASONS = [
{
id: "political",
name: "五(一) 政治敏感",
announcementContent: "**第五条** 以下内容被界定为“有害信息”:\n\n(一) 政治敏感的;",
hideReason: false
},
{
id: "disturbance",
name: "五(二) 扰乱秩序",
announcementContent: "**第五条** 以下内容被界定为“有害信息”:\n\n(二) 扰乱秩序的;",
hideReason: false
},
{
id: "discrimination",
name: "六(六) 歧视",
announcementContent: "**第六条** 以下内容被界定为“不良信息”:\n\n(六)引起对立,煽动人群歧视、地域歧视等,歧视、攻击特定的身份的;",
hideReason: false
},
{
id: "personal_attack",
name: "六(七) 损害他人名誉-不文明语言",
announcementContent: "**第六条** 以下内容被界定为“不良信息”:\n\n(七)损害他人名誉的内容,主要表现为:\n\n1. 以不文明的语言对他人进行的负面评价;",
hideReason: false
},
{
id: "nibufuqi",
name: "六(十一) 上级指导部门认定为不当言论",
announcementContent: "**第六条** 以下内容被界定为“不良信息”:\n\n(十一)上级指导部门认定为不当言论的。",
hideReason: false
},
{
id: "spam",
name: "七(一) 垃圾信息",
announcementContent: "**第七条** 以下内容被界定为“垃圾信息”:\n\n(一)误导性的、引起事端的、激化矛盾的内容,主要表现为:\n\n1. 使用夸张标题,或内容与标题相关性低的;\n2. 捏造、夸大、扭曲、隐藏细节或整体事实的;\n3. 搭配错误图文、过期信息、虚构情景的;\n4. 曲解原意,偷换概念,断章取义的;\n5. 使用缩写、简称、同源字、谐音字、形近字、通假字等引起歧义的;\n6. 未标注来源的利用深度学习、虚拟现实等生成合成类算法制作的文本、图像、音频、视频、虚拟场景等。",
hideReason: false
},
{
id: "provocation",
name: "九(二) 不友善行为",
announcementContent: "**第九条** 以下行为被界定为“不友善行为”:\n\n(二)激怒特定用户或群体,诱导其回应。",
hideReason: false
},
{
id: "other",
name: "十四 其他",
announcementContent: "**第十四条** 其他违反法律、行政法规,以及违反上海交通大学有关规章制度的内容或行为。",
hideReason: false
},
{
id: "custom",
name: "自定义",
announcementContent: "",
hideReason: false
},
{
id: "do_not_announce",
name: "删除但不公示",
announcementContent: "",
hideReason: true
}
];

const REMOVE_ANNOUNCEMENT_TEMPLATE = `!{target}
账号:@!{username}
[quote="system, post:1, topic:264238"]
!{reason}
[/quote]
处理意见:**删除内容**
---
对以上处理有异议的,请按[相关规定](https://shuiyuan.sjtu.edu.cn/faq#h-5)提出复议申请。
`;

export function addCustomReason(reason) {
REMOVE_REASONS.splice(REMOVE_REASONS.length - 2, 0, reason);
}

export default class RemovePost extends Component {
@service siteSettings;
@service modal;

@tracked reason = REMOVE_REASONS[0];
@tracked isSaving = false;
@tracked submitted = false;
@tracked announcementContent;

constructor() {
super(...arguments);
this.model = this.args.model;
this.announcementContent = this.announcementContentFromTemplate();
}

announcementContentFromTemplate() {
if (!this.reason) {
return "";
}
const target = `${this.isTopic ? "话题" : "帖子"}编号:${this.targetId}`;
return REMOVE_ANNOUNCEMENT_TEMPLATE
.replace("!{target}", target)
.replace("!{reason}", this.reason.announcementContent)
.replace("!{username}", this.model.reviewable.target_created_by.username);
}


get customPlaceholder() {
return "place holder";
}

get postNumber() {
const targetUrl = new URL(this.model.reviewable.target_url);
const pathSegments = targetUrl.pathname.split('/').filter(segment => segment);
return parseInt(pathSegments[pathSegments.length - 1], 10);
}

get topicId() {
const targetUrl = new URL(this.model.reviewable.target_url);
const pathSegments = targetUrl.pathname.split('/').filter(segment => segment);
return parseInt(pathSegments[pathSegments.length - 2], 10);
}

get targetId() {
return this.postNumber === 1 ? `${this.topicId}` : `${this.topicId}/${this.postNumber}`;
}

get isTopic() {
return this.postNumber === 1;
}

get reasonOptions() {
return REMOVE_REASONS;
}

get confirmButtonLabel() {
if(this.reason.id === "do_not_announce") {
return "discourse_moderation_announcement.confirm_delete_but_not_announce";
} else {
return "discourse_moderation_announcement.confirm_delete_and_announce";
}
}

@action
setReason(reasonId) {
this.reason = this.reasonOptions.find(option => option.id === reasonId);
this.announcementContent = this.announcementContentFromTemplate();
}

@action
async confirmDelete() {
const additionalData = {
reason_id: this.reason.id,
announcement_content: this.announcementContent,
should_announce: !this.reason.hideReason
};
await this.model.performConfirmed(this.model.action, additionalData);
await this.args.closeModal();
}

}
11 changes: 11 additions & 0 deletions assets/javascripts/discourse/initializers/moderator-modal-init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { withPluginApi } from "discourse/lib/plugin-api";
import RemovePostModal from "../components/modal/remove-post";

export default {
name: "moderation-announcement",
initialize() {
withPluginApi("0.8", api => {
api.registerReviewableActionModal("delete_and_agree", RemovePostModal);
});
}
};
5 changes: 5 additions & 0 deletions assets/stylesheets/common/remove-post-modal.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.remove-post-modal{
.announcement-message {
height: 300px;
}
}
10 changes: 3 additions & 7 deletions config/locales/client.en.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
en:
admin_js:
admin:
site_settings:
categories:
TODO_plugin_name: "Plugin Name"
js:
discourse_plugin_name:
placeholder: placeholder
discourse_moderation_announcement:
confirm_delete_and_announce: "Delete and announce"
confirm_delete_but_not_announce: "Delete but not announce"
6 changes: 6 additions & 0 deletions config/locales/client.zh_CN.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
zh_CN:
js:
discourse_moderation_announcement:
confirm_delete_and_announce: "删除并公示"
confirm_delete_but_not_announce: "删除但不公示"

3 changes: 3 additions & 0 deletions config/locales/server.zh_CN.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
zh_CN:
site_settings:
moderation_announcement_deletion_topic_id: "公示话题 ID"
10 changes: 7 additions & 3 deletions config/settings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
TODO_plugin_name:
plugin_name_enabled:
default: false
discourse-moderation-announcement:
moderation_announcement_enabled:
default: true
client: true
moderation_announcement_deletion_topic_id:
default: -1
type: integer
client: false
38 changes: 30 additions & 8 deletions plugin.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,43 @@
# frozen_string_literal: true

# name: discourse-plugin-name
# name: discourse-moderation-announcement
# about: TODO
# meta_topic_id: TODO
# version: 0.0.1
# authors: Discourse
# version: dev
# authors: pangbo
# url: TODO
# required_version: 2.7.0

enabled_site_setting :plugin_name_enabled
enabled_site_setting :moderation_announcement_enabled

module ::MyPluginModule
PLUGIN_NAME = "discourse-plugin-name"
module ::DiscourseModeratorModal
PLUGIN_NAME = "discourse-moderation-announcement"
end

require_relative "lib/my_plugin_module/engine"
register_asset "stylesheets/common/remove-post-modal.scss"

# require_relative "lib/my_plugin_module/engine"

after_initialize do
# Code which should run after Rails has finished booting
add_permitted_reviewable_param(:ReviewableFlaggedPost, :reason_id)
add_permitted_reviewable_param(:ReviewableFlaggedPost, :announcement_content)
add_permitted_reviewable_param(:ReviewableFlaggedPost, :should_announce)

module ::DiscourseModeratorModal
module OverrideReviewableFlaggedPost
def perform_delete_and_agree(performed_by, args)
result = super(performed_by, args)
if args["should_announce"] == "true" &&
SiteSetting.moderation_announcement_deletion_topic_id != -1
PostCreator.new(
performed_by,
raw: args["announcement_content"],
topic_id: SiteSetting.moderation_announcement_deletion_topic_id,
).create!
end
result
end
end
end
ReviewableFlaggedPost.prepend ::DiscourseModeratorModal::OverrideReviewableFlaggedPost
end

0 comments on commit 151ae2b

Please sign in to comment.