diff --git a/mobile/src/screens/LoginScreen.tsx b/mobile/src/screens/LoginScreen.tsx
index 7ebbcb9..8153775 100644
--- a/mobile/src/screens/LoginScreen.tsx
+++ b/mobile/src/screens/LoginScreen.tsx
@@ -12,6 +12,7 @@ import {
} from 'react-native';
import { GoonClient } from '../api';
import { GoonMark, GoonWordmark } from '../components/GoonWordmark';
+import { DEFAULT_API_KEY, DEFAULT_BACKEND_URL } from '../lib/backend';
import { saveCredentials } from '../storage';
import { theme } from '../theme';
@@ -20,9 +21,14 @@ interface Props {
}
export function LoginScreen({ onAuthenticated }: Props) {
- const [baseUrl, setBaseUrl] = useState('http://localhost:8000');
- const [apiKey, setApiKey] = useState('');
+ // Pairing jest domyślnie automatyczny (App.tsx auto-connectuje do publicznej instancji
+ // gdy brak zapisanych creds). Ten ekran pojawia się tylko po explicit "Sign out" —
+ // prefillujemy publiczne defaulty, więc reconnect to JEDEN tap, bez wpisywania URL/klucza.
+ // Ręczne pola są pod "Advanced" dla self-hosterów.
+ const [baseUrl, setBaseUrl] = useState(DEFAULT_BACKEND_URL);
+ const [apiKey, setApiKey] = useState(DEFAULT_API_KEY);
const [loading, setLoading] = useState(false);
+ const [advanced, setAdvanced] = useState(false);
const [urlFocused, setUrlFocused] = useState(false);
const [keyFocused, setKeyFocused] = useState(false);
@@ -67,35 +73,40 @@ export function LoginScreen({ onAuthenticated }: Props) {
Connect
- Pair this device with your backend. Credentials are stored encrypted in
- secure-storage on this device only.
+ {advanced
+ ? 'Point the app at your own self-hosted backend. Credentials are stored encrypted in secure-storage on this device only.'
+ : 'Connects to the public goon instance — no setup needed.'}
- Backend URL
- setUrlFocused(true)}
- onBlur={() => setUrlFocused(false)}
- autoCapitalize="none"
- keyboardType="url"
- placeholder="http://localhost:8000"
- placeholderTextColor={theme.mutedDim}
- />
+ {advanced && (
+ <>
+ Backend URL
+ setUrlFocused(true)}
+ onBlur={() => setUrlFocused(false)}
+ autoCapitalize="none"
+ keyboardType="url"
+ placeholder={DEFAULT_BACKEND_URL}
+ placeholderTextColor={theme.mutedDim}
+ />
- API Key
- setKeyFocused(true)}
- onBlur={() => setKeyFocused(false)}
- autoCapitalize="none"
- secureTextEntry
- placeholder="paste your X-API-Key"
- placeholderTextColor={theme.mutedDim}
- />
+ API Key
+ setKeyFocused(true)}
+ onBlur={() => setKeyFocused(false)}
+ autoCapitalize="none"
+ secureTextEntry
+ placeholder="paste your X-API-Key"
+ placeholderTextColor={theme.mutedDim}
+ />
+ >
+ )}
[
@@ -107,15 +118,34 @@ export function LoginScreen({ onAuthenticated }: Props) {
disabled={loading}
>
- {loading ? 'Connecting…' : 'Connect'}
+ {loading ? 'Connecting…' : advanced ? 'Connect' : 'Connect to public instance'}
+
+
+
+ {
+ if (advanced) {
+ // Powrót do publicznej instancji — reset pól do defaultów.
+ setBaseUrl(DEFAULT_BACKEND_URL);
+ setApiKey(DEFAULT_API_KEY);
+ }
+ setAdvanced((v) => !v);
+ }}
+ hitSlop={8}
+ style={styles.advancedToggle}
+ >
+
+ {advanced ? '← Use public instance' : 'Advanced · self-hosted backend'}
-
- Need help? Check the X-API-Key in your
- backend .env file.
-
+ {advanced && (
+
+ Need help? Check the X-API-Key in your
+ backend .env file.
+
+ )}
);
@@ -231,4 +261,12 @@ const styles = StyleSheet.create({
lineHeight: 18,
},
footerEm: { color: theme.muted, fontWeight: '700' },
+
+ advancedToggle: { marginTop: 16, alignItems: 'center' },
+ advancedToggleText: {
+ color: theme.muted,
+ fontSize: 12,
+ fontWeight: '600',
+ letterSpacing: 0.3,
+ },
});