mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-02-22 16:47:37 +00:00
refactor: Centralize platform mode detection using IS_PLATFORM constant; use token from Auth context in WebSocket connection
This commit is contained in:
@@ -63,3 +63,10 @@ export const CODEX_MODELS = {
|
|||||||
|
|
||||||
DEFAULT: 'gpt-5.2'
|
DEFAULT: 'gpt-5.2'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Environment Flag: Is Platform
|
||||||
|
* Indicates if the app is running in Platform mode (hosted) or OSS mode (self-hosted)
|
||||||
|
*/
|
||||||
|
export const IS_PLATFORM = import.meta.env.VITE_IS_PLATFORM === 'true';
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { X } from 'lucide-react';
|
import { X } from 'lucide-react';
|
||||||
import StandaloneShell from './StandaloneShell';
|
import StandaloneShell from './StandaloneShell';
|
||||||
|
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reusable login modal component for Claude, Cursor, and Codex CLI authentication
|
* Reusable login modal component for Claude, Cursor, and Codex CLI authentication
|
||||||
@@ -27,15 +28,13 @@ function LoginModal({
|
|||||||
const getCommand = () => {
|
const getCommand = () => {
|
||||||
if (customCommand) return customCommand;
|
if (customCommand) return customCommand;
|
||||||
|
|
||||||
const isPlatform = import.meta.env.VITE_IS_PLATFORM === 'true';
|
|
||||||
|
|
||||||
switch (provider) {
|
switch (provider) {
|
||||||
case 'claude':
|
case 'claude':
|
||||||
return isAuthenticated ? 'claude setup-token --dangerously-skip-permissions' : 'claude /exit --dangerously-skip-permissions';
|
return isAuthenticated ? 'claude setup-token --dangerously-skip-permissions' : 'claude /exit --dangerously-skip-permissions';
|
||||||
case 'cursor':
|
case 'cursor':
|
||||||
return 'cursor-agent login';
|
return 'cursor-agent login';
|
||||||
case 'codex':
|
case 'codex':
|
||||||
return isPlatform ? 'codex login --device-auth' : 'codex login';
|
return IS_PLATFORM ? 'codex login --device-auth' : 'codex login';
|
||||||
default:
|
default:
|
||||||
return isAuthenticated ? 'claude setup-token --dangerously-skip-permissions' : 'claude /exit --dangerously-skip-permissions';
|
return isAuthenticated ? 'claude setup-token --dangerously-skip-permissions' : 'claude /exit --dangerously-skip-permissions';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import CodexLogo from './CodexLogo';
|
|||||||
import LoginModal from './LoginModal';
|
import LoginModal from './LoginModal';
|
||||||
import { authenticatedFetch } from '../utils/api';
|
import { authenticatedFetch } from '../utils/api';
|
||||||
import { useAuth } from '../contexts/AuthContext';
|
import { useAuth } from '../contexts/AuthContext';
|
||||||
|
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||||
|
|
||||||
const Onboarding = ({ onComplete }) => {
|
const Onboarding = ({ onComplete }) => {
|
||||||
const [currentStep, setCurrentStep] = useState(0);
|
const [currentStep, setCurrentStep] = useState(0);
|
||||||
@@ -15,8 +16,7 @@ const Onboarding = ({ onComplete }) => {
|
|||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
|
|
||||||
const [activeLoginProvider, setActiveLoginProvider] = useState(null);
|
const [activeLoginProvider, setActiveLoginProvider] = useState(null);
|
||||||
const isPlatform = import.meta.env.VITE_IS_PLATFORM === 'true';
|
const [selectedProject] = useState({ name: 'default', fullPath: IS_PLATFORM ? '/workspace' : '' });
|
||||||
const [selectedProject] = useState({ name: 'default', fullPath: isPlatform ? '/workspace' : '' });
|
|
||||||
|
|
||||||
const [claudeAuthStatus, setClaudeAuthStatus] = useState({
|
const [claudeAuthStatus, setClaudeAuthStatus] = useState({
|
||||||
authenticated: false,
|
authenticated: false,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import SetupForm from './SetupForm';
|
|||||||
import LoginForm from './LoginForm';
|
import LoginForm from './LoginForm';
|
||||||
import Onboarding from './Onboarding';
|
import Onboarding from './Onboarding';
|
||||||
import { MessageSquare } from 'lucide-react';
|
import { MessageSquare } from 'lucide-react';
|
||||||
|
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||||
|
|
||||||
const LoadingScreen = () => (
|
const LoadingScreen = () => (
|
||||||
<div className="min-h-screen bg-background flex items-center justify-center p-4">
|
<div className="min-h-screen bg-background flex items-center justify-center p-4">
|
||||||
@@ -27,7 +28,7 @@ const LoadingScreen = () => (
|
|||||||
const ProtectedRoute = ({ children }) => {
|
const ProtectedRoute = ({ children }) => {
|
||||||
const { user, isLoading, needsSetup, hasCompletedOnboarding, refreshOnboardingStatus } = useAuth();
|
const { user, isLoading, needsSetup, hasCompletedOnboarding, refreshOnboardingStatus } = useAuth();
|
||||||
|
|
||||||
if (import.meta.env.VITE_IS_PLATFORM === 'true') {
|
if (IS_PLATFORM) {
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <LoadingScreen />;
|
return <LoadingScreen />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { WebglAddon } from '@xterm/addon-webgl';
|
|||||||
import { WebLinksAddon } from '@xterm/addon-web-links';
|
import { WebLinksAddon } from '@xterm/addon-web-links';
|
||||||
import '@xterm/xterm/css/xterm.css';
|
import '@xterm/xterm/css/xterm.css';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||||
|
|
||||||
const xtermStyles = `
|
const xtermStyles = `
|
||||||
.xterm .xterm-screen {
|
.xterm .xterm-screen {
|
||||||
@@ -55,10 +56,9 @@ function Shell({ selectedProject, selectedSession, initialCommand, isPlainShell
|
|||||||
if (isConnecting || isConnected) return;
|
if (isConnecting || isConnected) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const isPlatform = import.meta.env.VITE_IS_PLATFORM === 'true';
|
|
||||||
let wsUrl;
|
let wsUrl;
|
||||||
|
|
||||||
if (isPlatform) {
|
if (IS_PLATFORM) {
|
||||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
wsUrl = `${protocol}//${window.location.host}/shell`;
|
wsUrl = `${protocol}//${window.location.host}/shell`;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import ProjectCreationWizard from './ProjectCreationWizard';
|
|||||||
import { api } from '../utils/api';
|
import { api } from '../utils/api';
|
||||||
import { useTaskMaster } from '../contexts/TaskMasterContext';
|
import { useTaskMaster } from '../contexts/TaskMasterContext';
|
||||||
import { useTasksSettings } from '../contexts/TasksSettingsContext';
|
import { useTasksSettings } from '../contexts/TasksSettingsContext';
|
||||||
|
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||||
|
|
||||||
// Move formatTimeAgo outside component to avoid recreation on every render
|
// Move formatTimeAgo outside component to avoid recreation on every render
|
||||||
const formatTimeAgo = (dateString, currentTime, t) => {
|
const formatTimeAgo = (dateString, currentTime, t) => {
|
||||||
@@ -622,7 +623,7 @@ function Sidebar({
|
|||||||
<div className="md:p-4 md:border-b md:border-border">
|
<div className="md:p-4 md:border-b md:border-border">
|
||||||
{/* Desktop Header */}
|
{/* Desktop Header */}
|
||||||
<div className="hidden md:flex items-center justify-between">
|
<div className="hidden md:flex items-center justify-between">
|
||||||
{import.meta.env.VITE_IS_PLATFORM === 'true' ? (
|
{IS_PLATFORM ? (
|
||||||
<a
|
<a
|
||||||
href="https://cloudcli.ai/dashboard"
|
href="https://cloudcli.ai/dashboard"
|
||||||
className="flex items-center gap-3 hover:opacity-80 transition-opacity group"
|
className="flex items-center gap-3 hover:opacity-80 transition-opacity group"
|
||||||
@@ -673,7 +674,7 @@ function Sidebar({
|
|||||||
style={isPWA && isMobile ? { paddingTop: '16px' } : {}}
|
style={isPWA && isMobile ? { paddingTop: '16px' } : {}}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
{import.meta.env.VITE_IS_PLATFORM === 'true' ? (
|
{IS_PLATFORM ? (
|
||||||
<a
|
<a
|
||||||
href="https://cloudcli.ai/dashboard"
|
href="https://cloudcli.ai/dashboard"
|
||||||
className="flex items-center gap-3 active:opacity-70 transition-opacity"
|
className="flex items-center gap-3 active:opacity-70 transition-opacity"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React, { createContext, useContext, useEffect, useState } from 'react';
|
import React, { createContext, useContext, useEffect, useState } from 'react';
|
||||||
import { api } from '../utils/api';
|
import { api } from '../utils/api';
|
||||||
|
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||||
|
|
||||||
const AuthContext = createContext({
|
const AuthContext = createContext({
|
||||||
user: null,
|
user: null,
|
||||||
@@ -31,7 +32,7 @@ export const AuthProvider = ({ children }) => {
|
|||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (import.meta.env.VITE_IS_PLATFORM === 'true') {
|
if (IS_PLATFORM) {
|
||||||
setUser({ username: 'platform-user' });
|
setUser({ username: 'platform-user' });
|
||||||
setNeedsSetup(false);
|
setNeedsSetup(false);
|
||||||
checkOnboardingStatus();
|
checkOnboardingStatus();
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { createContext, useContext, useEffect, useRef, useState } from 'react';
|
import { createContext, useContext, useEffect, useRef, useState } from 'react';
|
||||||
|
import { useAuth } from './AuthContext';
|
||||||
|
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||||
|
|
||||||
type WebSocketContextType = {
|
type WebSocketContextType = {
|
||||||
ws: WebSocket | null;
|
ws: WebSocket | null;
|
||||||
@@ -18,9 +20,8 @@ export const useWebSocket = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const buildWebSocketUrl = (token: string | null) => {
|
const buildWebSocketUrl = (token: string | null) => {
|
||||||
const isPlatform = import.meta.env.VITE_IS_PLATFORM === 'true';
|
|
||||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
if (isPlatform) return `${protocol}//${window.location.host}/ws`; // Platform mode: Use same domain as the page (goes through proxy)
|
if (IS_PLATFORM) return `${protocol}//${window.location.host}/ws`; // Platform mode: Use same domain as the page (goes through proxy)
|
||||||
if (!token) return null;
|
if (!token) return null;
|
||||||
return `${protocol}//${window.location.host}/ws?token=${encodeURIComponent(token)}`; // OSS mode: Use same host:port that served the page
|
return `${protocol}//${window.location.host}/ws?token=${encodeURIComponent(token)}`; // OSS mode: Use same host:port that served the page
|
||||||
};
|
};
|
||||||
@@ -31,6 +32,7 @@ const useWebSocketProviderState = (): WebSocketContextType => {
|
|||||||
const [messages, setMessages] = useState<any[]>([]);
|
const [messages, setMessages] = useState<any[]>([]);
|
||||||
const [isConnected, setIsConnected] = useState(false);
|
const [isConnected, setIsConnected] = useState(false);
|
||||||
const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||||
|
const { token } = useAuth();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
connect();
|
connect();
|
||||||
@@ -49,10 +51,8 @@ const useWebSocketProviderState = (): WebSocketContextType => {
|
|||||||
const connect = () => {
|
const connect = () => {
|
||||||
if (unmountedRef.current) return; // Prevent connection if unmounted
|
if (unmountedRef.current) return; // Prevent connection if unmounted
|
||||||
try {
|
try {
|
||||||
const isPlatform = import.meta.env.VITE_IS_PLATFORM === 'true';
|
|
||||||
|
|
||||||
// Construct WebSocket URL
|
// Construct WebSocket URL
|
||||||
const wsUrl = buildWebSocketUrl(isPlatform ? null : localStorage.getItem('authToken'));
|
const wsUrl = buildWebSocketUrl(token);
|
||||||
|
|
||||||
if (!wsUrl) return console.warn('No authentication token found for WebSocket connection');
|
if (!wsUrl) return console.warn('No authentication token found for WebSocket connection');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user