diff --git a/locales/ar.po b/locales/ar.po index 239878e..e9afa2c 100644 --- a/locales/ar.po +++ b/locales/ar.po @@ -188,3 +188,6 @@ msgstr "فشل البحث في قاعدة البيانات" msgid "Template render failed" msgstr "فشل عرض القالب" + +msgid "Copied" +msgstr "تم النسخ" diff --git a/locales/de.po b/locales/de.po index e21117d..286edd2 100644 --- a/locales/de.po +++ b/locales/de.po @@ -188,3 +188,6 @@ msgstr "Datenbankabfrage fehlgeschlagen" msgid "Template render failed" msgstr "Vorlagen-Rendering fehlgeschlagen" + +msgid "Copied" +msgstr "Kopiert" diff --git a/locales/en.po b/locales/en.po index a1fe1bf..e552e65 100644 --- a/locales/en.po +++ b/locales/en.po @@ -188,3 +188,6 @@ msgstr "Database lookup failed" msgid "Template render failed" msgstr "Template render failed" + +msgid "Copied" +msgstr "Copied" diff --git a/locales/es.po b/locales/es.po index 7535d96..5eac1f7 100644 --- a/locales/es.po +++ b/locales/es.po @@ -188,3 +188,6 @@ msgstr "La consulta a la base de datos fallo" msgid "Template render failed" msgstr "La renderizacion de la plantilla fallo" + +msgid "Copied" +msgstr "Copiado" diff --git a/locales/fr.po b/locales/fr.po index 25a29a6..4eba0cd 100644 --- a/locales/fr.po +++ b/locales/fr.po @@ -188,3 +188,6 @@ msgstr "Echec de la recherche dans la base de donnees" msgid "Template render failed" msgstr "Echec du rendu du modele" + +msgid "Copied" +msgstr "Copie" diff --git a/locales/id.po b/locales/id.po index 6ee7410..7624459 100644 --- a/locales/id.po +++ b/locales/id.po @@ -188,3 +188,6 @@ msgstr "Pencarian basis data gagal" msgid "Template render failed" msgstr "Render template gagal" + +msgid "Copied" +msgstr "Disalin" diff --git a/locales/it.po b/locales/it.po index d9a7614..d1691de 100644 --- a/locales/it.po +++ b/locales/it.po @@ -188,3 +188,6 @@ msgstr "Ricerca nel database fallita" msgid "Template render failed" msgstr "Rendering del template fallito" + +msgid "Copied" +msgstr "Copiato" diff --git a/locales/ja.po b/locales/ja.po index ae26169..91923e3 100644 --- a/locales/ja.po +++ b/locales/ja.po @@ -188,3 +188,6 @@ msgstr "データベース検索に失敗しました" msgid "Template render failed" msgstr "テンプレートのレンダリングに失敗しました" + +msgid "Copied" +msgstr "コピーしました" diff --git a/locales/ko.po b/locales/ko.po index e8c26ba..9742fe5 100644 --- a/locales/ko.po +++ b/locales/ko.po @@ -188,3 +188,6 @@ msgstr "데이터베이스 조회 실패" msgid "Template render failed" msgstr "템플릿 렌더링 실패" + +msgid "Copied" +msgstr "복사됨" diff --git a/locales/nl.po b/locales/nl.po index c346603..28669be 100644 --- a/locales/nl.po +++ b/locales/nl.po @@ -188,3 +188,6 @@ msgstr "Database-opzoeking mislukt" msgid "Template render failed" msgstr "Sjabloonweergave mislukt" + +msgid "Copied" +msgstr "Gekopieerd" diff --git a/locales/pt.po b/locales/pt.po index 9a42001..8691f19 100644 --- a/locales/pt.po +++ b/locales/pt.po @@ -188,3 +188,6 @@ msgstr "Falha na consulta ao banco de dados" msgid "Template render failed" msgstr "Falha na renderização do template" + +msgid "Copied" +msgstr "Copiado" diff --git a/locales/ru.po b/locales/ru.po index 133379d..7a340e4 100644 --- a/locales/ru.po +++ b/locales/ru.po @@ -188,3 +188,6 @@ msgstr "Ошибка поиска в базе данных" msgid "Template render failed" msgstr "Ошибка рендеринга шаблона" + +msgid "Copied" +msgstr "Скопировано" diff --git a/locales/zh-Hans.po b/locales/zh-Hans.po index d7a2faf..3ae8883 100644 --- a/locales/zh-Hans.po +++ b/locales/zh-Hans.po @@ -188,3 +188,6 @@ msgstr "数据库查询失败" msgid "Template render failed" msgstr "模板渲染失败" + +msgid "Copied" +msgstr "已复制" diff --git a/locales/zh-Hant.po b/locales/zh-Hant.po index 65c2cb7..a5608df 100644 --- a/locales/zh-Hant.po +++ b/locales/zh-Hant.po @@ -188,3 +188,6 @@ msgstr "資料庫查詢失敗" msgid "Template render failed" msgstr "範本渲染失敗" + +msgid "Copied" +msgstr "已複製" diff --git a/src/handlers.rs b/src/handlers.rs index 03b0e87..ce8bf56 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -100,6 +100,7 @@ struct IndexTemplate { t_footer_source: &'static str, t_footer_db: &'static str, t_footer_attribution: &'static str, + t_copied: &'static str, t_table_aria: &'static str, t_faq_aria: &'static str, t_nav_aria: &'static str, @@ -332,6 +333,7 @@ fn build_translations(locale: Locale) -> Translations { t_footer_attribution: i18n::translate(locale, "IP data provided by:"), t_error: i18n::translate(locale, "Error"), t_go_home: i18n::translate(locale, "Go to Home"), + t_copied: i18n::translate(locale, "Copied"), t_table_aria: i18n::translate(locale, "IP address information"), t_faq_aria: i18n::translate(locale, "Frequently Asked Questions"), t_nav_aria: i18n::translate(locale, "Project links"), @@ -391,6 +393,7 @@ struct Translations { t_footer_attribution: &'static str, t_error: &'static str, t_go_home: &'static str, + t_copied: &'static str, t_table_aria: &'static str, t_faq_aria: &'static str, t_nav_aria: &'static str, @@ -636,6 +639,7 @@ pub async fn root( t_footer_source: t.t_footer_source, t_footer_db: t.t_footer_db, t_footer_attribution: t.t_footer_attribution, + t_copied: t.t_copied, t_table_aria: t.t_table_aria, t_faq_aria: t.t_faq_aria, t_nav_aria: t.t_nav_aria, diff --git a/static/script.js b/static/script.js index 485227e..f26e672 100644 --- a/static/script.js +++ b/static/script.js @@ -136,3 +136,33 @@ if(!error.hidden)showError(validate(input.value)); }); })(); + +(function(){ + "use strict"; + var wrap=document.querySelector(".ip-copy-wrap"); + if(!wrap)return; + var h1=wrap.querySelector(".ip-display"); + var tooltip=wrap.querySelector(".ip-copied-tooltip"); + if(!h1||!tooltip||!navigator.clipboard)return; + var timer=0; + wrap.style.cursor="pointer"; + wrap.setAttribute("role","button"); + wrap.setAttribute("tabindex","0"); + + function copyIp(){ + var ip=h1.textContent.trim(); + navigator.clipboard.writeText(ip).then(function(){ + tooltip.hidden=false; + clearTimeout(timer); + timer=setTimeout(function(){tooltip.hidden=true;},1500); + }); + } + + wrap.addEventListener("click",copyIp); + wrap.addEventListener("keydown",function(e){ + if(e.key==="Enter"||e.key===" "){ + e.preventDefault(); + copyIp(); + } + }); +})(); diff --git a/static/style.css b/static/style.css index 39c7281..233e93f 100644 --- a/static/style.css +++ b/static/style.css @@ -136,6 +136,13 @@ main { } } +.ip-copy-wrap { + position: relative; + display: flex; + flex-direction: column; + align-items: center; +} + .ip-display { text-align: center; font-size: clamp(28px, 6vw, 42px); @@ -146,6 +153,22 @@ main { word-break: break-all; } +.ip-copied-tooltip { + font-size: 13px; + font-weight: 500; + color: #FFF; + background: var(--color-label); + padding: 4px 12px; + border-radius: 6px; + pointer-events: none; + animation: ip-tooltip-fade 1.5s ease-out; +} + +@keyframes ip-tooltip-fade { + 0%, 70% { opacity: 1; } + 100% { opacity: 0; } +} + .info-table { inline-size: 100%; border-collapse: collapse; diff --git a/templates/index.html b/templates/index.html index cddf19b..81417d9 100644 --- a/templates/index.html +++ b/templates/index.html @@ -145,7 +145,10 @@ {% include "_search_form.html" %}
-

{{ ip }}

+
+

{{ ip }}

+ +