FEATURE: Add site setting and wizard step to set base font (#10250)

FEATURE: Add site setting and wizard step to set base font (#10250)

Co-authored-by: Neil Lalonde neillalonde@gmail.com

diff --git a/.gitignore b/.gitignore
index 4f56364..543d7dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -87,6 +87,7 @@ config/multisite.yml
 config/multisite1.yml
 config/fog_credentials.yml
 
+/public/fonts
 /public/uploads
 /public/backups
 /public/stylesheet-cache/*
@@ -131,6 +132,7 @@ node_modules
 
 # ignore auto-generated plugin js assets
 /app/assets/javascripts/plugins/*
+/app/assets/stylesheets/common/fonts.scss
 
 # ignore generated api documentation files
 openapi/*
diff --git a/Gemfile b/Gemfile
index 19bd41d..4736b82 100644
--- a/Gemfile
+++ b/Gemfile
@@ -69,6 +69,7 @@ gem 'http_accept_language', require: false
 gem 'ember-rails', '0.18.5'
 gem 'discourse-ember-source', '~> 3.12.2'
 gem 'ember-handlebars-template', '0.8.0'
+gem 'discourse-fonts'
 
 gem 'barber'
 
diff --git a/Gemfile.lock b/Gemfile.lock
index 3026474..6aca92f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -99,6 +99,7 @@ GEM
     diff-lcs (1.4.4)
     diffy (3.4.0)
     discourse-ember-source (3.12.2.2)
+    discourse-fonts (0.0.2)
     discourse_image_optim (0.26.2)
       exifr (~> 1.2, >= 1.2.2)
       fspath (~> 3.0)
@@ -461,6 +462,7 @@ DEPENDENCIES
   css_parser
   diffy
   discourse-ember-source (~> 3.12.2)
+  discourse-fonts
   discourse_image_optim
   email_reply_trimmer
   ember-handlebars-template (= 0.8.0)
diff --git a/app/assets/javascripts/wizard/components/font-preview.js b/app/assets/javascripts/wizard/components/font-preview.js
new file mode 100644
index 0000000..e3cf397
--- /dev/null
+++ b/app/assets/javascripts/wizard/components/font-preview.js
@@ -0,0 +1,125 @@
+import I18n from "I18n";
+import discourseComputed from "discourse-common/utils/decorators";
+import { observes } from "discourse-common/utils/decorators";
+import {
+  createPreviewComponent,
+  darkLightDiff,
+  chooseDarker,
+  LOREM
+} from "wizard/lib/preview";
+
+export default createPreviewComponent(305, 165, {
+  logo: null,
+  avatar: null,
+
+  classNameBindings: ["isSelected"],
+
+  @discourseComputed("selectedId", "fontId")
+  isSelected(selectedId, fontId) {
+    return selectedId === fontId;
+  },
+
+  click() {
+    this.onChange(this.fontId);
+  },
+
+  @observes("step.fieldsById.base_scheme_id.value")
+  themeChanged() {
+    this.triggerRepaint();
+  },
+
+  images() {
+    return {
+      logo: this.wizard.getLogoUrl(),
+      avatar: "/images/wizard/trout.png"
+    };
+  },
+
+  paint(ctx, colors, font, width, height) {
+    const headerHeight = height * 0.3;
+
+    this.drawFullHeader(colors, font);
+
+    const margin = width * 0.04;
+    const avatarSize = height * 0.2;
+    const lineHeight = height / 9.5;
+
+    // Draw a fake topic
+    this.scaleImage(
+      this.avatar,
+      margin,
+      headerHeight + height * 0.085,
+      avatarSize,
+      avatarSize
+    );
+
+    const titleFontSize = headerHeight / 44;
+
+    ctx.beginPath();
+    ctx.fillStyle = colors.primary;
+    ctx.font = `bold ${titleFontSize}em '${font}'`;
+    ctx.fillText(I18n.t("wizard.previews.topic_title"), margin, height * 0.3);
+
+    const bodyFontSize = height / 220.0;
+    ctx.font = `${bodyFontSize}em '${font}'`;
+
+    let line = 0;
+    const lines = LOREM.split("\n");
+    for (let i = 0; i < 4; i++) {
+      line = height * 0.35 + i * lineHeight;
+      ctx.fillText(lines[i], margin + avatarSize + margin, line);
+    }
+
+    // Share Button
+    ctx.beginPath();
+    ctx.rect(margin, line + lineHeight, width * 0.14, height * 0.14);
+    ctx.fillStyle = darkLightDiff(colors.primary, colors.secondary, 90, 65);
+    ctx.fill();
+    ctx.fillStyle = chooseDarker(colors.primary, colors.secondary);
+    ctx.font = `${bodyFontSize}em '${font}'`;
+    ctx.fillText(
+      I18n.t("wizard.previews.share_button"),
+      margin + width / 55,
+      line + lineHeight * 1.85
+    );
+
+    // Reply Button
+    ctx.beginPath();
+    ctx.rect(
+      margin * 2 + width * 0.14,
+      line + lineHeight,
+      width * 0.14,
+      height * 0.14
+    );
+    ctx.fillStyle = colors.tertiary;
+    ctx.fill();
+    ctx.fillStyle = colors.secondary;
+    ctx.font = `${bodyFontSize}em '${font}'`;
+    ctx.fillText(
+      I18n.t("wizard.previews.reply_button"),
+      margin * 2 + width * 0.14 + width / 55,
+      line + lineHeight * 1.85
+    );
+
+    // Draw Timeline
+    const timelineX = width * 0.8;
+    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);
+  }
+});
diff --git a/app/assets/javascripts/wizard/components/font-previews.js b/app/assets/javascripts/wizard/components/font-previews.js
new file mode 100644
index 0000000..6afd85c
--- /dev/null
+++ b/app/assets/javascripts/wizard/components/font-previews.js
@@ -0,0 +1,8 @@
+import Component from "@ember/component";
+export default Component.extend({
+  actions: {
+    changed(value) {
+      this.set("field.value", value);
+    }
+  }
+});
diff --git a/app/assets/javascripts/wizard/components/homepage-preview.js b/app/assets/javascripts/wizard/components/homepage-preview.js
index 4e61aac..ec669ce 100644
--- a/app/assets/javascripts/wizard/components/homepage-preview.js
+++ b/app/assets/javascripts/wizard/components/homepage-preview.js
@@ -21,36 +21,36 @@ export default createPreviewComponent(659, 320, {
     };
   },
 
-  paint(ctx, colors, width, height) {
-    this.drawFullHeader(colors);
+  paint(ctx, colors, font, width, height) {
+    this.drawFullHeader(colors, font);
 
     if (this.get("step.fieldsById.homepage_style.value") === "latest") {
-      this.drawPills(colors, height * 0.15);
-      this.renderLatest(ctx, colors, width, height);
+      this.drawPills(colors, font, height * 0.15);
+      this.renderLatest(ctx, colors, font, width, height);
     } else if (
       ["categories_only", "categories_with_featured_topics"].includes(
         this.get("step.fieldsById.homepage_style.value")
       )
     ) {
-      this.drawPills(colors, height * 0.15, { categories: true });
-      this.renderCategories(ctx, colors, width, height);
+      this.drawPills(colors, font, height * 0.15, { categories: true });
+      this.renderCategories(ctx, colors, font, width, height);
     } else if (
       ["categories_boxes", "categories_boxes_with_topics"].includes(
         this.get("step.fieldsById.homepage_style.value")
       )
     ) {
-      this.drawPills(colors, height * 0.15, { categories: true });
+      this.drawPills(colors, font, height * 0.15, { categories: true });
       const topics =
         this.get("step.fieldsById.homepage_style.value") ===
         "categories_boxes_with_topics";
-      this.renderCategoriesBoxes(ctx, colors, width, height, { topics });
+      this.renderCategoriesBoxes(ctx, colors, font, width, height, { topics });
     } else {
-      this.drawPills(colors, height * 0.15, { categories: true });
-      this.renderCategoriesWithTopics(ctx, colors, width, height);
+      this.drawPills(colors, font, height * 0.15, { categories: true });
+      this.renderCategoriesWithTopics(ctx, colors, font, width, height);
     }
   },
 
-  renderCategoriesBoxes(ctx, colors, width, height, opts) {
+  renderCategoriesBoxes(ctx, colors, font, width, height, opts) {
     opts = opts || {};
 
     const borderColor = darkLightDiff(
@@ -83,7 +83,7 @@ export default createPreviewComponent(659, 320, {
         ]
       );
 
-      ctx.font = `Bold ${bodyFontSize * 1.3}em 'Arial'`;
+      ctx.font = `Bold ${bodyFontSize * 1.3}em '${font}'`;
       ctx.fillStyle = colors.primary;
       ctx.textAlign = "center";

[... diff too long, it was truncated ...]

GitHub sha: f2e14a39

This commit appears in #10250 which was merged by nbianca.