fix share
This commit is contained in:
parent
ecfa339748
commit
df1ff96e3c
|
|
@ -23,6 +23,8 @@ interface ViewerModalProps {
|
|||
onClose: () => void;
|
||||
onDelete?: (assetId: string) => void;
|
||||
onShare?: (assetId: string) => void;
|
||||
shareToken?: string;
|
||||
sharePassword?: string;
|
||||
}
|
||||
|
||||
export default function ViewerModal({
|
||||
|
|
@ -31,10 +33,13 @@ export default function ViewerModal({
|
|||
onClose,
|
||||
onDelete,
|
||||
onShare,
|
||||
shareToken,
|
||||
sharePassword,
|
||||
}: ViewerModalProps) {
|
||||
const [currentUrl, setCurrentUrl] = useState<string>('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [currentIndex, setCurrentIndex] = useState(-1);
|
||||
const [isBlobUrl, setIsBlobUrl] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (asset) {
|
||||
|
|
@ -45,7 +50,7 @@ export default function ViewerModal({
|
|||
|
||||
// Cleanup blob URL on unmount or asset change
|
||||
return () => {
|
||||
if (currentUrl) {
|
||||
if (currentUrl && isBlobUrl) {
|
||||
URL.revokeObjectURL(currentUrl);
|
||||
}
|
||||
};
|
||||
|
|
@ -80,13 +85,26 @@ export default function ViewerModal({
|
|||
try {
|
||||
setLoading(true);
|
||||
// Revoke previous blob URL to prevent memory leaks
|
||||
if (currentUrl) {
|
||||
if (currentUrl && isBlobUrl) {
|
||||
URL.revokeObjectURL(currentUrl);
|
||||
}
|
||||
// Load media through backend proxy with auth
|
||||
|
||||
let url: string;
|
||||
let isBlob: boolean;
|
||||
|
||||
// If viewing shared content, use share download URL (pre-signed S3 URL)
|
||||
if (shareToken) {
|
||||
url = await api.getShareDownloadUrl(shareToken, asset.id, 'original', sharePassword);
|
||||
isBlob = false;
|
||||
} else {
|
||||
// Otherwise use authenticated media endpoint with blob
|
||||
const blob = await api.getMediaBlob(asset.id, 'original');
|
||||
const url = URL.createObjectURL(blob);
|
||||
url = URL.createObjectURL(blob);
|
||||
isBlob = true;
|
||||
}
|
||||
|
||||
setCurrentUrl(url);
|
||||
setIsBlobUrl(isBlob);
|
||||
} catch (error) {
|
||||
console.error('Failed to load media:', error);
|
||||
} finally {
|
||||
|
|
|
|||
|
|
@ -171,6 +171,8 @@ export default function ShareViewPage() {
|
|||
asset={viewerOpen ? asset : null}
|
||||
assets={[asset]}
|
||||
onClose={() => setViewerOpen(false)}
|
||||
shareToken={token}
|
||||
sharePassword={password}
|
||||
/>
|
||||
)}
|
||||
</Container>
|
||||
|
|
|
|||
|
|
@ -25,12 +25,18 @@ class ApiClient {
|
|||
},
|
||||
});
|
||||
|
||||
// Add auth token to requests
|
||||
// Add auth token to requests (except for public share endpoints)
|
||||
this.client.interceptors.request.use((config) => {
|
||||
// Skip auth for public share endpoints
|
||||
const isShareEndpoint = config.url?.startsWith('/shares/') &&
|
||||
!config.url?.includes('/revoke');
|
||||
|
||||
if (!isShareEndpoint) {
|
||||
const token = localStorage.getItem('access_token');
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
|
|
@ -41,8 +47,10 @@ class ApiClient {
|
|||
if (error.response?.status === 401) {
|
||||
localStorage.removeItem('access_token');
|
||||
localStorage.removeItem('refresh_token');
|
||||
// Redirect only if not already on login/register page
|
||||
if (!['/login', '/register'].includes(window.location.pathname)) {
|
||||
// Redirect only if not on login/register/share pages
|
||||
const path = window.location.pathname;
|
||||
const isPublicPage = ['/login', '/register'].includes(path) || path.startsWith('/share/');
|
||||
if (!isPublicPage) {
|
||||
window.location.href = '/login';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue