Fixed images on rtl mode
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
import { Link } from '@inertiajs/react';
|
||||
|
||||
export default function GuestLayout({ children }) {
|
||||
return (
|
||||
<div className="flex min-h-svh w-full items-center justify-center p-6 md:p-10">
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { Head, Link, useForm } from '@inertiajs/react';
|
||||
import GuestLayout from "@/Layouts/GuestLayout.jsx";
|
||||
|
||||
import InputError from '@/components/InputError';
|
||||
import Checkbox from '@/components/Checkbox';
|
||||
import PrimaryButton from '@/components/PrimaryButton';
|
||||
import TextInput from '@/components/TextInput';
|
||||
import { Head, Link, useForm } from '@inertiajs/react';
|
||||
import { Label } from "@/components/ui/label"
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card.jsx";
|
||||
import GuestLayout from "@/Layouts/GuestLayout.jsx";
|
||||
import { Alert, AlertDescription } from "@/components/ui/alert.jsx";
|
||||
|
||||
export default function Login({ status, canResetPassword }) {
|
||||
@@ -45,7 +46,7 @@ export default function Login({ status, canResetPassword }) {
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="email">E-mail Address</Label>
|
||||
<TextInput type="email" id="email" placeholder="me@yumj.in" value={ data.email }
|
||||
onChange={ (e) => setData('email', e.target.value) } required />
|
||||
tabIndex="1" onChange={ (e) => setData('email', e.target.value) } required />
|
||||
<InputError message={ errors.email } className="mt-2" />
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
@@ -57,26 +58,23 @@ export default function Login({ status, canResetPassword }) {
|
||||
</Link>
|
||||
</div>
|
||||
<TextInput id="password" type="password" name="password" value={ data.password }
|
||||
autoComplete="current-password"
|
||||
autoComplete="current-password" tabIndex="2"
|
||||
onChange={ (e) => setData('password', e.target.value) } />
|
||||
<InputError message={ errors.password } className="mt-2" />
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="remember"
|
||||
name="remember"
|
||||
checked={ data.remember }
|
||||
onChange={ (e) =>
|
||||
setData('remember', e.target.checked)
|
||||
}
|
||||
/>
|
||||
<Checkbox id="remember" tabIndex="3" name="remember" checked={ data.remember }
|
||||
onChange={ (e) => setData('remember', e.target.checked) } />
|
||||
<label htmlFor="remember"
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">Remember me</label>
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<PrimaryButton type="submit" disabled={ processing }
|
||||
className="w-full">Login</PrimaryButton>
|
||||
<PrimaryButton type="submit" disabled={ processing } tabIndex="4" className="w-full">
|
||||
Login
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
<div className="mt-4 text-center text-sm">
|
||||
Don't have an account?
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
import { Head, Link, router } from '@inertiajs/react';
|
||||
import { Plus, Star, ArrowDownNarrowWide, ArrowUpNarrowWide } from 'lucide-react';
|
||||
import { Plus, Star, ArrowDownNarrowWide, ArrowUpNarrowWide, ChevronsLeft, ChevronsRight } from 'lucide-react';
|
||||
|
||||
import AppLayout from '@/Layouts/AppLayout.jsx';
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
|
||||
export default function Chapters({ auth, comic, chapters, histories }) {
|
||||
export default function Chapters({ auth, comic, chapters, histories, offset }) {
|
||||
|
||||
const [group, setGroup] = useState('default');
|
||||
const [favourites, setFavourites] = useState(auth.user.favourites);
|
||||
@@ -113,11 +113,13 @@ export default function Chapters({ auth, comic, chapters, histories }) {
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="text-right pr-3">Authors</td>
|
||||
<td>{ comic.comic.author.map(a => (
|
||||
<td>
|
||||
{ comic.comic.author.map(a => (
|
||||
<Badge key={ a.path_word } className="m-2" variant="outline">
|
||||
<Link href={ route('comics.author', [a.path_word]) }>{ a.name }</Link>
|
||||
</Badge>
|
||||
) ) }</td>
|
||||
) ) }
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="text-right pr-3">Description</td>
|
||||
@@ -125,7 +127,11 @@ export default function Chapters({ auth, comic, chapters, histories }) {
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="text-right pr-3">Updated At</td>
|
||||
<td>{ comic.comic.datetime_updated }</td>
|
||||
<td>
|
||||
<Link href={ route('comics.read', [comic.comic.path_word, comic.comic.last_chapter.uuid])}>
|
||||
{ comic.comic.datetime_updated } - { comic.comic.last_chapter.name }
|
||||
</Link>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -151,9 +157,23 @@ export default function Chapters({ auth, comic, chapters, histories }) {
|
||||
</div>
|
||||
<TabsContent value={ group }>
|
||||
<div className="w-full grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 xl:grid-cols-12 gap-1">
|
||||
{ (chapters.total > chapters.limit && chapters.offset > 0) && (
|
||||
<Button size="sm" variant="outline" asChild>
|
||||
<Link href="?" only={['chapters', 'offset']} headers={{ offset: parseInt(chapters.offset) - chapters.limit }}>
|
||||
<ChevronsLeft /> Prev
|
||||
</Link>
|
||||
</Button>
|
||||
) }
|
||||
{ chapters.list.sort((a, b) => ascending ? (a.index - b.index) : (b.index - a.index)).map(c => (
|
||||
<ComicChapterLink key={ c.uuid } { ...c } />
|
||||
) ) }
|
||||
{ (chapters.total > chapters.limit && chapters.offset === 0) && (
|
||||
<Button size="sm" variant="outline" asChild>
|
||||
<Link href="?" only={['chapters', 'offset']} headers={{ offset: parseInt(chapters.offset) + chapters.limit }}>
|
||||
Next <ChevronsRight />
|
||||
</Link>
|
||||
</Button>
|
||||
) }
|
||||
</div>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
@@ -97,7 +97,7 @@ export default function Histories({ auth, histories }) {
|
||||
{ h.comic.name }
|
||||
</Link>
|
||||
</TableCell>
|
||||
<TableCell className="hidden lg:block">{ datetimeConversion(h.created_at) }</TableCell>
|
||||
<TableCell className="hidden lg:block">{ datetimeConversion(h.read_at) }</TableCell>
|
||||
</TableRow>
|
||||
)) }
|
||||
</TableBody>
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function Index({ comics, offset, auth }) {
|
||||
<CardContent>
|
||||
<CardTitle><Link href={ `/comic/${ props.path_word }` }>{ props.name }</Link></CardTitle>
|
||||
<CardDescription className="pt-2">
|
||||
{ props.author.map(a => (
|
||||
{ props.author && props.author.map(a => (
|
||||
<Badge className="m-1" key={ a.path_word } variant="outline">
|
||||
{ a.name }
|
||||
</Badge>)
|
||||
|
||||
@@ -76,7 +76,7 @@ export default function Read({ auth, comic, chapter }) {
|
||||
} else if (divDimensions[0] > divDimensions[1] && readingMode === 'utd') {
|
||||
imgStyles = { width: '50%' };
|
||||
} else if (readingMode === 'rtl') {
|
||||
imgStyles = { height: 'calc(100dvh - 90px)' };
|
||||
imgStyles = { width: '100%', height: 'calc(100dvh - 90px)', objectFit: 'contain' };
|
||||
}
|
||||
|
||||
const handleImageClick = (e) => {
|
||||
@@ -156,6 +156,10 @@ export default function Read({ auth, comic, chapter }) {
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Button variant="ghost">
|
||||
{ currentImage } / { chapter.sorted.length }
|
||||
</Button>
|
||||
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
@@ -204,10 +208,6 @@ export default function Read({ auth, comic, chapter }) {
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
) }
|
||||
|
||||
<Button variant="ghost">
|
||||
{ currentImage } / { chapter.sorted.length }
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useState } from 'react';
|
||||
import { Link, router, usePage } from '@inertiajs/react';
|
||||
|
||||
import { BadgeCheck, ChevronsUpDown, Star, History, ChevronDown, LogOut, Search, Book } from 'lucide-react';
|
||||
import { BadgeCheck, ChevronsUpDown, Star, History, ChevronDown, LogOut, Search, Book, TableOfContents } from 'lucide-react';
|
||||
|
||||
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
|
||||
@@ -57,7 +57,7 @@ export function AppSidebar({ auth }) {
|
||||
</div>
|
||||
<div className="flex flex-col gap-0.5 leading-none">
|
||||
<span className="font-semibold">Comic</span>
|
||||
<span>0.0.0</span>
|
||||
<span>0.0.1</span>
|
||||
</div>
|
||||
</Link>
|
||||
</SidebarMenuButton>
|
||||
@@ -73,6 +73,21 @@ export function AppSidebar({ auth }) {
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
</SidebarHeader>
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel>Others</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton asChild>
|
||||
<Link href={ route('comics.index')}>
|
||||
<TableOfContents />
|
||||
<span>Manual</span>
|
||||
</Link>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
<Collapsible defaultOpen className="group/collapsible">
|
||||
<SidebarGroup>
|
||||
<SidebarGroupLabel asChild>
|
||||
|
||||
Reference in New Issue
Block a user