feat: add navigation between weather arts
- Implement previous and next weather art navigation - Update weather arts controller to fetch adjacent weather arts - Modify show view to include navigation links This update enhances the user experience by allowing users to navigate through weather arts seamlessly. The previous and next buttons improve accessibility, providing a smoother browsing experience. The implementation also accounts for situations where no adjacent weather arts exist, ensuring clarity for users.
This commit is contained in:
parent
5d1846e0a0
commit
884e1dfc9f
4
Gemfile
4
Gemfile
@ -56,11 +56,13 @@ gem "ahoy_matey", "~> 5.2"
|
|||||||
gem "ruby-openai", "~> 7.3"
|
gem "ruby-openai", "~> 7.3"
|
||||||
gem "httparty", "~> 0.22.0"
|
gem "httparty", "~> 0.22.0"
|
||||||
gem "down", "~> 5.4"
|
gem "down", "~> 5.4"
|
||||||
gem "aws-sdk-s3", "~> 1.179"
|
gem "aws-sdk-s3", "~> 1.177"
|
||||||
gem "sidekiq", "~> 7.3"
|
gem "sidekiq", "~> 7.3"
|
||||||
gem "sidekiq-scheduler", "~> 5.0"
|
gem "sidekiq-scheduler", "~> 5.0"
|
||||||
|
|
||||||
gem "image_processing", "~> 1.13"
|
gem "image_processing", "~> 1.13"
|
||||||
|
gem "ruby-vips", "~> 2.2"
|
||||||
|
gem "mini_magick", "~> 4.13.2"
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
|
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
|
||||||
|
26
Gemfile.lock
26
Gemfile.lock
@ -84,8 +84,8 @@ GEM
|
|||||||
uri (>= 0.13.1)
|
uri (>= 0.13.1)
|
||||||
addressable (2.8.7)
|
addressable (2.8.7)
|
||||||
public_suffix (>= 2.0.2, < 7.0)
|
public_suffix (>= 2.0.2, < 7.0)
|
||||||
ahoy_matey (5.2.1)
|
ahoy_matey (5.3.0)
|
||||||
activesupport (>= 6.1)
|
activesupport (>= 7)
|
||||||
device_detector (>= 1)
|
device_detector (>= 1)
|
||||||
safely_block (>= 0.4)
|
safely_block (>= 0.4)
|
||||||
arbre (1.7.0)
|
arbre (1.7.0)
|
||||||
@ -93,8 +93,8 @@ GEM
|
|||||||
ruby2_keywords (>= 0.0.2)
|
ruby2_keywords (>= 0.0.2)
|
||||||
ast (2.4.2)
|
ast (2.4.2)
|
||||||
aws-eventstream (1.3.0)
|
aws-eventstream (1.3.0)
|
||||||
aws-partitions (1.1043.0)
|
aws-partitions (1.1044.0)
|
||||||
aws-sdk-core (3.217.0)
|
aws-sdk-core (3.217.1)
|
||||||
aws-eventstream (~> 1, >= 1.3.0)
|
aws-eventstream (~> 1, >= 1.3.0)
|
||||||
aws-partitions (~> 1, >= 1.992.0)
|
aws-partitions (~> 1, >= 1.992.0)
|
||||||
aws-sigv4 (~> 1.9)
|
aws-sigv4 (~> 1.9)
|
||||||
@ -238,7 +238,7 @@ GEM
|
|||||||
activerecord
|
activerecord
|
||||||
kaminari-core (= 1.2.2)
|
kaminari-core (= 1.2.2)
|
||||||
kaminari-core (1.2.2)
|
kaminari-core (1.2.2)
|
||||||
language_server-protocol (3.17.0.3)
|
language_server-protocol (3.17.0.4)
|
||||||
logger (1.6.5)
|
logger (1.6.5)
|
||||||
loofah (2.24.0)
|
loofah (2.24.0)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
@ -268,7 +268,7 @@ GEM
|
|||||||
net-protocol
|
net-protocol
|
||||||
net-protocol (0.2.2)
|
net-protocol (0.2.2)
|
||||||
timeout
|
timeout
|
||||||
net-scp (4.0.0)
|
net-scp (4.1.0)
|
||||||
net-ssh (>= 2.6.5, < 8.0.0)
|
net-ssh (>= 2.6.5, < 8.0.0)
|
||||||
net-sftp (4.0.0)
|
net-sftp (4.0.0)
|
||||||
net-ssh (>= 5.0.0, < 8.0.0)
|
net-ssh (>= 5.0.0, < 8.0.0)
|
||||||
@ -315,7 +315,7 @@ GEM
|
|||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
raabro (1.4.0)
|
raabro (1.4.0)
|
||||||
racc (1.8.1)
|
racc (1.8.1)
|
||||||
rack (3.1.8)
|
rack (3.1.9)
|
||||||
rack-session (2.1.0)
|
rack-session (2.1.0)
|
||||||
base64 (>= 0.1.0)
|
base64 (>= 0.1.0)
|
||||||
rack (>= 3.0.0)
|
rack (>= 3.0.0)
|
||||||
@ -369,17 +369,17 @@ GEM
|
|||||||
actionpack (>= 5.2)
|
actionpack (>= 5.2)
|
||||||
railties (>= 5.2)
|
railties (>= 5.2)
|
||||||
rexml (3.4.0)
|
rexml (3.4.0)
|
||||||
rubocop (1.70.0)
|
rubocop (1.71.1)
|
||||||
json (~> 2.3)
|
json (~> 2.3)
|
||||||
language_server-protocol (>= 3.17.0)
|
language_server-protocol (>= 3.17.0)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
parser (>= 3.3.0.2)
|
parser (>= 3.3.0.2)
|
||||||
rainbow (>= 2.2.2, < 4.0)
|
rainbow (>= 2.2.2, < 4.0)
|
||||||
regexp_parser (>= 2.9.3, < 3.0)
|
regexp_parser (>= 2.9.3, < 3.0)
|
||||||
rubocop-ast (>= 1.36.2, < 2.0)
|
rubocop-ast (>= 1.38.0, < 2.0)
|
||||||
ruby-progressbar (~> 1.7)
|
ruby-progressbar (~> 1.7)
|
||||||
unicode-display_width (>= 2.4.0, < 4.0)
|
unicode-display_width (>= 2.4.0, < 4.0)
|
||||||
rubocop-ast (1.37.0)
|
rubocop-ast (1.38.0)
|
||||||
parser (>= 3.3.1.0)
|
parser (>= 3.3.1.0)
|
||||||
rubocop-minitest (0.36.0)
|
rubocop-minitest (0.36.0)
|
||||||
rubocop (>= 1.61, < 2.0)
|
rubocop (>= 1.61, < 2.0)
|
||||||
@ -387,7 +387,7 @@ GEM
|
|||||||
rubocop-performance (1.23.1)
|
rubocop-performance (1.23.1)
|
||||||
rubocop (>= 1.48.1, < 2.0)
|
rubocop (>= 1.48.1, < 2.0)
|
||||||
rubocop-ast (>= 1.31.1, < 2.0)
|
rubocop-ast (>= 1.31.1, < 2.0)
|
||||||
rubocop-rails (2.29.0)
|
rubocop-rails (2.29.1)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
rack (>= 1.1)
|
rack (>= 1.1)
|
||||||
rubocop (>= 1.52.0, < 2.0)
|
rubocop (>= 1.52.0, < 2.0)
|
||||||
@ -511,7 +511,7 @@ PLATFORMS
|
|||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
activeadmin (~> 3.2)
|
activeadmin (~> 3.2)
|
||||||
ahoy_matey (~> 5.2)
|
ahoy_matey (~> 5.2)
|
||||||
aws-sdk-s3 (~> 1.179)
|
aws-sdk-s3 (~> 1.177)
|
||||||
bootsnap
|
bootsnap
|
||||||
brakeman
|
brakeman
|
||||||
capybara
|
capybara
|
||||||
@ -527,12 +527,14 @@ DEPENDENCIES
|
|||||||
kamal
|
kamal
|
||||||
kaminari (~> 1.2)
|
kaminari (~> 1.2)
|
||||||
meta-tags (~> 2.22)
|
meta-tags (~> 2.22)
|
||||||
|
mini_magick (~> 4.13.2)
|
||||||
pg (~> 1.5)
|
pg (~> 1.5)
|
||||||
propshaft
|
propshaft
|
||||||
puma (>= 5.0)
|
puma (>= 5.0)
|
||||||
rails (~> 8.0.1)
|
rails (~> 8.0.1)
|
||||||
rubocop-rails-omakase
|
rubocop-rails-omakase
|
||||||
ruby-openai (~> 7.3)
|
ruby-openai (~> 7.3)
|
||||||
|
ruby-vips (~> 2.2)
|
||||||
selenium-webdriver
|
selenium-webdriver
|
||||||
sidekiq (~> 7.3)
|
sidekiq (~> 7.3)
|
||||||
sidekiq-scheduler (~> 5.0)
|
sidekiq-scheduler (~> 5.0)
|
||||||
|
@ -3,6 +3,16 @@ class WeatherArtsController < ApplicationController
|
|||||||
@city = City.friendly.find(params[:city_id])
|
@city = City.friendly.find(params[:city_id])
|
||||||
@weather_art = @city.weather_arts.friendly.find(params[:slug])
|
@weather_art = @city.weather_arts.friendly.find(params[:slug])
|
||||||
|
|
||||||
|
@previous_weather_art = @city.weather_arts
|
||||||
|
.where("id < ?", @weather_art.id)
|
||||||
|
.order(weather_date: :desc)
|
||||||
|
.first
|
||||||
|
|
||||||
|
@next_weather_art = @city.weather_arts
|
||||||
|
.where("id > ?", @weather_art.id)
|
||||||
|
.order(weather_date: :asc)
|
||||||
|
.first
|
||||||
|
|
||||||
ahoy.track "View Weather Art", {
|
ahoy.track "View Weather Art", {
|
||||||
weather_art_id: @weather_art.id,
|
weather_art_id: @weather_art.id,
|
||||||
city_id: @weather_art.city_id,
|
city_id: @weather_art.city_id,
|
||||||
|
@ -86,6 +86,36 @@
|
|||||||
<%= @weather_art.prompt %>
|
<%= @weather_art.prompt %>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 上一个和下一个导航 -->
|
||||||
|
<div class="flex flex-col sm:flex-row justify-between items-center gap-4 mt-8">
|
||||||
|
<% if @previous_weather_art %>
|
||||||
|
<%= link_to city_weather_art_path(@city, @previous_weather_art),
|
||||||
|
class: "btn btn-outline btn-primary w-full sm:w-auto flex items-center justify-center gap-2" do %>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
|
||||||
|
</svg>
|
||||||
|
Previous Weather Art
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if @next_weather_art %>
|
||||||
|
<%= link_to city_weather_art_path(@city, @next_weather_art),
|
||||||
|
class: "btn btn-outline btn-primary w-full sm:w-auto flex items-center justify-center gap-2" do %>
|
||||||
|
Next Weather Art
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
||||||
|
</svg>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<% if @previous_weather_art.nil? && @next_weather_art.nil? %>
|
||||||
|
<div class="text-center text-base-content/70 py-4">
|
||||||
|
No more Weather Arts available
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
@ -1 +1 @@
|
|||||||
0Upt112zhMfb3aADOgxSWUCTTUNgtTrpoivR9+KJFKcazTjqRauvQ9W+uicYrjJjv497gHMFhusWZysDl1/uwHHaoHvyp7auIjRHiOR1YKfRLgbMSYMgSOKlP4HbiZ66hjhT+4T50JjmwwLcPFtgPaZG3lasTAXejc9ejiSn+OsIGvJje5MXnPREId5pvC/SNW4uCYMe6OEsfhTlsj8hES7odHJzMsGQGGuVkcg1EimogOE9oWK6FS0bj45R+7HCiIYlbcmDkRNraGDMGJI+oaxx2mi+34ENoxqfbYEv4PhsWPYcOROK8FyrpXwvRG/a1J8LFxTLkVloKsBIInLojvd9u8zwpcTOtsaHOxsQV7gLzUt2GbUiT4EZUdzHpIDRboJEuVxm6ioBctcJ744xnkn5rxOoJH+JWRhxf+CVLYojcYMdkcyGEOHv0nXtpWtu/xsJT3fTqJBLuyGWNQUfTDsw3qQDUOrsgSNvXvhEu1iWptoByp4d0adaCDS0+TVt+BFg2xPzSnIU3IAXgSnhyLTVd87jxBMHtcngIj4HAj+nDIs65KT4dk4Y+ns3eWE345Z0CzUz1J6M8ikva0cQiBB6wxMl1yghysCcSfKX4z/KbuJv6StQJIqw4HkDZ9youXEbnmiXTxuEaC0Yg3SE0dFf5k9Rj5govLMdCf1Msj04RQHt0b08s3UdTgegriru+j7dC6yTaDbHkrNorREME3SENzdksI1D5k08D4Z+TYpO/+yyZE5qKELEse9TgJiFZ6g1H2sFs9zCxBDif67ovFSqrRaNgP7qBY8uEfFNVP6Y6eSnfccJlFBGlwflhwwA1osit+5rKlvhqQs37qsmFZRuj9BdrAJbdr/0ogEbLyeTEw3Zq+0m0/Vf4j5ueCv2eDpk/gSQdl869v+5anLTqMUWM4KV1wS1OrPkMC5XkZHLUo1/1+Dl6FKfZhWydRso1R9WL5B0Jk7UEWMPX0qoxxuixR1jwWzYmlehq0iNw7hQPdgwCbDtRxEMPr8MkUnG5Fd0YZUfnhHJ+EWVCZHKhUJclRSB9LnDKVPJr/oFuOHLmJg6Vll4WHCnIK9nCHdr7ed6O89vA5Z8DRlE/6yAXFlPKrCldWYbrL3BAgzQK8MxD5fzgzRkGiwVEtQwhbtbdDHUJ9rdAEmLJZj1UJXLIhX9jFspB9stHqyRxrcef/Y+h9dBvuFdvSIFEXA0TWHintx9YDgsJb591d6rjJn+JYEmZs9UONEEuiijPf9waqTb0oIrUQwnlUOX69bBipiU5ZQ2yQvepuRY3ooK3IGHvngxZPT0F8Mfh5Zcx9GGJd17LZb9DJOs7uOlrpXydToq/3Qm1q6TmgjbFYpC6iyrhDyE5XLL/XwVavh7m2QYqVbUXk2tGk2C0UR6CTE6tsV1+kDs1nylIEgAA5Nr43HQtRAXPmo0k8Txy5wMMIbLE1keqjl7XdGPnLsX9CJi6ue6KZxhigwcdakvW6Y=--H101ebDKrzdM39ll--a5R5klrhU6QgghGPjjWfAQ==
|
zSnch4RlzPEpqZOE+TyBVBnHu+wyiNfNZoe1zi+cGNcgN/0BMw3xVQNIdu5ZgZzklukyimLlvkic7/G3PZE5aooqKIPeaGIgVKwdBvIGZYkTbrLTPtiA2Mx2iay4u6XI3eLDZZdy9g446GTngz9beQFR9s7dBbRBewOdIuCjA17seywsv722x97wHCv1xoGBeknK0DrEaYQcnECcy3G3esAsGeoKCQRMNHIf5/IbB6J+ZsoyOpnwtjOXdfEUnmtieLqvyw1xjgOxQTp2GMJk8zq+dGUBR3nIzplzccJbotppWfUbd9nxuT0stxWdFtKRPceynUfJ4awQNOmx+qGXi2/sYZH9lEB0nnyuKUpte6/bf1kcxcXyqTcsjaw0f9DXC3z9jx0pPbf2+O1MLZSFmo7Sr18mXjHVWjSCXnuYmWWkkuKESl4DwW5KScguWdnsf+/Y1eHds2MpE9dRLynlf5ONvFMY495iXuN4bR7UE5utAmU3imAg8vhErDqiro2L0GKMY5boMg+9NIObSlxwI6uAer8HaIKBVioiXGHFoFofR0LpmIKTbHiRF9ZZM3KCunsrQXAvRB4X7jL18JR08cDGGML2m03u9fcn9VuCYgcr+TLnsBozoG+ATP03kXc6lxkxjDvOc2z/AKqPmHUejCvsTLibFuEgw34E/NnVgcrC/Cggh/pp2Vmc6Yg2aQN7NcUmz0enGpzaTcnwiiB/8U8ig5WUovZP/iG3JH8S4KtBhDVz4hzz3FDOFBZCHd0rDrLtcyPtOcI3/WTZ0BgV5SXxA6L1gmM+aSYXtiyKZ2iUUOkMnNPvmHtimd+IWJZn2qXswX8RuE5QTqL5R5PRIdawdMSf9QrBSmDllNCo3czzClBRSNMYk2+ueWtiyvRuxP/xyNVl5e8nGOhAFWjCA+DVVA1xGWvS+R+3nxMSMtNaqTc2RPHQ3u4hY4k/0UH2TmnnzIJHS8vYScO4EzasTb/9FMeUEDnx369D7gvkXW6OapIKxwV0oQR8a/ZYUpOVyV6rSUIvEKrlpXCG8fh/6LwprYTPrnWe8iIwGqxKcuecrmtRSijAHgI2ZzMpSN91tomBBn9Qs+5svRbcXCO9KUKtjB9V82J7xqT+LwOyf1wa+v9zcO1aQxel2npRTsg7a4eIyIx1iyP7hHLAAuYIeEj1pBjiY/LiGZw+ScrXu1sIFTpt2SIKUOCVSN1y52/zXkwTRHc3qf4IdeHX6DqzWmWUiEHwm9Lva1fJ6poJ3vqWi7OLWJqyDtiN2FHJqybQ9mrgWPb0WBYi3umnfPy6ZYMQ6jQ8YarK8aFHsVdjUL0I4DKigAuer47p2rUcaFvySGCoMaSu5krSBw3VkDR6y1J8wIAm7nKZOSyoKwRjrgwXOl8yTN+zoemiaUMNJI1mTu1JQeg5rX2yUvwLEu5hu/5eOuRCkoSiwcG1+LmcnZbYRgSRvDzRcKYKZ/5hzQkPCLRkwAhh1Zp7mtc=--dyeF3fjnBpbK0tnw--nWdBu1crWT0VX9aHfnoKRw==
|
22
db/seeds.rb
22
db/seeds.rb
@ -183,3 +183,25 @@ guangzhou_weather_art2.image.attach(
|
|||||||
filename: "sample-guangzhou-weather-art-2.png",
|
filename: "sample-guangzhou-weather-art-2.png",
|
||||||
content_type: "image/png"
|
content_type: "image/png"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
guangzhou_weather_art3 = WeatherArt.create!(
|
||||||
|
city: guangzhou,
|
||||||
|
weather_date: 2.day.ago,
|
||||||
|
description: 'Sunny with some clouds',
|
||||||
|
temperature: 23.21,
|
||||||
|
feeling_temp: 22.11,
|
||||||
|
humidity: 65,
|
||||||
|
wind_scale: "0.7",
|
||||||
|
wind_speed: 15,
|
||||||
|
precipitation: 0,
|
||||||
|
pressure: 1014,
|
||||||
|
visibility: 10000,
|
||||||
|
cloud: 30,
|
||||||
|
prompt: "A clear day in Guangzhou, China. In the foreground, people are walking near the iconic Canton Tower, surrounded by vibrant greenery and modern buildings. The sky is blue with no clouds, and the sun is shining brightly. It's a perfect day, with a temperature of around 23 degrees Celsius. The scene captures the lively atmosphere of the city, showing locals enjoying their day out."
|
||||||
|
)
|
||||||
|
guangzhou_weather_art3.image.attach(
|
||||||
|
io: File.open("db/seeds/images/sample-guangzhou-weather-art-2.png"),
|
||||||
|
filename: "sample-guangzhou-weather-art-2.png",
|
||||||
|
content_type: "image/png"
|
||||||
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user