diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 2b5c9432c..16c0188a9 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,5 +1,7 @@ # Pull Request Template +> ⚠️ **Please open this PR against the `dev` branch, not `main`.** All contributions go through `dev`; `main` only receives release merges. + ## Description Please include a summary of the change and which issue is fixed. @@ -10,6 +12,7 @@ Please include a summary of the change and which issue is fixed. - [ ] Documentation update ## Checklist: +- [ ] This PR targets the `dev` branch, not `main`. - [ ] I have followed the contribution guidelines. - [ ] My code follows the style guidelines of this project. - [ ] I have performed a self-review of my own code. diff --git a/AGENTS.md b/AGENTS.md index 5e74380ce..13219fa1e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -77,10 +77,15 @@ This project uses **pnpm** as its package manager (pinned via the `packageManage - **JavaScript only.** New files are `.js` / `.vue`; ` diff --git a/frontend/components/StandalonePageHeader.vue b/frontend/components/StandalonePageHeader.vue new file mode 100644 index 000000000..eb94f9095 --- /dev/null +++ b/frontend/components/StandalonePageHeader.vue @@ -0,0 +1,49 @@ + + + diff --git a/frontend/components/StandaloneTool.vue b/frontend/components/StandaloneTool.vue index d18927e25..fddb76761 100644 --- a/frontend/components/StandaloneTool.vue +++ b/frontend/components/StandaloneTool.vue @@ -4,31 +4,8 @@ component the drawer does, just inside a minimal page chrome instead of the homepage + drawer. -->
- -
-
- - - - IPCheck.ing - - - - - -
-
+ +
@@ -52,9 +29,7 @@ import { useI18n } from 'vue-i18n'; import { TOOL_BY_SLUG } from '@/data/tools.js'; import { useDocumentMeta } from '@/composables/use-document-meta.js'; import Footer from '@/components/Footer.vue'; -import brandIcon from '@/components/svgicons/Brand.vue'; -import { ArrowLeft } from '@lucide/vue'; -import { Button } from '@/components/ui/button'; +import StandalonePageHeader from '@/components/StandalonePageHeader.vue'; const { t } = useI18n(); const route = useRoute(); @@ -65,12 +40,12 @@ const toolComponent = computed(() => (tool.value ? defineAsyncComponent(tool.val // Per-tool head: localized title + description, self-referential canonical. useDocumentMeta(() => { - if (!tool.value) return {}; - return { - title: `${t(tool.value.titleKey)} · IPCheck.ing`, - description: t(tool.value.noteKey), - canonical: `${window.location.origin}/tools/${tool.value.slug}`, - }; + if (!tool.value) return {}; + return { + title: `${t(tool.value.titleKey)} · IPCheck.ing`, + description: t(tool.value.noteKey), + canonical: `${window.location.origin}/tools/${tool.value.slug}`, + }; }); // Unknown slug → bounce to the homepage rather than show an empty shell. diff --git a/frontend/components/WebRtcTest.vue b/frontend/components/WebRtcTest.vue index 7be3f0bfe..2da2b1754 100644 --- a/frontend/components/WebRtcTest.vue +++ b/frontend/components/WebRtcTest.vue @@ -46,7 +46,7 @@ + :class="textClass(toneOf(stun))" :data-mask="maskAttr(stun.ip)" />
@@ -125,6 +125,7 @@ import { Button } from '@/components/ui/button'; import { Card, CardContent } from '@/components/ui/card'; import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '@/components/ui/collapsible'; import { useStatusTone, ipFieldTone, isFieldPending as isFieldPendingShared } from '@/composables/use-status-tone.js'; +import { createMaskGate } from '@/composables/use-info-mask.js'; import { useMaxmind } from '@/composables/use-maxmind.js'; import { Play, MapPin, EthernetPort, Flower, Network, RotateCw, FileText, ChevronDown } from '@lucide/vue'; import { Icon } from '@iconify/vue'; @@ -135,6 +136,8 @@ import { INLINE_TIERS } from '@/composables/use-fit-text.js'; const { t } = useI18n(); const store = useMainStore(); const userPreferences = computed(() => store.userPreferences); +// Skip the info-mask blur on waiting/error placeholders (not a real IP). +const maskAttr = createMaskGate(t); const isSimpleMode = computed(() => userPreferences.value.simpleMode); const { dotClass, textClass } = useStatusTone(); const { lookupMaxmind } = useMaxmind(); diff --git a/frontend/components/advanced-tools/RuleTest.vue b/frontend/components/advanced-tools/RuleTest.vue index 7e5bb0eb5..10d1cb880 100644 --- a/frontend/components/advanced-tools/RuleTest.vue +++ b/frontend/components/advanced-tools/RuleTest.vue @@ -19,7 +19,8 @@ -

+

{{ test.url }}

@@ -31,8 +32,7 @@ - @@ -207,7 +207,7 @@ const checkAchievements = () => { }; onMounted(() => { - setTimeout(() => { checkAllRuleTest(); }, 1000); + setTimeout(() => { checkAllRuleTest(); }, 300); }); watch(IPArray, () => { diff --git a/frontend/components/ip-infos/IPCard.vue b/frontend/components/ip-infos/IPCard.vue index 7fb3e08ff..95a6ab754 100644 --- a/frontend/components/ip-infos/IPCard.vue +++ b/frontend/components/ip-infos/IPCard.vue @@ -11,17 +11,13 @@ {{ t('ipInfos.Source') }}: - {{ card.source }} + {{ card.source }}
- +