mirror of
https://github.com/MoonTechLab/LunaTV.git
synced 2026-05-14 00:39:37 +08:00
feat: refine ios safari padding & enable reverse episodes order
This commit is contained in:
@@ -113,7 +113,7 @@ function AggregatePageClient() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout activePath='/aggregate'>
|
<PageLayout activePath='/aggregate'>
|
||||||
<div className='px-2 sm:px-10 py-4 sm:py-8 overflow-visible'>
|
<div className='flex flex-col min-h-full px-2 sm:px-10 pt-4 sm:pt-8 pb-[calc(3.5rem+env(safe-area-inset-bottom))] overflow-visible'>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className='flex items-center justify-center min-h-[60vh]'>
|
<div className='flex items-center justify-center min-h-[60vh]'>
|
||||||
<div className='animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500'></div>
|
<div className='animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500'></div>
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ function DetailPageClient() {
|
|||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [playRecord, setPlayRecord] = useState<PlayRecord | null>(null);
|
const [playRecord, setPlayRecord] = useState<PlayRecord | null>(null);
|
||||||
const [favorited, setFavorited] = useState(false);
|
const [favorited, setFavorited] = useState(false);
|
||||||
|
// 是否倒序显示选集
|
||||||
|
const [reverseEpisodeOrder, setReverseEpisodeOrder] = useState(false);
|
||||||
|
|
||||||
const fallbackTitle = searchParams.get('title') || '';
|
const fallbackTitle = searchParams.get('title') || '';
|
||||||
const fallbackYear = searchParams.get('year') || '';
|
const fallbackYear = searchParams.get('year') || '';
|
||||||
@@ -106,7 +108,7 @@ function DetailPageClient() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout activePath='/detail'>
|
<PageLayout activePath='/detail'>
|
||||||
<div className='px-2 sm:px-10 py-4 sm:py-8 overflow-visible'>
|
<div className='flex flex-col min-h-full px-2 sm:px-10 pt-4 sm:pt-8 pb-[calc(3.5rem+env(safe-area-inset-bottom))] overflow-visible'>
|
||||||
{/* 顶部返回按钮已移入右侧信息容器 */}
|
{/* 顶部返回按钮已移入右侧信息容器 */}
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className='flex items-center justify-center min-h-[60vh]'>
|
<div className='flex items-center justify-center min-h-[60vh]'>
|
||||||
@@ -309,9 +311,29 @@ function DetailPageClient() {
|
|||||||
<div className='text-gray-400 ml-2'>
|
<div className='text-gray-400 ml-2'>
|
||||||
共 {detail.episodes.length} 集
|
共 {detail.episodes.length} 集
|
||||||
</div>
|
</div>
|
||||||
|
{/* 倒序切换 */}
|
||||||
|
<span
|
||||||
|
onClick={() => setReverseEpisodeOrder((prev) => !prev)}
|
||||||
|
className={`ml-4 text-sm cursor-pointer select-none transition-colors ${
|
||||||
|
reverseEpisodeOrder
|
||||||
|
? 'text-green-500'
|
||||||
|
: 'text-gray-400 hover:text-gray-500'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
倒序
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='grid grid-cols-3 gap-2 sm:grid-cols-[repeat(auto-fill,_minmax(6rem,_6rem))] sm:gap-4 justify-start'>
|
<div className='grid grid-cols-3 gap-2 sm:grid-cols-[repeat(auto-fill,_minmax(6rem,_6rem))] sm:gap-4 justify-start'>
|
||||||
{detail.episodes.map((episode, idx) => (
|
{(reverseEpisodeOrder
|
||||||
|
? Array.from(
|
||||||
|
{ length: detail.episodes.length },
|
||||||
|
(_, i) => i
|
||||||
|
).reverse()
|
||||||
|
: Array.from(
|
||||||
|
{ length: detail.episodes.length },
|
||||||
|
(_, i) => i
|
||||||
|
)
|
||||||
|
).map((idx) => (
|
||||||
<a
|
<a
|
||||||
key={idx}
|
key={idx}
|
||||||
href={`/play?source=${searchParams.get(
|
href={`/play?source=${searchParams.get(
|
||||||
@@ -325,7 +347,7 @@ function DetailPageClient() {
|
|||||||
}`}
|
}`}
|
||||||
className='bg-gray-500/80 hover:bg-green-500 dark:bg-gray-700/80 dark:hover:bg-green-600 text-white px-5 py-2 rounded-lg transition-colors text-base font-medium w-24 text-center'
|
className='bg-gray-500/80 hover:bg-green-500 dark:bg-gray-700/80 dark:hover:bg-green-600 text-white px-5 py-2 rounded-lg transition-colors text-base font-medium w-24 text-center'
|
||||||
>
|
>
|
||||||
第{idx + 1}集
|
{idx + 1}
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ function PlayPageClient() {
|
|||||||
const [showShortcutHint, setShowShortcutHint] = useState(false);
|
const [showShortcutHint, setShowShortcutHint] = useState(false);
|
||||||
const [shortcutText, setShortcutText] = useState('');
|
const [shortcutText, setShortcutText] = useState('');
|
||||||
const [shortcutDirection, setShortcutDirection] = useState('');
|
const [shortcutDirection, setShortcutDirection] = useState('');
|
||||||
|
const [reverseEpisodeOrder, setReverseEpisodeOrder] = useState(false);
|
||||||
const shortcutHintTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
const shortcutHintTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||||
|
|
||||||
// 换源相关状态
|
// 换源相关状态
|
||||||
@@ -1435,7 +1436,22 @@ function PlayPageClient() {
|
|||||||
>
|
>
|
||||||
<div className='p-6 h-full flex flex-col'>
|
<div className='p-6 h-full flex flex-col'>
|
||||||
<div className='flex items-center justify-between mb-6'>
|
<div className='flex items-center justify-between mb-6'>
|
||||||
<h3 className='text-white text-xl font-semibold'>选集列表</h3>
|
<div className='flex items-center gap-4'>
|
||||||
|
<h3 className='text-white text-xl font-semibold'>
|
||||||
|
选集列表
|
||||||
|
</h3>
|
||||||
|
{/* 倒序小字 */}
|
||||||
|
<span
|
||||||
|
onClick={() => setReverseEpisodeOrder((prev) => !prev)}
|
||||||
|
className={`text-sm cursor-pointer select-none transition-colors ${
|
||||||
|
reverseEpisodeOrder
|
||||||
|
? 'text-green-500'
|
||||||
|
: 'text-gray-400 hover:text-gray-500'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
倒序
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setShowEpisodePanel(false);
|
setShowEpisodePanel(false);
|
||||||
@@ -1465,7 +1481,13 @@ function PlayPageClient() {
|
|||||||
|
|
||||||
<div className='flex-1 overflow-y-auto'>
|
<div className='flex-1 overflow-y-auto'>
|
||||||
<div className='grid grid-cols-4 gap-3'>
|
<div className='grid grid-cols-4 gap-3'>
|
||||||
{Array.from({ length: totalEpisodes }, (_, idx) => (
|
{(reverseEpisodeOrder
|
||||||
|
? Array.from(
|
||||||
|
{ length: totalEpisodes },
|
||||||
|
(_, i) => i
|
||||||
|
).reverse()
|
||||||
|
: Array.from({ length: totalEpisodes }, (_, i) => i)
|
||||||
|
).map((idx) => (
|
||||||
<button
|
<button
|
||||||
key={idx}
|
key={idx}
|
||||||
onClick={() => handleEpisodeChange(idx)}
|
onClick={() => handleEpisodeChange(idx)}
|
||||||
|
|||||||
Reference in New Issue
Block a user