生态应用
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
+209
-2
@@ -22,6 +22,7 @@ import {
|
|||||||
Monitor,
|
Monitor,
|
||||||
MoveDown,
|
MoveDown,
|
||||||
MoveUp,
|
MoveUp,
|
||||||
|
Package,
|
||||||
Rss,
|
Rss,
|
||||||
Settings,
|
Settings,
|
||||||
Shield,
|
Shield,
|
||||||
@@ -65,6 +66,7 @@ export const UserMenu: React.FC = () => {
|
|||||||
const [isFavoritesPanelOpen, setIsFavoritesPanelOpen] = useState(false);
|
const [isFavoritesPanelOpen, setIsFavoritesPanelOpen] = useState(false);
|
||||||
const [isEmailSettingsOpen, setIsEmailSettingsOpen] = useState(false);
|
const [isEmailSettingsOpen, setIsEmailSettingsOpen] = useState(false);
|
||||||
const [isDeviceManagementOpen, setIsDeviceManagementOpen] = useState(false);
|
const [isDeviceManagementOpen, setIsDeviceManagementOpen] = useState(false);
|
||||||
|
const [isEcoAppsOpen, setIsEcoAppsOpen] = useState(false);
|
||||||
const [authInfo, setAuthInfo] = useState<AuthInfo | null>(null);
|
const [authInfo, setAuthInfo] = useState<AuthInfo | null>(null);
|
||||||
const [storageType, setStorageType] = useState<string>('localstorage');
|
const [storageType, setStorageType] = useState<string>('localstorage');
|
||||||
const [mounted, setMounted] = useState(false);
|
const [mounted, setMounted] = useState(false);
|
||||||
@@ -78,7 +80,7 @@ export const UserMenu: React.FC = () => {
|
|||||||
|
|
||||||
// Body 滚动锁定 - 使用 overflow 方式避免布局问题
|
// Body 滚动锁定 - 使用 overflow 方式避免布局问题
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isSettingsOpen || isChangePasswordOpen || isSubscribeOpen || isOfflineDownloadPanelOpen || isEmailSettingsOpen || isDeviceManagementOpen) {
|
if (isSettingsOpen || isChangePasswordOpen || isSubscribeOpen || isOfflineDownloadPanelOpen || isEmailSettingsOpen || isDeviceManagementOpen || isEcoAppsOpen) {
|
||||||
const body = document.body;
|
const body = document.body;
|
||||||
const html = document.documentElement;
|
const html = document.documentElement;
|
||||||
|
|
||||||
@@ -97,7 +99,7 @@ export const UserMenu: React.FC = () => {
|
|||||||
html.style.overflow = originalHtmlOverflow;
|
html.style.overflow = originalHtmlOverflow;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [isSettingsOpen, isChangePasswordOpen, isSubscribeOpen, isOfflineDownloadPanelOpen, isEmailSettingsOpen, isDeviceManagementOpen]);
|
}, [isSettingsOpen, isChangePasswordOpen, isSubscribeOpen, isOfflineDownloadPanelOpen, isEmailSettingsOpen, isDeviceManagementOpen, isEcoAppsOpen]);
|
||||||
|
|
||||||
// 设置相关状态
|
// 设置相关状态
|
||||||
const [defaultAggregateSearch, setDefaultAggregateSearch] = useState(true);
|
const [defaultAggregateSearch, setDefaultAggregateSearch] = useState(true);
|
||||||
@@ -1285,6 +1287,18 @@ export const UserMenu: React.FC = () => {
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* 生态应用按钮 */}
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setIsOpen(false);
|
||||||
|
setIsEcoAppsOpen(true);
|
||||||
|
}}
|
||||||
|
className='w-full px-3 py-2 text-left flex items-center gap-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors text-sm'
|
||||||
|
>
|
||||||
|
<Package className='w-4 h-4 text-gray-500 dark:text-gray-400' />
|
||||||
|
<span className='font-medium'>生态应用</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
{/* 分割线 */}
|
{/* 分割线 */}
|
||||||
<div className='my-1 border-t border-gray-200 dark:border-gray-700'></div>
|
<div className='my-1 border-t border-gray-200 dark:border-gray-700'></div>
|
||||||
|
|
||||||
@@ -2859,6 +2873,194 @@ export const UserMenu: React.FC = () => {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 生态应用面板内容
|
||||||
|
const ecoAppsPanel = (
|
||||||
|
<>
|
||||||
|
{/* 背景遮罩 */}
|
||||||
|
<div
|
||||||
|
className='fixed inset-0 bg-black/50 backdrop-blur-sm z-[1000]'
|
||||||
|
onClick={() => setIsEcoAppsOpen(false)}
|
||||||
|
onTouchMove={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
}}
|
||||||
|
onWheel={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
touchAction: 'none',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* 生态应用面板 */}
|
||||||
|
<div
|
||||||
|
className='fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-2xl bg-white dark:bg-gray-900 rounded-xl shadow-xl z-[1001] overflow-hidden'
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className='h-full max-h-[85vh] flex flex-col'
|
||||||
|
data-panel-content
|
||||||
|
onTouchMove={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
touchAction: 'auto',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* 标题栏 */}
|
||||||
|
<div className='flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-700'>
|
||||||
|
<h3 className='text-xl font-bold text-gray-800 dark:text-gray-200'>
|
||||||
|
生态应用
|
||||||
|
</h3>
|
||||||
|
<button
|
||||||
|
onClick={() => setIsEcoAppsOpen(false)}
|
||||||
|
className='w-8 h-8 p-1 rounded-full flex items-center justify-center text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors'
|
||||||
|
aria-label='Close'
|
||||||
|
>
|
||||||
|
<X className='w-full h-full' />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 应用列表 */}
|
||||||
|
<div className='flex-1 overflow-y-auto p-6'>
|
||||||
|
<div className='grid gap-6 md:grid-cols-1'>
|
||||||
|
{/* MoonTVPlus-PC 客户端 */}
|
||||||
|
<div className='bg-gray-50 dark:bg-gray-800 rounded-lg p-5 border border-gray-200 dark:border-gray-700'>
|
||||||
|
<div className='flex items-start gap-4'>
|
||||||
|
<div className='flex-shrink-0 relative'>
|
||||||
|
<img
|
||||||
|
src='/logo.png'
|
||||||
|
alt='MoonTVPlus-PC'
|
||||||
|
className='w-16 h-16 rounded-xl object-cover'
|
||||||
|
/>
|
||||||
|
<div className='absolute -bottom-1 -right-1 w-6 h-6 bg-blue-500 rounded-full flex items-center justify-center shadow-lg'>
|
||||||
|
<Monitor className='w-3.5 h-3.5 text-white' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='flex-1 min-w-0'>
|
||||||
|
<h4 className='text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2'>
|
||||||
|
MoonTVPlus-PC客户端
|
||||||
|
</h4>
|
||||||
|
<p className='text-sm text-gray-600 dark:text-gray-400 mb-3'>
|
||||||
|
专为Windows开发的客户端,完美支持私人影库mkv视频
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
href='https://github.com/mtvpls/MoonTVPlus-PC/releases'
|
||||||
|
target='_blank'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
className='inline-flex items-center gap-2 px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white text-sm font-medium rounded-lg transition-colors'
|
||||||
|
>
|
||||||
|
<Download className='w-4 h-4' />
|
||||||
|
下载
|
||||||
|
<ExternalLink className='w-3 h-3' />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Selene 跨平台客户端 */}
|
||||||
|
<div className='bg-gray-50 dark:bg-gray-800 rounded-lg p-5 border border-gray-200 dark:border-gray-700'>
|
||||||
|
<div className='flex items-start gap-4'>
|
||||||
|
<div className='flex-shrink-0 relative'>
|
||||||
|
<img
|
||||||
|
src='/icons/Selene.png'
|
||||||
|
alt='Selene'
|
||||||
|
className='w-16 h-16 rounded-xl object-cover'
|
||||||
|
/>
|
||||||
|
<span className='absolute -top-1 -right-1 px-1.5 py-0.5 bg-orange-500 text-white text-[10px] font-bold rounded'>
|
||||||
|
二开
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className='flex-1 min-w-0'>
|
||||||
|
<h4 className='text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2'>
|
||||||
|
Selene 跨平台客户端
|
||||||
|
</h4>
|
||||||
|
<p className='text-sm text-gray-600 dark:text-gray-400 mb-3'>
|
||||||
|
多平台客户端
|
||||||
|
</p>
|
||||||
|
<div className='flex flex-wrap gap-2'>
|
||||||
|
<a
|
||||||
|
href='https://github.com/mtvpls/MoonTVPlus/releases/tag/Selene_Beta4'
|
||||||
|
target='_blank'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
className='inline-flex items-center gap-2 px-4 py-2 bg-green-500 hover:bg-green-600 text-white text-sm font-medium rounded-lg transition-colors'
|
||||||
|
>
|
||||||
|
<Download className='w-4 h-4' />
|
||||||
|
安卓下载
|
||||||
|
<ExternalLink className='w-3 h-3' />
|
||||||
|
</a>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
const ua = navigator.userAgent.toLowerCase();
|
||||||
|
let targetUrl = 'https://github.com/mtvpls/Selene-Build/actions/workflows/build.yml';
|
||||||
|
|
||||||
|
// 根据 UA 判断平台
|
||||||
|
if (ua.includes('windows')) {
|
||||||
|
targetUrl = 'https://github.com/mtvpls/Selene-Build/actions/workflows/build.yml';
|
||||||
|
} else if (ua.includes('mac')) {
|
||||||
|
targetUrl = 'https://github.com/mtvpls/Selene-Build/actions/workflows/build.yml';
|
||||||
|
} else if (ua.includes('linux')) {
|
||||||
|
targetUrl = 'https://github.com/mtvpls/Selene-Build/actions/workflows/build.yml';
|
||||||
|
}
|
||||||
|
|
||||||
|
window.open(targetUrl, '_blank');
|
||||||
|
}}
|
||||||
|
className='inline-flex items-center gap-2 px-4 py-2 bg-purple-500 hover:bg-purple-600 text-white text-sm font-medium rounded-lg transition-colors'
|
||||||
|
>
|
||||||
|
<Download className='w-4 h-4' />
|
||||||
|
其他平台
|
||||||
|
<ExternalLink className='w-3 h-3' />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* OrionTV TV专用客户端 */}
|
||||||
|
<div className='bg-gray-50 dark:bg-gray-800 rounded-lg p-5 border border-gray-200 dark:border-gray-700'>
|
||||||
|
<div className='flex items-start gap-4'>
|
||||||
|
<div className='flex-shrink-0 relative'>
|
||||||
|
<img
|
||||||
|
src='/icons/OrionTV.png'
|
||||||
|
alt='OrionTV'
|
||||||
|
className='w-16 h-16 rounded-xl object-cover'
|
||||||
|
/>
|
||||||
|
<span className='absolute -top-1 -right-1 px-1.5 py-0.5 bg-orange-500 text-white text-[10px] font-bold rounded'>
|
||||||
|
二开
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className='flex-1 min-w-0'>
|
||||||
|
<h4 className='text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2'>
|
||||||
|
OrionTV TV专用客户端
|
||||||
|
</h4>
|
||||||
|
<p className='text-sm text-gray-600 dark:text-gray-400 mb-3'>
|
||||||
|
tv专用
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
href='https://github.com/mtvpls/MoonTVPlus/releases/tag/OrionTV%E9%80%82%E9%85%8D%E7%89%882'
|
||||||
|
target='_blank'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
className='inline-flex items-center gap-2 px-4 py-2 bg-indigo-500 hover:bg-indigo-600 text-white text-sm font-medium rounded-lg transition-colors'
|
||||||
|
>
|
||||||
|
<Download className='w-4 h-4' />
|
||||||
|
下载
|
||||||
|
<ExternalLink className='w-3 h-3' />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 底部说明 */}
|
||||||
|
<div className='p-6 pt-4 border-t border-gray-200 dark:border-gray-700'>
|
||||||
|
<p className='text-xs text-gray-500 dark:text-gray-400 text-center'>
|
||||||
|
选择适合您设备的客户端下载使用
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='relative'>
|
<div className='relative'>
|
||||||
@@ -2942,6 +3144,11 @@ export const UserMenu: React.FC = () => {
|
|||||||
mounted &&
|
mounted &&
|
||||||
createPortal(deviceManagementPanel, document.body)}
|
createPortal(deviceManagementPanel, document.body)}
|
||||||
|
|
||||||
|
{/* 使用 Portal 将生态应用面板渲染到 document.body */}
|
||||||
|
{isEcoAppsOpen &&
|
||||||
|
mounted &&
|
||||||
|
createPortal(ecoAppsPanel, document.body)}
|
||||||
|
|
||||||
{/* 确认对话框 */}
|
{/* 确认对话框 */}
|
||||||
{confirmDialog.isOpen &&
|
{confirmDialog.isOpen &&
|
||||||
mounted &&
|
mounted &&
|
||||||
|
|||||||
Reference in New Issue
Block a user