mirror of
https://github.com/Termix-SSH/Mobile.git
synced 2026-07-28 05:51:43 +02:00
6c40d2f0cc
* fix: register physical Tab key on iPadOS/iOS hardware keyboards (#14) The native module only registered Shift+Tab but not bare Tab, so iOS intercepted it for UI focus navigation. Register an unmodified Tab UIKeyCommand with wantsPriorityOverSystemBehavior and handle both Tab and Shift+Tab in the same JS branch. Fixes Termix-SSH/Support#557 * fix: pass jumpHosts, forceKeyboardInteractive, and overrideCredentialUsername to terminal connection (#15) These fields were defined on SSHHost but omitted from the terminal hostConfig passthrough. Without jumpHosts the backend cannot route through jump servers; without forceKeyboardInteractive hosts that require keyboard-interactive auth fail silently; without overrideCredentialUsername shared credentials use the wrong username. Fixes Termix-SSH/Support#422 Fixes Termix-SSH/Support#638 * fix: improve mobile terminal scroll recovery (#17) * Add mobile remote desktop sessions (#18) * feat: add mobile remote desktop sessions * feat: add remote desktop input controls * feat: polish remote desktop controls * feat: add mobile terminal font selection (#19) * feat: add mobile shift tab hotkey (#20) * feat: initial UI redesign * feat: revamp server login system * chore: update app icon/background color * fix: remove unused fields in the settings tab * feat: improve the user pin system and update all settings modals to use new ui * fix: active server not updating unless app restarts * feat: add version in settings * feat: improve host page UI (updated host form and added credential management) * fix: preserve composed iOS terminal input * ci: restore mobile checks * feat: rewrite of connection system for all types * fix: preserve mobile jump hosts (#30) * fix: guard android user ca trust (#29) * fix: capture ios hardware tab key (#27) * fix: reset terminal input after special keys (#28) * fix: open oidc in system browser (#26) * fix: preserve websocket auth context (#25) * fix: keep none-auth terminal prompts alive (#23) * fix: allow local network SSL in Android app (#21) * feat: allow oidc passkeys * feat: bundeled xterm into app and added docker loading screen * feat: add 2fa, api key, and active sessions to settings and addressed multiple bug fixes and inconsistencies with termix web * chore: update repo images and readme * chore: update readme to split table for screenshots * chore: rename ios to apple in build workflow * fix: android build failure * feat: add snippet management and fix several bugs * fix: web login and oidc incorrect logic * chore: run linter --------- Co-authored-by: ZacharyZcR <zacharyzcr1984@gmail.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
147 lines
3.7 KiB
TypeScript
147 lines
3.7 KiB
TypeScript
import React, {
|
|
createContext,
|
|
useContext,
|
|
useState,
|
|
useEffect,
|
|
useCallback,
|
|
} from "react";
|
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
import { TerminalConfig } from "@/types";
|
|
import { MOBILE_DEFAULT_TERMINAL_CONFIG } from "@/constants/terminal-config";
|
|
|
|
const STORAGE_KEY = "terminalConfig";
|
|
|
|
const getDefaultConfig = (): Partial<TerminalConfig> => {
|
|
return MOBILE_DEFAULT_TERMINAL_CONFIG;
|
|
};
|
|
|
|
interface TerminalCustomizationContextType {
|
|
config: Partial<TerminalConfig>;
|
|
isLoading: boolean;
|
|
updateConfig: (config: Partial<TerminalConfig>) => Promise<void>;
|
|
resetConfig: () => Promise<void>;
|
|
|
|
updateFontSize: (fontSize: number) => Promise<void>;
|
|
updateFontFamily: (fontFamily: string) => Promise<void>;
|
|
updateLetterSpacing: (letterSpacing: number) => Promise<void>;
|
|
updateLineHeight: (lineHeight: number) => Promise<void>;
|
|
resetToDefault: () => Promise<void>;
|
|
}
|
|
|
|
const TerminalCustomizationContext = createContext<
|
|
TerminalCustomizationContextType | undefined
|
|
>(undefined);
|
|
|
|
export const TerminalCustomizationProvider: React.FC<{
|
|
children: React.ReactNode;
|
|
}> = ({ children }) => {
|
|
const [config, setConfig] =
|
|
useState<Partial<TerminalConfig>>(getDefaultConfig());
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
const loadConfig = async () => {
|
|
try {
|
|
const stored = await AsyncStorage.getItem(STORAGE_KEY);
|
|
if (stored) {
|
|
const parsed = JSON.parse(stored) as Partial<TerminalConfig>;
|
|
setConfig({
|
|
...getDefaultConfig(),
|
|
...parsed,
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error("Failed to load terminal configuration:", error);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
loadConfig();
|
|
}, []);
|
|
|
|
const saveConfig = useCallback(async (newConfig: Partial<TerminalConfig>) => {
|
|
try {
|
|
await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(newConfig));
|
|
setConfig(newConfig);
|
|
} catch (error) {
|
|
console.error("Failed to save terminal configuration:", error);
|
|
}
|
|
}, []);
|
|
|
|
const updateConfig = useCallback(
|
|
async (updates: Partial<TerminalConfig>) => {
|
|
const newConfig = {
|
|
...config,
|
|
...updates,
|
|
};
|
|
await saveConfig(newConfig);
|
|
},
|
|
[config, saveConfig],
|
|
);
|
|
|
|
const resetConfig = useCallback(async () => {
|
|
await saveConfig(getDefaultConfig());
|
|
}, [saveConfig]);
|
|
|
|
const updateFontSize = useCallback(
|
|
async (fontSize: number) => {
|
|
await updateConfig({ fontSize });
|
|
},
|
|
[updateConfig],
|
|
);
|
|
|
|
const updateFontFamily = useCallback(
|
|
async (fontFamily: string) => {
|
|
await updateConfig({ fontFamily });
|
|
},
|
|
[updateConfig],
|
|
);
|
|
|
|
const updateLetterSpacing = useCallback(
|
|
async (letterSpacing: number) => {
|
|
await updateConfig({ letterSpacing });
|
|
},
|
|
[updateConfig],
|
|
);
|
|
|
|
const updateLineHeight = useCallback(
|
|
async (lineHeight: number) => {
|
|
await updateConfig({ lineHeight });
|
|
},
|
|
[updateConfig],
|
|
);
|
|
|
|
const resetToDefault = useCallback(async () => {
|
|
await resetConfig();
|
|
}, [resetConfig]);
|
|
|
|
const value: TerminalCustomizationContextType = {
|
|
config,
|
|
isLoading,
|
|
updateConfig,
|
|
resetConfig,
|
|
updateFontSize,
|
|
updateFontFamily,
|
|
updateLetterSpacing,
|
|
updateLineHeight,
|
|
resetToDefault,
|
|
};
|
|
|
|
return (
|
|
<TerminalCustomizationContext.Provider value={value}>
|
|
{children}
|
|
</TerminalCustomizationContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useTerminalCustomization = () => {
|
|
const context = useContext(TerminalCustomizationContext);
|
|
if (!context) {
|
|
throw new Error(
|
|
"useTerminalCustomization must be used within a TerminalCustomizationProvider",
|
|
);
|
|
}
|
|
return context;
|
|
};
|