mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 06:25:41 +00:00
chore(orbit): auto-switch to the link's server on paste / join
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
|||||||
readOrbitState,
|
readOrbitState,
|
||||||
joinOrbitSession,
|
joinOrbitSession,
|
||||||
} from '../utils/orbit';
|
} from '../utils/orbit';
|
||||||
|
import { switchActiveServer } from '../utils/switchActiveServer';
|
||||||
import { showToast } from '../utils/toast';
|
import { showToast } from '../utils/toast';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -44,13 +45,25 @@ export default function OrbitJoinModal({ onClose }: Props) {
|
|||||||
const active = useAuthStore.getState().getActiveServer();
|
const active = useAuthStore.getState().getActiveServer();
|
||||||
const activeUrl = (active?.url ?? '').replace(/\/+$/, '');
|
const activeUrl = (active?.url ?? '').replace(/\/+$/, '');
|
||||||
const wantUrl = parsed.serverBase.replace(/\/+$/, '');
|
const wantUrl = parsed.serverBase.replace(/\/+$/, '');
|
||||||
if (activeUrl !== wantUrl) {
|
|
||||||
setError(t('orbit.toastSwitchServer', { url: wantUrl }));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
try {
|
try {
|
||||||
|
// Auto-switch to the link's server if the user has an account for it.
|
||||||
|
// switch itself tears down any lingering orbit session.
|
||||||
|
if (activeUrl !== wantUrl) {
|
||||||
|
const targetServer = useAuthStore.getState().servers
|
||||||
|
.find(s => s.url.replace(/\/+$/, '') === wantUrl);
|
||||||
|
if (!targetServer) {
|
||||||
|
setError(t('orbit.toastNoAccountForServer', { url: wantUrl }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const switched = await switchActiveServer(targetServer);
|
||||||
|
if (!switched) {
|
||||||
|
setError(t('orbit.toastSwitchFailed', { url: wantUrl }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const playlistId = await findSessionPlaylistId(parsed.sid);
|
const playlistId = await findSessionPlaylistId(parsed.sid);
|
||||||
if (!playlistId) { setError(t('orbit.joinErrNotFound')); return; }
|
if (!playlistId) { setError(t('orbit.joinErrNotFound')); return; }
|
||||||
const state = await readOrbitState(playlistId);
|
const state = await readOrbitState(playlistId);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
readOrbitState,
|
readOrbitState,
|
||||||
OrbitJoinError,
|
OrbitJoinError,
|
||||||
} from '../utils/orbit';
|
} from '../utils/orbit';
|
||||||
|
import { switchActiveServer } from '../utils/switchActiveServer';
|
||||||
import ConfirmModal from './ConfirmModal';
|
import ConfirmModal from './ConfirmModal';
|
||||||
|
|
||||||
const ORBIT_JOIN_ERROR_KEYS: Record<string, string> = {
|
const ORBIT_JOIN_ERROR_KEYS: Record<string, string> = {
|
||||||
@@ -81,21 +82,35 @@ export default function PasteClipboardHandler() {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (!isLoggedIn) { showToast(t('orbit.toastLoginFirst'), 4000, 'info'); return; }
|
if (!isLoggedIn) { showToast(t('orbit.toastLoginFirst'), 4000, 'info'); return; }
|
||||||
const active = useAuthStore.getState().getActiveServer();
|
|
||||||
const activeUrl = (active?.url ?? '').replace(/\/+$/, '');
|
|
||||||
const wantUrl = orbit.serverBase.replace(/\/+$/, '');
|
|
||||||
if (activeUrl !== wantUrl) {
|
|
||||||
showToast(t('orbit.toastSwitchServer', { url: wantUrl }), 5000, 'info');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (busy.current) return;
|
if (busy.current) return;
|
||||||
|
|
||||||
// Preview the session state so the confirm dialog can show the host
|
|
||||||
// and session name. Failures (session vanished / ended / unreachable)
|
|
||||||
// surface the same error toasts the join would, without ever showing
|
|
||||||
// the confirm.
|
|
||||||
busy.current = true;
|
busy.current = true;
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
const active = useAuthStore.getState().getActiveServer();
|
||||||
|
const activeUrl = (active?.url ?? '').replace(/\/+$/, '');
|
||||||
|
const wantUrl = orbit.serverBase.replace(/\/+$/, '');
|
||||||
|
|
||||||
|
// Auto-switch to the link's target server if the user has an
|
||||||
|
// account registered for it. No account → clear error. switch
|
||||||
|
// itself tears down any lingering orbit session (see
|
||||||
|
// switchActiveServer) so the join below starts clean.
|
||||||
|
if (activeUrl !== wantUrl) {
|
||||||
|
const targetServer = useAuthStore.getState().servers
|
||||||
|
.find(s => s.url.replace(/\/+$/, '') === wantUrl);
|
||||||
|
if (!targetServer) {
|
||||||
|
showToast(t('orbit.toastNoAccountForServer', { url: wantUrl }), 5000, 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const switched = await switchActiveServer(targetServer);
|
||||||
|
if (!switched) {
|
||||||
|
showToast(t('orbit.toastSwitchFailed', { url: wantUrl }), 5000, 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preview the session state so the confirm dialog can show the
|
||||||
|
// host and session name. Failures surface the same error toasts
|
||||||
|
// the join would, without ever showing the confirm.
|
||||||
const playlistId = await findSessionPlaylistId(orbit.sid);
|
const playlistId = await findSessionPlaylistId(orbit.sid);
|
||||||
if (!playlistId) { handleJoinError('not-found'); return; }
|
if (!playlistId) { handleJoinError('not-found'); return; }
|
||||||
const state = await readOrbitState(playlistId);
|
const state = await readOrbitState(playlistId);
|
||||||
|
|||||||
@@ -1546,6 +1546,8 @@ export const deTranslation = {
|
|||||||
toastJoined: 'Session beigetreten',
|
toastJoined: 'Session beigetreten',
|
||||||
toastLoginFirst: 'Erst anmelden, um einer Session beizutreten',
|
toastLoginFirst: 'Erst anmelden, um einer Session beizutreten',
|
||||||
toastSwitchServer: 'Wechsle erst zu {{url}} und füge den Link dann erneut ein',
|
toastSwitchServer: 'Wechsle erst zu {{url}} und füge den Link dann erneut ein',
|
||||||
|
toastNoAccountForServer: 'Du hast keinen Zugang zu {{url}}. Bitte den Host um einen Einladungslink.',
|
||||||
|
toastSwitchFailed: 'Wechsel zu {{url}} fehlgeschlagen',
|
||||||
toastJoinFail: 'Session konnte nicht beigetreten werden',
|
toastJoinFail: 'Session konnte nicht beigetreten werden',
|
||||||
joinErrNotFound: 'Session nicht gefunden',
|
joinErrNotFound: 'Session nicht gefunden',
|
||||||
joinErrEnded: 'Session wurde beendet',
|
joinErrEnded: 'Session wurde beendet',
|
||||||
|
|||||||
@@ -1549,6 +1549,8 @@ export const enTranslation = {
|
|||||||
toastJoined: 'Joined session',
|
toastJoined: 'Joined session',
|
||||||
toastLoginFirst: 'Log in before joining a session',
|
toastLoginFirst: 'Log in before joining a session',
|
||||||
toastSwitchServer: 'Switch to {{url}} first, then paste again',
|
toastSwitchServer: 'Switch to {{url}} first, then paste again',
|
||||||
|
toastNoAccountForServer: "You don't have access to {{url}}. Ask the host for an invite.",
|
||||||
|
toastSwitchFailed: "Couldn't switch to {{url}}",
|
||||||
toastJoinFail: "Couldn't join session",
|
toastJoinFail: "Couldn't join session",
|
||||||
joinErrNotFound: 'Session not found',
|
joinErrNotFound: 'Session not found',
|
||||||
joinErrEnded: 'Session has ended',
|
joinErrEnded: 'Session has ended',
|
||||||
|
|||||||
Reference in New Issue
Block a user