From 8087229d8760b20762f25de2fd971639d3a6d5e9 Mon Sep 17 00:00:00 2001 From: Eugene Burmakin Date: Sat, 3 May 2025 20:36:09 +0200 Subject: [PATCH] Fix pmtiles map --- .../api/v1/subscriptions_controller.rb | 4 +- app/controllers/exports_controller.rb | 2 + app/controllers/imports_controller.rb | 2 + .../controllers/direct_upload_controller.js | 56 +++++++++++++++++++ app/javascript/maps/layers.js | 18 ++++-- app/services/exception_reporter.rb | 9 +++ app/services/visits/suggest.rb | 2 + app/views/imports/_form.html.erb | 10 +++- 8 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 app/javascript/controllers/direct_upload_controller.js create mode 100644 app/services/exception_reporter.rb diff --git a/app/controllers/api/v1/subscriptions_controller.rb b/app/controllers/api/v1/subscriptions_controller.rb index 1b14fde4..8a35ee86 100644 --- a/app/controllers/api/v1/subscriptions_controller.rb +++ b/app/controllers/api/v1/subscriptions_controller.rb @@ -10,10 +10,10 @@ class Api::V1::SubscriptionsController < ApiController render json: { message: 'Subscription updated successfully' } rescue JWT::DecodeError => e - Sentry.capture_exception(e) + ExceptionReporter.call(e) render json: { message: 'Failed to verify subscription update.' }, status: :unauthorized rescue ArgumentError => e - Sentry.capture_exception(e) + ExceptionReporter.call(e) render json: { message: 'Invalid subscription data received.' }, status: :unprocessable_entity end end diff --git a/app/controllers/exports_controller.rb b/app/controllers/exports_controller.rb index d6fe19e8..efd2d502 100644 --- a/app/controllers/exports_controller.rb +++ b/app/controllers/exports_controller.rb @@ -25,6 +25,8 @@ class ExportsController < ApplicationController rescue StandardError => e export&.destroy + ExceptionReporter.call(e) + redirect_to exports_url, alert: "Export failed to initiate: #{e.message}", status: :unprocessable_entity end diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb index f93ba11a..1a663c60 100644 --- a/app/controllers/imports_controller.rb +++ b/app/controllers/imports_controller.rb @@ -48,6 +48,8 @@ class ImportsController < ApplicationController rescue StandardError => e Import.where(user: current_user, name: files.map(&:original_filename)).destroy_all + ExceptionReporter.call(e) + flash.now[:error] = e.message redirect_to new_import_path, notice: e.message, status: :unprocessable_entity diff --git a/app/javascript/controllers/direct_upload_controller.js b/app/javascript/controllers/direct_upload_controller.js new file mode 100644 index 00000000..4885f3bd --- /dev/null +++ b/app/javascript/controllers/direct_upload_controller.js @@ -0,0 +1,56 @@ +import { Controller } from "@hotwired/stimulus" +import { DirectUpload } from "@rails/activestorage" + +export default class extends Controller { + static targets = ["input", "progress", "submit"] + static values = { + url: String + } + + connect() { + this.inputTarget.addEventListener("change", this.upload.bind(this)) + } + + upload() { + const files = this.inputTarget.files + if (files.length === 0) return + + // Disable submit button during upload + this.submitTarget.disabled = true + + // Create progress bar if it doesn't exist + if (!this.hasProgressTarget) { + const progressBar = document.createElement("div") + progressBar.setAttribute("data-direct-upload-target", "progress") + progressBar.className = "w-full bg-gray-200 rounded-full h-2.5 mt-2" + this.inputTarget.parentNode.appendChild(progressBar) + } + + Array.from(files).forEach(file => { + const upload = new DirectUpload(file, this.urlValue, this) + upload.create((error, blob) => { + if (error) { + console.error("Error uploading file:", error) + } else { + const hiddenField = document.createElement("input") + hiddenField.setAttribute("type", "hidden") + hiddenField.setAttribute("name", this.inputTarget.name) + hiddenField.setAttribute("value", blob.signed_id) + this.element.appendChild(hiddenField) + } + }) + }) + } + + directUploadWillStoreFileWithXHR(request) { + request.upload.addEventListener("progress", event => { + const progress = (event.loaded / event.total) * 100 + this.progressTarget.style.width = `${progress}%` + }) + } + + directUploadDidProgress(event) { + // This method is called by ActiveStorage during the upload + // We're handling progress in directUploadWillStoreFileWithXHR instead + } +} diff --git a/app/javascript/maps/layers.js b/app/javascript/maps/layers.js index b8705524..6125beef 100644 --- a/app/javascript/maps/layers.js +++ b/app/javascript/maps/layers.js @@ -12,7 +12,7 @@ export function createMapLayer(map, selectedLayerName, layerKey, selfHosted) { } let layer; - console.log("isSelfhosted: ", selfHosted) + if (selfHosted === "true") { layer = L.tileLayer(config.url, { maxZoom: config.maxZoom, @@ -21,13 +21,21 @@ export function createMapLayer(map, selectedLayerName, layerKey, selfHosted) { // Add any other config properties that might be needed }); } else { - layer = protomapsL.leafletLayer( - { + // Use the global protomapsL object (loaded via script tag) + try { + if (typeof window.protomapsL === 'undefined') { + throw new Error('protomapsL is not defined'); + } + + layer = window.protomapsL.leafletLayer({ url: config.url, flavor: config.flavor, crossOrigin: true, - } - ) + }); + } catch (error) { + console.error('Error creating protomaps layer:', error); + throw new Error('Failed to create vector tile layer. protomapsL may not be available.'); + } } if (selectedLayerName === layerKey) { diff --git a/app/services/exception_reporter.rb b/app/services/exception_reporter.rb new file mode 100644 index 00000000..297f11fb --- /dev/null +++ b/app/services/exception_reporter.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class ExceptionReporter + def self.call(exception) + return unless DawarichSettings.self_hosted? + + Sentry.capture_exception(exception) + end +end diff --git a/app/services/visits/suggest.rb b/app/services/visits/suggest.rb index 5ee7881c..39f0ef11 100644 --- a/app/services/visits/suggest.rb +++ b/app/services/visits/suggest.rb @@ -27,6 +27,8 @@ class Visits::Suggest title: 'Error suggesting visits', content: "Error suggesting visits: #{e.message}\n#{e.backtrace.join("\n")}" ) + + ExceptionReporter.call(e) end private diff --git a/app/views/imports/_form.html.erb b/app/views/imports/_form.html.erb index 2e77a631..68e6e2de 100644 --- a/app/views/imports/_form.html.erb +++ b/app/views/imports/_form.html.erb @@ -1,4 +1,4 @@ -<%= form_with model: import, class: "contents" do |form| %> +<%= form_with model: import, class: "contents", data: { controller: "direct-upload", direct_upload_url_value: rails_direct_uploads_url } do |form| %>
- <%= form.submit class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer" %> + <%= form.submit class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer", + data: { direct_upload_target: "submit" } %>
<% end %>