diff --git a/app/assets/javascripts/discourse/app/components/composer-messages.hbs b/app/assets/javascripts/discourse/app/components/composer-messages.hbs
index ea42db24a83..202cbfc62e7 100644
--- a/app/assets/javascripts/discourse/app/components/composer-messages.hbs
+++ b/app/assets/javascripts/discourse/app/components/composer-messages.hbs
@@ -2,7 +2,13 @@
+ {{#if this.showShareModal}}
+
+ {{/if}}
{{/each}}
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/app/components/composer-messages.js b/app/assets/javascripts/discourse/app/components/composer-messages.js
index 43e9d59ee7b..bc2527c1ecf 100644
--- a/app/assets/javascripts/discourse/app/components/composer-messages.js
+++ b/app/assets/javascripts/discourse/app/components/composer-messages.js
@@ -4,14 +4,18 @@ import EmberObject, { action } from "@ember/object";
import I18n from "I18n";
import LinkLookup from "discourse/lib/link-lookup";
import { not } from "@ember/object/computed";
-import showModal from "discourse/lib/show-modal";
import { ajax } from "discourse/lib/ajax";
+import { inject as service } from "@ember/service";
+import { tracked } from "@glimmer/tracking";
let _messagesCache = {};
let _recipient_names = [];
@classNameBindings(":composer-popup-container", "hidden")
export default class ComposerMessages extends Component {
+ @service modal;
+ @tracked showShareModal;
+
checkedMessages = false;
messages = null;
messagesByTemplate = null;
@@ -309,19 +313,17 @@ export default class ComposerMessages extends Component {
}
}
- @action
- shareModal() {
+ get shareModalData() {
const { topic } = this.composer;
- const controller = showModal("share-topic", { model: topic.category });
-
- controller.setProperties({
+ return {
+ topic,
+ category: topic.category,
allowInvites:
topic.details.can_invite_to &&
!topic.archived &&
!topic.closed &&
!topic.deleted,
- topic,
- });
+ };
}
@action
diff --git a/app/assets/javascripts/discourse/app/templates/modal/share-topic.hbs b/app/assets/javascripts/discourse/app/components/modal/share-topic.hbs
similarity index 91%
rename from app/assets/javascripts/discourse/app/templates/modal/share-topic.hbs
rename to app/assets/javascripts/discourse/app/components/modal/share-topic.hbs
index 1741bba57b2..b18a4b294bf 100644
--- a/app/assets/javascripts/discourse/app/templates/modal/share-topic.hbs
+++ b/app/assets/javascripts/discourse/app/components/modal/share-topic.hbs
@@ -1,10 +1,14 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/app/components/modal/share-topic.js b/app/assets/javascripts/discourse/app/components/modal/share-topic.js
new file mode 100644
index 00000000000..fa00bc6b543
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/components/modal/share-topic.js
@@ -0,0 +1,121 @@
+import Component from "@ember/component";
+import { action } from "@ember/object";
+import { getAbsoluteURL } from "discourse-common/lib/get-url";
+import discourseComputed, {
+ afterRender,
+} from "discourse-common/utils/decorators";
+import { readOnly } from "@ember/object/computed";
+import { longDateNoYear } from "discourse/lib/formatter";
+import Sharing from "discourse/lib/sharing";
+import showModal from "discourse/lib/show-modal";
+import { bufferedProperty } from "discourse/mixins/buffered-content";
+import I18n from "I18n";
+import Category from "discourse/models/category";
+import { getOwner } from "discourse-common/lib/get-owner";
+
+const ShareTopicModal = Component.extend(bufferedProperty("invite"), {
+ topic: readOnly("model.topic"),
+ post: readOnly("model.post"),
+ category: readOnly("model.category"),
+ allowInvites: readOnly("model.allowInvites"),
+
+ didInsertElement() {
+ this._showRestrictedGroupWarning();
+ this._selectUrl();
+ this._super();
+ },
+
+ @afterRender
+ _showRestrictedGroupWarning() {
+ if (!this.category) {
+ return;
+ }
+
+ Category.fetchVisibleGroups(this.category.id).then((result) => {
+ if (result.groups.length > 0) {
+ this.setProperties({
+ flash: I18n.t("topic.share.restricted_groups", {
+ count: result.groups.length,
+ groupNames: result.groups.join(", "),
+ }),
+ flashType: "warning",
+ });
+ }
+ });
+ },
+
+ @afterRender
+ _selectUrl() {
+ const input = document.querySelector("input.invite-link");
+ if (input && !this.site.mobileView) {
+ // if the input is auto-focused on mobile, iOS requires two taps of the copy button
+ input.setSelectionRange(0, this.url.length);
+ input.focus();
+ }
+ },
+
+ @discourseComputed("post.shareUrl", "topic.shareUrl")
+ url(postUrl, topicUrl) {
+ if (postUrl) {
+ return getAbsoluteURL(postUrl);
+ } else if (topicUrl) {
+ return getAbsoluteURL(topicUrl);
+ }
+ },
+
+ @discourseComputed("post.created_at", "post.wiki", "post.last_wiki_edit")
+ displayDate(createdAt, wiki, lastWikiEdit) {
+ const date = wiki && lastWikiEdit ? lastWikiEdit : createdAt;
+ return longDateNoYear(new Date(date));
+ },
+
+ @discourseComputed(
+ "topic.{isPrivateMessage,invisible,category.read_restricted}"
+ )
+ sources(topic) {
+ const privateContext =
+ this.siteSettings.login_required ||
+ topic?.isPrivateMessage ||
+ topic?.invisible ||
+ topic?.category?.read_restricted;
+
+ return Sharing.activeSources(this.siteSettings.share_links, privateContext);
+ },
+
+ @action
+ share(source) {
+ Sharing.shareSource(source, {
+ title: this.topic.title,
+ url: this.url,
+ });
+ },
+
+ @action
+ inviteUsers() {
+ const controller = showModal("create-invite");
+ controller.setProperties({
+ inviteToTopic: true,
+ topics: [this.topic],
+ });
+ controller.buffered.setProperties({
+ topicId: this.topic.id,
+ topicTitle: this.topic.title,
+ });
+ },
+
+ @action
+ replyAsNewTopic() {
+ const postStream = this.topic.postStream;
+ const postId = this.post?.id || postStream.findPostIdForPostNumber(1);
+ const post = postStream.findLoadedPost(postId);
+ const topicController = getOwner(this).lookup("controller:topic");
+ topicController.actions.replyAsNewTopic.call(topicController, post);
+ this.closeModal();
+ },
+});
+
+ShareTopicModal.reopenClass({
+ modalClass: "share-topic-modal",
+});
+
+export default ShareTopicModal;
diff --git a/app/assets/javascripts/discourse/app/controllers/share-topic.js b/app/assets/javascripts/discourse/app/controllers/share-topic.js
deleted file mode 100644
index 5f9766af2c4..00000000000
--- a/app/assets/javascripts/discourse/app/controllers/share-topic.js
+++ /dev/null
@@ -1,126 +0,0 @@
-import Controller from "@ember/controller";
-import { action } from "@ember/object";
-import { getAbsoluteURL } from "discourse-common/lib/get-url";
-import discourseComputed, {
- afterRender,
-} from "discourse-common/utils/decorators";
-import { longDateNoYear } from "discourse/lib/formatter";
-import Sharing from "discourse/lib/sharing";
-import showModal from "discourse/lib/show-modal";
-import { bufferedProperty } from "discourse/mixins/buffered-content";
-import ModalFunctionality from "discourse/mixins/modal-functionality";
-import I18n from "I18n";
-import Category from "discourse/models/category";
-import { getOwner } from "discourse-common/lib/get-owner";
-
-export default Controller.extend(
- ModalFunctionality,
- bufferedProperty("invite"),
- {
- topic: null,
- post: null,
- allowInvites: false,
-
- onShow() {
- this.setProperties({
- topic: null,
- post: null,
- allowInvites: false,
- });
-
- this._showRestrictedGroupWarning();
- this._selectUrl();
- },
-
- @afterRender
- _showRestrictedGroupWarning() {
- if (!this.model) {
- return;
- }
-
- Category.fetchVisibleGroups(this.model.id).then((result) => {
- if (result.groups.length > 0) {
- this.flash(
- I18n.t("topic.share.restricted_groups", {
- count: result.groups.length,
- groupNames: result.groups.join(", "),
- }),
- "warning"
- );
- }
- });
- },
-
- @afterRender
- _selectUrl() {
- const input = document.querySelector("input.invite-link");
- if (input && !this.site.mobileView) {
- // if the input is auto-focused on mobile, iOS requires two taps of the copy button
- input.setSelectionRange(0, this.url.length);
- input.focus();
- }
- },
-
- @discourseComputed("post.shareUrl", "topic.shareUrl")
- url(postUrl, topicUrl) {
- if (postUrl) {
- return getAbsoluteURL(postUrl);
- } else if (topicUrl) {
- return getAbsoluteURL(topicUrl);
- }
- },
-
- @discourseComputed("post.created_at", "post.wiki", "post.last_wiki_edit")
- displayDate(createdAt, wiki, lastWikiEdit) {
- const date = wiki && lastWikiEdit ? lastWikiEdit : createdAt;
- return longDateNoYear(new Date(date));
- },
-
- @discourseComputed(
- "topic.{isPrivateMessage,invisible,category.read_restricted}"
- )
- sources(topic) {
- const privateContext =
- this.siteSettings.login_required ||
- topic?.isPrivateMessage ||
- topic?.invisible ||
- topic?.category?.read_restricted;
-
- return Sharing.activeSources(
- this.siteSettings.share_links,
- privateContext
- );
- },
-
- @action
- share(source) {
- Sharing.shareSource(source, {
- title: this.topic.title,
- url: this.url,
- });
- },
-
- @action
- inviteUsers() {
- const controller = showModal("create-invite");
- controller.setProperties({
- inviteToTopic: true,
- topics: [this.topic],
- });
- controller.buffered.setProperties({
- topicId: this.topic.id,
- topicTitle: this.topic.title,
- });
- },
-
- @action
- replyAsNewTopic() {
- const postStream = this.topic.postStream;
- const postId = this.post?.id || postStream.findPostIdForPostNumber(1);
- const post = postStream.findLoadedPost(postId);
- const topicController = getOwner(this).lookup("controller:topic");
- topicController.actions.replyAsNewTopic.call(topicController, post);
- this.send("closeModal");
- },
- }
-);
diff --git a/app/assets/javascripts/discourse/app/instance-initializers/topic-footer-buttons.js b/app/assets/javascripts/discourse/app/instance-initializers/topic-footer-buttons.js
index df290f09397..f1e3b651822 100644
--- a/app/assets/javascripts/discourse/app/instance-initializers/topic-footer-buttons.js
+++ b/app/assets/javascripts/discourse/app/instance-initializers/topic-footer-buttons.js
@@ -4,7 +4,7 @@ import {
WITH_REMINDER_ICON,
} from "discourse/models/bookmark";
import { registerTopicFooterButton } from "discourse/lib/register-topic-footer-button";
-import showModal from "discourse/lib/show-modal";
+import ShareTopicModal from "discourse/components/modal/share-topic";
const SHARE_PRIORITY = 1000;
const BOOKMARK_PRIORITY = 900;
@@ -13,7 +13,7 @@ const FLAG_PRIORITY = 700;
const DEFER_PRIORITY = 500;
export default {
- initialize() {
+ initialize(owner) {
registerTopicFooterButton({
id: "share-and-invite",
icon: "d-topic-share",
@@ -25,15 +25,15 @@ export default {
},
title: "topic.share.help",
action() {
- const controller = showModal("share-topic", {
- model: this.topic.category,
- });
- controller.setProperties({
- allowInvites:
- this.currentUser.can_invite_to_forum &&
- this.canInviteTo &&
- !this.inviteDisabled,
- topic: this.topic,
+ owner.lookup("service:modal").show(ShareTopicModal, {
+ model: {
+ category: this.topic.category,
+ topic: this.topic,
+ allowInvites:
+ this.currentUser.can_invite_to_forum &&
+ this.canInviteTo &&
+ !this.inviteDisabled,
+ },
});
},
dropdown() {
diff --git a/app/assets/javascripts/discourse/app/widgets/post.js b/app/assets/javascripts/discourse/app/widgets/post.js
index ff04f2fbda7..f37656a822d 100644
--- a/app/assets/javascripts/discourse/app/widgets/post.js
+++ b/app/assets/javascripts/discourse/app/widgets/post.js
@@ -23,9 +23,10 @@ import {
import { relativeAgeMediumSpan } from "discourse/lib/formatter";
import { transformBasicPost } from "discourse/lib/transform-post";
import autoGroupFlairForUser from "discourse/lib/avatar-flair";
-import showModal from "discourse/lib/show-modal";
import { nativeShare } from "discourse/lib/pwa-utils";
import { hideUserTip } from "discourse/lib/user-tips";
+import ShareTopicModal from "discourse/components/modal/share-topic";
+import { getOwner } from "@ember/application";
function transformWithCallbacks(post) {
let transformed = transformBasicPost(post);
@@ -410,8 +411,11 @@ createWidget("post-date", {
showShareModal() {
const post = this.findAncestorModel();
const topic = post.topic;
- const controller = showModal("share-topic", { model: topic.category });
- controller.setProperties({ topic, post });
+ getOwner(this)
+ .lookup("service:modal")
+ .show(ShareTopicModal, {
+ model: { category: topic.category, topic, post },
+ });
},
});
@@ -627,8 +631,11 @@ createWidget("post-contents", {
const post = this.findAncestorModel();
nativeShare(this.capabilities, { url: post.shareUrl }).catch(() => {
const topic = post.topic;
- const controller = showModal("share-topic", { model: topic.category });
- controller.setProperties({ topic, post });
+ getOwner(this)
+ .lookup("service:modal")
+ .show(ShareTopicModal, {
+ model: { category: topic.category, topic, post },
+ });
});
},