mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-11 09:41:40 -05:00
Merge pull request #1197 from Freika/feature/mi-km-settings
Feature/mi km settings
This commit is contained in:
commit
7c8754de26
40 changed files with 238 additions and 150 deletions
|
|
@ -28,7 +28,6 @@ services:
|
||||||
APPLICATION_HOSTS: localhost
|
APPLICATION_HOSTS: localhost
|
||||||
TIME_ZONE: Europe/London
|
TIME_ZONE: Europe/London
|
||||||
APPLICATION_PROTOCOL: http
|
APPLICATION_PROTOCOL: http
|
||||||
DISTANCE_UNIT: km
|
|
||||||
PROMETHEUS_EXPORTER_ENABLED: false
|
PROMETHEUS_EXPORTER_ENABLED: false
|
||||||
PROMETHEUS_EXPORTER_HOST: 0.0.0.0
|
PROMETHEUS_EXPORTER_HOST: 0.0.0.0
|
||||||
PROMETHEUS_EXPORTER_PORT: 9394
|
PROMETHEUS_EXPORTER_PORT: 9394
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,3 @@ DATABASE_PASSWORD=password
|
||||||
DATABASE_NAME=dawarich_development
|
DATABASE_NAME=dawarich_development
|
||||||
DATABASE_PORT=5432
|
DATABASE_PORT=5432
|
||||||
REDIS_URL=redis://localhost:6379/1
|
REDIS_URL=redis://localhost:6379/1
|
||||||
DISTANCE_UNIT='km'
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ If you're running your own Photon instance, you can safely set `STORE_GEODATA` t
|
||||||
- Reverse geocoding is now working as on-demand job instead of storing the result in the database.
|
- Reverse geocoding is now working as on-demand job instead of storing the result in the database.
|
||||||
- Stats cards now show the last update time. #733
|
- Stats cards now show the last update time. #733
|
||||||
- Visit card now shows buttons to confirm or decline a visit only if it's not confirmed or declined yet.
|
- Visit card now shows buttons to confirm or decline a visit only if it's not confirmed or declined yet.
|
||||||
|
- Distance unit is now being stored in the user settings. You can choose between kilometers and miles, default is kilometers. The setting is accessible in the user settings -> Maps -> Distance Unit. You might want to recalculate your stats after changing the unit.
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
|
|
@ -50,6 +51,10 @@ If you're running your own Photon instance, you can safely set `STORE_GEODATA` t
|
||||||
- PostGIS extension is now being enabled only if it's not already enabled. #1186
|
- PostGIS extension is now being enabled only if it's not already enabled. #1186
|
||||||
- Fixed a bug where visits were returning into Suggested state after being confirmed or declined. #848
|
- Fixed a bug where visits were returning into Suggested state after being confirmed or declined. #848
|
||||||
|
|
||||||
|
## Removed
|
||||||
|
|
||||||
|
- Removed `DISTANCE_UNIT` constant. It can be safely removed from your environment variables in docker-compose.yml.
|
||||||
|
|
||||||
|
|
||||||
# 0.26.0 - 2025-05-08
|
# 0.26.0 - 2025-05-08
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -36,7 +36,9 @@ class MapController < ApplicationController
|
||||||
@distance ||= 0
|
@distance ||= 0
|
||||||
|
|
||||||
@coordinates.each_cons(2) do
|
@coordinates.each_cons(2) do
|
||||||
@distance += Geocoder::Calculations.distance_between([_1[0], _1[1]], [_2[0], _2[1]], units: DISTANCE_UNIT)
|
@distance += Geocoder::Calculations.distance_between(
|
||||||
|
[_1[0], _1[1]], [_2[0], _2[1]], units: current_user.safe_settings.distance_unit.to_sym
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@distance.round(1)
|
@distance.round(1)
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,6 @@ class Settings::MapsController < ApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def settings_params
|
def settings_params
|
||||||
params.require(:maps).permit(:name, :url)
|
params.require(:maps).permit(:name, :url, :distance_unit)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def year_distance_stat(year, user)
|
def year_distance_stat(year, user)
|
||||||
# In km or miles, depending on the application settings (DISTANCE_UNIT)
|
# In km or miles, depending on the user.safe_settings.distance_unit
|
||||||
Stat.year_distance(year, user).sum { _1[1] }
|
Stat.year_distance(year, user).sum { _1[1] }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ module ApplicationHelper
|
||||||
def sidebar_distance(distance)
|
def sidebar_distance(distance)
|
||||||
return unless distance
|
return unless distance
|
||||||
|
|
||||||
"#{distance} #{DISTANCE_UNIT}"
|
"#{distance} #{current_user.safe_settings.distance_unit}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def sidebar_points(points)
|
def sidebar_points(points)
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ export default class extends BaseController {
|
||||||
this.clearFogRadius = parseInt(this.userSettings.fog_of_war_meters) || 50;
|
this.clearFogRadius = parseInt(this.userSettings.fog_of_war_meters) || 50;
|
||||||
this.fogLinethreshold = parseInt(this.userSettings.fog_of_war_threshold) || 90;
|
this.fogLinethreshold = parseInt(this.userSettings.fog_of_war_threshold) || 90;
|
||||||
this.routeOpacity = parseFloat(this.userSettings.route_opacity) || 0.6;
|
this.routeOpacity = parseFloat(this.userSettings.route_opacity) || 0.6;
|
||||||
this.distanceUnit = this.element.dataset.distance_unit || "km";
|
this.distanceUnit = this.userSettings.maps.distance_unit || "km";
|
||||||
this.pointsRenderingMode = this.userSettings.points_rendering_mode || "raw";
|
this.pointsRenderingMode = this.userSettings.points_rendering_mode || "raw";
|
||||||
this.liveMapEnabled = this.userSettings.live_map_enabled || false;
|
this.liveMapEnabled = this.userSettings.live_map_enabled || false;
|
||||||
this.countryCodesMap = countryCodesMap();
|
this.countryCodesMap = countryCodesMap();
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export default class extends BaseController {
|
||||||
this.apiKey = this.containerTarget.dataset.api_key
|
this.apiKey = this.containerTarget.dataset.api_key
|
||||||
this.userSettings = JSON.parse(this.containerTarget.dataset.user_settings || '{}')
|
this.userSettings = JSON.parse(this.containerTarget.dataset.user_settings || '{}')
|
||||||
this.timezone = this.containerTarget.dataset.timezone
|
this.timezone = this.containerTarget.dataset.timezone
|
||||||
this.distanceUnit = this.containerTarget.dataset.distance_unit
|
this.distanceUnit = this.userSettings.maps.distance_unit || "km"
|
||||||
|
|
||||||
// Initialize map and layers
|
// Initialize map and layers
|
||||||
this.initializeMap()
|
this.initializeMap()
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,6 @@
|
||||||
module Distanceable
|
module Distanceable
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
DISTANCE_UNITS = {
|
|
||||||
km: 1000, # to meters
|
|
||||||
mi: 1609.34, # to meters
|
|
||||||
m: 1, # already in meters
|
|
||||||
ft: 0.3048, # to meters
|
|
||||||
yd: 0.9144 # to meters
|
|
||||||
}.freeze
|
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
def total_distance(points = nil, unit = :km)
|
def total_distance(points = nil, unit = :km)
|
||||||
# Handle method being called directly on relation vs with array
|
# Handle method being called directly on relation vs with array
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,6 @@
|
||||||
module Nearable
|
module Nearable
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
DISTANCE_UNITS = {
|
|
||||||
km: 1000, # to meters
|
|
||||||
mi: 1609.34, # to meters
|
|
||||||
m: 1, # already in meters
|
|
||||||
ft: 0.3048, # to meters
|
|
||||||
yd: 0.9144 # to meters
|
|
||||||
}.freeze
|
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
||||||
# It accepts an array of coordinates [latitude, longitude]
|
# It accepts an array of coordinates [latitude, longitude]
|
||||||
# and an optional radius and distance unit
|
# and an optional radius and distance unit
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ class Stat < ApplicationRecord
|
||||||
def calculate_daily_distances(monthly_points)
|
def calculate_daily_distances(monthly_points)
|
||||||
timespan.to_a.map.with_index(1) do |day, index|
|
timespan.to_a.map.with_index(1) do |day, index|
|
||||||
daily_points = filter_points_for_day(monthly_points, day)
|
daily_points = filter_points_for_day(monthly_points, day)
|
||||||
distance = Point.total_distance(daily_points, DISTANCE_UNIT)
|
distance = Point.total_distance(daily_points, user.safe_settings.distance_unit)
|
||||||
[index, distance.round(2)]
|
[index, distance.round(2)]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class Trip < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def calculate_distance
|
def calculate_distance
|
||||||
distance = Point.total_distance(points, DISTANCE_UNIT)
|
distance = Point.total_distance(points, user.safe_settings.distance_unit)
|
||||||
|
|
||||||
self.distance = distance.round
|
self.distance = distance.round
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ class User < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def total_distance
|
def total_distance
|
||||||
# In km or miles, depending on the application settings (DISTANCE_UNIT)
|
# In km or miles, depending on user.safe_settings.distance_unit
|
||||||
stats.sum(:distance)
|
stats.sum(:distance)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,9 @@ class Visit < ApplicationRecord
|
||||||
return area&.radius if area.present?
|
return area&.radius if area.present?
|
||||||
|
|
||||||
radius = points.map do |point|
|
radius = points.map do |point|
|
||||||
Geocoder::Calculations.distance_between(center, [point.lat, point.lon])
|
Geocoder::Calculations.distance_between(
|
||||||
|
center, [point.lat, point.lon], units: user.safe_settings.distance_unit.to_sym
|
||||||
|
)
|
||||||
end.max
|
end.max
|
||||||
|
|
||||||
radius && radius >= 15 ? radius : 15
|
radius && radius >= 15 ? radius : 15
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,14 @@ class Areas::Visits::Create
|
||||||
|
|
||||||
def area_points(area)
|
def area_points(area)
|
||||||
area_radius =
|
area_radius =
|
||||||
if ::DISTANCE_UNIT == :km
|
if user.safe_settings.distance_unit == :km
|
||||||
area.radius / 1000.0
|
area.radius / DISTANCE_UNITS[:km]
|
||||||
else
|
else
|
||||||
area.radius / 1609.344
|
area.radius / DISTANCE_UNITS[user.safe_settings.distance_unit.to_sym]
|
||||||
end
|
end
|
||||||
|
|
||||||
points = Point.where(user_id: user.id)
|
points = Point.where(user_id: user.id)
|
||||||
.near([area.latitude, area.longitude], area_radius, DISTANCE_UNIT)
|
.near([area.latitude, area.longitude], area_radius, user.safe_settings.distance_unit)
|
||||||
.order(timestamp: :asc)
|
.order(timestamp: :asc)
|
||||||
|
|
||||||
# check if all points within the area are assigned to a visit
|
# check if all points within the area are assigned to a visit
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ class ReverseGeocoding::Places::FetchData
|
||||||
limit: 10,
|
limit: 10,
|
||||||
distance_sort: true,
|
distance_sort: true,
|
||||||
radius: 1,
|
radius: 1,
|
||||||
units: ::DISTANCE_UNIT
|
units: :km
|
||||||
)
|
)
|
||||||
|
|
||||||
data.reject do |place|
|
data.reject do |place|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ class Users::SafeSettings
|
||||||
immich_api_key: immich_api_key,
|
immich_api_key: immich_api_key,
|
||||||
photoprism_url: photoprism_url,
|
photoprism_url: photoprism_url,
|
||||||
photoprism_api_key: photoprism_api_key,
|
photoprism_api_key: photoprism_api_key,
|
||||||
maps: maps
|
maps: maps,
|
||||||
|
distance_unit: distance_unit
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
# rubocop:enable Metrics/MethodLength
|
# rubocop:enable Metrics/MethodLength
|
||||||
|
|
@ -90,4 +91,8 @@ class Users::SafeSettings
|
||||||
def maps
|
def maps
|
||||||
settings['maps'] || {}
|
settings['maps'] || {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def distance_unit
|
||||||
|
settings.dig('maps', 'distance_unit') || 'km'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ module Visits
|
||||||
|
|
||||||
def geocoder_results
|
def geocoder_results
|
||||||
@geocoder_results ||= Geocoder.search(
|
@geocoder_results ||= Geocoder.search(
|
||||||
center, limit: 10, distance_sort: true, radius: 1, units: ::DISTANCE_UNIT
|
center, limit: 10, distance_sort: true, radius: 1, units: :km
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,6 @@
|
||||||
class="w-full z-0"
|
class="w-full z-0"
|
||||||
data-controller="maps points"
|
data-controller="maps points"
|
||||||
data-points-target="map"
|
data-points-target="map"
|
||||||
data-distance_unit="<%= DISTANCE_UNIT %>"
|
|
||||||
data-api_key="<%= current_user.api_key %>"
|
data-api_key="<%= current_user.api_key %>"
|
||||||
data-self_hosted="<%= @self_hosted %>"
|
data-self_hosted="<%= @self_hosted %>"
|
||||||
data-user_settings='<%= current_user.settings.to_json.html_safe %>'
|
data-user_settings='<%= current_user.settings.to_json.html_safe %>'
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
<div role="tablist" class="tabs tabs-lifted tabs-lg">
|
<div class="tabs tabs-boxed mb-6">
|
||||||
<%= link_to 'Integrations', settings_path, role: 'tab', class: "tab #{active_tab?(settings_path)}" %>
|
<%= link_to 'Integrations', settings_path, role: 'tab', class: "tab tab-lg #{active_tab?(settings_path)}" %>
|
||||||
|
<%= link_to 'Map', settings_maps_path, role: 'tab', class: "tab tab-lg #{active_tab?(settings_maps_path)}" %>
|
||||||
<% if DawarichSettings.self_hosted? && current_user.admin? %>
|
<% if DawarichSettings.self_hosted? && current_user.admin? %>
|
||||||
<%= link_to 'Users', settings_users_path, role: 'tab', class: "tab #{active_tab?(settings_users_path)}" %>
|
<%= link_to 'Users', settings_users_path, role: 'tab', class: "tab tab-lg #{active_tab?(settings_users_path)}" %>
|
||||||
<%= link_to 'Background Jobs', settings_background_jobs_path, role: 'tab', class: "tab #{active_tab?(settings_background_jobs_path)}" %>
|
<%= link_to 'Background Jobs', settings_background_jobs_path, role: 'tab', class: "tab tab-lg #{active_tab?(settings_background_jobs_path)}" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<%= link_to 'Map', settings_maps_path, role: 'tab', class: "tab #{active_tab?(settings_maps_path)}" %>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
<% content_for :title, "Background jobs" %>
|
<% content_for :title, "Background jobs" %>
|
||||||
|
|
||||||
<div class="min-h-content w-full my-5">
|
<div class="min-h-content w-full my-5">
|
||||||
|
<h1 class="text-3xl font-bold mb-6">Background jobs</h1>
|
||||||
<%= render 'settings/navigation' %>
|
<%= render 'settings/navigation' %>
|
||||||
|
|
||||||
<div class="flex justify-between items-center mt-5">
|
|
||||||
<h1 class="font-bold text-4xl">Background jobs</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div role="alert" class="alert m-5">
|
<div role="alert" class="alert m-5">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,78 @@
|
||||||
<% content_for :title, 'Settings' %>
|
<% content_for :title, 'Settings' %>
|
||||||
|
|
||||||
<div class="min-h-content w-full my-5">
|
<div class="min-h-content w-full my-5">
|
||||||
|
<h1 class="text-3xl font-bold mb-6">User Settings</h1>
|
||||||
<%= render 'settings/navigation' %>
|
<%= render 'settings/navigation' %>
|
||||||
|
|
||||||
<div class="flex flex-col lg:flex-row w-full my-10 space-x-4">
|
<div class="card bg-base-200 shadow-xl">
|
||||||
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5 mx-5">
|
<%= form_for :settings, url: settings_path, method: :patch, data: { turbo_method: :patch, turbo: false } do |f| %>
|
||||||
<h2 class="text-2xl font-bold">Edit your Integrations settings!</h1>
|
<div class="card-body">
|
||||||
<%= form_for :settings, url: settings_path, method: :patch, data: { turbo_method: :patch, turbo: false } do |f| %>
|
<div class="space-y-8 animate-fade-in">
|
||||||
<div class="form-control my-2">
|
<div>
|
||||||
<%= f.label :immich_url %>
|
<h2 class="text-2xl font-bold mb-4 flex items-center">
|
||||||
<%= f.text_field :immich_url, value: current_user.safe_settings.immich_url, class: "input input-bordered", placeholder: 'http://192.168.0.1:2283' %>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-camera mr-2 text-primary">
|
||||||
|
<path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"></path>
|
||||||
|
<circle cx="12" cy="13" r="3"></circle>
|
||||||
|
</svg>Immich Integration
|
||||||
|
</h2>
|
||||||
|
<div class="bg-base-100 p-5 rounded-lg shadow-sm space-y-4">
|
||||||
|
<div class="form-control w-full">
|
||||||
|
<%= f.label :immich_url, class: 'label' do %>
|
||||||
|
<span class="label-text font-medium">Immich URL</span>
|
||||||
|
<% end %>
|
||||||
|
<%= f.url_field :immich_url, value: current_user.safe_settings.immich_url, class: "input input-bordered w-full pr-10", placeholder: 'http://192.168.0.1:2283' %>
|
||||||
|
<span class="label-text-alt mt-1">The base URL of your Immich instance</span>
|
||||||
|
</div>
|
||||||
|
<div class="form-control w-full">
|
||||||
|
<%= f.label :immich_api_key, class: 'label' do %>
|
||||||
|
<span class="label-text font-medium">Immich API Key</span>
|
||||||
|
<% end %>
|
||||||
|
<div class="relative">
|
||||||
|
<%= f.password_field :immich_api_key, value: current_user.safe_settings.immich_api_key, class: "input input-bordered w-full pr-10", placeholder: 'xxxxxxxxxxxxxx' %>
|
||||||
|
</div>
|
||||||
|
<span class="label-text-alt mt-1">Found in your Immich admin panel under API settings</span>
|
||||||
|
</div>
|
||||||
|
<%# <div class="flex justify-end">
|
||||||
|
<button class="btn btn-sm btn-outline">Test Connection</button>
|
||||||
|
</div> %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2 class="text-2xl font-bold mb-4 flex items-center">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-camera mr-2 text-primary">
|
||||||
|
<path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"></path>
|
||||||
|
<circle cx="12" cy="13" r="3"></circle>
|
||||||
|
</svg>Photoprism Integration
|
||||||
|
</h2>
|
||||||
|
<div class="bg-base-100 p-5 rounded-lg shadow-sm space-y-4">
|
||||||
|
<div class="form-control w-full">
|
||||||
|
<%= f.label :photoprism_url, class: 'label' do %>
|
||||||
|
<span class="label-text font-medium">Photoprism URL</span>
|
||||||
|
<% end %>
|
||||||
|
<div class="relative">
|
||||||
|
<%= f.url_field :photoprism_url, value: current_user.safe_settings.photoprism_url, class: "input input-bordered w-full pr-10", placeholder: 'http://192.168.0.1:2342' %>
|
||||||
|
</div>
|
||||||
|
<span class="label-text-alt mt-1">The base URL of your Photoprism instance</span>
|
||||||
|
</div>
|
||||||
|
<div class="form-control w-full">
|
||||||
|
<%= f.label :photoprism_api_key, class: 'label' do %>
|
||||||
|
<span class="label-text font-medium">Photoprism API Key</span>
|
||||||
|
<% end %>
|
||||||
|
<div class="relative">
|
||||||
|
<%= f.password_field :photoprism_api_key, value: current_user.safe_settings.photoprism_api_key, class: "input input-bordered w-full pr-10", placeholder: 'xxxxxxxxxxxxxx' %>
|
||||||
|
</div>
|
||||||
|
<span class="label-text-alt mt-1">Found in your Photoprism settings under Library</span>
|
||||||
|
</div>
|
||||||
|
<%# <div class="flex justify-end">
|
||||||
|
<button class="btn btn-sm btn-outline">Test Connection</button>
|
||||||
|
</div> %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-control my-2">
|
<div class="card-actions justify-end mt-6">
|
||||||
<%= f.label :immich_api_key %>
|
<%= f.submit "Save changes", class: "btn btn-primary" %>
|
||||||
<%= f.text_field :immich_api_key, value: current_user.safe_settings.immich_api_key, class: "input input-bordered", placeholder: 'xxxxxxxxxxxxxx' %>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="divider"></div>
|
</div>
|
||||||
<div class="form-control my-2">
|
<% end %>
|
||||||
<%= f.label :photoprism_url %>
|
|
||||||
<%= f.text_field :photoprism_url, value: current_user.safe_settings.photoprism_url, class: "input input-bordered", placeholder: 'http://192.168.0.1:2342' %>
|
|
||||||
</div>
|
|
||||||
<div class="form-control my-2">
|
|
||||||
<%= f.label :photoprism_api_key %>
|
|
||||||
<%= f.text_field :photoprism_api_key, value: current_user.safe_settings.photoprism_api_key, class: "input input-bordered", placeholder: 'xxxxxxxxxxxxxx' %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-control my-2">
|
|
||||||
<%= f.submit "Update", class: "btn btn-primary" %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
<% content_for :title, "Map settings" %>
|
<% content_for :title, "Map settings" %>
|
||||||
|
|
||||||
<div class="min-h-content w-full my-5">
|
<div class="min-h-content w-full my-5">
|
||||||
|
<h1 class="text-3xl font-bold mb-6">Map settings</h1>
|
||||||
<%= render 'settings/navigation' %>
|
<%= render 'settings/navigation' %>
|
||||||
|
|
||||||
<div class="flex justify-between items-center my-5">
|
|
||||||
<h1 class="font-bold text-4xl">Maps settings</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div role="alert" class="alert alert-info">
|
<div role="alert" class="alert alert-info">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|
@ -22,50 +19,106 @@
|
||||||
<span>Please remember, that using a custom tile URL may result in extra costs. Check your map tile provider's terms of service for more information.</span>
|
<span>Please remember, that using a custom tile URL may result in extra costs. Check your map tile provider's terms of service for more information.</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4 mt-5" data-controller="map-preview">
|
<div class="card bg-base-200 shadow-xl">
|
||||||
<div class="flex flex-col gap-4">
|
<%= form_for :maps,
|
||||||
<%= form_for :maps,
|
url: settings_maps_path,
|
||||||
url: settings_maps_path,
|
method: :patch,
|
||||||
method: :patch,
|
autocomplete: "off",
|
||||||
autocomplete: "off",
|
data: { turbo_method: :patch, turbo: false } do |f| %>
|
||||||
data: { turbo_method: :patch, turbo: false } do |f| %>
|
|
||||||
<div class="form-control my-2">
|
<div class="card-body">
|
||||||
<%= f.label :name %>
|
<div class="space-y-8 animate-fade-in">
|
||||||
<%= f.text_field :name, value: @maps['name'], placeholder: 'Example: OpenStreetMap', class: "input input-bordered" %>
|
<div>
|
||||||
|
<h2 class="text-2xl font-bold mb-4 flex items-center">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-map mr-2 text-primary">
|
||||||
|
<polygon points="3 6 9 3 15 6 21 3 21 18 15 21 9 18 3 21"></polygon>
|
||||||
|
<line x1="9" x2="9" y1="3" y2="18"></line>
|
||||||
|
<line x1="15" x2="15" y1="6" y2="21"></line>
|
||||||
|
</svg>Map Configuration
|
||||||
|
</h2>
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6" data-controller="map-preview">
|
||||||
|
<div class="bg-base-100 p-5 rounded-lg shadow-sm space-y-4">
|
||||||
|
<div class="form-control w-full">
|
||||||
|
<%= f.label :name, class: 'label' do %>
|
||||||
|
<span class="label-text font-medium">Map Name</span>
|
||||||
|
<% end %>
|
||||||
|
<div class="relative">
|
||||||
|
<%= f.text_field :name, value: @maps['name'], placeholder: 'Example: OpenStreetMap', class: "input input-bordered w-full pr-10" %>
|
||||||
|
</div>
|
||||||
|
<span class="label-text-alt mt-1">A descriptive name for your map configuration</span>
|
||||||
|
</div>
|
||||||
|
<div class="form-control w-full">
|
||||||
|
<%= f.label :url, class: 'label' do %>
|
||||||
|
<span class="label-text font-medium">Tile URL</span>
|
||||||
|
<% end %>
|
||||||
|
<div class="relative">
|
||||||
|
<%= f.text_field :url,
|
||||||
|
value: @maps['url'],
|
||||||
|
autocomplete: "off",
|
||||||
|
placeholder: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||||
|
class: "input input-bordered w-full pr-10",
|
||||||
|
data: {
|
||||||
|
map_preview_target: "urlInput",
|
||||||
|
action: "input->map-preview#updatePreview"
|
||||||
|
} %>
|
||||||
|
</div>
|
||||||
|
<span class="label-text-alt mt-1">URL pattern for map tiles. Must include {x}, {y}, and {z} placeholders</span>
|
||||||
|
</div>
|
||||||
|
<div class="form-control">
|
||||||
|
<label class="label cursor-pointer justify-start">
|
||||||
|
<span class="label-text mr-4 flex items-center">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-globe mr-2 w-4 h-4">
|
||||||
|
<circle cx="12" cy="12" r="10"></circle>
|
||||||
|
<path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"></path>
|
||||||
|
<path d="M2 12h20"></path>
|
||||||
|
</svg>Distance Unit </span>
|
||||||
|
<div class="flex items-center space-x-2">
|
||||||
|
<%= f.label :distance_unit_km, 'Kilometers', class: 'cursor-pointer' %>
|
||||||
|
<%= f.radio_button :distance_unit, 'km', id: 'maps_distance_unit_km', class: 'radio radio-primary ml-1 mr-4', checked: @maps['distance_unit'] == 'km' %>
|
||||||
|
<%= f.label :distance_unit_mi, 'Miles', class: 'cursor-pointer' %>
|
||||||
|
<%= f.radio_button :distance_unit, 'mi', id: 'maps_distance_unit_mi', class: 'radio radio-primary ml-1', checked: @maps['distance_unit'] == 'mi' %>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-base-100 p-5 rounded-lg shadow-sm">
|
||||||
|
<h3 class="font-semibold mb-2">Map Preview</h3>
|
||||||
|
<div class="h-[250px] w-full rounded-lg overflow-hidden border border-base-300">
|
||||||
|
<div class="h-full w-full relative">
|
||||||
|
<div style="height: 500px;">
|
||||||
|
<div
|
||||||
|
data-map-preview-target="mapContainer"
|
||||||
|
class="w-full h-full rounded-lg border"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bg-base-100 p-5 mt-5 rounded-lg shadow-sm">
|
||||||
|
<h3 class="font-semibold mb-4">Tile Usage (Last 7 Days)</h3>
|
||||||
|
<div class="h-[250px]">
|
||||||
|
<%= line_chart(
|
||||||
|
@tile_usage,
|
||||||
|
height: '200px',
|
||||||
|
xtitle: 'Days',
|
||||||
|
ytitle: 'Tiles',
|
||||||
|
suffix: ' tiles loaded'
|
||||||
|
) %>
|
||||||
|
</div>
|
||||||
|
<div class="mt-4 text-sm text-base-content/70">
|
||||||
|
<p>Total usage this week: <span class="font-semibold"><%= @tile_usage.sum { |_, count| count } %> tiles</span>
|
||||||
|
</p>
|
||||||
|
<!--p>Monthly quota: <span class="font-semibold">100,000 tiles</span-->
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card-actions justify-end mt-6">
|
||||||
<div class="form-control my-2">
|
<%= f.submit 'Save changes', class: "btn btn-primary", data: { map_preview_target: "saveButton" } %>
|
||||||
<%= f.label :url, 'URL' %>
|
|
||||||
<%= f.text_field :url,
|
|
||||||
value: @maps['url'],
|
|
||||||
autocomplete: "off",
|
|
||||||
placeholder: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
|
||||||
class: "input input-bordered",
|
|
||||||
data: {
|
|
||||||
map_preview_target: "urlInput",
|
|
||||||
action: "input->map-preview#updatePreview"
|
|
||||||
} %>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<%= f.submit 'Save', class: "btn btn-primary", data: { map_preview_target: "saveButton" } %>
|
<% end %>
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<h2 class="text-lg font-bold">Tile usage</h2>
|
|
||||||
|
|
||||||
<%= line_chart(
|
|
||||||
@tile_usage,
|
|
||||||
height: '200px',
|
|
||||||
xtitle: 'Days',
|
|
||||||
ytitle: 'Tiles',
|
|
||||||
suffix: ' tiles loaded'
|
|
||||||
) %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="height: 500px;">
|
|
||||||
<div
|
|
||||||
data-map-preview-target="mapContainer"
|
|
||||||
class="w-full h-full rounded-lg border"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<% content_for :title, 'Users' %>
|
<% content_for :title, 'Users' %>
|
||||||
|
|
||||||
<div class="min-h-content w-full">
|
<div class="min-h-content w-full my-5">
|
||||||
|
<h1 class="text-3xl font-bold mb-6">Users management</h1>
|
||||||
<%= render 'settings/navigation' %>
|
<%= render 'settings/navigation' %>
|
||||||
|
|
||||||
<div class="flex flex-col lg:flex-row w-full my-10 space-x-4">
|
<div class="flex flex-col lg:flex-row w-full my-10 space-x-4">
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
<%= link_to '🔄', update_year_month_stats_path(stat.year, stat.month), data: { turbo_method: :put }, class: 'text-sm text-gray-500 hover:underline' %>
|
<%= link_to '🔄', update_year_month_stats_path(stat.year, stat.month), data: { turbo_method: :put }, class: 'text-sm text-gray-500 hover:underline' %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p><%= number_with_delimiter stat.distance %><%= DISTANCE_UNIT %></p>
|
<p><%= number_with_delimiter stat.distance %><%= current_user.safe_settings.distance_unit %></p>
|
||||||
<% if DawarichSettings.reverse_geocoding_enabled? %>
|
<% if DawarichSettings.reverse_geocoding_enabled? %>
|
||||||
<div class="card-actions justify-end">
|
<div class="card-actions justify-end">
|
||||||
<%= countries_and_cities_stat_for_month(stat) %>
|
<%= countries_and_cities_stat_for_month(stat) %>
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
<%= column_chart(
|
<%= column_chart(
|
||||||
stat.daily_distance,
|
stat.daily_distance,
|
||||||
height: '100px',
|
height: '100px',
|
||||||
suffix: " #{DISTANCE_UNIT}",
|
suffix: " #{current_user.safe_settings.distance_unit}",
|
||||||
xtitle: 'Days',
|
xtitle: 'Days',
|
||||||
ytitle: 'Distance'
|
ytitle: 'Distance'
|
||||||
) %>
|
) %>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<%= column_chart(
|
<%= column_chart(
|
||||||
Stat.year_distance(year, current_user),
|
Stat.year_distance(year, current_user),
|
||||||
height: '200px',
|
height: '200px',
|
||||||
suffix: " #{DISTANCE_UNIT}",
|
suffix: " #{current_user.safe_settings.distance_unit}",
|
||||||
xtitle: 'Days',
|
xtitle: 'Days',
|
||||||
ytitle: 'Distance'
|
ytitle: 'Distance'
|
||||||
) %>
|
) %>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="stats stats-vertical lg:stats-horizontal shadow w-full bg-base-200">
|
<div class="stats stats-vertical lg:stats-horizontal shadow w-full bg-base-200">
|
||||||
<div class="stat text-center">
|
<div class="stat text-center">
|
||||||
<div class="stat-value text-primary">
|
<div class="stat-value text-primary">
|
||||||
<%= number_with_delimiter(current_user.total_distance) %> <%= DISTANCE_UNIT %>
|
<%= number_with_delimiter(current_user.total_distance) %> <%= current_user.safe_settings.distance_unit %>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-title">Total distance</div>
|
<div class="stat-title">Total distance</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
<% cache [current_user, 'year_distance_stat', year], skip_digest: true do %>
|
<% cache [current_user, 'year_distance_stat', year], skip_digest: true do %>
|
||||||
<%= number_with_delimiter year_distance_stat(year, current_user) %><%= DISTANCE_UNIT %>
|
<%= number_with_delimiter year_distance_stat(year, current_user) %><%= current_user.safe_settings.distance_unit %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</p>
|
</p>
|
||||||
<% if DawarichSettings.reverse_geocoding_enabled? %>
|
<% if DawarichSettings.reverse_geocoding_enabled? %>
|
||||||
|
|
@ -50,7 +50,7 @@
|
||||||
<%= column_chart(
|
<%= column_chart(
|
||||||
Stat.year_distance(year, current_user),
|
Stat.year_distance(year, current_user),
|
||||||
height: '200px',
|
height: '200px',
|
||||||
suffix: " #{DISTANCE_UNIT}",
|
suffix: " #{current_user.safe_settings.distance_unit}",
|
||||||
xtitle: 'Days',
|
xtitle: 'Days',
|
||||||
ytitle: 'Distance'
|
ytitle: 'Distance'
|
||||||
) %>
|
) %>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<% if trip.countries.any? %>
|
<% if trip.countries.any? %>
|
||||||
<p class="text-md text-base-content/60">
|
<p class="text-md text-base-content/60">
|
||||||
<%= "#{trip.countries.join(', ')} (#{trip.distance} #{DISTANCE_UNIT})" %>
|
<%= "#{trip.countries.join(', ')} (#{trip.distance} #{current_user.safe_settings.distance_unit})" %>
|
||||||
</p>
|
</p>
|
||||||
<% elsif trip.visited_countries.present? %>
|
<% elsif trip.visited_countries.present? %>
|
||||||
<p class="text-md text-base-content/60">
|
<p class="text-md text-base-content/60">
|
||||||
<%= "#{trip.visited_countries.join(', ')} (#{trip.distance} #{DISTANCE_UNIT})" %>
|
<%= "#{trip.visited_countries.join(', ')} (#{trip.distance} #{current_user.safe_settings.distance_unit})" %>
|
||||||
</p>
|
</p>
|
||||||
<% else %>
|
<% else %>
|
||||||
<p class="text-md text-base-content/60">
|
<p class="text-md text-base-content/60">
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<% if trip.distance.present? %>
|
<% if trip.distance.present? %>
|
||||||
<span class="text-md"><%= trip.distance %> <%= DISTANCE_UNIT %></span>
|
<span class="text-md"><%= trip.distance %> <%= current_user.safe_settings.distance_unit %></span>
|
||||||
<% else %>
|
<% else %>
|
||||||
<span class="text-md">Calculating...</span>
|
<span class="text-md">Calculating...</span>
|
||||||
<span class="loading loading-dots loading-sm"></span>
|
<span class="loading loading-dots loading-sm"></span>
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
id='map trips-container'
|
id='map trips-container'
|
||||||
class="w-full h-full rounded-lg"
|
class="w-full h-full rounded-lg"
|
||||||
data-trips-target="container"
|
data-trips-target="container"
|
||||||
data-distance_unit="<%= DISTANCE_UNIT %>"
|
|
||||||
data-api_key="<%= current_user.api_key %>"
|
data-api_key="<%= current_user.api_key %>"
|
||||||
data-user_settings="<%= current_user.settings.to_json %>"
|
data-user_settings="<%= current_user.settings.to_json %>"
|
||||||
data-path="<%= trip.path.to_json %>"
|
data-path="<%= trip.path.to_json %>"
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
class="w-full h-full rounded-lg z-0"
|
class="w-full h-full rounded-lg z-0"
|
||||||
data-controller="trips"
|
data-controller="trips"
|
||||||
data-trips-target="container"
|
data-trips-target="container"
|
||||||
data-distance_unit="<%= DISTANCE_UNIT %>"
|
|
||||||
data-api_key="<%= trip.user.api_key %>"
|
data-api_key="<%= trip.user.api_key %>"
|
||||||
data-user_settings="<%= trip.user.settings.to_json %>"
|
data-user_settings="<%= trip.user.settings.to_json %>"
|
||||||
data-path="<%= trip.path.coordinates.to_json %>"
|
data-path="<%= trip.path.coordinates.to_json %>"
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<span class="hover:underline"><%= trip.name %></span>
|
<span class="hover:underline"><%= trip.name %></span>
|
||||||
</h2>
|
</h2>
|
||||||
<p class="text-sm text-gray-600 text-center">
|
<p class="text-sm text-gray-600 text-center">
|
||||||
<%= "#{human_date(trip.started_at)} – #{human_date(trip.ended_at)}, #{trip.distance} #{DISTANCE_UNIT}" %>
|
<%= "#{human_date(trip.started_at)} – #{human_date(trip.ended_at)}, #{trip.distance} #{current_user.safe_settings.distance_unit}" %>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div style="width: 100%; aspect-ratio: 1/1;"
|
<div style="width: 100%; aspect-ratio: 1/1;"
|
||||||
|
|
@ -16,8 +16,7 @@
|
||||||
data-trip-map-path-value="<%= trip.path.coordinates.to_json %>"
|
data-trip-map-path-value="<%= trip.path.coordinates.to_json %>"
|
||||||
data-trip-map-api-key-value="<%= current_user.api_key %>"
|
data-trip-map-api-key-value="<%= current_user.api_key %>"
|
||||||
data-trip-map-user-settings-value="<%= current_user.settings.to_json %>"
|
data-trip-map-user-settings-value="<%= current_user.settings.to_json %>"
|
||||||
data-trip-map-timezone-value="<%= Rails.configuration.time_zone %>"
|
data-trip-map-timezone-value="<%= Rails.configuration.time_zone %>">
|
||||||
data-trip-map-distance-unit-value="<%= DISTANCE_UNIT %>">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,14 @@
|
||||||
SELF_HOSTED = ENV.fetch('SELF_HOSTED', 'true') == 'true'
|
SELF_HOSTED = ENV.fetch('SELF_HOSTED', 'true') == 'true'
|
||||||
|
|
||||||
MIN_MINUTES_SPENT_IN_CITY = ENV.fetch('MIN_MINUTES_SPENT_IN_CITY', 60).to_i
|
MIN_MINUTES_SPENT_IN_CITY = ENV.fetch('MIN_MINUTES_SPENT_IN_CITY', 60).to_i
|
||||||
DISTANCE_UNIT = ENV.fetch('DISTANCE_UNIT', 'km').to_sym
|
|
||||||
|
DISTANCE_UNITS = {
|
||||||
|
km: 1000, # to meters
|
||||||
|
mi: 1609.34, # to meters
|
||||||
|
m: 1, # already in meters
|
||||||
|
ft: 0.3048, # to meters
|
||||||
|
yd: 0.9144 # to meters
|
||||||
|
}.freeze
|
||||||
|
|
||||||
APP_VERSION = File.read('.app_version').strip
|
APP_VERSION = File.read('.app_version').strip
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
timeout: 5,
|
timeout: 5,
|
||||||
units: DISTANCE_UNIT,
|
units: :km,
|
||||||
cache: Redis.new,
|
cache: Redis.new,
|
||||||
always_raise: :all,
|
always_raise: :all,
|
||||||
use_https: PHOTON_API_USE_HTTPS,
|
use_https: PHOTON_API_USE_HTTPS,
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,6 @@ services:
|
||||||
APPLICATION_HOSTS: localhost,::1,127.0.0.1
|
APPLICATION_HOSTS: localhost,::1,127.0.0.1
|
||||||
TIME_ZONE: Europe/London
|
TIME_ZONE: Europe/London
|
||||||
APPLICATION_PROTOCOL: http
|
APPLICATION_PROTOCOL: http
|
||||||
DISTANCE_UNIT: km
|
|
||||||
PROMETHEUS_EXPORTER_ENABLED: false
|
PROMETHEUS_EXPORTER_ENABLED: false
|
||||||
PROMETHEUS_EXPORTER_HOST: 0.0.0.0
|
PROMETHEUS_EXPORTER_HOST: 0.0.0.0
|
||||||
PROMETHEUS_EXPORTER_PORT: 9394
|
PROMETHEUS_EXPORTER_PORT: 9394
|
||||||
|
|
@ -119,7 +118,6 @@ services:
|
||||||
APPLICATION_HOSTS: localhost,::1,127.0.0.1
|
APPLICATION_HOSTS: localhost,::1,127.0.0.1
|
||||||
BACKGROUND_PROCESSING_CONCURRENCY: 10
|
BACKGROUND_PROCESSING_CONCURRENCY: 10
|
||||||
APPLICATION_PROTOCOL: http
|
APPLICATION_PROTOCOL: http
|
||||||
DISTANCE_UNIT: km
|
|
||||||
PROMETHEUS_EXPORTER_ENABLED: false
|
PROMETHEUS_EXPORTER_ENABLED: false
|
||||||
PROMETHEUS_EXPORTER_HOST: dawarich_app
|
PROMETHEUS_EXPORTER_HOST: dawarich_app
|
||||||
PROMETHEUS_EXPORTER_PORT: 9394
|
PROMETHEUS_EXPORTER_PORT: 9394
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,6 @@ services:
|
||||||
APPLICATION_HOSTS: localhost
|
APPLICATION_HOSTS: localhost
|
||||||
TIME_ZONE: Europe/London
|
TIME_ZONE: Europe/London
|
||||||
APPLICATION_PROTOCOL: http
|
APPLICATION_PROTOCOL: http
|
||||||
DISTANCE_UNIT: km
|
|
||||||
PROMETHEUS_EXPORTER_ENABLED: false
|
PROMETHEUS_EXPORTER_ENABLED: false
|
||||||
PROMETHEUS_EXPORTER_HOST: 0.0.0.0
|
PROMETHEUS_EXPORTER_HOST: 0.0.0.0
|
||||||
PROMETHEUS_EXPORTER_PORT: 9394
|
PROMETHEUS_EXPORTER_PORT: 9394
|
||||||
|
|
@ -118,7 +117,6 @@ services:
|
||||||
APPLICATION_HOSTS: localhost
|
APPLICATION_HOSTS: localhost
|
||||||
BACKGROUND_PROCESSING_CONCURRENCY: 10
|
BACKGROUND_PROCESSING_CONCURRENCY: 10
|
||||||
APPLICATION_PROTOCOL: http
|
APPLICATION_PROTOCOL: http
|
||||||
DISTANCE_UNIT: km
|
|
||||||
PROMETHEUS_EXPORTER_ENABLED: false
|
PROMETHEUS_EXPORTER_ENABLED: false
|
||||||
PROMETHEUS_EXPORTER_HOST: dawarich_app
|
PROMETHEUS_EXPORTER_HOST: dawarich_app
|
||||||
PROMETHEUS_EXPORTER_PORT: 9394
|
PROMETHEUS_EXPORTER_PORT: 9394
|
||||||
|
|
|
||||||
|
|
@ -100,8 +100,6 @@ spec:
|
||||||
value: "dawarich.example.com, localhost"
|
value: "dawarich.example.com, localhost"
|
||||||
- name: APPLICATION_PROTOCOL
|
- name: APPLICATION_PROTOCOL
|
||||||
value: http
|
value: http
|
||||||
- name: DISTANCE_UNIT
|
|
||||||
value: km
|
|
||||||
- name: PHOTON_API_HOST
|
- name: PHOTON_API_HOST
|
||||||
value: photon.komoot.io
|
value: photon.komoot.io
|
||||||
- name: PHOTON_API_USE_HTTPS
|
- name: PHOTON_API_USE_HTTPS
|
||||||
|
|
@ -109,7 +107,7 @@ spec:
|
||||||
- name: RAILS_MIN_THREADS
|
- name: RAILS_MIN_THREADS
|
||||||
value: "5"
|
value: "5"
|
||||||
- name: RAILS_MAX_THREADS
|
- name: RAILS_MAX_THREADS
|
||||||
value: "10"
|
value: "10"
|
||||||
image: freikin/dawarich:0.16.4
|
image: freikin/dawarich:0.16.4
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
|
|
@ -149,7 +147,7 @@ spec:
|
||||||
- name: RAILS_MIN_THREADS
|
- name: RAILS_MIN_THREADS
|
||||||
value: "5"
|
value: "5"
|
||||||
- name: RAILS_MAX_THREADS
|
- name: RAILS_MAX_THREADS
|
||||||
value: "10"
|
value: "10"
|
||||||
- name: BACKGROUND_PROCESSING_CONCURRENCY
|
- name: BACKGROUND_PROCESSING_CONCURRENCY
|
||||||
value: "20"
|
value: "20"
|
||||||
- name: APPLICATION_HOST
|
- name: APPLICATION_HOST
|
||||||
|
|
@ -158,8 +156,6 @@ spec:
|
||||||
value: "dawarich.example.com, localhost"
|
value: "dawarich.example.com, localhost"
|
||||||
- name: APPLICATION_PROTOCOL
|
- name: APPLICATION_PROTOCOL
|
||||||
value: http
|
value: http
|
||||||
- name: DISTANCE_UNIT
|
|
||||||
value: km
|
|
||||||
- name: PHOTON_API_HOST
|
- name: PHOTON_API_HOST
|
||||||
value: photon.komoot.io
|
value: photon.komoot.io
|
||||||
- name: PHOTON_API_USE_HTTPS
|
- name: PHOTON_API_USE_HTTPS
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,6 @@ RSpec.describe Stats::CalculateMonth do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when units are kilometers' do
|
context 'when units are kilometers' do
|
||||||
before { stub_const('DISTANCE_UNIT', :km) }
|
|
||||||
|
|
||||||
it 'creates stats' do
|
it 'creates stats' do
|
||||||
expect { calculate_stats }.to change { Stat.count }.by(1)
|
expect { calculate_stats }.to change { Stat.count }.by(1)
|
||||||
end
|
end
|
||||||
|
|
@ -72,7 +70,9 @@ RSpec.describe Stats::CalculateMonth do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when units are miles' do
|
context 'when units are miles' do
|
||||||
before { stub_const('DISTANCE_UNIT', :mi) }
|
before do
|
||||||
|
user.update(settings: { maps: { distance_unit: 'mi' } })
|
||||||
|
end
|
||||||
|
|
||||||
it 'creates stats' do
|
it 'creates stats' do
|
||||||
expect { calculate_stats }.to change { Stat.count }.by(1)
|
expect { calculate_stats }.to change { Stat.count }.by(1)
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ RSpec.describe Users::SafeSettings do
|
||||||
immich_api_key: nil,
|
immich_api_key: nil,
|
||||||
photoprism_url: nil,
|
photoprism_url: nil,
|
||||||
photoprism_api_key: nil,
|
photoprism_api_key: nil,
|
||||||
maps: {}
|
maps: {},
|
||||||
|
distance_unit: 'km'
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
@ -68,7 +69,8 @@ RSpec.describe Users::SafeSettings do
|
||||||
immich_api_key: 'immich-key',
|
immich_api_key: 'immich-key',
|
||||||
photoprism_url: 'https://photoprism.example.com',
|
photoprism_url: 'https://photoprism.example.com',
|
||||||
photoprism_api_key: 'photoprism-key',
|
photoprism_api_key: 'photoprism-key',
|
||||||
maps: { 'name' => 'custom', 'url' => 'https://custom.example.com' }
|
maps: { 'name' => 'custom', 'url' => 'https://custom.example.com' },
|
||||||
|
distance_unit: 'km'
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue