From f680bd95bcb2b1f56eb6195da4ee581af7c1b9ce Mon Sep 17 00:00:00 2001 From: Pablo Brasero Date: Mon, 20 Apr 2026 15:26:48 +0100 Subject: [PATCH] Implement web notifications for GPX imports completion --- app/models/user_notifications.rb | 58 +++++++++++++++++++ app/views/notifications/_gpx_details.html.erb | 24 ++++++++ .../_gpx_import_failure.html.erb | 23 ++++++++ .../_gpx_import_success.html.erb | 29 ++++++++++ config/locales/en.yml | 12 ++++ .../gpx_import_failure_view_test.rb | 31 ++++++++++ .../gpx_import_success_view_test.rb | 33 +++++++++++ 7 files changed, 210 insertions(+) create mode 100644 app/views/notifications/_gpx_details.html.erb create mode 100644 app/views/notifications/_gpx_import_failure.html.erb create mode 100644 app/views/notifications/_gpx_import_success.html.erb create mode 100644 test/controllers/notifications/gpx_import_failure_view_test.rb create mode 100644 test/controllers/notifications/gpx_import_success_view_test.rb diff --git a/app/models/user_notifications.rb b/app/models/user_notifications.rb index 719501044..fac6656eb 100644 --- a/app/models/user_notifications.rb +++ b/app/models/user_notifications.rb @@ -72,6 +72,62 @@ class UserNotifications end end + class GpxImportFailureNotification < Notification + def timestamp + @notification.created_at + end + + def trace_filename + @notification.params[:trace_name] + end + + def trace_description + @notification.params[:trace_description] + end + + def trace_tags + @notification.params[:trace_tags] + end + + def trace_possible_points + nil + end + + def trace_points + nil + end + + def error + @notification.params[:error] + end + end + + class GpxImportSuccessNotification < Notification + delegate :timestamp, :to => :record + + def trace_filename + record.name + end + + def trace_description + record.description + end + + def trace_tags + record.tags.map(&:tag) + end + + def trace_possible_points + @notification.params[:possible_points] + end + + def trace_points + record.size + end + + delegate :user, :to => :record + end + class NewFollowerNotification < Notification delegate :follower, :to => :record end @@ -103,6 +159,8 @@ class UserNotifications LISTABLE_NOTIFICATIONS = %w[ ChangesetCommentNotifier::Notification DiaryCommentNotifier::Notification + GpxImportFailureNotifier::Notification + GpxImportSuccessNotifier::Notification NewFollowerNotifier::Notification NoteCommentNotifier::Notification ].freeze diff --git a/app/views/notifications/_gpx_details.html.erb b/app/views/notifications/_gpx_details.html.erb new file mode 100644 index 000000000..a4da7eda0 --- /dev/null +++ b/app/views/notifications/_gpx_details.html.erb @@ -0,0 +1,24 @@ +<%# locals: (notification:) %> + +
+
<%= t(".filename") %>
+
<%= notification.trace_filename %>
+ +
<%= t(".description") %>
+
<%= notification.trace_description %>
+ + <% if notification.trace_tags.length.positive? %> +
<%= t(".tags") %>
+
<%= notification.trace_tags.join(", ") %>
+ <% end %> + + <% if notification.trace_possible_points %> +
<%= t(".total_points") %>
+
<%= notification.trace_possible_points %>
+ <% end %> + + <% if notification.trace_points %> +
<%= t(".imported_points") %>
+
<%= notification.trace_points %>
+ <% end %> +
diff --git a/app/views/notifications/_gpx_import_failure.html.erb b/app/views/notifications/_gpx_import_failure.html.erb new file mode 100644 index 000000000..0cd3a94ab --- /dev/null +++ b/app/views/notifications/_gpx_import_failure.html.erb @@ -0,0 +1,23 @@ +<%# locals: (notification:) %> + +
+
+

+ <%= t(".headline") %> +

+

<%= friendly_date_ago(notification.timestamp) %>

+
+ +
+
+ +
+
+ <%= render "notifications/gpx_details", :notification => notification %> +
+
+
<%= t(".error_message") %>
+
<%= notification.error %>
+
+
+
diff --git a/app/views/notifications/_gpx_import_success.html.erb b/app/views/notifications/_gpx_import_success.html.erb new file mode 100644 index 000000000..3da792dd9 --- /dev/null +++ b/app/views/notifications/_gpx_import_success.html.erb @@ -0,0 +1,29 @@ +<%# locals: (notification:) %> + +
+
+

+ <%= link_to t(".headline"), show_trace_path(notification.user, notification.record) %> +

+

<%= friendly_date_ago(notification.timestamp) %>

+
+ +
+
+ <% if Settings.status != "gpx_offline" %> + <% if notification.record.inserted %> + <%= link_to trace_icon(notification.record), + show_trace_path(notification.record.user, notification.record), + :class => "d-inline-block" %> + <% else %> + <%= t ".pending" %> + <% end %> + <% end %> +
+
+ <%= render "notifications/gpx_details", :notification => notification %> +
+
+

+

+
diff --git a/config/locales/en.yml b/config/locales/en.yml index 0398b8cb5..ba0bf2c80 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -615,6 +615,18 @@ en: headline: Changeset comment description_with_summary_html: "User %{commenter_name_with_link} left a comment on changeset %{changeset_id_with_link} (\"%{changeset_summary}\")" description_without_summary_html: "User %{commenter_name_with_link} left a comment on changeset %{changeset_id_with_link}" + gpx_details: + filename: Filename + description: Description + tags: Tags + total_points: Total number of points + imported_points: Number of imported points + gpx_import_failure: + headline: GPS trace could not be imported + error_message: Error message + gpx_import_success: + headline: GPS trace imported successfully + description_html: "User %{commenter_name_with_link} left a comment on changeset %{changeset_id_with_link} (\"%{changeset_text}\")" new_follower: headline: New follower description_html: "User %{follower_name_with_link} started following you. You can %{link} if you wish." diff --git a/test/controllers/notifications/gpx_import_failure_view_test.rb b/test/controllers/notifications/gpx_import_failure_view_test.rb new file mode 100644 index 000000000..7d3d31c59 --- /dev/null +++ b/test/controllers/notifications/gpx_import_failure_view_test.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require "test_helper" + +module Notifications + class GpxImportFailureViewTest < ActionView::TestCase + def test_render + notification = build_stubbed( + :notification, + :notifier_class => GpxImportFailureNotifier, + :notifier_params => { + :trace_name => "random-file.jpg", + :trace_description => "Random file", + :trace_tags => %w[random file], + :error => "Ooops, wrong file" + } + ) + + notification_wrapper = UserNotifications::GpxImportFailureNotification.new(notification) + + render "notifications/gpx_import_failure", :notification => notification_wrapper + + assert_dom ".user-notification h2", "GPS trace could not be imported" + assert_dom ".user-notification time", "less than 1 minute ago" + assert_dom ".user-notification dd", "random-file.jpg" + assert_dom ".user-notification dd", "Random file" + assert_dom ".user-notification dd", "random, file" + assert_dom ".user-notification pre", "Ooops, wrong file" + end + end +end diff --git a/test/controllers/notifications/gpx_import_success_view_test.rb b/test/controllers/notifications/gpx_import_success_view_test.rb new file mode 100644 index 000000000..e1a6b0f37 --- /dev/null +++ b/test/controllers/notifications/gpx_import_success_view_test.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require "test_helper" + +module Notifications + class GpxImportSuccessViewTest < ActionView::TestCase + def test_render + trace = build_stubbed( + :trace, + :name => "test-trace-file.gpx", + :description => "Test trace file" + ) + notification = build_stubbed( + :notification, + :record => trace, + :notifier_class => GpxImportSuccessNotifier, + :notifier_params => { + :possible_points => 5 + } + ) + + notification_wrapper = UserNotifications::GpxImportSuccessNotification.new(notification) + + render "notifications/gpx_import_success", :notification => notification_wrapper + + assert_dom ".user-notification h2", "GPS trace imported successfully" + assert_dom ".user-notification time", "less than 1 minute ago" + assert_dom ".user-notification dd", "test-trace-file.gpx" + assert_dom ".user-notification dd", "Test trace file" + assert_dom ".user-notification dd", "5" + end + end +end -- 2.47.3