mirror of
https://ghfast.top/https://github.com/discourse/discourse-shared-edits.git
synced 2026-07-15 11:17:01 +08:00
230 lines
5.9 KiB
JavaScript
230 lines
5.9 KiB
JavaScript
import { action } from "@ember/object";
|
|
import { service } from "@ember/service";
|
|
import { trustHTML } from "@ember/template";
|
|
import { ajax } from "discourse/lib/ajax";
|
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
|
import { USER_OPTION_COMPOSITION_MODES } from "discourse/lib/constants";
|
|
import { iconHTML } from "discourse/lib/icon-library";
|
|
import { withPluginApi } from "discourse/lib/plugin-api";
|
|
import {
|
|
registerCustomizationCallback,
|
|
SAVE_ICONS,
|
|
SAVE_LABELS,
|
|
} from "discourse/models/composer";
|
|
import SharedEditButton from "../components/shared-edit-button";
|
|
import sharedEditsProsemirrorExtension from "../lib/shared-edits-prosemirror-extension";
|
|
|
|
const SHARED_EDIT_ACTION = "sharedEdit";
|
|
|
|
function formatSharedEditActionTitle(model) {
|
|
if (model.action !== SHARED_EDIT_ACTION) {
|
|
return;
|
|
}
|
|
|
|
const opts = model.replyOptions;
|
|
if (!opts?.userAvatar || !opts?.userLink || !opts?.postLink) {
|
|
return;
|
|
}
|
|
|
|
return trustHTML(`
|
|
${iconHTML("far-pen-to-square", { title: "shared_edits.composer_title" })}
|
|
<a class="post-link" href="${opts.postLink.href}">${opts.postLink.anchor}</a>
|
|
${opts.userAvatar}
|
|
<span class="username">${opts.userLink.anchor}</span>
|
|
`);
|
|
}
|
|
|
|
function initWithApi(api, siteSettings) {
|
|
SAVE_LABELS[SHARED_EDIT_ACTION] = "composer.save_edit";
|
|
SAVE_ICONS[SHARED_EDIT_ACTION] = "pencil";
|
|
|
|
registerCustomizationCallback({
|
|
actionTitle: formatSharedEditActionTitle,
|
|
});
|
|
|
|
api.registerValueTransformer(
|
|
"composer-force-editor-mode",
|
|
({ value, context }) => {
|
|
if (context.model?.action === SHARED_EDIT_ACTION) {
|
|
if (siteSettings?.shared_edits_editor_mode === "rich") {
|
|
return USER_OPTION_COMPOSITION_MODES.rich;
|
|
}
|
|
return USER_OPTION_COMPOSITION_MODES.markdown;
|
|
}
|
|
return value;
|
|
}
|
|
);
|
|
|
|
api.registerRichEditorExtension(sharedEditsProsemirrorExtension);
|
|
|
|
customizePostMenu(api);
|
|
|
|
const currentUser = api.getCurrentUser();
|
|
|
|
api.addPostAdminMenuButton((attrs) => {
|
|
if (!currentUser?.staff && currentUser?.trust_level < 4) {
|
|
return;
|
|
}
|
|
|
|
return {
|
|
icon: "far-pen-to-square",
|
|
className: "admin-toggle-shared-edits",
|
|
label: attrs.shared_edits_enabled
|
|
? "shared_edits.disable_shared_edits"
|
|
: "shared_edits.enable_shared_edits",
|
|
action: async (post) => {
|
|
const url = `/shared_edits/p/${post.id}/${
|
|
post.shared_edits_enabled ? "disable" : "enable"
|
|
}.json`;
|
|
|
|
try {
|
|
await ajax(url, { type: "PUT" });
|
|
post.set("shared_edits_enabled", !post.shared_edits_enabled);
|
|
} catch (e) {
|
|
popupAjaxError(e);
|
|
}
|
|
},
|
|
};
|
|
});
|
|
|
|
api.addTrackedPostProperties("shared_edits_enabled");
|
|
|
|
api.addPostClassesCallback((attrs) => {
|
|
if (attrs.shared_edits_enabled && attrs.canEdit) {
|
|
return ["shared-edits-post"];
|
|
}
|
|
});
|
|
|
|
api.modifyClass(
|
|
"model:composer",
|
|
(Superclass) =>
|
|
class extends Superclass {
|
|
get creatingSharedEdit() {
|
|
return this.get("action") === SHARED_EDIT_ACTION;
|
|
}
|
|
|
|
get editingPost() {
|
|
return super.editingPost || this.creatingSharedEdit;
|
|
}
|
|
}
|
|
);
|
|
|
|
api.modifyClass(
|
|
"controller:topic",
|
|
(Superclass) =>
|
|
class extends Superclass {
|
|
init() {
|
|
super.init(...arguments);
|
|
|
|
this.appEvents.on(
|
|
"shared-edit-on-post",
|
|
this,
|
|
this._handleSharedEditOnPost
|
|
);
|
|
}
|
|
|
|
willDestroy() {
|
|
super.willDestroy(...arguments);
|
|
this.appEvents.off(
|
|
"shared-edit-on-post",
|
|
this,
|
|
this._handleSharedEditOnPost
|
|
);
|
|
}
|
|
|
|
async _handleSharedEditOnPost(post) {
|
|
const draftKey = post.get("topic.draft_key");
|
|
const draftSequence = post.get("topic.draft_sequence");
|
|
|
|
let raw;
|
|
try {
|
|
const result = await ajax(`/posts/${post.id}.json`);
|
|
raw = result.raw;
|
|
} catch (e) {
|
|
popupAjaxError(e);
|
|
return;
|
|
}
|
|
|
|
this.get("composer").open({
|
|
post,
|
|
action: SHARED_EDIT_ACTION,
|
|
draftKey,
|
|
draftSequence,
|
|
reply: raw,
|
|
});
|
|
}
|
|
}
|
|
);
|
|
|
|
api.modifyClass(
|
|
"component:d-editor",
|
|
(Superclass) =>
|
|
class extends Superclass {
|
|
@service composer;
|
|
@service sharedEditManager;
|
|
|
|
@action
|
|
onChange(event) {
|
|
super.onChange(event);
|
|
|
|
if (this.composer?.model?.action !== SHARED_EDIT_ACTION) {
|
|
return;
|
|
}
|
|
|
|
this.sharedEditManager?.syncFromComposerValue?.(
|
|
event?.target?.value ?? ""
|
|
);
|
|
}
|
|
}
|
|
);
|
|
|
|
api.modifyClass(
|
|
"component:composer-messages",
|
|
(Superclass) =>
|
|
class extends Superclass {
|
|
async _findMessages() {
|
|
if (this.composer?.action === SHARED_EDIT_ACTION) {
|
|
this.set("checkedMessages", true);
|
|
return;
|
|
}
|
|
|
|
return super._findMessages(...arguments);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
function customizePostMenu(api) {
|
|
api.registerValueTransformer(
|
|
"post-menu-buttons",
|
|
({ value: dag, context: { post, buttonLabels, buttonKeys } }) => {
|
|
if (!post.shared_edits_enabled || !post.canEdit) {
|
|
return;
|
|
}
|
|
|
|
dag.replace(buttonKeys.EDIT, SharedEditButton, {
|
|
after: [buttonKeys.SHOW_MORE, buttonKeys.REPLY],
|
|
});
|
|
dag.reposition(buttonKeys.REPLY, {
|
|
after: buttonKeys.SHOW_MORE,
|
|
before: buttonKeys.EDIT,
|
|
});
|
|
|
|
buttonLabels.hide(buttonKeys.REPLY);
|
|
}
|
|
);
|
|
|
|
api.addTrackedPostProperties("shared_edits_enabled");
|
|
}
|
|
|
|
export default {
|
|
name: "discourse-shared-edits",
|
|
initialize: (container) => {
|
|
const siteSettings = container.lookup("service:site-settings");
|
|
if (!siteSettings.shared_edits_enabled) {
|
|
return;
|
|
}
|
|
|
|
withPluginApi((api) => initWithApi(api, siteSettings));
|
|
},
|
|
};
|