UX: puts back share-panel as floating pane on post actions (#7066)
This commit is contained in:
@@ -1,15 +1,12 @@
|
||||
import { escapeExpression } from "discourse/lib/utilities";
|
||||
import { longDateNoYear } from "discourse/lib/formatter";
|
||||
import { default as computed } from "ember-addons/ember-computed-decorators";
|
||||
import Sharing from "discourse/lib/sharing";
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: null,
|
||||
|
||||
date: Ember.computed.alias("panel.model.date"),
|
||||
type: Ember.computed.alias("panel.model.type"),
|
||||
postNumber: Ember.computed.alias("panel.model.postNumber"),
|
||||
postId: Ember.computed.alias("panel.model.postId"),
|
||||
|
||||
topic: Ember.computed.alias("panel.model.topic"),
|
||||
|
||||
@computed
|
||||
@@ -17,21 +14,9 @@ export default Ember.Component.extend({
|
||||
return Sharing.activeSources(this.siteSettings.share_links);
|
||||
},
|
||||
|
||||
@computed("date")
|
||||
postDate(date) {
|
||||
return date ? longDateNoYear(new Date(date)) : null;
|
||||
},
|
||||
|
||||
@computed("type", "postNumber", "postDate", "topic.title")
|
||||
shareTitle(type, postNumber, postDate, topicTitle) {
|
||||
@computed("type", "topic.title")
|
||||
shareTitle(type, topicTitle) {
|
||||
topicTitle = escapeExpression(topicTitle);
|
||||
|
||||
if (type === "topic") {
|
||||
return I18n.t("share.topic_html", { topicTitle });
|
||||
}
|
||||
if (postNumber) {
|
||||
return I18n.t("share.post_html", { postNumber, postDate });
|
||||
}
|
||||
return I18n.t("share.topic_html", { topicTitle });
|
||||
},
|
||||
|
||||
@@ -81,27 +66,10 @@ export default Ember.Component.extend({
|
||||
|
||||
actions: {
|
||||
share(source) {
|
||||
const url = source.generateUrl(
|
||||
this.get("shareUrl"),
|
||||
this.get("topic.title")
|
||||
);
|
||||
const options = {
|
||||
menubar: "no",
|
||||
toolbar: "no",
|
||||
resizable: "yes",
|
||||
scrollbars: "yes",
|
||||
width: 600,
|
||||
height: source.popupHeight || 315
|
||||
};
|
||||
const stringOptions = Object.keys(options)
|
||||
.map(k => `${k}=${options[k]}`)
|
||||
.join(",");
|
||||
|
||||
if (source.shouldOpenInPopup) {
|
||||
window.open(url, "", stringOptions);
|
||||
} else {
|
||||
window.open(url, "_blank");
|
||||
}
|
||||
Sharing.shareSource(source, {
|
||||
url: this.get("shareUrl"),
|
||||
title: this.get("topic.title")
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
import { wantsNewWindow } from "discourse/lib/intercept-click";
|
||||
import { longDateNoYear } from "discourse/lib/formatter";
|
||||
import computed from "ember-addons/ember-computed-decorators";
|
||||
import Sharing from "discourse/lib/sharing";
|
||||
import { nativeShare } from "discourse/lib/pwa-utils";
|
||||
|
||||
export default Ember.Component.extend({
|
||||
elementId: "share-link",
|
||||
classNameBindings: ["visible"],
|
||||
link: null,
|
||||
visible: null,
|
||||
|
||||
@computed
|
||||
sources() {
|
||||
return Sharing.activeSources(this.siteSettings.share_links);
|
||||
},
|
||||
|
||||
@computed("type", "postNumber")
|
||||
shareTitle(type, postNumber) {
|
||||
if (type === "topic") {
|
||||
return I18n.t("share.topic");
|
||||
}
|
||||
if (postNumber) {
|
||||
return I18n.t("share.post", { postNumber });
|
||||
}
|
||||
return I18n.t("share.topic");
|
||||
},
|
||||
|
||||
@computed("date")
|
||||
displayDate(date) {
|
||||
return longDateNoYear(new Date(date));
|
||||
},
|
||||
|
||||
_focusUrl() {
|
||||
const link = this.get("link");
|
||||
if (!this.capabilities.touch) {
|
||||
const $linkInput = $("#share-link input");
|
||||
$linkInput.val(link);
|
||||
|
||||
// Wait for the fade-in transition to finish before selecting the link:
|
||||
window.setTimeout(() => $linkInput.select().focus(), 160);
|
||||
} else {
|
||||
const $linkForTouch = $("#share-link .share-for-touch a");
|
||||
$linkForTouch.attr("href", link);
|
||||
$linkForTouch.text(link);
|
||||
const range = window.document.createRange();
|
||||
range.selectNode($linkForTouch[0]);
|
||||
window.getSelection().addRange(range);
|
||||
}
|
||||
},
|
||||
|
||||
_showUrl($target, url) {
|
||||
const $currentTargetOffset = $target.offset();
|
||||
const $this = this.$();
|
||||
|
||||
if (Ember.isEmpty(url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Relative urls
|
||||
if (url.indexOf("/") === 0) {
|
||||
url = window.location.protocol + "//" + window.location.host + url;
|
||||
}
|
||||
|
||||
const shareLinkWidth = $this.width();
|
||||
let x = $currentTargetOffset.left - shareLinkWidth / 2;
|
||||
if (x < 25) {
|
||||
x = 25;
|
||||
}
|
||||
if (x + shareLinkWidth > $(window).width()) {
|
||||
x -= shareLinkWidth / 2;
|
||||
}
|
||||
|
||||
const header = $(".d-header");
|
||||
let y = $currentTargetOffset.top - ($this.height() + 20);
|
||||
if (y < header.offset().top + header.height()) {
|
||||
y = $currentTargetOffset.top + 10;
|
||||
}
|
||||
|
||||
$this.css({ top: "" + y + "px" });
|
||||
|
||||
if (!this.site.mobileView) {
|
||||
$this.css({ left: "" + x + "px" });
|
||||
}
|
||||
this.set("link", encodeURI(url));
|
||||
this.set("visible", true);
|
||||
|
||||
Ember.run.scheduleOnce("afterRender", this, this._focusUrl);
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
this._super(...arguments);
|
||||
|
||||
const $html = $("html");
|
||||
$html.on("mousedown.outside-share-link", e => {
|
||||
// Use mousedown instead of click so this event is handled before routing occurs when a
|
||||
// link is clicked (which is a click event) while the share dialog is showing.
|
||||
if (this.$().has(e.target).length !== 0) {
|
||||
return;
|
||||
}
|
||||
this.send("close");
|
||||
return true;
|
||||
});
|
||||
|
||||
$html.on(
|
||||
"click.discourse-share-link",
|
||||
"button[data-share-url], .post-info .post-date[data-share-url]",
|
||||
e => {
|
||||
// if they want to open in a new tab, let it so
|
||||
if (wantsNewWindow(e)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
const $currentTarget = $(e.currentTarget);
|
||||
const url = $currentTarget.data("share-url");
|
||||
const postNumber = $currentTarget.data("post-number");
|
||||
const postId = $currentTarget.closest("article").data("post-id");
|
||||
const date = $currentTarget.children().data("time");
|
||||
|
||||
this.setProperties({ postNumber, date, postId });
|
||||
|
||||
// use native webshare only when the user clicks on the "chain" icon
|
||||
if (!$currentTarget.hasClass("post-date")) {
|
||||
nativeShare({ url }).then(null, () =>
|
||||
this._showUrl($currentTarget, url)
|
||||
);
|
||||
} else {
|
||||
this._showUrl($currentTarget, url);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
$html.on("keydown.share-view", e => {
|
||||
if (e.keyCode === 27) {
|
||||
this.send("close");
|
||||
}
|
||||
});
|
||||
|
||||
this.appEvents.on("share:url", (url, $target) =>
|
||||
this._showUrl($target, url)
|
||||
);
|
||||
},
|
||||
|
||||
willDestroyElement() {
|
||||
this._super(...arguments);
|
||||
$("html")
|
||||
.off("click.discourse-share-link")
|
||||
.off("mousedown.outside-share-link")
|
||||
.off("keydown.share-view");
|
||||
},
|
||||
|
||||
actions: {
|
||||
close() {
|
||||
this.setProperties({
|
||||
link: null,
|
||||
postNumber: null,
|
||||
postId: null,
|
||||
visible: false
|
||||
});
|
||||
},
|
||||
|
||||
share(source) {
|
||||
Sharing.shareSource(source, {
|
||||
url: this.get("link"),
|
||||
title: this.get("topic.title")
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user