1. 17 Jul, 2025 2 commits
  2. 15 Jul, 2025 13 commits
    • refactor: layout logic to enhance front-end responsiveness · 31adc393
      Merge pull request #1377 from QuantumNous/refactor/layout
      同語 committed
    • 🧹 refactor(PageLayout): remove unused state variables · bf6e1bed
      Removed unused `userState` and `statusState` bindings from `PageLayout.js`
      while retaining their dispatch functions for authentication and status
      management. Confirmed correct use of array destructuring to skip the
      unused toggle function returned by `useSidebarCollapsed`.
      
      This change introduces no functional differences and solely improves
      readability and maintainability.
      t0ng7u committed
    • 🐛 fix: SSR hydration mismatch in mobile detection & clean up sidebar style · 409a3eac
      - Added a server-snapshot fallback (`() => false`) to `useIsMobile` to ensure
        consistent results between server-side rendering and the browser, preventing
        hydration mismatches.
      - Removed a redundant ternary in `PageLayout` sidebar styles, replacing
        `isMobile ? 'fixed' : 'fixed'` with a single `'fixed'` value for clarity.
      
      These changes improve SSR reliability and tidy up inline styles without
      affecting runtime functionality.
      t0ng7u committed
    • 🎨 feat(sidebar): replace custom collapse button with Semi UI Button · 94e0c0d8
      * Replaced the handmade collapse/expand div with Semi UI `<Button>`
        * Uses `theme="outline"` and `type="tertiary"` for outlined style
        * Shows icon + text when sidebar is expanded, icon-only when collapsed
      * Added `iconOnly` prop and dynamic padding to remove extra text area in collapsed state
      * Ensured full-width layout with consistent padding for both states
      * Updated imports to include `Button` from `@douyinfe/semi-ui`
      * Maintains tooltip content for accessibility and better UX
      t0ng7u committed
    • ️ refactor(auth, ui): simplify Loading component & optimize OAuth2Callback flow · 7ee3a7d6
      * Removed `prompt` prop from `Loading` and switched to built-in Spin indicator with default size `small`
      * Dropped overlay background to make the spinner more reusable
      * Replaced custom text span; callers can now supply tip via their own UI if needed
      * Cleaned up `OAuth2Callback`:
        - Eliminated unused state/variables
        - Added MAX_RETRIES with incremental back-off
        - Centralized error handling via try/catch
        - Streamlined navigation logic on success/failure
        - Updated imports to match new Loading signature
      
      BREAKING CHANGE: `Loading` no longer accepts a `prompt` prop. Update all invocations accordingly.
      t0ng7u committed
    • feat(HeaderBar): ensure skeleton shows ≥500 ms and waits for real status data · a3f098c5
      The header’s skeleton screen now remains visible for at least 500 ms and
      only disappears after `/api/status` has successfully populated
      `StatusContext`.
      
      Changes include:
      • Added `loadingStartRef` to record the mount time.
      • Reworked loading effect to compute the remaining delay based on the
        elapsed time and the presence of real status data.
      • Removed the previous fixed‐timer logic, preventing premature content
        rendering and improving perceived loading consistency across pages.
      t0ng7u committed
    • 📱 feat(ui): auto-close sidebar on mobile after menu navigation · c4718a1e
      Adds a smoother mobile experience by automatically closing the sidebar
      drawer once a menu item is tapped.
      
      ### Details
      * SiderBar
        * Introduce `onNavigate` prop and invoke it on every `<Link>` click.
        * Remove unused `useIsMobile` hook and related `isMobile` variable.
      * PageLayout
        * Pass `onNavigate` callback to `SiderBar` that sets `drawerOpen` to
          `false` when on mobile, ensuring the sidebar collapses after
          navigation.
      
      This eliminates the “isMobile declared but never used” warning and
      aligns the behaviour of the sidebar with common mobile UX expectations.
      t0ng7u committed
    • 💄 style(layout): add horizontal padding to top-offset divs for consistent spacing · 527b9966
      Replaced every instance of
      <div className="mt-[64px]">
      with
      <div className="mt-[64px] px-2">
      to provide uniform horizontal padding across pages. No functional changes—visual layout improvement only.
      t0ng7u committed
    • 🖌️ feat(ui): always show colorful console banner for NewAPI in every environment · eab06767
      Add a branded console log to `web/src/index.js` that prints:
      
      “We  NewAPI  Github: https://github.com/QuantumNous/new-api”
      
      Changes include:
      • Remove the `NODE_ENV` guard so the banner appears in both development and production.
      • Increase font size to 24 px and keep “NewAPI” in bold green for stronger branding.
      
      This is a purely visual/developer-experience enhancement—no runtime behavior is affected.
      t0ng7u committed
    • 🔧 chore(router): enable React Router v7 future flags to suppress warnings · 9c36aaa2
      Add `future` prop to `BrowserRouter` in `web/src/index.js` with
      `v7_startTransition` and `v7_relativeSplatPath` turned on.
      This opts the app into upcoming React Router v7 behavior, removes
      console warnings, and readies the codebase for a smoother future upgrade.
      
      No runtime behavior changes; developer-experience improvement only.
      t0ng7u committed
    • 📱 refactor(web): remove legacy isMobile util and migrate to useIsMobile hook · edb4f2f6
      BREAKING CHANGE:
      helpers/utils.js no longer exports `isMobile()`.
      Any external code that relied on this function must switch to the `useIsMobile` React hook.
      
      Summary
      -------
      1. Deleted the obsolete `isMobile()` function from helpers/utils.js.
      2. Introduced `MOBILE_BREAKPOINT` constant and `matchMedia`-based detection for non-React contexts.
      3. Reworked toast positioning logic in utils.js to rely on `matchMedia`.
      4. Updated render.js:
         • Removed isMobile import.
         • Added MOBILE_BREAKPOINT detection in `truncateText`.
      5. Migrated every page/component to the `useIsMobile` hook:
         • Layout: HeaderBar, PageLayout, SiderBar
         • Pages: Home, Detail, Playground, User (Add/Edit), Token, Channel, Redemption, Ratio Sync
         • Components: ChannelsTable, ChannelSelectorModal, ConflictConfirmModal
      6. Purged all remaining `isMobile()` calls and legacy imports.
      7. Added missing `const isMobile = useIsMobile()` declarations where required.
      
      Benefits
      --------
      • Unifies mobile detection with a React-friendly hook.
      • Eliminates duplicated logic and improves maintainability.
      • Keeps non-React helpers lightweight by using `matchMedia` directly.
      t0ng7u committed
    • 🚀 feat(frontend): add robust boolean handling across settings pages · 0480d43b
      Summary
      -------
      1. Introduced a reusable `toBoolean` utility (`web/src/helpers/boolean.js`) that converts
         strings (`'true'/'false'`, `'1'/'0'`), numbers, and native booleans to a proper boolean.
      2. Re-exported `toBoolean` via `web/src/helpers/index.js` for simple one-line imports.
      
      Refactors
      ---------
      • Systematically replaced all legacy `item.value === 'true'` checks with `toBoolean(item.value)` in
        the following components:
        – `SystemSetting.js`
        – `OperationSetting.js`
        – `PaymentSetting.js`
        – `RatioSetting.js`
        – `RateLimitSetting.js`
        – `ModelSetting.js`
        – `DrawingSetting.js`
        – `DashboardSetting.js`
        – `ChatsSetting.js`
      
      • Unified import statements to
        `import { …, toBoolean } from '../../helpers';`
        removing redundant `../../helpers/boolean` paths.
      
      Why
      ---
      SQLite sometimes returns `1/0` or boolean literals instead of the string `'true'/'false'`, causing
      checkbox states to reset on page reload. The new utility guarantees consistent boolean parsing,
      fixing the issue across all environments (SQLite, MySQL, etc.) while improving code clarity.
      t0ng7u committed
    • 🐛 fix: multi-key channel sync and Vertex-AI key-upload edge cases · 3425b6eb
      Backend
      1. controller/channel.go
         • Always hydrate `ChannelInfo` from DB in `UpdateChannel`, keeping `IsMultiKey` true so `MultiKeySize` is recalculated.
      
      2. model/channel.go
         • getKeys(): accept both newline-separated keys and JSON array (`[ {...}, {...} ]`).
         • Update(): reuse new parser-logic to recalc `MultiKeySize`; prune stale indices in `MultiKeyStatusList`.
      
      Frontend
      1. pages/Channel/EditChannel.js
         • `handleVertexUploadChange`
           – Reset `vertexErroredNames` on every change so the “ignored files” prompt always re-appears.
           – In single-key mode keep only the last file; in batch mode keep all valid files.
           – Parse files, display “以下文件解析失败,已忽略:…”.
         • Batch-toggle checkbox
           – When switching from batch→single while multiple files are present, show a confirm dialog and retain only the first file (synchronises state, form and local caches).
         • On opening the “new channel” side-sheet, clear `vertexErroredNames` to restore error prompts.
      
      Result
      • “已启用 x/x” count updates immediately after editing multi-key channels.
      • Vertex-AI key upload works intuitively: proper error feedback, no duplicated files, and safe down-switch from batch to single mode.
      t0ng7u committed
  3. 14 Jul, 2025 11 commits
  4. 13 Jul, 2025 12 commits
    • 🎨 feat(ui): Enhance model dropdowns with icons in Token & Channel editors · 3df78868
      Summary
      • Added visual model icons to dropdown options in both Token (`EditToken.js`) and Channel (`EditChannel.js`) editors.
      
      Details
      1. Token Editor
         - Imported `getModelCategories` from helpers.
         - Re-built Model Limits option list to prepend the matching icon to each model label.
      
      2. Channel Editor
         - Imported `getModelCategories`.
         - Extended model‐option construction to include icons, unifying behaviour with Token editor.
         - Maintained existing logic for merging origin options and user-selected models.
      
      Benefits
      • Provides immediate visual identification of model vendors.
      • Aligns UX with existing icon usage across the application, improving consistency and clarity.
      • No functional changes to data handling; purely UI/UX enhancement.
      
      Co-authored-by: [Your Name]
      t0ng7u committed
    • 💄 feat(ui): Enhance TokensTable quota presentation and clean up code · 7731a020
      Summary
      • Re-architect the status column to embed quota information directly inside the Tag suffix.
      • Consolidate rendering logic for clearer structure and easier maintenance.
      
      Details
      • Moved the quota Progress bar under the remaining / total text, inside `quotaSuffix`.
      • Added “Unlimited” label for tokens with `unlimited_quota`; hides Progress and Tooltip in this case.
      • Tightened vertical spacing with a flex container (`gap-[2px]`, `leading-none`) and removed extra wrappers; Progress now has zero top/bottom margin and full-width style.
      • Refactored variables:
        – Replaced `tagNode/bodyContent` with a single `content` node.
        – Wrapped `content` with Tooltip only when quota is limited.
      • Visual tweaks:
        – Applied `size='large'` to the Tag for better alignment.
        – Ensured consistent color via shared `getProgressColor`.
      • Deleted obsolete comments and redundant code.
      
      Result
      Improves readability of the component and delivers a cleaner, more compact quota display.
      t0ng7u committed
    • 🔍 feat(edit-token): add search capability to model limit selector · 301c78d9
      Changes:
      • `Form.Select` for “Model Limits” now supports in-dropdown searching (`filter` + `searchPosition='dropdown'`) enabling quick model lookup.
      • Removed `maxTagCount` to display all selected models without truncation.
      
      Benefit: simplifies selecting specific models when the list is large, improving usability during token creation/editing.
      t0ng7u committed
    • 🎨 style(tokens-table): enhance quota usage progress bar UI · ac5f028d
      Improves the “Balance” column in `TokensTable`:
      
      • Re-styled progress bar: wider container (`w-[140px]`) and `showInfo` enabled to display percentage label.
      • Added `format={() => \`\${percent}%\`}` for precise percentage feedback.
      • Maintains dynamic color mapping (success / warning / danger) for clarity.
      
      Result: clearer, more informative visual representation of remaining token quota.
      t0ng7u committed
    • 🔄 fix(tables): keep current page after edits & auto-fallback when page becomes empty · c2448377
      Includes ChannelsTable, RedemptionsTable and UsersTable:
      
      • Refactor `refresh(page = activePage)` in all three tables so data reloads the requested (or current) page instead of forcing page 1.
      • On single-row deletion (and bulk deletion in ChannelsTable):
        – Refresh current page immediately.
        – If the refreshed page has no data and `activePage > 1`, automatically load the previous page to avoid blank views.
      • RedemptionsTable: corrected prior bug where `refresh` used `activePage - 1`.
      • Misc: removed outdated inline comments and aligned search / reset flows.
      
      Result: smoother UX—users stay on their working page, and pagination gracefully adjusts after deletions.
      t0ng7u committed
    • feat(tokens-table): show “Other” avatar for models without vendor logo · 5a92a5fe
      Adds UI fallback in TokensTable “Available Models” column:
      • Tracks models already matched to a known vendor icon.
      • Collects unmatched models and renders a neutral “Other” avatar (labelled via `t('其他')`) with a tooltip listing the model names.
      • Removes previous generic fallback so every model is now either vendor-specific or grouped under “Other”.
      
      This improves clarity for users by explicitly indicating models from unrecognized providers rather than leaving them unlabelled.
      t0ng7u committed
    • 🔄 update: add bun.lock file copy to Dockerfile for dependency management · a2f7c876
      - Included the `bun.lock` file in the Dockerfile to ensure consistent dependency installation during the build process.
      CaIon committed
    • 🔄 update: downgrade several Babel and Astro dependencies in bun.lock · 706df56e
      - Updated `@astrojs/compiler`, `@babel/code-frame`, `@babel/compat-data`, `@babel/core`, `@babel/generator`, `@babel/helper-compilation-targets`, `@babel/helper-define-polyfill-provider`, `@babel/helper-module-imports`, `@babel/helper-module-transforms`, `@babel/plugin-transform-runtime`, `@babel/runtime`, and other related packages to earlier versions to ensure compatibility and stability.
      - Adjusted various dependencies within the `bun.lock` file to reflect these changes.
      CaIon committed
    • feat: add bun.lock file to manage dependencies and remove bun.lockb · 4af505e6
      - Introduced a new `bun.lock` file to track project dependencies and their versions.
      - Deleted the outdated `bun.lockb` file to streamline dependency management.
      CaIon committed
  5. 12 Jul, 2025 2 commits
    • 🎨 refactor: TokensTable UI for clearer quota info & compact controls · c39b3cfe
      • Display remaining-quota percentage instead of used-quota in the Progress indicator
        - 100 % when quota is untouched, shown in green
        - Warn at ≤ 30 % (yellow) and at ≤ 10 % (red)
        - Hide internal label (`showInfo={false}`) and move the percentage text into the Tooltip
        - Switch Progress `size` to `small` for a lighter visual footprint
      
      • Update Tooltip to list used, remaining, total quota and the new percentage value
      
      • Uniformly set `size="small"` on all header Buttons and Form inputs within the table
        — enhances readability and keeps the main content centered
      
      UI/UX improvement only; no backend logic affected.
      t0ng7u committed
    • 🚑 fix: safeguard `NewAPIError.Error()` against nil pointer panic · 1eb07211
      Backend
      • `types/error.go`
        – Return empty string when receiver itself is `nil`.
        – If `Err` is `nil`, fall back to `errorCode` string to avoid calling `nil.Error()`.
      
      This prevents runtime panics when the error handler builds an OpenAI-style error response but the underlying `Err` field has not been set.
      t0ng7u committed