From f85769eb55fcc93868f12e0a5269e2d14b2efd2b Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Wed, 22 Dec 2021 19:21:09 +0100 Subject: [PATCH 01/11] Add mute rules --- app/models/mute_rule.rb | 7 +++++++ app/workers/question_worker.rb | 5 ++++- db/migrate/20211222165159_create_mute_rules.rb | 10 ++++++++++ db/schema.rb | 9 +++++++++ spec/models/mute_rule_spec.rb | 13 +++++++++++++ spec/workers/question_worker_spec.rb | 14 ++++++++++++++ 6 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 app/models/mute_rule.rb create mode 100644 db/migrate/20211222165159_create_mute_rules.rb create mode 100644 spec/models/mute_rule_spec.rb diff --git a/app/models/mute_rule.rb b/app/models/mute_rule.rb new file mode 100644 index 00000000..14cfabf2 --- /dev/null +++ b/app/models/mute_rule.rb @@ -0,0 +1,7 @@ +class MuteRule < ApplicationRecord + belongs_to :user + + def applies_to?(post) + !!(post.content =~ /\b#{muted_phrase}\b/i) + end +end diff --git a/app/workers/question_worker.rb b/app/workers/question_worker.rb index b49ced7c..cd054e6b 100644 --- a/app/workers/question_worker.rb +++ b/app/workers/question_worker.rb @@ -9,9 +9,12 @@ class QuestionWorker # @param question_id [Integer] newly created question id def perform(user_id, question_id) user = User.find(user_id) + question = Question.find(question_id) user.followers.each do |f| - Inbox.create(user_id: f.id, question_id: question_id, new: true) + unless MuteRule.where(user: f).any? { |rule| rule.applies_to? question } + Inbox.create(user_id: f.id, question_id: question_id, new: true) + end end rescue StandardError => e logger.info "failed to ask question: #{e.message}" diff --git a/db/migrate/20211222165159_create_mute_rules.rb b/db/migrate/20211222165159_create_mute_rules.rb new file mode 100644 index 00000000..417aeec8 --- /dev/null +++ b/db/migrate/20211222165159_create_mute_rules.rb @@ -0,0 +1,10 @@ +class CreateMuteRules < ActiveRecord::Migration[5.2] + def change + create_table :mute_rules do |t| + t.references :user, foreign_key: true + t.string :muted_phrase + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 017794d2..7fb74408 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -107,6 +107,14 @@ ActiveRecord::Schema.define(version: 2021_12_28_135426) do t.index ["user_id"], name: "index_moderation_votes_on_user_id" end + create_table "mute_rules", force: :cascade do |t| + t.bigint "user_id" + t.string "muted_phrase" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["user_id"], name: "index_mute_rules_on_user_id" + end + create_table "notifications", id: :serial, force: :cascade do |t| t.string "target_type" t.bigint "target_id" @@ -306,4 +314,5 @@ ActiveRecord::Schema.define(version: 2021_12_28_135426) do end add_foreign_key "profiles", "users" + add_foreign_key "mute_rules", "users" end diff --git a/spec/models/mute_rule_spec.rb b/spec/models/mute_rule_spec.rb new file mode 100644 index 00000000..5d47fac6 --- /dev/null +++ b/spec/models/mute_rule_spec.rb @@ -0,0 +1,13 @@ +require 'rails_helper' + +RSpec.describe MuteRule, type: :model do + describe "#applies_to?" do + let(:user) { FactoryBot.create(:user) } + let(:rule) { MuteRule.create(user: user, muted_phrase: "trial") } + let(:question) { Question.create(user: user, content: "Did you know that the critically acclaimed MMORPG Final Fantasy XIV has a free trial, and includes the entirety of A Realm Reborn AND the award-winning Heavensward expansion up to level 60 with no restrictions on playtime?") } + + it "only returns true for questions matching a certain phrase" do + expect(rule.applies_to?(question)).to be(true) + end + end +end diff --git a/spec/workers/question_worker_spec.rb b/spec/workers/question_worker_spec.rb index 832276ac..dc069f82 100644 --- a/spec/workers/question_worker_spec.rb +++ b/spec/workers/question_worker_spec.rb @@ -26,5 +26,19 @@ describe QuestionWorker do .to(5) ) end + + it "respects mute rules" do + question.content = 'Some spicy question text' + question.save + + MuteRule.create(user_id: user.followers.first.id, muted_phrase: 'spicy') + + expect { subject } + .to( + change { Inbox.where(user_id: user.followers.ids, question_id: question_id, new: true).count } + .from(0) + .to(4) + ) + end end end From 18de4681983e8261e340bb56f1187fb6a80f7a7c Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Wed, 22 Dec 2021 19:30:55 +0100 Subject: [PATCH 02/11] Add inverse relationship for mute rules <-> users --- app/models/user.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/user.rb b/app/models/user.rb index 5e86fc31..f3407967 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -41,6 +41,7 @@ class User < ApplicationRecord has_many :moderation_votes, dependent: :destroy has_many :lists, dependent: :destroy has_many :list_memberships, class_name: "ListMember", foreign_key: 'user_id', dependent: :destroy + has_many :mute_rules, dependent: :destroy has_many :subscriptions, dependent: :destroy has_many :totp_recovery_codes, dependent: :destroy From 249438e5a86470f89d7145e9227add2c6373c342 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Wed, 22 Dec 2021 19:33:19 +0100 Subject: [PATCH 03/11] Escape muted strings --- app/models/mute_rule.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/mute_rule.rb b/app/models/mute_rule.rb index 14cfabf2..b5b828b4 100644 --- a/app/models/mute_rule.rb +++ b/app/models/mute_rule.rb @@ -2,6 +2,6 @@ class MuteRule < ApplicationRecord belongs_to :user def applies_to?(post) - !!(post.content =~ /\b#{muted_phrase}\b/i) + !!(post.content =~ /\b#{Regexp.escape(muted_phrase)}\b/i) end end From c31ab3578d0e8772d9de54d1a2c0c6949bf93161 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Wed, 22 Dec 2021 19:45:08 +0100 Subject: [PATCH 04/11] Apply mute filters to questions asked directly --- app/controllers/ajax/question_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/ajax/question_controller.rb b/app/controllers/ajax/question_controller.rb index c3c34737..9a140bef 100644 --- a/app/controllers/ajax/question_controller.rb +++ b/app/controllers/ajax/question_controller.rb @@ -66,7 +66,9 @@ class Ajax::QuestionController < AjaxController return end - Inbox.create!(user_id: u.id, question_id: question.id, new: true) + unless MuteRule.where(user: u).any? { |rule| rule.applies_to? question } + Inbox.create!(user_id: u.id, question_id: question.id, new: true) + end end @response[:status] = :okay From 6c0e6b1d303d386ec50d13bcd03c042d532a5b51 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Wed, 22 Dec 2021 23:15:47 +0100 Subject: [PATCH 05/11] Create mute rules AJAX controller --- app/controllers/ajax/mute_rule_controller.rb | 67 ++++++++++++++ config/routes.rb | 3 + .../ajax/mute_rule_controller_spec.rb | 89 +++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 app/controllers/ajax/mute_rule_controller.rb create mode 100644 spec/controllers/ajax/mute_rule_controller_spec.rb diff --git a/app/controllers/ajax/mute_rule_controller.rb b/app/controllers/ajax/mute_rule_controller.rb new file mode 100644 index 00000000..e0db82f4 --- /dev/null +++ b/app/controllers/ajax/mute_rule_controller.rb @@ -0,0 +1,67 @@ +class Ajax::MuteRuleController < AjaxController + def create + params.require :muted_phrase + + unless user_signed_in? + @response[:status] = :noauth + @response[:message] = I18n.t('messages.noauth') + return + end + + rule = MuteRule.create!(user: current_user, muted_phrase: params[:muted_phrase]) + @response[:status] = :okay + @response[:success] = true + @response[:message] = "Rule added successfully." + @response[:id] = rule.id + end + + def update + params.require :id + params.require :muted_phrase + + unless user_signed_in? + @response[:status] = :noauth + @response[:message] = I18n.t('messages.noauth') + return + end + + rule = MuteRule.find(params[:id]) + + if rule.user_id != current_user.id + @response[:status] = :nopriv + @response[:message] = "Can't edit other people's rules" + return + end + + rule.muted_phrase = params[:muted_phrase] + rule.save! + + @response[:status] = :okay + @response[:message] = "Rule updated successfully." + @response[:success] = true + end + + def destroy + params.require :id + + unless user_signed_in? + @response[:status] = :noauth + @response[:message] = I18n.t('messages.noauth') + return + end + + rule = MuteRule.find(params[:id]) + + if rule.user_id != current_user.id + @response[:status] = :nopriv + @response[:message] = "Can't edit other people's rules" + return + end + + rule.destroy! + + @response[:status] = :okay + @response[:message] = "Rule deleted successfully." + @response[:success] = true + end +end diff --git a/config/routes.rb b/config/routes.rb index 064e6ab0..1e321272 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -114,6 +114,9 @@ Rails.application.routes.draw do match '/list_membership', to: 'list#membership', via: :post, as: :list_membership match '/subscribe', to: 'subscription#subscribe', via: :post, as: :subscribe_answer match '/unsubscribe', to: 'subscription#unsubscribe', via: :post, as: :unsubscribe_answer + match '/mute', to: 'mute_rule#create', via: :post, as: :create_mute_rule + match '/mute/:id', to: 'mute_rule#update', via: :post, as: :update_mute_rule + match '/mute/:id', to: 'mute_rule#destroy', via: :delete, as: :delete_mute_rule end match '/discover', to: 'discover#index', via: :get, as: :discover diff --git a/spec/controllers/ajax/mute_rule_controller_spec.rb b/spec/controllers/ajax/mute_rule_controller_spec.rb new file mode 100644 index 00000000..603a6f97 --- /dev/null +++ b/spec/controllers/ajax/mute_rule_controller_spec.rb @@ -0,0 +1,89 @@ +require 'rails_helper' + +describe Ajax::MuteRuleController, :ajax_controller, type: :controller do + + describe "#create" do + subject { post(:create, params: params) } + + context "when user is signed in" do + before(:each) { sign_in(user) } + + let(:params) { { muted_phrase: 'test' } } + let(:expected_response) do + { + "success" => true, + "status" => "okay", + "id" => MuteRule.last.id, + "message" => "Rule added successfully.", + } + end + + it "creates a mute rule" do + expect { subject }.to change { MuteRule.count }.by(1) + expect(response).to have_http_status(:success) + + rule = MuteRule.first + expect(rule.user_id).to eq(user.id) + expect(rule.muted_phrase).to eq('test') + end + + include_examples "returns the expected response" + end + end + + describe "#update" do + subject { post(:update, params: params) } + + context "when user is signed in" do + before(:each) { sign_in(user) } + + let(:rule) { MuteRule.create(user: user, muted_phrase: 'test') } + let(:params) { { id: rule.id, muted_phrase: 'dogs' } } + let(:expected_response) do + { + "success" => true, + "status" => "okay", + "message" => "Rule updated successfully." + } + end + + it "updates a mute rule" do + subject + expect(response).to have_http_status(:success) + + expect(rule.reload.muted_phrase).to eq('dogs') + end + + include_examples "returns the expected response" + end + end + + describe "#destroy" do + subject { delete(:destroy, params: params) } + + context "when user is signed in" do + before(:each) { sign_in(user) } + + let(:rule) { MuteRule.create(user: user, muted_phrase: 'test') } + let(:params) { { id: rule.id } } + let(:expected_response) do + { + "success" => true, + "status" => "okay", + "message" => "Rule deleted successfully." + } + end + + it "deletes a mute rule" do + subject + expect(response).to have_http_status(:success) + + expect(MuteRule.exists?(rule.id)).to eq(false) + + end + + include_examples "returns the expected response" + end + end + +end From 6b626765a84385e99cdf24060f31bc2d3d2f1501 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Thu, 23 Dec 2021 00:03:42 +0100 Subject: [PATCH 06/11] Create views for managing muted words --- app/controllers/user_controller.rb | 6 ++++++ app/views/settings/_muted.haml | 17 +++++++++++++++++ app/views/tabs/_settings.haml | 1 + app/views/user/edit_mute.haml | 4 ++++ config/routes.rb | 1 + 5 files changed, 29 insertions(+) create mode 100644 app/views/settings/_muted.haml create mode 100644 app/views/user/edit_mute.haml diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index edf88087..dcb5c57c 100644 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -224,4 +224,10 @@ class UserController < ApplicationController @recovery_keys = TotpRecoveryCode.generate_for(current_user) render 'settings/security/recovery_keys' end + + # region Muting + def edit_mute + @rules = MuteRule.where(user: current_user) + end + # endregion end diff --git a/app/views/settings/_muted.haml b/app/views/settings/_muted.haml new file mode 100644 index 00000000..5bb51661 --- /dev/null +++ b/app/views/settings/_muted.haml @@ -0,0 +1,17 @@ +.card + .card-body + %h2 Muted words + %p Muting words (or longer phrases) will prevent questions containing those to appear in your inbox. + %p Note: Filtered questions are discarded completely from your inbox, and won't reappear if you remove a filter later on. + - @rules.each do |rule| + .form-group + .input-group + %input.form-control#new-rule-text{disabled: true, value: rule.muted_phrase} + .input-group-append + %button.btn.btn-danger#new-rule-submit{type: 'button'} Remove + .form-group + %form + .input-group + %input.form-control#new-rule-text{placeholder: 'Add a new muted word...'} + .input-group-append + %button.btn.btn-primary#new-rule-submit{type: 'submit'} Add \ No newline at end of file diff --git a/app/views/tabs/_settings.haml b/app/views/tabs/_settings.haml index d6210214..9195899a 100644 --- a/app/views/tabs/_settings.haml +++ b/app/views/tabs/_settings.haml @@ -5,6 +5,7 @@ = list_group_item t('views.settings.tabs.privacy'), edit_user_privacy_path = list_group_item t('views.settings.tabs.security'), edit_user_security_path = list_group_item t('views.settings.tabs.sharing'), services_path + = list_group_item 'Muted words', edit_user_mute_rules_path = list_group_item 'Theme', edit_user_theme_path = list_group_item 'Your Data', user_data_path = list_group_item 'Export', user_export_path diff --git a/app/views/user/edit_mute.haml b/app/views/user/edit_mute.haml new file mode 100644 index 00000000..aa4c6812 --- /dev/null +++ b/app/views/user/edit_mute.haml @@ -0,0 +1,4 @@ += render 'settings/muted' + +- provide(:title, generate_title('Muted words')) +- parent_layout 'user/settings' diff --git a/config/routes.rb b/config/routes.rb index 1e321272..6ff41bee 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -73,6 +73,7 @@ Rails.application.routes.draw do match '/settings/security/2fa', to: 'user#update_2fa', via: :patch, as: :update_user_2fa match '/settings/security/2fa', to: 'user#destroy_2fa', via: :delete, as: :destroy_user_2fa match '/settings/security/recovery', to: 'user#reset_user_recovery_codes', via: :delete, as: :reset_user_recovery_codes + match '/settings/muted', to: 'user#edit_mute', via: :get, as: :edit_user_mute_rules # resources :services, only: [:index, :destroy] match '/settings/services', to: 'services#index', via: 'get', as: :services From 23a5fb55d1b05eeca6068ec0925af28e27ce73d3 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Thu, 23 Dec 2021 01:20:47 +0100 Subject: [PATCH 07/11] Implement frontend for adding mute rules --- app/javascript/packs/application.ts | 2 ++ .../retrospring/features/settings/index.ts | 14 ++++++++ .../retrospring/features/settings/mute.ts | 32 +++++++++++++++++++ app/views/settings/_muted.haml | 21 ++++++++---- 4 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 app/javascript/retrospring/features/settings/index.ts create mode 100644 app/javascript/retrospring/features/settings/mute.ts diff --git a/app/javascript/packs/application.ts b/app/javascript/packs/application.ts index 3fa1a7a6..41a9f0fb 100644 --- a/app/javascript/packs/application.ts +++ b/app/javascript/packs/application.ts @@ -2,10 +2,12 @@ import start from 'retrospring/common'; import initAnswerbox from 'retrospring/features/answerbox/index'; import initInbox from 'retrospring/features/inbox/index'; import initUser from 'retrospring/features/user'; +import initSettings from 'retrospring/features/settings/index'; import initLists from 'retrospring/features/lists'; start(); document.addEventListener('turbolinks:load', initAnswerbox); document.addEventListener('turbolinks:load', initInbox); document.addEventListener('DOMContentLoaded', initUser); +document.addEventListener('turbolinks:load', initSettings); document.addEventListener('DOMContentLoaded', initLists); \ No newline at end of file diff --git a/app/javascript/retrospring/features/settings/index.ts b/app/javascript/retrospring/features/settings/index.ts new file mode 100644 index 00000000..507031a0 --- /dev/null +++ b/app/javascript/retrospring/features/settings/index.ts @@ -0,0 +1,14 @@ +import {createSubmitEvent} from "retrospring/features/settings/mute"; + +export default (): void => { + const submit: HTMLButtonElement = document.getElementById('new-rule-submit') as HTMLButtonElement; + if (submit.classList.contains('js-initialized')) return; + + const rulesList = document.querySelector('.js-rules-list'); + const textEntry: HTMLButtonElement = document.getElementById('new-rule-text') as HTMLButtonElement; + const template: HTMLTemplateElement = document.getElementById('rule-template') as HTMLTemplateElement; + + submit.form.onsubmit = createSubmitEvent(submit, rulesList, textEntry, template) + + submit.classList.add('js-initialized') +} \ No newline at end of file diff --git a/app/javascript/retrospring/features/settings/mute.ts b/app/javascript/retrospring/features/settings/mute.ts new file mode 100644 index 00000000..e9ef07fb --- /dev/null +++ b/app/javascript/retrospring/features/settings/mute.ts @@ -0,0 +1,32 @@ +import Rails from '@rails/ujs'; + +export function createSubmitEvent( + submit: HTMLButtonElement, + rulesList: HTMLDivElement, + textEntry: HTMLButtonElement, + template: HTMLTemplateElement +): (event: Event) => void { + return (event) => { + event.preventDefault(); + submit.disabled = true; + + Rails.ajax({ + url: '/ajax/mute', + type: 'POST', + dataType: 'json', + data: new URLSearchParams({muted_phrase: textEntry.value}).toString(), + success: (data) => { + submit.disabled = false; + if (!data.success) return; + + const newEntryFragment = template.content.cloneNode(true) as Element; + newEntryFragment.querySelector('input').value = textEntry.value; + newEntryFragment.querySelector('button').dataset.id = String(data.id); + + rulesList.appendChild(newEntryFragment) + + textEntry.value = '' + } + }); + }; +} \ No newline at end of file diff --git a/app/views/settings/_muted.haml b/app/views/settings/_muted.haml index 5bb51661..2d1cab73 100644 --- a/app/views/settings/_muted.haml +++ b/app/views/settings/_muted.haml @@ -3,15 +3,22 @@ %h2 Muted words %p Muting words (or longer phrases) will prevent questions containing those to appear in your inbox. %p Note: Filtered questions are discarded completely from your inbox, and won't reappear if you remove a filter later on. - - @rules.each do |rule| - .form-group - .input-group - %input.form-control#new-rule-text{disabled: true, value: rule.muted_phrase} - .input-group-append - %button.btn.btn-danger#new-rule-submit{type: 'button'} Remove + .js-rules-list + - @rules.each do |rule| + .form-group + .input-group + %input.form-control{disabled: true, value: rule.muted_phrase} + .input-group-append + %button.btn.btn-danger{type: 'button', data: {id: rule.id}} Remove .form-group %form .input-group %input.form-control#new-rule-text{placeholder: 'Add a new muted word...'} .input-group-append - %button.btn.btn-primary#new-rule-submit{type: 'submit'} Add \ No newline at end of file + %button.btn.btn-primary#new-rule-submit{type: 'submit'} Add +%template#rule-template + .form-group + .input-group + %input.form-control{disabled: true} + .input-group-append + %button.btn.btn-danger{type: 'button'} Remove \ No newline at end of file From 05ed2143678acfd2ad4a9f2ab7e7e60e5b032f52 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Thu, 23 Dec 2021 01:29:48 +0100 Subject: [PATCH 08/11] Implement frontend for deleting mute rules --- .../retrospring/features/settings/index.ts | 6 +++- .../retrospring/features/settings/mute.ts | 29 ++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/app/javascript/retrospring/features/settings/index.ts b/app/javascript/retrospring/features/settings/index.ts index 507031a0..e885ca11 100644 --- a/app/javascript/retrospring/features/settings/index.ts +++ b/app/javascript/retrospring/features/settings/index.ts @@ -1,10 +1,14 @@ -import {createSubmitEvent} from "retrospring/features/settings/mute"; +import {createDeleteEvent, createSubmitEvent} from "retrospring/features/settings/mute"; export default (): void => { const submit: HTMLButtonElement = document.getElementById('new-rule-submit') as HTMLButtonElement; if (submit.classList.contains('js-initialized')) return; const rulesList = document.querySelector('.js-rules-list'); + rulesList.querySelectorAll('.form-group:not(.js-initalized)').forEach(entry => { + const button = entry.querySelector('button') + button.onclick = createDeleteEvent(entry, button) + }) const textEntry: HTMLButtonElement = document.getElementById('new-rule-text') as HTMLButtonElement; const template: HTMLTemplateElement = document.getElementById('rule-template') as HTMLTemplateElement; diff --git a/app/javascript/retrospring/features/settings/mute.ts b/app/javascript/retrospring/features/settings/mute.ts index e9ef07fb..a402538d 100644 --- a/app/javascript/retrospring/features/settings/mute.ts +++ b/app/javascript/retrospring/features/settings/mute.ts @@ -21,7 +21,12 @@ export function createSubmitEvent( const newEntryFragment = template.content.cloneNode(true) as Element; newEntryFragment.querySelector('input').value = textEntry.value; - newEntryFragment.querySelector('button').dataset.id = String(data.id); + const newDeleteButton = newEntryFragment.querySelector('button') + newDeleteButton.dataset.id = String(data.id); + newDeleteButton.onclick = createDeleteEvent( + newEntryFragment.querySelector('.form-group'), + newDeleteButton + ) rulesList.appendChild(newEntryFragment) @@ -29,4 +34,26 @@ export function createSubmitEvent( } }); }; +} + +export function createDeleteEvent( + entry: HTMLDivElement, + deleteButton: HTMLButtonElement +): () => void { + return () => { + deleteButton.disabled = true; + + Rails.ajax({ + url: '/ajax/mute/' + deleteButton.dataset.id, + type: 'DELETE', + dataType: 'json', + success: (data) => { + if (data.success) { + entry.parentElement.removeChild(entry) + } else { + deleteButton.disabled = false; + } + } + }) + } } \ No newline at end of file From abe33a831fd262bd4062b22b30216ef01bbc01b3 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Thu, 23 Dec 2021 01:32:59 +0100 Subject: [PATCH 09/11] Fix lint errors --- .../retrospring/features/settings/index.ts | 2 +- app/views/settings/_muted.haml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/javascript/retrospring/features/settings/index.ts b/app/javascript/retrospring/features/settings/index.ts index e885ca11..3aa64226 100644 --- a/app/javascript/retrospring/features/settings/index.ts +++ b/app/javascript/retrospring/features/settings/index.ts @@ -8,7 +8,7 @@ export default (): void => { rulesList.querySelectorAll('.form-group:not(.js-initalized)').forEach(entry => { const button = entry.querySelector('button') button.onclick = createDeleteEvent(entry, button) - }) + }); const textEntry: HTMLButtonElement = document.getElementById('new-rule-text') as HTMLButtonElement; const template: HTMLTemplateElement = document.getElementById('rule-template') as HTMLTemplateElement; diff --git a/app/views/settings/_muted.haml b/app/views/settings/_muted.haml index 2d1cab73..2fea6e29 100644 --- a/app/views/settings/_muted.haml +++ b/app/views/settings/_muted.haml @@ -7,18 +7,18 @@ - @rules.each do |rule| .form-group .input-group - %input.form-control{disabled: true, value: rule.muted_phrase} + %input.form-control{ disabled: true, value: rule.muted_phrase } .input-group-append - %button.btn.btn-danger{type: 'button', data: {id: rule.id}} Remove + %button.btn.btn-danger{ type: 'button', data: { id: rule.id } } Remove .form-group %form .input-group - %input.form-control#new-rule-text{placeholder: 'Add a new muted word...'} + %input.form-control#new-rule-text{ placeholder: 'Add a new muted word...' } .input-group-append - %button.btn.btn-primary#new-rule-submit{type: 'submit'} Add + %button.btn.btn-primary#new-rule-submit{ type: 'submit' } Add %template#rule-template .form-group .input-group - %input.form-control{disabled: true} + %input.form-control{ disabled: true } .input-group-append - %button.btn.btn-danger{type: 'button'} Remove \ No newline at end of file + %button.btn.btn-danger{ type: 'button' } Remove From c3fcd4eb07c63284563c24851da6893be54b1d5b Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Sat, 25 Dec 2021 23:58:04 +0100 Subject: [PATCH 10/11] Update `schema.rb` (post-rebase) --- db/schema.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 7fb74408..aea4b2f5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -313,6 +313,6 @@ ActiveRecord::Schema.define(version: 2021_12_28_135426) do t.index ["user_id"], name: "index_users_roles_on_user_id" end - add_foreign_key "profiles", "users" add_foreign_key "mute_rules", "users" + add_foreign_key "profiles", "users" end From 3acdfafcae989cc2e8ffcc216593772d24dd6b48 Mon Sep 17 00:00:00 2001 From: Karina Kwiatek Date: Sun, 2 Jan 2022 15:30:04 +0100 Subject: [PATCH 11/11] Use timestamp IDs for mute rules --- db/migrate/20211222165159_create_mute_rules.rb | 2 ++ db/schema.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/db/migrate/20211222165159_create_mute_rules.rb b/db/migrate/20211222165159_create_mute_rules.rb index 417aeec8..0e548bc5 100644 --- a/db/migrate/20211222165159_create_mute_rules.rb +++ b/db/migrate/20211222165159_create_mute_rules.rb @@ -6,5 +6,7 @@ class CreateMuteRules < ActiveRecord::Migration[5.2] t.timestamps end + + change_column(:mute_rules, :id, :bigint, default: -> { "gen_timestamp_id('mute_rules'::text)" }) end end diff --git a/db/schema.rb b/db/schema.rb index aea4b2f5..a1294985 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -107,7 +107,7 @@ ActiveRecord::Schema.define(version: 2021_12_28_135426) do t.index ["user_id"], name: "index_moderation_votes_on_user_id" end - create_table "mute_rules", force: :cascade do |t| + create_table "mute_rules", id: :bigint, default: -> { "gen_timestamp_id('mute_rules'::text)" }, force: :cascade do |t| t.bigint "user_id" t.string "muted_phrase" t.datetime "created_at", null: false