mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-01-31 13:57:34 +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'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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 StandaloneShell from './StandaloneShell';
|
||||
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||
|
||||
/**
|
||||
* Reusable login modal component for Claude, Cursor, and Codex CLI authentication
|
||||
@@ -27,15 +28,13 @@ function LoginModal({
|
||||
const getCommand = () => {
|
||||
if (customCommand) return customCommand;
|
||||
|
||||
const isPlatform = import.meta.env.VITE_IS_PLATFORM === 'true';
|
||||
|
||||
switch (provider) {
|
||||
case 'claude':
|
||||
return isAuthenticated ? 'claude setup-token --dangerously-skip-permissions' : 'claude /exit --dangerously-skip-permissions';
|
||||
case 'cursor':
|
||||
return 'cursor-agent login';
|
||||
case 'codex':
|
||||
return isPlatform ? 'codex login --device-auth' : 'codex login';
|
||||
return IS_PLATFORM ? 'codex login --device-auth' : 'codex login';
|
||||
default:
|
||||
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 { authenticatedFetch } from '../utils/api';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||
|
||||
const Onboarding = ({ onComplete }) => {
|
||||
const [currentStep, setCurrentStep] = useState(0);
|
||||
@@ -15,8 +16,7 @@ const Onboarding = ({ onComplete }) => {
|
||||
const [error, setError] = useState('');
|
||||
|
||||
const [activeLoginProvider, setActiveLoginProvider] = useState(null);
|
||||
const isPlatform = import.meta.env.VITE_IS_PLATFORM === 'true';
|
||||
const [selectedProject] = useState({ name: 'default', fullPath: isPlatform ? '/workspace' : '' });
|
||||
const [selectedProject] = useState({ name: 'default', fullPath: IS_PLATFORM ? '/workspace' : '' });
|
||||
|
||||
const [claudeAuthStatus, setClaudeAuthStatus] = useState({
|
||||
authenticated: false,
|
||||
|
||||
@@ -4,6 +4,7 @@ import SetupForm from './SetupForm';
|
||||
import LoginForm from './LoginForm';
|
||||
import Onboarding from './Onboarding';
|
||||
import { MessageSquare } from 'lucide-react';
|
||||
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||
|
||||
const LoadingScreen = () => (
|
||||
<div className="min-h-screen bg-background flex items-center justify-center p-4">
|
||||
@@ -27,7 +28,7 @@ const LoadingScreen = () => (
|
||||
const ProtectedRoute = ({ children }) => {
|
||||
const { user, isLoading, needsSetup, hasCompletedOnboarding, refreshOnboardingStatus } = useAuth();
|
||||
|
||||
if (import.meta.env.VITE_IS_PLATFORM === 'true') {
|
||||
if (IS_PLATFORM) {
|
||||
if (isLoading) {
|
||||
return <LoadingScreen />;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { WebglAddon } from '@xterm/addon-webgl';
|
||||
import { WebLinksAddon } from '@xterm/addon-web-links';
|
||||
import '@xterm/xterm/css/xterm.css';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||
|
||||
const xtermStyles = `
|
||||
.xterm .xterm-screen {
|
||||
@@ -55,10 +56,9 @@ function Shell({ selectedProject, selectedSession, initialCommand, isPlainShell
|
||||
if (isConnecting || isConnected) return;
|
||||
|
||||
try {
|
||||
const isPlatform = import.meta.env.VITE_IS_PLATFORM === 'true';
|
||||
let wsUrl;
|
||||
|
||||
if (isPlatform) {
|
||||
if (IS_PLATFORM) {
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
wsUrl = `${protocol}//${window.location.host}/shell`;
|
||||
} else {
|
||||
|
||||
@@ -16,6 +16,7 @@ import ProjectCreationWizard from './ProjectCreationWizard';
|
||||
import { api } from '../utils/api';
|
||||
import { useTaskMaster } from '../contexts/TaskMasterContext';
|
||||
import { useTasksSettings } from '../contexts/TasksSettingsContext';
|
||||
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||
|
||||
// Move formatTimeAgo outside component to avoid recreation on every render
|
||||
const formatTimeAgo = (dateString, currentTime, t) => {
|
||||
@@ -622,7 +623,7 @@ function Sidebar({
|
||||
<div className="md:p-4 md:border-b md:border-border">
|
||||
{/* Desktop Header */}
|
||||
<div className="hidden md:flex items-center justify-between">
|
||||
{import.meta.env.VITE_IS_PLATFORM === 'true' ? (
|
||||
{IS_PLATFORM ? (
|
||||
<a
|
||||
href="https://cloudcli.ai/dashboard"
|
||||
className="flex items-center gap-3 hover:opacity-80 transition-opacity group"
|
||||
@@ -673,7 +674,7 @@ function Sidebar({
|
||||
style={isPWA && isMobile ? { paddingTop: '16px' } : {}}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
{import.meta.env.VITE_IS_PLATFORM === 'true' ? (
|
||||
{IS_PLATFORM ? (
|
||||
<a
|
||||
href="https://cloudcli.ai/dashboard"
|
||||
className="flex items-center gap-3 active:opacity-70 transition-opacity"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { createContext, useContext, useEffect, useState } from 'react';
|
||||
import { api } from '../utils/api';
|
||||
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||
|
||||
const AuthContext = createContext({
|
||||
user: null,
|
||||
@@ -31,7 +32,7 @@ export const AuthProvider = ({ children }) => {
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (import.meta.env.VITE_IS_PLATFORM === 'true') {
|
||||
if (IS_PLATFORM) {
|
||||
setUser({ username: 'platform-user' });
|
||||
setNeedsSetup(false);
|
||||
checkOnboardingStatus();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { createContext, useContext, useEffect, useRef, useState } from 'react';
|
||||
import { useAuth } from './AuthContext';
|
||||
import { IS_PLATFORM } from '../../shared/modelConstants';
|
||||
|
||||
type WebSocketContextType = {
|
||||
ws: WebSocket | null;
|
||||
@@ -18,9 +20,8 @@ export const useWebSocket = () => {
|
||||
};
|
||||
|
||||
const buildWebSocketUrl = (token: string | null) => {
|
||||
const isPlatform = import.meta.env.VITE_IS_PLATFORM === 'true';
|
||||
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;
|
||||
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 [isConnected, setIsConnected] = useState(false);
|
||||
const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const { token } = useAuth();
|
||||
|
||||
useEffect(() => {
|
||||
connect();
|
||||
@@ -49,10 +51,8 @@ const useWebSocketProviderState = (): WebSocketContextType => {
|
||||
const connect = () => {
|
||||
if (unmountedRef.current) return; // Prevent connection if unmounted
|
||||
try {
|
||||
const isPlatform = import.meta.env.VITE_IS_PLATFORM === 'true';
|
||||
|
||||
// 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');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user