feat: implement social sharing functionality
- Added `share_controller.js` to handle sharing logic. - Created `_share_social.html.erb` partial for social sharing buttons. - Integrated share buttons into city and weather art show pages. - Added sharer.js dependency. This feature allows users to share city and weather art pages on various social media platforms such as Facebook, Twitter, LinkedIn, Pinterest, Telegram, and WhatsApp, increasing content visibility.
This commit is contained in:
parent
d4deddbb8c
commit
3f8b0dd231
@ -9,6 +9,7 @@ import FlashMessageController from "./flash_controller"
|
||||
import SearchController from "./search_controller"
|
||||
import PageLoadTimeController from "./page_load_time_controller"
|
||||
import MapController from "./map_controller"
|
||||
import ShareController from "./share_controller"
|
||||
|
||||
application.register("hello", HelloController)
|
||||
application.register("photo-swipe-lightbox", PhotoSwipeLightBoxController)
|
||||
@ -16,4 +17,5 @@ application.register("flash", FlashMessageController)
|
||||
application.register("search", SearchController)
|
||||
application.register("page-load-time", PageLoadTimeController)
|
||||
application.register("map", MapController)
|
||||
application.register("share", ShareController)
|
||||
|
||||
|
12
app/javascript/controllers/share_controller.js
Normal file
12
app/javascript/controllers/share_controller.js
Normal file
@ -0,0 +1,12 @@
|
||||
// app/javascript/controllers/share_controller.js
|
||||
import { Controller } from "@hotwired/stimulus"
|
||||
import Sharer from "sharer.js"
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["button"]
|
||||
|
||||
connect() {
|
||||
// 初始化 sharer.js
|
||||
window.Sharer.init()
|
||||
}
|
||||
}
|
@ -77,23 +77,23 @@ class WeatherArt < ApplicationRecord
|
||||
# 设置时区对象
|
||||
time_zone = ActiveSupport::TimeZone[timezone_info["zoneName"]] ||
|
||||
ActiveSupport::TimeZone["UTC"]
|
||||
time = self.updated_at
|
||||
|
||||
date_string = self.weather_date&.strftime("%B %d, %Y")
|
||||
time_string =
|
||||
use_local_timezone ?
|
||||
"#{time.in_time_zone(time_zone).strftime('%H:%M')} #{timezone_info['gmtOffsetName']}" :
|
||||
"#{time.utc.strftime('%H:%M')} UTC"
|
||||
|
||||
case type
|
||||
when :date
|
||||
# 格式化日期
|
||||
self&.weather_date&.strftime("%B %d, %Y")
|
||||
date_string
|
||||
when :time
|
||||
# 获取时间
|
||||
time = updated_at
|
||||
|
||||
if use_local_timezone
|
||||
# 使用本地时区
|
||||
local_time = time.in_time_zone(time_zone)
|
||||
"#{local_time.strftime('%H:%M')} #{timezone_info['gmtOffsetName']}"
|
||||
else
|
||||
# 使用 UTC
|
||||
"#{time.utc.strftime('%H:%M')} UTC"
|
||||
end
|
||||
time_string
|
||||
when :all
|
||||
"#{date_string} #{time_string}"
|
||||
else
|
||||
"#{date_string} #{time_string}"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -70,6 +70,27 @@
|
||||
</div>
|
||||
|
||||
<%= render 'cities/admin_panel' %>
|
||||
|
||||
<div class="card bg-base-100 backdrop-blur-md shadow-lg border border-primary/20 overflow-hidden">
|
||||
<%
|
||||
# 构建更吸引人的分享标题
|
||||
share_title =
|
||||
"🎨 #{@city.full_name}'s Weather Transformed into Art"
|
||||
|
||||
# 构建更有描述性的分享描述
|
||||
share_description = [
|
||||
"Discover this stunning AI-generated weather art!",
|
||||
"in #{@city.full_name}.",
|
||||
"Visit TodayAIWeather to see more amazing weather art."
|
||||
].join(" ")
|
||||
%>
|
||||
<%= render "shared/share_social",
|
||||
title: share_title,
|
||||
description: share_description,
|
||||
tags: "AIWeather,Art,AIart,Weather,#{@city&.name},#{@city&.country&.name}",
|
||||
image: url_for(@city&.latest_weather_art&.webp_image&.processed)
|
||||
%>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -99,4 +120,5 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
74
app/views/shared/_share_social.html.erb
Normal file
74
app/views/shared/_share_social.html.erb
Normal file
@ -0,0 +1,74 @@
|
||||
<!-- app/views/shared/_share_social.html.erb -->
|
||||
<div class="card bg-base-100 p-4 rounded-2xl shadow-xl overflow-hidden"
|
||||
data-controller="share">
|
||||
<h3 class="font-display text-base font-medium center mb-4">Share This Page</h3>
|
||||
|
||||
<div class="flex flex-wrap gap-4 justify-center">
|
||||
<!-- Facebook -->
|
||||
<button class="btn btn-primary"
|
||||
data-sharer="facebook"
|
||||
data-title="<%= title %>"
|
||||
data-url="<%= request.original_url %>">
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M9 8h-3v4h3v12h5v-12h3.642l.358-4h-4v-1.667c0-.955.192-1.333 1.115-1.333h2.885v-5h-3.808c-3.596 0-5.192 1.583-5.192 4.615v3.385z"/>
|
||||
</svg>
|
||||
Facebook
|
||||
</button>
|
||||
|
||||
<!-- Twitter/X -->
|
||||
<button class="btn btn-info"
|
||||
data-sharer="twitter"
|
||||
data-title="<%= title %>"
|
||||
data-hashtags=<%= tags %>
|
||||
data-url="<%= request.original_url %>">
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
|
||||
</svg>
|
||||
Twitter
|
||||
</button>
|
||||
|
||||
<!-- LinkedIn -->
|
||||
<button class="btn btn-secondary"
|
||||
data-sharer="linkedin"
|
||||
data-url="<%= request.original_url %>">
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
|
||||
</svg>
|
||||
LinkedIn
|
||||
</button>
|
||||
|
||||
<!-- Pinterest -->
|
||||
<button class="btn btn-accent"
|
||||
data-sharer="pinterest"
|
||||
data-url="<%= request.original_url %>"
|
||||
data-image="<%= image %>"
|
||||
data-description="<%= description %>">
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 0c-6.627 0-12 5.372-12 12 0 5.084 3.163 9.426 7.627 11.174-.105-.949-.2-2.405.042-3.441.218-.937 1.407-5.965 1.407-5.965s-.359-.719-.359-1.782c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738.098.119.112.224.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.631-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146 1.124.347 2.317.535 3.554.535 6.627 0 12-5.373 12-12 0-6.628-5.373-12-12-12z"/>
|
||||
</svg>
|
||||
Pinterest
|
||||
</button>
|
||||
|
||||
<!-- WhatsApp -->
|
||||
<button class="btn btn-success"
|
||||
data-sharer="whatsapp"
|
||||
data-title="<%= title %>"
|
||||
data-url="<%= request.original_url %>">
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413Z"/>
|
||||
</svg>
|
||||
WhatsApp
|
||||
</button>
|
||||
|
||||
<!-- Telegram -->
|
||||
<button class="btn btn-info"
|
||||
data-sharer="telegram"
|
||||
data-title="<%= title %>"
|
||||
data-url="<%= request.original_url %>">
|
||||
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z"/>
|
||||
</svg>
|
||||
Telegram
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
@ -94,6 +94,29 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<%
|
||||
# 构建更吸引人的分享标题
|
||||
share_title = [
|
||||
"🎨 Amazing AI Weather Art: #{@weather_art.city.full_name}",
|
||||
"#{@weather_art.description} at #{@weather_art.temperature}°C",
|
||||
"#{@weather_art.formatted_time(:all, true)}"
|
||||
].join("\n")
|
||||
|
||||
# 构建更有描述性的分享描述
|
||||
share_description = [
|
||||
"Discover this stunning AI-generated weather art!",
|
||||
"#{@weather_art.description} in #{@weather_art.city.full_name}.",
|
||||
"Created at #{@weather_art.formatted_time(:time, true)}",
|
||||
"Visit TodayAIWeather to see more amazing weather art."
|
||||
].join(" ")
|
||||
%>
|
||||
<%= render "shared/share_social",
|
||||
title: share_title,
|
||||
description: share_description,
|
||||
tags: "AIWeather,Art,AIart,Weather,#{@weather_art.city&.name},#{@weather_art&.city&.country&.name}",
|
||||
image: url_for(@weather_art.webp_image.processed)
|
||||
%>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -23,6 +23,7 @@
|
||||
"photoswipe": "^5.4.4",
|
||||
"postcss": "^8.5.1",
|
||||
"sass": "^1.83.4",
|
||||
"sharer.js": "^0.5.2",
|
||||
"tailwindcss": "^3.4.17"
|
||||
}
|
||||
}
|
||||
|
@ -1265,6 +1265,11 @@ serialize-to-js@^3.1.2:
|
||||
resolved "https://registry.yarnpkg.com/serialize-to-js/-/serialize-to-js-3.1.2.tgz#844b8a1c2d72412f68ea30da55090b3fc8e95790"
|
||||
integrity sha512-owllqNuDDEimQat7EPG0tH7JjO090xKNzUtYz6X+Sk2BXDnOCilDdNLwjWeFywG9xkJul1ULvtUQa9O4pUaY0w==
|
||||
|
||||
sharer.js@^0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/sharer.js/-/sharer.js-0.5.2.tgz#68926277a4186384f98c8328d4cbd424d7d42aaa"
|
||||
integrity sha512-HdwWYNSP+dJjCV5ogUOhKO7SormXamWC/00ThEcZMDBVuhsQ2/P0lBv/HYQ8jf5NxwxN/wad4YWEMPsfqlGecA==
|
||||
|
||||
shebang-command@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
|
||||
|
Loading…
Reference in New Issue
Block a user