122 Commits
Author SHA1 Message Date
Claude 96525d2fc7 Chore: trim the branch — leftovers, redundancy, comments
A pass over every file the branch touched, after the iOS animation hunt
left tries and reverts behind it. Removed what nothing reaches: the
view-transition rule for a transition no code starts, an unreachable
guard in the transition hook, a no-op KeepAlive key branch, a sign-in
guard the menu already enforces, usage-dialog wrappers that only
forwarded to the store, a duplicated modifier-click check and card
filter (isPlainClick / listedTools), a test that hand-rolled
listedTools, a drawer-era fixture parameter. auth-flow.js folded into
auth-redirect.js. Comments cut to what the code cannot say itself —
file headers of a few lines, the measured iOS reasons, non-obvious
orderings — and stale ones fixed (Nav under KeepAlive, Home.vue
reusing DEFAULT_META, "from Nav", enabledCards). AGENTS.md sections
tightened to the code as it is now.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GbLTGMZ45MV78qd2tHoco
2026-10-05 16:50:16 +00:00
Claude 34d69f8ec9 Fix(pwa): keep the iOS status bar opaque in the installed app
Since iOS 26 the system draws its Liquid Glass scroll-edge blur over
the top of a Home Screen web app whose page runs under the status bar,
which black-translucent asked for, and the blur covered the Nav. With
no apple-mobile-web-app-status-bar-style the status bar stays opaque
system chrome above the web view; the strip Nav.vue painted under a
translucent one goes with it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GbLTGMZ45MV78qd2tHoco
2026-10-05 16:06:07 +00:00
Claude f0d27fe510 Refactor(nav): one navigation bar on every route, breadcrumb in the page
The homepage sections and the advanced tools are peers, so every route
shows the same Nav, rendered once from App.vue alongside the User and
Preferences hosts. What differs is the click: on the homepage a section
link scrolls; elsewhere it navigates home and then scrolls, re-aiming
while the freshly mounted homepage still resizes; an advanced tool
entry opens /tools/<slug> from anywhere (utils/nav-target.js +
composables/use-nav-target.js). The slim page header, its tools menu
and the body padding switch it needed are gone; open sheets close on a
route change.

Tool pages, /privacy and /r/:id carry a breadcrumb above their title
(PageBreadcrumb.vue): Home steps back in history when the homepage is
the previous entry, Advanced Tools goes home to the cards, the current
page is the last crumb. Cards use an arrow instead of the drawer icon.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GbLTGMZ45MV78qd2tHoco
2026-10-05 14:43:20 +00:00
Claude 2f5d3b426b Feat(tools): open the Advanced Tools as pages
Every way into a tool — the homepage cards, the nav dropdown and mobile
sheet, the keyboard shortcuts, ASN Info's profile link, the banners —
navigates to /tools/<slug>; the bottom drawer, its full-screen toggle
and the ?tool= query it was driven by are gone from Advanced.vue. The
pages stay alive (App.vue / ToolPage.vue), so browser back and forward
move between tools and the homepage, each restored as it was left.

Legacy /?tool=<slug> links redirect to the page in a router beforeEach
(utils/legacy-tool-link.js: known slug → its page with the remaining
query, unknown → the homepage). Persona Check drops noStandalone: with
the homepage kept alive its dependency commands stay registered, so the
page dispatches them in place and only a direct visit navigates home
first. The four sign-in tools no longer close a drawer before opening
the usage dialog, which PageHeader's User hosts.

Changelog entries in the six full locales; frontend/AGENTS.md describes
the page model.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GbLTGMZ45MV78qd2tHoco
2026-10-05 14:25:02 +00:00
Claude 728dd7d087 Refactor(nav): shared page header with tools and account menus
The pages outside the homepage (/tools/:slug, /privacy, /r/:id) get one
PageHeader: a back button that steps back in history when the previous
entry is the homepage (restoring the kept-alive page and its scroll) and
pushes / otherwise (utils/back-target.js), the brand, a tools menu
grouped by category (ToolsMenu.vue, over listedTools() in
utils/tool-availability.js) so a tool can be switched without going
home, the current page's title, and the account menu. Below `sm` the
row keeps the back arrow, the title and icon triggers.

The account menu is UserMenu.vue, extracted from Nav.vue, which keeps
its look; the header also hosts User and Preferences so sign-in,
benefits & usage and the preferences sheet work on every page. Each
Preferences instance opens only on the page on screen and closes when
its page is left; My Achievements off the homepage navigates home first.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GbLTGMZ45MV78qd2tHoco
2026-10-05 14:10:34 +00:00
jason5ng32 076a9e36d8 Improvements 2026-10-03 22:42:22 +08:00
jason5ng32andClaude Fable 5 00b21a73b0 Feat(i18n): promote Brazilian Portuguese to full locale status
- flip pt-BR to status:'full' in the locale registry
- add pt-BR boot-screen quips and slow hint to index.html, and list it
  in the JSON-LD inLanguage
- fill the productivity import-list name that landed after the pt-BR pack
- swap TRANSLATING.md's new-language walkthrough example to es-MX now
  that pt-BR is a real full locale

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-26 09:30:12 +08:00
jason5ng32andClaude Fable 5 eb16afb539 Feat(i18n): promote Traditional Chinese to full
Backfill zh-TW across all 163 changelog entries with Taiwan terminology
aligned to the UI pack, flip the registry status to full and group the
locale under Simplified Chinese as plain 繁體中文, add the zh-TW boot
copy index.html requires of full locales, and update the full-locale
enumerations in the contributor docs (including the stale 161-entry
changelog count).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 00:15:14 +08:00
jason5ng32andClaude Fable 5 084fe65eaa Feat(i18n): hold index.html's inline copy to the locale registry
index.html can't import the registry, so its boot quips, JSON-LD and
inline language pick have always been synced by hand. A new spec now
holds them to it: full locales must cover the boot copy (beta ones are
exempt), JSON-LD inLanguage mirrors the full locales' htmlLang — fixing
the imprecise "zh" — and a sentinel evaluates the inline matcher against
matchLocale so the two can't drift apart silently. The inline pick
itself gains the same exact/base/family steps, closing the split where
?hl=zh-CN booted in one language and mounted in another.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 21:17:20 +08:00
Jason Hiddle cd621c1a1f Try to fix scrolling bug 2026-08-20 09:29:08 +08:00
jason5ng32 87b085fc02 Improvements 2026-08-06 21:48:30 +08:00
jason5ng32andClaude Fable 5 55286689af Replace the Turkish locale with Russian
GA shows <10 daily Turkish-language visitors after years of a native
UI, while ~100 Russian-language visitors show the longest engagement
on the site despite seeing English. Swap keeps the maintenance surface
at four locales. Stored lang=tr preferences fall back gracefully, and
MaxMind natively carries ru geo names (it never had tr ones).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 02:10:31 +08:00
jason5ng32 a356d04af7 Improve mount speed 2026-07-16 12:04:12 +08:00
jason5ng32 922ac2f2e6 Improvements 2026-07-08 23:12:59 +08:00
jason5ng32 055922993f Improvements 2026-07-08 23:08:02 +08:00
jason5ng32 af5c03d43f Improvements 2026-06-15 09:23:18 +08:00
jason5ng32andClaude Opus 4.8 dea0cc157e Feat(advanced-tools): standalone /tools/:slug pages + history routing
Advanced tools can now be opened two ways: the existing in-page drawer, and
a real standalone page at /tools/:slug (shareable, crawlable, new-tab-able).
Same tool components render in both; only the wrapper differs.

- Router moves to HTML5 history mode: `/` → Home.vue, `/tools/:slug` →
  StandaloneTool.vue. The drawer is now driven by a `?tool=<slug>` query on the
  home route instead of a nested route, so ⌘/Ctrl-click, middle-click and the
  drawer-header ↗ open the standalone page.
- App.vue is now a thin shell (tooltip / toast / PWA / theme + <router-view>);
  the homepage body moved to the new Home.vue.
- Legacy hash links are preserved: main.js rewrites `/#/whois` → `/?tool=whois`
  (and `/#/` → `/`) before the router resolves, so old bookmarks still work.
- Standalone pages drop the homepage's fixed-Nav body padding via a
  `body.jn-standalone-page` class toggled on the `/tools/:slug` route.
- MtrTest / GlobalLatencyTest depend on store.allIPs (populated by the
  homepage). On a standalone page that's empty, so they now fall back to a
  validated free-form IP input when no known IPs exist.
- Shortcuts updated to openTool(slug) / data-adv-slug / isToolOpen; tests and
  frontend/AGENTS.md updated to match.

Note: the server-side SPA fallback (so pnpm start / prod serve /tools/*) and
per-route meta land in the next change; dev / preview already have fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 13:00:19 +08:00
jason5ng32 fccd320e68 UI Improvements 2026-05-27 11:34:37 +08:00
jason5ng32andClaude Opus 4.7 1752576374 Feat(mobile): scroll-hide nav, iOS PWA safe-area painter, theme refactor
- Nav slides up on scroll-down / down on scroll-up on mobile, with
  threshold + top-of-page protection
- iOS PWA: apple-mobile-web-app-status-bar-style=black-translucent +
  fixed-position safe-area painter in Nav, driven by --page-bg CSS var.
  Works around WebKit's refusal to honor JS theme-color updates and
  media-variant theme-color tags in standalone PWA mode.
- Sheet + Drawer primitives now respect safe-area-inset via inline
  padding (top/left/right get inset-top; bottom gets inset-bottom)
- Extract theme orchestration from Preferences.vue into use-theme.js
  composable mounted at App root — Preferences is now pure UI
- Align page-bg color literals across style.css (--page-bg),
  index.html (html bg + meta theme-color), and manifest.webmanifest

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 01:10:35 +08:00
jason5ng32andClaude Opus 4.7 853d5e0aa9 Improvements
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 01:11:37 +08:00
jason5ng32 28990302a4 Improvements 2026-05-15 00:25:58 +08:00
jason5ng32 582a888571 Improvements 2026-05-15 00:01:46 +08:00
jason5ng32andClaude Opus 4.7 bff8466885 Feat(boot): staged pre-Vue overlay hand-off with scale animation
Fixed overlay (position: fixed) avoids mobile 100vh scrollbars, and
App.vue hands off in three stages — text fade, logo shrink, then
reveal #app with a scale-in — instead of display:none'ing the boot
screen instantly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 10:55:53 +08:00
jason5ng32 df9c7e0ba2 UI Improvement 2026-04-19 20:12:44 +08:00
jason5ng32andClaude Sonnet 4.5 64657cd311 Fix(theme): dark/light mode no longer splits when system scheme differs from user choice
Two overlapping bugs:

1. In Preferences.vue, the old handleThemeChange read
   `userPreferences.theme` and then called `store.setDarkMode` + class
   toggles, but `prefTheme('auto')` invoked it *before* persisting the
   newly-selected theme value, so switching to Auto could stick on the
   previous manual state. The refactor funnels every trigger (mount / OS
   flip / preference change) through a single `applyTheme()` that reads
   the current values and applies them once. A `watch` on the theme pref
   keeps the handler firing even if future code paths mutate it directly,
   and `onUnmounted` removes the matchMedia listener for cleanliness.

2. In index.html, the inline `<style>` had a
   `@media (prefers-color-scheme: dark) { html { background: #0a0a0a } }`
   override. That rule is gated strictly on the OS preference and ignores
   the `.dark` class that Tailwind (and Preferences.vue) use to control
   dark mode. With system=dark + user=light, Tailwind correctly flipped
   to light but the inline media query kept the `<html>` background
   painted dark — which then showed through every gap in the light-mode
   layout under the Sheet overlay, producing the UI in the report.

   Swap the media query for `html.dark { ... }` so the inline CSS now
   respects the same class-based switch. Seed that class before first
   paint via a short inline script at the top of `<head>` — reads
   `localStorage.userPreferences.theme`, falls back to
   `prefers-color-scheme` on auto, adds `.dark` if needed. This keeps the
   boot screen and the mounted app in agreement from frame 1 (no FOUC,
   no flash).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-19 15:39:35 +08:00
jason5ng32 c496acfe1f UI Improvements 2026-04-19 14:42:24 +08:00
jason5ng32andClaude Sonnet 4.5 bf50fc850c Refactor(index.html): modernize boot screen and prevent FOUC shake on first paint
The page shook on initial load because Tailwind v4 Preflight arrived after the
browser's first paint and invalidated the box model and text metrics the boot
screen had been drawn with:

  * body margin 8px → 0                           ≈ 8px shift up + left
  * *, ::before, ::after { box-sizing: border-box } ≈ .jn-spinner 28×28 → 20×20,
                                                      content below jumps up 8px
  * html line-height normal → 1.5                 ≈ every line grows 4-6px

Fix by mirroring the exact Preflight subset the boot screen depends on in an
inline <style>, so the stylesheet's arrival causes zero visual change. Also
reserves the scrollbar width up-front via `scrollbar-gutter: stable` so the
eventual app scrollbar never shifts the page sideways.

Other cleanup while here:
- Deduped viewport / favicon / title meta that had drifted into two copies.
- Dropped invalid SVG attrs (text-rendering, image-rendering) that applied to
  nothing.
- Moved the 12s "slow network" hint off `innerHTML = ...` onto a `<p hidden>`
  that simply flips `hidden = false` — same UX, no string parse, smaller XSS
  surface.
- Added a `<noscript>` fallback and ARIA labelling (role=status / aria-live /
  aria-hidden on the decorative logo / aria-label on the spinner).
- Boot screen tracks `prefers-color-scheme: dark` via media query so pre-Vue
  dark-mode users don't flash a white screen.
- Annotated the two DOM contracts (`#jn-loading`, `meta[name=theme-color]` +
  `meta[name=background-color]`) so future edits don't accidentally break
  `App.vue` / `Preferences.vue`.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-19 13:16:01 +08:00
jason5ng32 8438697b41 refactor(ui): Advanced rebuilt with shadcn Card + Sheet → vaul Drawer
Advanced Tools panel gets the modern treatment:

- The 9 tool tiles are shadcn <Card> with keyboard-shortcut-card jn-card
  markers; hover -translate-y-1.5; semantic tokens throughout; emoji
  hover lift+scale preserved as MyIP's playful signature
- Bottom Sheet (reka-ui) → vaul-vue Drawer: drag-to-close + body-scale
  iOS-like depth feeling
- Drawer wrapper turns off setBackgroundColorOnScale to avoid vaul's
  hard-coded black body bg breaking light mode
- Fullscreen toggle: added transition: transform + height mixed transition
- Advanced cards no longer participate in keyboard navigation (opening a
  sub-page has a different semantic than the homepage status cards)

Section header + note paragraph use the same class rhythm as the other
4 refactored modules; the tile labels, descriptions, and layout are
unified.
2026-04-17 17:23:10 +08:00
jason5ng32 2c25229762 build: migrate PWA to Serwist and Vite 8 2026-04-14 12:23:07 +08:00
jason5ng32 f3b29a1d23 Improvements 2025-01-28 10:47:16 +08:00
jason5ng32 841587472e Improvements 2025-01-28 10:44:53 +08:00
jason5ng32 70c1237110 Improvements 2025-01-27 20:46:44 +08:00
jason5ng32 83d0020207 Improvements 2024-11-08 01:46:44 +08:00
jason5ng32 d20c7f7434 Update index.html 2024-11-08 01:38:53 +08:00
jason5ng32 03748227a0 Improvements 2024-11-08 01:34:58 +08:00
jason5ng32 136ab2ec76 Improvements 2024-09-09 10:35:34 +08:00
jason5ng32 83948e9a30 Improvements 2024-05-17 11:08:33 +08:00
jason5ng32 62850429a5 Improvements 2024-05-15 01:50:59 +08:00
jason5ng32 4e6e5972e8 Structure improvements 2024-05-12 10:34:07 +08:00
jason5ng32 1b00197299 improvements 2024-04-01 10:10:56 +08:00
jason5ng32 f150a509b4 Merge branch 'main' of https://github.com/jason5ng32/MyIP 2024-03-07 15:52:07 +08:00
jason5ng32 67b75c5cbb Improvements 2024-03-07 15:51:35 +08:00
Jason Ng 571032893d Merge pull request #139 from jason5ng32/dev
Improvements
2024-03-07 15:50:49 +08:00
jason5ng32 234484943d Update index.html 2024-03-07 15:49:49 +08:00
jason5ng32 a27dc2dfd2 Improvements 2024-03-06 10:04:38 +08:00
jason5ng32 ff31a7bc0c Bug fixed 2024-02-21 22:13:23 +08:00
jason5ng32 24dc59fe2a UX Improvements 2024-02-05 12:52:31 +08:00
jason5ng32 3cf467d957 PWA Improvements 2024-01-30 10:22:45 +08:00
jason5ng32 8a7d94f180 Bug Fixed 2024-01-27 22:42:37 +08:00
jason5ng32 d2073ccdfe Version 3.0 2024-01-27 16:22:47 +08:00