diff --git a/Gemfile b/Gemfile index c5c0dac5..5c26901c 100644 --- a/Gemfile +++ b/Gemfile @@ -77,7 +77,7 @@ gem 'redis' gem 'csv' # Admin -gem 'rails_admin', '~> 1.3' +gem 'rails_admin', '~> 2.0' # Tech debt & hacks gem 'binding_of_caller' # see has_changelog.rb @@ -137,7 +137,7 @@ group :worker do # Document understanding gem 'htmlentities' - gem 'birch', github: 'billthompson/birch', branch: 'birch-ruby22' + gem 'birch', git: 'https://github.com/billthompson/birch.git', branch: 'birch-ruby22' gem 'engtagger' gem 'ibm_watson' diff --git a/Gemfile.lock b/Gemfile.lock index 737df373..2b7853dc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,5 +1,5 @@ GIT - remote: git://github.com/billthompson/birch.git + remote: https://github.com/billthompson/birch.git revision: dc6c8e5d667f6c946c989f4d8f159f622d3bf77a branch: birch-ruby22 specs: @@ -13,7 +13,7 @@ GIT GIT remote: https://github.com/indentlabs/thredded.git - revision: a558800725d701cc341194b446744cb7292c1a65 + revision: 20c41ae6c25ffc1a0b01d3a761fc4f4746cd3f68 branch: feature/report-posts specs: thredded (0.16.12) @@ -71,6 +71,10 @@ GEM globalid (>= 0.3.6) activemodel (5.2.3) activesupport (= 5.2.3) + activemodel-serializers-xml (1.0.2) + activemodel (> 5.x) + activesupport (> 5.x) + builder (~> 3.1) activerecord (5.2.3) activemodel (= 5.2.3) activesupport (= 5.2.3) @@ -94,7 +98,7 @@ GEM ast (2.4.0) authority (3.3.0) activesupport (>= 3.0.0) - autoprefixer-rails (9.6.1) + autoprefixer-rails (9.6.1.1) execjs aws-eventstream (1.0.3) aws-partitions (1.193.0) @@ -815,7 +819,7 @@ GEM binding_of_caller (0.8.0) debug_inspector (>= 0.0.1) builder (3.2.3) - bullet (6.0.1) + bullet (6.0.2) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) bundler-audit (0.6.1) @@ -872,23 +876,23 @@ GEM railties (>= 4.2, < 7) cucumber-tag_expressions (1.1.1) cucumber-wire (0.0.1) - d3-rails (4.13.0) + d3-rails (5.9.2) railties (>= 3.1) database_cleaner (1.7.0) dateslices (0.0.4) rails (> 4) - db_text_search (0.3.0) - activerecord (>= 4.1.15, < 6.0) + db_text_search (0.3.1) + activerecord (>= 4.1.15, < 7.0) debug_inspector (0.0.3) - devise (4.6.2) + devise (4.7.0) bcrypt (~> 3.0) orm_adapter (~> 0.1) - railties (>= 4.1.0, < 6.0) + railties (>= 4.1.0) responders warden (~> 1.2.3) diff-lcs (1.3) docile (1.1.5) - domain_name (0.5.20180417) + domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) engtagger (0.2.1) erubi (1.8.0) @@ -901,7 +905,7 @@ GEM railties (>= 4.2.0) faraday (0.15.4) multipart-post (>= 1.2, < 3) - faye-websocket (0.10.7) + faye-websocket (0.10.9) eventmachine (>= 0.12.0) websocket-driver (>= 0.5.1) ffi (1.11.1) @@ -931,7 +935,7 @@ GEM guard-rubocop (1.3.0) guard (~> 2.0) rubocop (~> 0.20) - haml (5.0.4) + haml (5.1.2) temple (>= 0.8.0) tilt hashdiff (1.0.0) @@ -950,27 +954,30 @@ GEM http_parser.rb (0.6.0) i18n (1.6.0) concurrent-ruby (~> 1.0) - ibm_cloud_sdk_core (0.1.2) + ibm_cloud_sdk_core (0.3.3) concurrent-ruby (~> 1.0) http (~> 4.1.0) - ibm_watson (0.16.1) + jwt (~> 2.2.1) + ibm_watson (0.20.1) concurrent-ruby (~> 1.0) eventmachine (~> 1.2) faye-websocket (~> 0.10) http (~> 4.1.0) - ibm_cloud_sdk_core (~> 0.1.1) + ibm_cloud_sdk_core (~> 0.3.3) + jwt (~> 2.2.1) inline_svg (1.5.2) activesupport (>= 3.0) nokogiri (>= 1.6) jaro_winkler (1.5.3) jmespath (1.4.0) - jquery-rails (4.3.3) + jquery-rails (4.3.5) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) jquery-ui-rails (6.0.1) railties (>= 3.2.16) json (2.2.0) + jwt (2.2.1) kaminari (1.1.1) activesupport (>= 4.1.0) kaminari-actionview (= 1.1.1) @@ -1027,7 +1034,7 @@ GEM net-http-persistent (3.1.0) connection_pool (~> 2.2) newrelic_rpm (6.5.0.357) - nio4r (2.4.0) + nio4r (2.5.1) nokogiri (1.10.4) mini_portile2 (~> 2.4.0) nokogumbo (2.0.1) @@ -1035,7 +1042,7 @@ GEM notiffany (0.1.1) nenv (~> 0.1) shellany (~> 0.0) - onebox (1.9.9) + onebox (1.9.12) htmlentities (~> 4.3) moneta (~> 1.0) multi_json (~> 1.11) @@ -1062,12 +1069,12 @@ GEM puma (3.12.1) puma-heroku (1.0.0) puma (~> 3.0) - pundit (2.0.1) + pundit (2.1.0) activesupport (>= 3.0.0) rack (2.0.7) rack-mini-profiler (1.0.2) rack (>= 1.2.0) - rack-pjax (1.0.0) + rack-pjax (1.1.0) nokogiri (~> 1.5) rack (>= 1.1) rack-protection (2.0.5) @@ -1104,19 +1111,18 @@ GEM rails_12factor (0.0.3) rails_serve_static_assets rails_stdout_logging - rails_admin (1.4.2) + rails_admin (2.0.0) + activemodel-serializers-xml (>= 1.0) builder (~> 3.1) - coffee-rails (~> 4.0) - font-awesome-rails (>= 3.0, < 5) haml (>= 4.0, < 6) jquery-rails (>= 3.0, < 5) jquery-ui-rails (>= 5.0, < 7) kaminari (>= 0.14, < 2.0) nested_form (~> 0.3) rack-pjax (>= 0.7) - rails (>= 4.0, < 6) + rails (>= 5.0, < 7) remotipart (~> 1.3) - sass-rails (>= 4.0, < 6) + sassc-rails (>= 1.3, < 3) rails_serve_static_assets (0.0.5) rails_stdout_logging (0.0.5) railties (5.2.3) @@ -1134,10 +1140,10 @@ GEM redcarpet (3.5.0) redis (4.1.2) regexp_parser (1.6.0) - remotipart (1.4.2) - responders (2.4.1) - actionpack (>= 4.2.0, < 6.0) - railties (>= 4.2.0, < 6.0) + remotipart (1.4.3) + responders (3.0.0) + actionpack (>= 5.0) + railties (>= 5.0) rinku (2.0.6) rmagick (4.0.0) rspec (3.8.0) @@ -1180,20 +1186,19 @@ GEM crass (~> 1.0.2) nokogiri (>= 1.8.0) nokogumbo (~> 2.0) - sass (3.7.3) + sass (3.7.4) sass-listen (~> 4.0.0) sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - sass-rails (5.0.7) - railties (>= 4.0.0, < 6) + sass-rails (5.1.0) + railties (>= 5.2.0) sass (~> 3.1) sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) - sassc (2.0.1) + sassc (2.2.0) ffi (~> 1.9) - rake sassc-rails (2.1.2) railties (>= 4.0.0) sassc (>= 2.0) @@ -1237,7 +1242,7 @@ GEM stripe_event (2.2.0) activesupport (>= 3.1) stripe (>= 2.8, < 5.0) - temple (0.8.0) + temple (0.8.1) terrapin (0.6.0) climate_control (>= 0.0.3, < 1.0) thor (0.20.3) @@ -1329,7 +1334,7 @@ DEPENDENCIES rails-perftest rails-ujs rails_12factor - rails_admin (~> 1.3) + rails_admin (~> 2.0) redcarpet redis rmagick diff --git a/app/assets/javascripts/document_editor.coffee b/app/assets/javascripts/document_editor.coffee index be80cc00..2c9ac9f0 100644 --- a/app/assets/javascripts/document_editor.coffee +++ b/app/assets/javascripts/document_editor.coffee @@ -43,6 +43,7 @@ class Notebook.DocumentEditor 'justifyRight' 'justifyFull' 'orderedlist' + 'unorderedlist' 'quote' 'anchor' 'removeFormat' diff --git a/app/assets/javascripts/keyboardControlDefault.js b/app/assets/javascripts/keyboardControlDefault.js index e61addd3..2999495f 100644 --- a/app/assets/javascripts/keyboardControlDefault.js +++ b/app/assets/javascripts/keyboardControlDefault.js @@ -4,67 +4,73 @@ * If you'd like to add any new keyboard controls, this is the place to do it.' */ -var KEYCODES = { - "?" : 191, - "n" : 78, - "c" : 67, - "u" : 85, - "i" : 73, - "l" : 76 -}; +function keycode_for(letter) { + // Pretty sure this only works for alphanumeric (e.g. ? is incorrect) + // Since ? is the only symbol we're using now lets uh not talk about this + if (letter == '?') { + return 191; + } + + return letter.toUpperCase().charCodeAt(0); +} + +function add_redirect_shortcut(key_after_N, page_type) { + active_redirect_shortcuts.push({ + page: page_type, + key: key_after_N + }); + + default_keyboard_controls.push( + { + "input" : [ + { key : keycode_for("n"), shiftKey : true, ctrlKey : false }, + { key : keycode_for(key_after_N), shiftKey : false, ctrlKey : false } + ], + "result" : function () { + document.location.pathname = '/plan/' + page_type + '/new'; + } + } + ); +} var default_keyboard_controls = [ // ? => keyboard control { "input" : [ - { key : KEYCODES["?"], shiftKey : true, ctrlKey : false } + { key : keycode_for('?'), shiftKey : true, ctrlKey : false } ], "result" : function () { $("#keyboard-controls-help-modal").modal('open'); } - }, - - // N+c => new character form - { - "input" : [ - { key : KEYCODES["n"], shiftKey : true, ctrlKey : false }, - { key : KEYCODES["c"], shiftKey : false, ctrlKey : false } - ], - "result" : function () { - document.location.pathname = "/plan/characters/new"; - } - }, - - // N+u => new universe form - { - "input" : [ - { key : KEYCODES["n"], shiftKey : true, ctrlKey : false }, - { key : KEYCODES["u"], shiftKey : false, ctrlKey : false } - ], - "result" : function () { - document.location.pathname = "/plan/universes/new"; - } - }, - - // N+l => new location form - { - "input" : [ - { key : KEYCODES["n"], shiftKey : true, ctrlKey : false }, - { key : KEYCODES["l"], shiftKey : false, ctrlKey : false } - ], - "result" : function () { - document.location.pathname = "/plan/locations/new"; - } - }, - - // N+i => new item form - { - "input" : [ - { key : KEYCODES["n"], shiftKey : true, ctrlKey : false }, - { key : KEYCODES["i"], shiftKey : false, ctrlKey : false } - ], - "result" : function () { - document.location.pathname = "/plan/items/new"; - } } ]; + +var active_redirect_shortcuts = []; +add_redirect_shortcut("b", "buildings"); +add_redirect_shortcut("c", "characters"); +add_redirect_shortcut("n", "conditions"); +add_redirect_shortcut("u", "countries"); +add_redirect_shortcut("r", "creatures"); +add_redirect_shortcut("d", "deities"); +add_redirect_shortcut("y", "floras"); +add_redirect_shortcut("f", "foods"); +add_redirect_shortcut("g", "governments"); +add_redirect_shortcut("o", "groups"); +add_redirect_shortcut("i", "items"); +add_redirect_shortcut("j", "jobs"); +add_redirect_shortcut("l", "landmarks"); +add_redirect_shortcut("a", "languages"); +add_redirect_shortcut("t", "locations"); +add_redirect_shortcut("m", "magics"); +add_redirect_shortcut("p", "planets"); +add_redirect_shortcut("r", "races"); +add_redirect_shortcut("x", "religions"); +add_redirect_shortcut("s", "scenes"); +add_redirect_shortcut("h", "schools"); +add_redirect_shortcut("z", "sports"); +add_redirect_shortcut("h", "technologies"); +add_redirect_shortcut("w", "towns"); +add_redirect_shortcut("m", "traditions"); +add_redirect_shortcut("u", "universes"); +add_redirect_shortcut("v", "vehicles"); + diff --git a/app/assets/javascripts/keyboardControls.js b/app/assets/javascripts/keyboardControls.js index 070186f4..6269d740 100644 --- a/app/assets/javascripts/keyboardControls.js +++ b/app/assets/javascripts/keyboardControls.js @@ -108,7 +108,12 @@ function KeyboardControlStackManager( entryTime, stackEvaluationFunction ) { } } $(document).ready( function () { - if( document.querySelector("body[data-in-app]") ){ - keyboardControlManager(default_keyboard_controls); + if (document.querySelector("body[data-in-app]")) { + if ((typeof DISABLE_KEYBOARD_SHORTCUTS === 'undefined' || !DISABLE_KEYBOARD_SHORTCUTS)) { + keyboardControlManager(default_keyboard_controls); + console.log('Keyboard shortcuts are enabled on this page'); + } else { + console.log('Keyboard shortcuts are disabled on this page.'); + } } }); diff --git a/app/assets/stylesheets/editor.css.scss b/app/assets/stylesheets/editor.css.scss index a2ea04fd..fbcf70a4 100644 --- a/app/assets/stylesheets/editor.css.scss +++ b/app/assets/stylesheets/editor.css.scss @@ -42,6 +42,15 @@ h4 { font-size: 1.25em; } + + ul { + list-style-type: disc; + padding-left: 40px; + + li { + list-style-type: disc; + } + } } .mobile-navbar-spacer { diff --git a/app/controllers/content_controller.rb b/app/controllers/content_controller.rb index 797aa811..3f5ba701 100644 --- a/app/controllers/content_controller.rb +++ b/app/controllers/content_controller.rb @@ -63,6 +63,9 @@ class ContentController < ApplicationController @content = content_type.find_by(id: params[:id]) return redirect_to(root_path, notice: "You don't have permission to view that content.") if @content.nil? + return redirect_to(root_path) if @content.user.nil? # deleted user's content + return if ENV.key?('CONTENT_BLACKLIST') && ENV['CONTENT_BLACKLIST'].split(',').include?(@content.user.try(:email)) + @serialized_content = ContentSerializer.new(@content) if user_signed_in? @@ -77,9 +80,6 @@ class ContentController < ApplicationController } end - return redirect_to(root_path) if @content.user.nil? # deleted user's content - return if ENV.key?('CONTENT_BLACKLIST') && ENV['CONTENT_BLACKLIST'].split(',').include?(@content.user.try(:email)) - if (current_user || User.new).can_read?(@content) if current_user if @content.updated_at > 30.minutes.ago diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 0526038e..321ec3a0 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -24,7 +24,8 @@ class RegistrationsController < Devise::RegistrationsController def account_update_params params.require(:user).permit( :name, :email, :username, :password, :password_confirmation, :email_updates, :fluid_preference, - :bio, :favorite_genre, :favorite_author, :interests, :age, :location, :gender, :forums_badge_text + :bio, :favorite_genre, :favorite_author, :interests, :age, :location, :gender, :forums_badge_text, + :keyboard_shortcuts_preference ) end diff --git a/app/views/content/_keyboard_controls_help_modal.html.erb b/app/views/content/_keyboard_controls_help_modal.html.erb index aee3434b..c5e1d880 100644 --- a/app/views/content/_keyboard_controls_help_modal.html.erb +++ b/app/views/content/_keyboard_controls_help_modal.html.erb @@ -2,25 +2,16 @@ @@ -28,3 +19,17 @@ close + + \ No newline at end of file diff --git a/app/views/content/edit.html.erb b/app/views/content/edit.html.erb index f7ec8e31..9ed22b64 100644 --- a/app/views/content/edit.html.erb +++ b/app/views/content/edit.html.erb @@ -56,6 +56,10 @@ }); + + <% if @content.persisted? %> <%= render partial: 'content/share', locals: { shared_content: @content} %> <% end %> diff --git a/app/views/content/new.html.erb b/app/views/content/new.html.erb index cc2c2ba7..6a0266ee 100644 --- a/app/views/content/new.html.erb +++ b/app/views/content/new.html.erb @@ -16,6 +16,10 @@ <% end %> + + <% if @content.persisted? %> <%= render partial: 'content/share', locals: { shared_content: @content} %> <% end %> diff --git a/app/views/devise/registrations/panes/_preferences.html.erb b/app/views/devise/registrations/panes/_preferences.html.erb index 7b60ba41..6714c807 100644 --- a/app/views/devise/registrations/panes/_preferences.html.erb +++ b/app/views/devise/registrations/panes/_preferences.html.erb @@ -10,6 +10,20 @@ +
+
+

Accessibility settings

+
+ <%= f.label :keyboard_shortcuts_preference do %> + <%= f.check_box :keyboard_shortcuts_preference %> + + Enable keyboard shortcuts that let me navigate around the site without using a mouse. Press ? to view what's available. + + <% end %> +
+
+
+

Email preferences

diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index e3ee0159..bee63ec5 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -23,13 +23,18 @@ <%= render 'layouts/footer' unless defined?(@show_footer) && !@show_footer %> - <%= render partial: 'content/keyboard_controls_help_modal' %> + + <%= render partial: 'content/keyboard_controls_help_modal' %> <%= render 'layouts/ganalytics' %> diff --git a/app/views/layouts/editor.html.erb b/app/views/layouts/editor.html.erb index e016d88a..1f085a03 100644 --- a/app/views/layouts/editor.html.erb +++ b/app/views/layouts/editor.html.erb @@ -26,6 +26,8 @@ <%= render 'cards/ui/notice' %> diff --git a/db/migrate/20190829222650_add_shortcuts_preference_to_users.rb b/db/migrate/20190829222650_add_shortcuts_preference_to_users.rb new file mode 100644 index 00000000..c2f99f0f --- /dev/null +++ b/db/migrate/20190829222650_add_shortcuts_preference_to_users.rb @@ -0,0 +1,5 @@ +class AddShortcutsPreferenceToUsers < ActiveRecord::Migration[5.2] + def change + add_column :users, :keyboard_shortcuts_preference, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index ff12c95e..c8dfb76a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2019_08_24_040322) do +ActiveRecord::Schema.define(version: 2019_08_29_222650) do create_table "api_keys", force: :cascade do |t| t.integer "user_id" @@ -1551,6 +1551,17 @@ ActiveRecord::Schema.define(version: 2019_08_24_040322) do t.datetime "updated_at", null: false end + create_table "page_settings_overrides", force: :cascade do |t| + t.string "page_type" + t.string "name_override" + t.string "icon_override" + t.string "hex_color_override" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["user_id"], name: "index_page_settings_overrides_on_user_id" + end + create_table "page_tags", force: :cascade do |t| t.string "page_type" t.integer "page_id" @@ -2554,6 +2565,7 @@ ActiveRecord::Schema.define(version: 2019_08_24_040322) do t.string "gender" t.string "interests" t.string "forums_badge_text" + t.boolean "keyboard_shortcuts_preference" t.index ["deleted_at", "username"], name: "index_users_on_deleted_at_and_username" t.index ["deleted_at"], name: "index_users_on_deleted_at" t.index ["email"], name: "index_users_on_email", unique: true