From 89cf828cfad0e27c819ac7fd696af5ba3584d013 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Sun, 26 Jan 2025 20:34:02 +0100 Subject: [PATCH] Make entry show an icon and add icon link to original page --- Gemfile | 1 + Gemfile.lock | 4 +++ .../icons/arrow-top-right-on-square.svg | 3 +++ app/assets/images/icons/eye.svg | 4 +++ app/assets/styles/base/index.css | 9 +++++++ app/views/entries/index.html.erb | 9 +++++-- app/views/subscriptions/show.html.erb | 9 +++++-- config/initializers/inline_svg.rb | 8 ++++++ gemset.nix | 11 ++++++++ lib/inline_svg/vite_file_loader.rb | 26 +++++++++++++++++++ 10 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 app/assets/images/icons/arrow-top-right-on-square.svg create mode 100644 app/assets/images/icons/eye.svg create mode 100644 config/initializers/inline_svg.rb create mode 100644 lib/inline_svg/vite_file_loader.rb diff --git a/Gemfile b/Gemfile index 63b11ce0..a418d92a 100644 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,7 @@ gem 'bootsnap', require: false # Reduces boot times through caching; required in gem 'feedjira' # Parse RSS feeds gem 'good_job' # Multithreaded, Postgres-based, ActiveJob backend for Ruby on Rails gem 'image_processing' # Use Active Storage variants +gem 'inline_svg' # Render inline SVGs gem 'pagy' # Use pagy for pagination gem 'pg' # Use postgresql as the database for Active Record gem 'puma' # Use the Puma web server [https://github.com/puma/puma] diff --git a/Gemfile.lock b/Gemfile.lock index d4b40e0f..f10bd94b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -154,6 +154,9 @@ GEM image_processing (1.13.0) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) + inline_svg (1.10.0) + activesupport (>= 3.0) + nokogiri (>= 1.6) io-console (0.8.0) irb (1.15.1) pp (>= 0.6.0) @@ -384,6 +387,7 @@ DEPENDENCIES feedjira good_job image_processing + inline_svg pagy pg pgreset diff --git a/app/assets/images/icons/arrow-top-right-on-square.svg b/app/assets/images/icons/arrow-top-right-on-square.svg new file mode 100644 index 00000000..4f1e3aef --- /dev/null +++ b/app/assets/images/icons/arrow-top-right-on-square.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/assets/images/icons/eye.svg b/app/assets/images/icons/eye.svg new file mode 100644 index 00000000..9d0d2a79 --- /dev/null +++ b/app/assets/images/icons/eye.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/assets/styles/base/index.css b/app/assets/styles/base/index.css index cb5686d4..bad18ed2 100644 --- a/app/assets/styles/base/index.css +++ b/app/assets/styles/base/index.css @@ -6,3 +6,12 @@ html { font-size: var(--text-base); font-family: var(--font-body); } + +.table__cell--actions { + white-space: nowrap; +} + +.icon { + width: 2rem; + height: 2rem; +} diff --git a/app/views/entries/index.html.erb b/app/views/entries/index.html.erb index 481f2181..18eb9cbe 100644 --- a/app/views/entries/index.html.erb +++ b/app/views/entries/index.html.erb @@ -28,8 +28,13 @@ <%= content_tag :td, entry.author, class: 'table__cell' %> <%= content_tag :td, entry.published_at.present? ? l(entry.published_at) : t('.published_at_unknown'), class: 'table__cell' %> <%= content_tag :td, entry.read?, class: 'table__cell' %> - <%= content_tag :td, class: 'table__cell' do %> - <%= link_to t('.show'), entry, class: 'table__link' %> + <%= content_tag :td, class: 'table__cell table__cell--actions' do %> + <%= link_to entry, class: 'table__link', aria: { label: t('.show') } do %> + <%= inline_svg_tag 'images/icons/eye.svg', class: 'icon' %> + <% end %> + <%= link_to entry.url, class: 'table__link', aria: { label: t('.go_to_original') } do %> + <%= inline_svg_tag 'images/icons/arrow-top-right-on-square.svg', class: 'icon' %> + <% end %> <% end %> <%- end %> diff --git a/app/views/subscriptions/show.html.erb b/app/views/subscriptions/show.html.erb index 53639c96..9e3ee3e6 100644 --- a/app/views/subscriptions/show.html.erb +++ b/app/views/subscriptions/show.html.erb @@ -21,8 +21,13 @@ <%= content_tag :td, entry.title, class: 'table__cell' %> <%= content_tag :td, entry.author, class: 'table__cell' %> <%= content_tag :td, entry.published_at.present? ? l(entry.published_at) : t('.published_at_unknown'), class: 'table__cell' %> - <%= content_tag :td, class: 'table__cell' do %> - <%= link_to t('.show'), entry, class: 'table__link' %> + <%= content_tag :td, class: 'table__cell table__cell--actions' do %> + <%= link_to entry, class: 'table__link', aria: { label: t('.show') } do %> + <%= inline_svg_tag 'images/icons/eye.svg', class: 'icon' %> + <% end %> + <%= link_to entry.url, class: 'table__link', aria: { label: t('.go_to_original') } do %> + <%= inline_svg_tag 'images/icons/arrow-top-right-on-square.svg', class: 'icon' %> + <% end %> <% end %> <%- end %> diff --git a/config/initializers/inline_svg.rb b/config/initializers/inline_svg.rb new file mode 100644 index 00000000..cd1044e0 --- /dev/null +++ b/config/initializers/inline_svg.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +require 'inline_svg/vite_file_loader' + +InlineSvg.configure do |config| + config.asset_file = InlineSvg::ViteFileLoader + config.raise_on_file_not_found = Rails.env.test? +end diff --git a/gemset.nix b/gemset.nix index 6da889aa..041fd38b 100644 --- a/gemset.nix +++ b/gemset.nix @@ -514,6 +514,17 @@ }; version = "1.13.0"; }; + inline_svg = { + dependencies = ["activesupport" "nokogiri"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "03x1z55sh7cpb63g46cbd6135jmp13idcgqzqsnzinbg4cs2jrav"; + type = "gem"; + }; + version = "1.10.0"; + }; io-console = { groups = ["default" "development" "production" "test"]; platforms = [{ diff --git a/lib/inline_svg/vite_file_loader.rb b/lib/inline_svg/vite_file_loader.rb new file mode 100644 index 00000000..ab62c5bd --- /dev/null +++ b/lib/inline_svg/vite_file_loader.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'open-uri' + +module InlineSvg + class ViteFileLoader + def self.named(filename) + path = ViteRuby.instance.manifest.path_for(filename) + + return fetch_from_dev_server(path) if ViteRuby.instance.dev_server_running? + + Rails.public_path.join(path[1..]).read + end + + def self.fetch_from_dev_server(path) + config = ViteRuby.config + + path = "#{config.protocol}://#{config.host_with_port}#{path}" + + # rubocop:disable Security/Open + # This is only used in dev to load an inline SVG, so security implications are very limited. + URI.open(path) + # rubocop:enable Security/Open + end + end +end