discourse/app/assets/javascripts/wizard/addon/components/styling-preview.js
Godfrey Chan c34f8b65cb
DEV: Rename I18n imports to discourse-i18n (#23915)
As of #23867 this is now a real package, so updating the imports to
use the real package name, rather than relying on the alias. The
name change in the package name is because `I18n` is not a valid
name as NPM packages must be all lowercase.

This commit also introduces an eslint rule to prevent importing from
the old I18n path.

For themes/plugins, the old 'i18n' name remains functional.
2023-10-18 11:07:09 +01:00

218 lines
5.5 KiB
JavaScript

import { action } from "@ember/object";
import { bind, observes } from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
import { chooseDarker, darkLightDiff } from "wizard/lib/preview";
import WizardPreviewBaseComponent from "./wizard-preview-base";
const LOREM = `
Lorem ipsum dolor sit amet, consectetur adipiscing.
Nullam eget sem non elit tincidunt rhoncus. Fusce
velit nisl, porttitor sed nisl ac, consectetur interdum
metus. Fusce in consequat augue, vel facilisis felis.`;
export default WizardPreviewBaseComponent.extend({
width: 628,
height: 322,
logo: null,
avatar: null,
previewTopic: true,
draggingActive: false,
startX: 0,
scrollLeft: 0,
init() {
this._super(...arguments);
this.wizard.on("homepageStyleChanged", this.onHomepageStyleChange);
},
willDestroy() {
this._super(...arguments);
this.wizard.off("homepageStyleChanged", this.onHomepageStyleChange);
},
didInsertElement() {
this._super(...arguments);
this.element.addEventListener("mouseleave", this.handleMouseLeave);
this.element.addEventListener("mousemove", this.handleMouseMove);
},
willDestroyElement() {
this._super(...arguments);
this.element.removeEventListener("mouseleave", this.handleMouseLeave);
this.element.removeEventListener("mousemove", this.handleMouseMove);
},
mouseDown(e) {
const slider = this.element.querySelector(".previews");
this.setProperties({
draggingActive: true,
startX: e.pageX - slider.offsetLeft,
scrollLeft: slider.scrollLeft,
});
},
@bind
handleMouseLeave() {
this.set("draggingActive", false);
},
mouseUp() {
this.set("draggingActive", false);
},
@bind
handleMouseMove(e) {
if (!this.draggingActive) {
return;
}
e.preventDefault();
const slider = this.element.querySelector(".previews"),
x = e.pageX - slider.offsetLeft,
walk = (x - this.startX) * 1.5;
slider.scrollLeft = this.scrollLeft - walk;
if (slider.scrollLeft < 50) {
this.set("previewTopic", true);
}
if (slider.scrollLeft > slider.offsetWidth - 50) {
this.set("previewTopic", false);
}
},
didUpdateAttrs() {
this._super(...arguments);
this.triggerRepaint();
},
@bind
onHomepageStyleChange() {
this.set("previewTopic", false);
},
@observes("previewTopic")
scrollPreviewArea() {
const el = this.element.querySelector(".previews");
el.scrollTo({
top: 0,
left: this.previewTopic ? 0 : el.scrollWidth - el.offsetWidth,
behavior: "smooth",
});
},
images() {
return {
logo: this.wizard.getLogoUrl(),
avatar: "/images/wizard/trout.png",
};
},
paint({ ctx, colors, font, headingFont, width, height }) {
const headerHeight = height * 0.3;
this.drawFullHeader(colors, headingFont, this.logo);
const margin = 20;
const avatarSize = height * 0.15;
const lineHeight = height / 14;
// Draw a fake topic
this.scaleImage(
this.avatar,
margin,
headerHeight + height * 0.09,
avatarSize,
avatarSize
);
const titleFontSize = headerHeight / 55;
ctx.beginPath();
ctx.fillStyle = colors.primary;
ctx.font = `bold ${titleFontSize}em '${headingFont}'`;
ctx.fillText(I18n.t("wizard.previews.topic_title"), margin, height * 0.3);
const bodyFontSize = height / 330.0;
ctx.font = `${bodyFontSize}em '${font}'`;
let line = 0;
const lines = LOREM.split("\n");
for (let i = 0; i < 5; i++) {
line = height * 0.35 + i * lineHeight;
ctx.fillText(lines[i], margin + avatarSize + margin, line);
}
// Share Button
const shareButtonWidth = I18n.t("wizard.previews.share_button").length * 11;
ctx.beginPath();
ctx.rect(margin, line + lineHeight, shareButtonWidth, height * 0.1);
// accounts for hard-set color variables in solarized themes
ctx.fillStyle =
colors.primary_low ||
darkLightDiff(colors.primary, colors.secondary, 90, 65);
ctx.fillStyle = chooseDarker(colors.primary, colors.secondary);
ctx.font = `${bodyFontSize}em '${font}'`;
ctx.fillText(
I18n.t("wizard.previews.share_button"),
margin + 10,
line + lineHeight * 1.9
);
// Reply Button
const replyButtonWidth = I18n.t("wizard.previews.reply_button").length * 11;
ctx.beginPath();
ctx.rect(
shareButtonWidth + margin + 10,
line + lineHeight,
replyButtonWidth,
height * 0.1
);
ctx.fillStyle = colors.tertiary;
ctx.fill();
ctx.fillStyle = colors.secondary;
ctx.font = `${bodyFontSize}em '${font}'`;
ctx.fillText(
I18n.t("wizard.previews.reply_button"),
shareButtonWidth + margin + 20,
line + lineHeight * 1.9
);
// Draw Timeline
const timelineX = width * 0.86;
ctx.beginPath();
ctx.strokeStyle = colors.tertiary;
ctx.lineWidth = 0.5;
ctx.moveTo(timelineX, height * 0.3);
ctx.lineTo(timelineX, height * 0.7);
ctx.stroke();
// Timeline
ctx.beginPath();
ctx.strokeStyle = colors.tertiary;
ctx.lineWidth = 2;
ctx.moveTo(timelineX, height * 0.3);
ctx.lineTo(timelineX, height * 0.4);
ctx.stroke();
ctx.font = `Bold ${bodyFontSize}em ${font}`;
ctx.fillStyle = colors.primary;
ctx.fillText("1 / 20", timelineX + margin, height * 0.3 + margin * 1.5);
},
@action
setPreviewHomepage(event) {
event?.preventDefault();
this.set("previewTopic", false);
},
@action
setPreviewTopic(event) {
event?.preventDefault();
this.set("previewTopic", true);
},
});