feat: Add public URL field in settings and services
This commit is contained in:
@@ -26,6 +26,7 @@ interface Settings {
|
||||
cloudDriveEnabled?: boolean;
|
||||
openListApiUrl?: string;
|
||||
openListToken?: string;
|
||||
openListPublicUrl?: string;
|
||||
cloudDrivePath?: string;
|
||||
homeSidebarOpen?: boolean;
|
||||
subtitlesEnabled?: boolean;
|
||||
@@ -49,6 +50,7 @@ const defaultSettings: Settings = {
|
||||
cloudDriveEnabled: false,
|
||||
openListApiUrl: "",
|
||||
openListToken: "",
|
||||
openListPublicUrl: "",
|
||||
cloudDrivePath: "",
|
||||
homeSidebarOpen: true,
|
||||
subtitlesEnabled: true,
|
||||
|
||||
@@ -9,6 +9,7 @@ interface CloudDriveConfig {
|
||||
enabled: boolean;
|
||||
apiUrl: string;
|
||||
token: string;
|
||||
publicUrl?: string;
|
||||
uploadPath: string;
|
||||
}
|
||||
|
||||
@@ -19,6 +20,7 @@ export class CloudStorageService {
|
||||
enabled: settings.cloudDriveEnabled || false,
|
||||
apiUrl: settings.openListApiUrl || "",
|
||||
token: settings.openListToken || "",
|
||||
publicUrl: settings.openListPublicUrl || undefined,
|
||||
uploadPath: settings.cloudDrivePath || "/",
|
||||
};
|
||||
}
|
||||
@@ -399,10 +401,10 @@ export class CloudStorageService {
|
||||
thumbnailThumbUrl?: string;
|
||||
} = {};
|
||||
|
||||
// Extract domain from apiBaseUrl
|
||||
// If apiBaseUrl is like https://example.com/api/fs/put, then apiBaseUrl will be https://example.com
|
||||
// Use this as the base domain for building file URLs
|
||||
const domain = apiBaseUrl;
|
||||
// Use publicUrl if set, otherwise extract domain from apiBaseUrl
|
||||
// If publicUrl is set (e.g., https://cloudflare-tunnel-domain.com), use it for file URLs
|
||||
// Otherwise, use apiBaseUrl (e.g., http://127.0.0.1:5244)
|
||||
const domain = config.publicUrl || apiBaseUrl;
|
||||
|
||||
// Find video file
|
||||
if (videoFilename) {
|
||||
@@ -445,6 +447,22 @@ export class CloudStorageService {
|
||||
);
|
||||
// Also handle \u0026 encoding
|
||||
thumbUrl = thumbUrl.replace(/\\u0026/g, "&");
|
||||
// If publicUrl is set, replace the domain in thumbUrl with publicUrl
|
||||
if (config.publicUrl) {
|
||||
try {
|
||||
const thumbUrlObj = new URL(thumbUrl);
|
||||
const publicUrlObj = new URL(config.publicUrl);
|
||||
thumbUrl = thumbUrl.replace(
|
||||
thumbUrlObj.origin,
|
||||
publicUrlObj.origin
|
||||
);
|
||||
} catch (e) {
|
||||
// If URL parsing fails, use thumbUrl as is
|
||||
logger.debug(
|
||||
`[CloudStorage] Failed to replace domain in thumbUrl: ${thumbUrl}`
|
||||
);
|
||||
}
|
||||
}
|
||||
result.thumbnailThumbUrl = thumbUrl;
|
||||
}
|
||||
} else {
|
||||
@@ -461,6 +479,22 @@ export class CloudStorageService {
|
||||
"width=1280&height=720"
|
||||
);
|
||||
thumbUrl = thumbUrl.replace(/\\u0026/g, "&");
|
||||
// If publicUrl is set, replace the domain in thumbUrl with publicUrl
|
||||
if (config.publicUrl) {
|
||||
try {
|
||||
const thumbUrlObj = new URL(thumbUrl);
|
||||
const publicUrlObj = new URL(config.publicUrl);
|
||||
thumbUrl = thumbUrl.replace(
|
||||
thumbUrlObj.origin,
|
||||
publicUrlObj.origin
|
||||
);
|
||||
} catch (e) {
|
||||
// If URL parsing fails, use thumbUrl as is
|
||||
logger.debug(
|
||||
`[CloudStorage] Failed to replace domain in thumbUrl: ${thumbUrl}`
|
||||
);
|
||||
}
|
||||
}
|
||||
result.thumbnailThumbUrl = thumbUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,22 @@ const CloudDriveSettings: React.FC<CloudDriveSettingsProps> = ({ settings, onCha
|
||||
return null;
|
||||
};
|
||||
|
||||
// Validate public URL format
|
||||
const validatePublicUrl = (url: string): string | null => {
|
||||
if (!url.trim()) {
|
||||
return null; // Optional field
|
||||
}
|
||||
try {
|
||||
const urlObj = new URL(url);
|
||||
if (!urlObj.protocol.startsWith('http')) {
|
||||
return 'URL must start with http:// or https://';
|
||||
}
|
||||
} catch {
|
||||
return 'Invalid URL format';
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
// Validate upload path
|
||||
const validateUploadPath = (path: string): string | null => {
|
||||
if (!path.trim()) {
|
||||
@@ -47,6 +63,9 @@ const CloudDriveSettings: React.FC<CloudDriveSettingsProps> = ({ settings, onCha
|
||||
const apiUrlError = settings.cloudDriveEnabled && settings.openListApiUrl
|
||||
? validateApiUrl(settings.openListApiUrl)
|
||||
: null;
|
||||
const publicUrlError = settings.cloudDriveEnabled && settings.openListPublicUrl
|
||||
? validatePublicUrl(settings.openListPublicUrl)
|
||||
: null;
|
||||
const uploadPathError = settings.cloudDriveEnabled && settings.cloudDrivePath
|
||||
? validateUploadPath(settings.cloudDrivePath)
|
||||
: null;
|
||||
@@ -155,6 +174,21 @@ const CloudDriveSettings: React.FC<CloudDriveSettingsProps> = ({ settings, onCha
|
||||
fullWidth
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label={t('publicUrl')}
|
||||
value={settings.openListPublicUrl || ''}
|
||||
onChange={(e) => onChange('openListPublicUrl', e.target.value)}
|
||||
helperText={t('publicUrlHelper')}
|
||||
error={!!publicUrlError}
|
||||
placeholder="https://your-cloudflare-tunnel-domain.com"
|
||||
fullWidth
|
||||
/>
|
||||
{publicUrlError && (
|
||||
<Typography variant="caption" color="error" sx={{ mt: -1.5 }}>
|
||||
{publicUrlError}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
<TextField
|
||||
label={t('uploadPath')}
|
||||
value={settings.cloudDrivePath || ''}
|
||||
|
||||
@@ -52,6 +52,7 @@ const SettingsPage: React.FC = () => {
|
||||
cloudDriveEnabled: false,
|
||||
openListApiUrl: '',
|
||||
openListToken: '',
|
||||
openListPublicUrl: '',
|
||||
cloudDrivePath: '',
|
||||
itemsPerPage: 12,
|
||||
ytDlpConfig: '',
|
||||
|
||||
@@ -66,6 +66,7 @@ export interface Settings {
|
||||
cloudDriveEnabled: boolean;
|
||||
openListApiUrl: string;
|
||||
openListToken: string;
|
||||
openListPublicUrl?: string;
|
||||
cloudDrivePath: string;
|
||||
homeSidebarOpen?: boolean;
|
||||
subtitlesEnabled?: boolean;
|
||||
|
||||
@@ -140,6 +140,8 @@ export const ar = {
|
||||
apiUrl: "رابط API",
|
||||
apiUrlHelper: "مثال: https://your-alist-instance.com/api/fs/put",
|
||||
token: "الرمز المميز (Token)",
|
||||
publicUrl: "عنوان URL العام",
|
||||
publicUrlHelper: "النطاق العام للوصول إلى الملفات (مثال: https://your-cloudflare-tunnel-domain.com). إذا تم تعيينه، سيتم استخدامه بدلاً من عنوان API للوصول إلى الملفات.",
|
||||
uploadPath: "مسار التحميل",
|
||||
cloudDrivePathHelper: "مسار الدليل في التخزين السحابي، مثال: /mytube-uploads",
|
||||
cloudDriveNote:
|
||||
|
||||
@@ -136,6 +136,8 @@ export const de = {
|
||||
apiUrl: "API-URL",
|
||||
apiUrlHelper: "z.B. https://your-alist-instance.com/api/fs/put",
|
||||
token: "Token",
|
||||
publicUrl: "Öffentliche URL",
|
||||
publicUrlHelper: "Öffentliche Domain für den Dateizugriff (z.B. https://your-cloudflare-tunnel-domain.com). Wenn gesetzt, wird diese anstelle der API-URL für den Dateizugriff verwendet.",
|
||||
uploadPath: "Upload-Pfad",
|
||||
cloudDrivePathHelper:
|
||||
"Verzeichnispfad im Cloud-Speicher, z.B. /mytube-uploads",
|
||||
|
||||
@@ -137,6 +137,8 @@ export const en = {
|
||||
apiUrl: "API URL",
|
||||
apiUrlHelper: "e.g. https://your-alist-instance.com/api/fs/put",
|
||||
token: "Token",
|
||||
publicUrl: "Public URL",
|
||||
publicUrlHelper: "Public domain for accessing files (e.g., https://your-cloudflare-tunnel-domain.com). If set, this will be used instead of the API URL for file access.",
|
||||
uploadPath: "Upload Path",
|
||||
cloudDrivePathHelper: "Directory path in cloud drive, e.g. /mytube-uploads",
|
||||
cloudDriveNote:
|
||||
|
||||
@@ -151,6 +151,8 @@ export const es = {
|
||||
apiUrl: "URL de la API",
|
||||
apiUrlHelper: "ej. https://your-alist-instance.com/api/fs/put",
|
||||
token: "Token",
|
||||
publicUrl: "URL Público",
|
||||
publicUrlHelper: "Dominio público para acceder a archivos (ej. https://your-cloudflare-tunnel-domain.com). Si se establece, se usará en lugar de la URL de la API para acceder a archivos.",
|
||||
uploadPath: "Ruta de carga",
|
||||
cloudDrivePathHelper: "Ruta del directorio en la nube, ej. /mytube-uploads",
|
||||
cloudDriveNote:
|
||||
|
||||
@@ -150,6 +150,8 @@ export const fr = {
|
||||
apiUrl: "URL de l'API",
|
||||
apiUrlHelper: "ex. https://your-alist-instance.com/api/fs/put",
|
||||
token: "Jeton (Token)",
|
||||
publicUrl: "URL Publique",
|
||||
publicUrlHelper: "Domaine public pour accéder aux fichiers (ex. https://your-cloudflare-tunnel-domain.com). S'il est défini, il sera utilisé à la place de l'URL de l'API pour accéder aux fichiers.",
|
||||
uploadPath: "Chemin de téléchargement",
|
||||
cloudDrivePathHelper:
|
||||
"Chemin du répertoire dans le cloud, ex. /mytube-uploads",
|
||||
|
||||
@@ -145,6 +145,8 @@ export const ja = {
|
||||
apiUrl: "API URL",
|
||||
apiUrlHelper: "例: https://your-alist-instance.com/api/fs/put",
|
||||
token: "トークン",
|
||||
publicUrl: "公開URL",
|
||||
publicUrlHelper: "ファイルにアクセスするための公開ドメイン(例: https://your-cloudflare-tunnel-domain.com)。設定されている場合、ファイルアクセスにはAPI URLの代わりにこれが使用されます。",
|
||||
uploadPath: "アップロードパス",
|
||||
cloudDrivePathHelper:
|
||||
"クラウドドライブ内のディレクトリパス、例: /mytube-uploads",
|
||||
|
||||
@@ -142,6 +142,8 @@ export const ko = {
|
||||
apiUrl: "API URL",
|
||||
apiUrlHelper: "예: https://your-alist-instance.com/api/fs/put",
|
||||
token: "토큰",
|
||||
publicUrl: "공개 URL",
|
||||
publicUrlHelper: "파일 액세스를 위한 공개 도메인 (예: https://your-cloudflare-tunnel-domain.com). 설정된 경우 파일 액세스에 API URL 대신 이것이 사용됩니다.",
|
||||
uploadPath: "업로드 경로",
|
||||
cloudDrivePathHelper:
|
||||
"클라우드 드라이브 내 디렉토리 경로, 예: /mytube-uploads",
|
||||
|
||||
@@ -146,6 +146,8 @@ export const pt = {
|
||||
apiUrl: "URL da API",
|
||||
apiUrlHelper: "ex. https://your-alist-instance.com/api/fs/put",
|
||||
token: "Token",
|
||||
publicUrl: "URL Público",
|
||||
publicUrlHelper: "Domínio público para acessar arquivos (ex. https://your-cloudflare-tunnel-domain.com). Se definido, será usado em vez da URL da API para acessar arquivos.",
|
||||
uploadPath: "Caminho de upload",
|
||||
cloudDrivePathHelper: "Caminho do diretório na nuvem, ex. /mytube-uploads",
|
||||
cloudDriveNote:
|
||||
|
||||
@@ -154,6 +154,8 @@ export const ru = {
|
||||
apiUrl: "URL API",
|
||||
apiUrlHelper: "напр. https://your-alist-instance.com/api/fs/put",
|
||||
token: "Токен",
|
||||
publicUrl: "Публичный URL",
|
||||
publicUrlHelper: "Публичный домен для доступа к файлам (напр. https://your-cloudflare-tunnel-domain.com). Если установлен, будет использоваться вместо URL API для доступа к файлам.",
|
||||
uploadPath: "Путь загрузки",
|
||||
cloudDrivePathHelper: "Путь к каталогу в облаке, напр. /mytube-uploads",
|
||||
cloudDriveNote:
|
||||
|
||||
@@ -137,6 +137,8 @@ export const zh = {
|
||||
apiUrl: "API 地址",
|
||||
apiUrlHelper: "例如:https://your-alist-instance.com/api/fs/put",
|
||||
token: "Token",
|
||||
publicUrl: "公开访问域名",
|
||||
publicUrlHelper: "用于访问文件的公开域名(例如:https://your-cloudflare-tunnel-domain.com)。如果设置,将使用此域名而不是 API 地址来访问文件。",
|
||||
uploadPath: "上传路径",
|
||||
cloudDrivePathHelper: "云端存储中的目录路径,例如:/mytube-uploads",
|
||||
cloudDriveNote:
|
||||
|
||||
Reference in New Issue
Block a user