Various bug fixes and performance improvements

Various bug fixes and performance improvements

  • FIX: update_holiday_usernames wasn’t deleting “on_holiday” user custom fields when no users were on holiday
  • FIX: flair wasn’t working on mentions when using subfolder
  • PERF: only decorateCooked and addPosterIcon if there’s at least one user on holiday
  • Migration to remove duplicate “on_holiday” user custom fields
  • Add unique index for the “on_holiday” user custom field
  • Localize the “On Holiday” title
  • Add the boolean type to the “on_holiday” user custom field
diff --git a/assets/javascripts/initializers/add-holiday-flair.js.es6 b/assets/javascripts/initializers/add-holiday-flair.js.es6
index 09adf86..ef03480 100644
--- a/assets/javascripts/initializers/add-holiday-flair.js.es6
+++ b/assets/javascripts/initializers/add-holiday-flair.js.es6
@@ -1,47 +1,38 @@
 import { withPluginApi } from "discourse/lib/plugin-api";
 import { iconHTML } from "discourse-common/lib/icon-library";
 
-function customBool(field) {
-  if (field) {
-    return Array.isArray(field) ? field.some(x => x === "t") : field === "t";
-  }
-  return false;
-}
-
 export default {
   name: "add-holiday-flair",
+
   initialize() {
-    withPluginApi("0.1", api => {
-      const usersOnHoliday = Discourse.Site.current().users_on_holiday;
-      api.decorateCooked(
-        el => {
-          if (!usersOnHoliday) {
-            return;
-          }
+    withPluginApi("0.8", api => {
+      const usernames = api.container.lookup("site:main").users_on_holiday;
 
-          usersOnHoliday.forEach(username => {
-            $(el)
-              .find(`a.mention[href="/u/${username}"]`)
-              .not(".on-holiday")
+      if (usernames && usernames.length > 0) {
+        api.decorateCooked(el => {
+          const $el = $(el);
+
+          usernames.forEach(username => {
+            const href = `${Discourse.BaseUri}/u/${username}`;
+
+            $el
+              .find(`a.mention[href="${href}"]:not(.on-holiday)`)
               .append(iconHTML("calendar-alt"))
               .addClass("on-holiday");
           });
-        },
-        { id: "discourse-calendar-holiday-flair" }
-      );
 
-      api.addPosterIcon(cfs => {
-        const onHoliday = customBool(cfs.on_holiday);
-        if (!onHoliday) {
-          return;
-        }
+        }, { id: "discourse-calendar-holiday-flair" });
 
-        return {
-          emoji: "desert_island",
-          className: "holiday",
-          title: "on holiday"
-        };
-      });
+        api.addPosterIcon(cfs => {
+          if (cfs.on_holiday) {
+            return {
+              emoji: "desert_island",
+              className: "holiday",
+              title: I18n.t("discourse_calendar.on_holiday")
+            };
+          }
+        });
+      }
     });
   }
 };
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 9cab764..7ca1a00 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1,6 +1,7 @@
 en:
   js:
     discourse_calendar:
+      on_holiday: "On Holiday"
       timezone:
         title: "Timezone"
         instructions: "Your current timezone is %{timezone}."
diff --git a/db/migrate/20190724181542_add_on_holiday_index.rb b/db/migrate/20190724181542_add_on_holiday_index.rb
new file mode 100644
index 0000000..72ecf75
--- /dev/null
+++ b/db/migrate/20190724181542_add_on_holiday_index.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class AddOnHolidayIndex < ActiveRecord::Migration[5.2]
+  def up
+    execute <<~SQL
+      DELETE
+        FROM user_custom_fields a
+       USING user_custom_fields b
+       WHERE a.name = 'on_holiday'
+         AND a.name = b.name
+         AND a.id > b.id
+    SQL
+
+    add_index :user_custom_fields,
+      [:name, :user_id],
+      unique: true,
+      name: :idx_user_custom_fields_on_holiday,
+      where: "name = 'on_holiday'"
+  end
+
+  def down
+    remove_index :user_custom_fields, name: :idx_user_custom_fields_on_holiday
+  end
+end
diff --git a/jobs/scheduled/update_holiday_usernames.rb b/jobs/scheduled/update_holiday_usernames.rb
index 89fbec3..9db1fbb 100644
--- a/jobs/scheduled/update_holiday_usernames.rb
+++ b/jobs/scheduled/update_holiday_usernames.rb
@@ -40,18 +40,22 @@ module Jobs
       user_ids = User.where(username_lower: usernames).pluck(:id).compact
 
       if user_ids.present?
-        DB.exec <<~SQL
+        values = user_ids.map { |id| "(#{id}, '#{cf_name}', 't', now(), now())" }
+
+        DB.exec <<~SQL, cf_name
           INSERT INTO user_custom_fields (user_id, name, value, created_at, updated_at)
-          VALUES #{user_ids.map { |id| "(#{id}, '#{cf_name}', 't', now(), now())" }.join(",")}
-          ON CONFLICT DO NOTHING
+          VALUES #{values.join(",")}
+          ON CONFLICT (user_id, name) WHERE (name = ?) DO NOTHING
         SQL
-      end
 
-      DB.exec <<~SQL, cf_name, user_ids
-        DELETE FROM user_custom_fields
-         WHERE name = ?
-           AND user_id NOT IN (?)
-      SQL
+        DB.exec <<~SQL, cf_name, user_ids
+          DELETE FROM user_custom_fields
+           WHERE name = ?
+             AND user_id NOT IN (?)
+        SQL
+      else
+        DB.exec("DELETE FROM user_custom_fields WHERE name = ?", cf_name)
+      end
     end
   end
 end
diff --git a/plugin.rb b/plugin.rb
index 485ada0..5757ad3 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -67,6 +67,8 @@ after_initialize do
   register_post_custom_field_type(DiscourseCalendar::CALENDAR_HOLIDAYS_CUSTOM_FIELD, :json)
   register_post_custom_field_type(DiscourseCalendar::CALENDAR_CUSTOM_FIELD, :string)
 
+  register_user_custom_field_type(DiscourseCalendar::HOLIDAY_CUSTOM_FIELD, :boolean)
+
   whitelist_staff_user_custom_field(DiscourseCalendar::HOLIDAY_CUSTOM_FIELD)
   whitelist_staff_user_custom_field(DiscourseCalendar::TIMEZONE_CUSTOM_FIELD)
 
diff --git a/spec/jobs/update_holiday_usernames_spec.rb b/spec/jobs/update_holiday_usernames_spec.rb
index 2cb67c1..d678638 100644
--- a/spec/jobs/update_holiday_usernames_spec.rb
+++ b/spec/jobs/update_holiday_usernames_spec.rb
@@ -9,23 +9,18 @@ describe DiscourseCalendar::UpdateHolidayUsernames do
     SiteSetting.holiday_calendar_topic_id = @op.topic_id
   end
 
-  it "should update users on holiday list" do
+  it "works" do
     raw = 'Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]'
+
     post = create_post(raw: raw, topic: @op.topic)
     CookedPostProcessor.new(post).post_process
 
-    freeze_time Time.strptime("2018-06-05 18:40:00 UTC", "%Y-%m-%d %H:%M:%S %Z")
+    freeze_time Time.new(2018, 6, 5, 18, 40)
     DiscourseCalendar::UpdateHolidayUsernames.new.execute(nil)
 
     expect(DiscourseCalendar.users_on_holiday).to eq([post.user.username])
-  end
-
-  it "should have empty users on holiday list" do
-    raw = 'Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]'
-    post = create_post(raw: raw, topic: @op.topic)
-    CookedPostProcessor.new(post).post_process
 
-    freeze_time Time.strptime("2018-06-07 18:40:00 UTC", "%Y-%m-%d %H:%M:%S %Z")
+    freeze_time Time.new(2018, 6, 7, 18, 40)
     DiscourseCalendar::UpdateHolidayUsernames.new.execute(nil)
 
     expect(DiscourseCalendar.users_on_holiday).to eq([])

GitHub sha: b1fe4456

1 Like