Update trips page and dockerfiles

This commit is contained in:
Eugene Burmakin
2025-05-19 19:00:34 +02:00
parent 3e8e49139a
commit 34c82e82a5
10 changed files with 116 additions and 71 deletions

View File

@@ -5,14 +5,6 @@
{ "url": "https://github.com/heroku/heroku-buildpack-nodejs.git" },
{ "url": "https://github.com/heroku/heroku-buildpack-ruby.git" }
],
"formation": {
"web": {
"quantity": 1
},
"worker": {
"quantity": 1
}
},
"scripts": {
"dokku": {
"predeploy": "bundle exec rails db:migrate"

View File

@@ -23,4 +23,38 @@ module TripsHelper
photoprism_search_url(settings['photoprism_url'], start_date, end_date)
end
end
def trip_duration(trip)
start_time = trip.started_at.to_time
end_time = trip.ended_at.to_time
# Calculate the difference
years = end_time.year - start_time.year
months = end_time.month - start_time.month
days = end_time.day - start_time.day
hours = end_time.hour - start_time.hour
# Adjust for negative values
if hours < 0
hours += 24
days -= 1
end
if days < 0
prev_month = end_time.prev_month
days += (end_time - prev_month).to_i / 1.day
months -= 1
end
if months < 0
months += 12
years -= 1
end
parts = []
parts << "#{years} year#{'s' if years != 1}" if years > 0
parts << "#{months} month#{'s' if months != 1}" if months > 0
parts << "#{days} day#{'s' if days != 1}" if days > 0
parts << "#{hours} hour#{'s' if hours != 1}" if hours > 0
parts = ["0 hours"] if parts.empty?
parts.join(', ')
end
end

View File

@@ -3,23 +3,23 @@
class Trips::CalculateDistanceJob < ApplicationJob
queue_as :default
def perform(trip_id)
def perform(trip_id, distance_unit)
trip = Trip.find(trip_id)
trip.calculate_distance
trip.save!
broadcast_update(trip)
broadcast_update(trip, distance_unit)
end
private
def broadcast_update(trip)
def broadcast_update(trip, distance_unit)
Turbo::StreamsChannel.broadcast_update_to(
"trip_#{trip.id}",
target: "trip_distance",
partial: "trips/distance",
locals: { trip: trip }
locals: { trip: trip, distance_unit: distance_unit }
)
end
end

View File

@@ -33,6 +33,10 @@
<%= f.password_field :password_confirmation, autocomplete: "new-password", class: 'input input-bordered' %>
</div>
<% if !DawarichSettings.self_hosted? %>
<div class="cf-turnstile" data-sitekey="<%= ENV['TURNSTILE_SITE_KEY'] %>" data-theme="dark"></div>
<% end %>
<div class="form-control mt-6">
<%= f.submit "Sign up", class: 'btn btn-primary' %>
</div>

View File

@@ -1,14 +1,29 @@
<% if trip.countries.any? %>
<p class="text-md text-base-content/60">
<%= "#{trip.countries.join(', ')} (#{trip.distance} #{current_user.safe_settings.distance_unit})" %>
</p>
<% elsif trip.visited_countries.present? %>
<p class="text-md text-base-content/60">
<%= "#{trip.visited_countries.join(', ')} (#{trip.distance} #{current_user.safe_settings.distance_unit})" %>
</p>
<% else %>
<p class="text-md text-base-content/60">
<span>Countries are being calculated...</span>
<span class="loading loading-dots loading-sm"></span>
</p>
<% end %>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-4 mb-4">
<div class="card bg-base-200 shadow-lg">
<div class="card-body p-4">
<div class="stat-title text-xs">Distance</div>
<div class="stat-value text-lg"><%= @trip.distance %> <%= current_user.safe_settings.distance_unit %></div>
</div>
</div>
<div class="card bg-base-200 shadow-lg">
<div class="card-body p-4">
<div class="stat-title text-xs">Duration</div>
<div class="stat-value text-lg"><%= trip_duration(@trip) %></div>
</div>
</div>
<div class="card bg-base-200 shadow-lg">
<div class="card-body p-4">
<div class="stat-title text-xs">Countries</div>
<div class="stat-value text-lg">
<% if @trip.countries.any? %>
<%= @trip.countries.join(', ') %>
<% elsif @trip.visited_countries.present? %>
<%= @trip.visited_countries.join(', ') %>
<% else %>
<span>Countries are being calculated...</span>
<span class="loading loading-dots loading-sm"></span>
<% end %>
</div>
</div>
</div>
</div>

View File

@@ -1,5 +1,5 @@
<% if trip.distance.present? %>
<span class="text-md"><%= trip.distance %> <%= current_user.safe_settings.distance_unit %></span>
<span class="text-md"><%= trip.distance %> <%= distance_unit %></span>
<% else %>
<span class="text-md">Calculating...</span>
<span class="loading loading-dots loading-sm"></span>

View File

@@ -1,7 +1,7 @@
<% if trip.path.present? %>
<div
id='map'
class="w-full h-full rounded-lg z-0"
class="w-full h-full md:h-64 rounded-lg z-0"
data-controller="trips"
data-trips-target="container"
data-api_key="<%= trip.user.api_key %>"
@@ -10,7 +10,7 @@
data-started_at="<%= trip.started_at %>"
data-ended_at="<%= trip.ended_at %>"
data-timezone="<%= Rails.configuration.time_zone %>">
<div data-trips-target="container" class="h-[25rem] w-full min-h-screen">
<div data-trips-target="container" class="h-[25rem] w-full min-h-screen md:h-64">
</div>
</div>
<% else %>

View File

@@ -2,40 +2,30 @@
<%= turbo_stream_from "trip_#{@trip.id}" %>
<div class="container mx-auto px-4 max-w-4xl my-5">
<div class="text-center mb-8">
<h1 class="text-4xl font-bold mb-2"><%= @trip.name %></h1>
<p class="text-md text-base-content/60">
<%= human_date(@trip.started_at) %> - <%= human_date(@trip.ended_at) %>
</p>
<% if @trip.countries.any? || @trip.visited_countries.present? %>
<div id="trip_countries">
<%= render "trips/countries", trip: @trip %>
</div>
<% else %>
<div id="trip_countries">
<p class="text-md text-base-content/60">
<span>Countries are being calculated...</span>
<span class="loading loading-dots loading-sm"></span>
</p>
</div>
<% end %>
</div>
<div class="bg-base-100 my-8 p-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="w-full" id="trip_path">
<div class="container mx-auto px-4 my-5">
<div class="bg-base-100 p-4">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="w-full block" id="trip_path">
<%= render "trips/path", trip: @trip, current_user: current_user %>
</div>
<div class="w-full">
<div class="text-center mb-8">
<h1 class="text-4xl font-bold mb-2"><%= @trip.name %></h1>
<p class="text-md text-base-content/60 mb-4">
<%= human_date(@trip.started_at) %> - <%= human_date(@trip.ended_at) %>
</p>
<%= render "trips/countries", trip: @trip, current_user: current_user %>
</div>
<div>
<%= @trip.notes.body %>
</div>
<!-- Photos Grid Section -->
<% if @photo_previews.any? %>
<% @photo_previews.each_slice(4) do |slice| %>
<div class="h-32 flex gap-4 mt-4 justify-center">
<% @photo_previews.each_slice(3) do |slice| %>
<div class="h-48 flex gap-4 mt-4 justify-center">
<% slice.each do |photo| %>
<div class="flex-1 h-full overflow-hidden rounded-lg transition-transform duration-300 hover:scale-105 hover:shadow-lg">
<img

View File

@@ -1,4 +1,4 @@
FROM ruby:3.4.1-alpine
FROM ruby:3.4.1-slim
ENV APP_PATH=/var/app
ENV BUNDLE_VERSION=2.5.21
@@ -10,25 +10,30 @@ ENV SELF_HOSTED=true
ENV SIDEKIQ_USERNAME=sidekiq
ENV SIDEKIQ_PASSWORD=password
# Install dependencies for application
RUN apk -U add --no-cache \
build-base \
RUN apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
build-essential \
git \
postgresql-dev \
postgresql-client \
libpq-dev \
libxml2-dev \
libxslt-dev \
nodejs \
yarn \
libyaml-dev \
libgeos-dev libgeos++-dev \
imagemagick \
tzdata \
nodejs \
yarn \
less \
yaml-dev \
gcompat \
geos \
&& mkdir -p $APP_PATH
libjemalloc2 libjemalloc-dev \
&& mkdir -p $APP_PATH \
&& rm -rf /var/lib/apt/lists/*
# Update gem system and install bundler
# Use jemalloc
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
# Optional: Set YJIT explicitly (enabled by default in 3.4.1 MRI builds)
ENV RUBY_YJIT_ENABLE=1
# Update RubyGems and install Bundler
RUN gem update --system 3.6.2 \
&& gem install bundler --version "$BUNDLE_VERSION" \
&& rm -rf $GEM_HOME/cache/*
@@ -37,15 +42,12 @@ WORKDIR $APP_PATH
COPY ../Gemfile ../Gemfile.lock ../.ruby-version ../vendor ./
# Install all gems into the image
RUN bundle config set --local path 'vendor/bundle' \
&& bundle install --jobs 4 --retry 3 \
&& rm -rf vendor/bundle/ruby/3.4.1/cache/*.gem
# Copy the rest of the application
COPY ../. ./
# Copy entrypoint scripts and grant execution permissions
COPY ./docker/web-entrypoint.sh /usr/local/bin/web-entrypoint.sh
RUN chmod +x /usr/local/bin/web-entrypoint.sh
@@ -54,4 +56,4 @@ RUN chmod +x /usr/local/bin/sidekiq-entrypoint.sh
EXPOSE $RAILS_PORT
ENTRYPOINT [ "bundle", "exec" ]
ENTRYPOINT ["bundle", "exec"]

View File

@@ -6,6 +6,7 @@ ENV BUNDLE_PATH=/usr/local/bundle/gems
ENV RAILS_LOG_TO_STDOUT=true
ENV RAILS_PORT=3000
ENV RAILS_ENV=production
ENV SELF_HOSTED=true
# Install dependencies for application
RUN apk -U add --no-cache \
@@ -23,8 +24,15 @@ RUN apk -U add --no-cache \
yaml-dev \
gcompat \
geos \
jemalloc \
&& mkdir -p $APP_PATH
# Use jemalloc
ENV LD_PRELOAD=/usr/lib/libjemalloc.so.2
# Enable YJIT
ENV RUBY_YJIT_ENABLE=1
# Update gem system and install bundler
RUN gem update --system 3.6.2 \
&& gem install bundler --version "$BUNDLE_VERSION" \