Skip to content

Commit

Permalink
iPad size UI (#73)
Browse files Browse the repository at this point in the history
Fixes #62
  • Loading branch information
andrew-codes authored Jan 3, 2024
2 parents e43fd1d + b9ee5b6 commit 7ce6c08
Show file tree
Hide file tree
Showing 16 changed files with 89 additions and 31 deletions.
14 changes: 14 additions & 0 deletions apps/playnite-web/src/api/layout/desktopLayout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { LayoutApi } from './types'

const layoutApi: LayoutApi = {
getGameDimensions: async function (
request: Request,
): Promise<[number, number]> {
const width = 300
const height = (width * 4) / 3

return [width, height]
},
}

export default layoutApi
17 changes: 17 additions & 0 deletions apps/playnite-web/src/api/layout/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import desktopLayout from './desktopLayout'
import tabletLayout from './tabletLayout'
import type { LayoutApi } from './types'

const inferredLayout: LayoutApi = {
getGameDimensions: function (request: Request): Promise<[number, number]> {
const userAgent = request.headers.get('user-agent')

if (userAgent?.includes('Mobile')) {
return tabletLayout.getGameDimensions(request)
}

return desktopLayout.getGameDimensions(request)
},
}

export default inferredLayout
14 changes: 14 additions & 0 deletions apps/playnite-web/src/api/layout/tabletLayout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { LayoutApi } from './types'

const layoutApi: LayoutApi = {
getGameDimensions: async function (
request: Request,
): Promise<[number, number]> {
const width = 200
const height = (width * 4) / 3

return [width, height]
},
}

export default layoutApi
5 changes: 5 additions & 0 deletions apps/playnite-web/src/api/layout/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
interface LayoutApi {
getGameDimensions: (request: Request) => Promise<[number, number]>
}

export { LayoutApi }
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
34 changes: 17 additions & 17 deletions apps/playnite-web/src/components/GameList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import _ from 'lodash'
import { FC, useMemo } from 'react'
import useDimensions from 'react-use-dimensions'
import { styled } from 'styled-components'
import type { Game } from '../api/types'
import type { Game } from '../api/playnite/types'

const { chunk, groupBy } = _

Expand Down Expand Up @@ -79,16 +79,16 @@ const ListItem = styled.li.attrs<{

const GameList: FC<{
games: Game[]
maxGameWidth: number
maxGameHeight: number
gameWidth: number
gameHeight: number
spacing: number
Game: FC<{
cover: string
game: Game
height: number
width: number
}>
}> = ({ games, spacing, maxGameWidth, maxGameHeight, Game }) => {
}> = ({ games, spacing, gameWidth, gameHeight, Game }) => {
const normalizedGames = useMemo<Game[][]>(
() => Object.values(groupBy(games, 'sortName')),
[games],
Expand All @@ -98,48 +98,48 @@ const GameList: FC<{

const [rows, columns, perPage] = useMemo(() => {
if (actualWidth && actualHeight) {
const rows = Math.floor(actualHeight / maxGameHeight)
const columns = Math.floor(actualWidth / maxGameWidth)
const rows = Math.floor(actualHeight / gameHeight)
const columns = Math.floor(actualWidth / gameWidth)
return [rows, columns, rows * columns]
}

return [null, null, 0]
}, [actualWidth, actualHeight, maxGameHeight, maxGameWidth])
}, [actualWidth, actualHeight, gameHeight, gameWidth])

const pages = chunk(normalizedGames, perPage)

return (
<FillParent ref={ref}>
{!!rows && !!columns ? (
<Viewport
$height={rows * (maxGameHeight + spacing * 2)}
$width={columns * (maxGameWidth + spacing * 2)}
$height={rows * (gameHeight + spacing * 2)}
$width={columns * (gameWidth + spacing * 2)}
>
<GamePages
$height={rows * (maxGameHeight + spacing * 2)}
$width={pages.length * columns * (maxGameWidth + spacing * 2)}
$height={rows * (gameHeight + spacing * 2)}
$width={pages.length * columns * (gameWidth + spacing * 2)}
>
{pages.map((page: Game[], index: number) => {
return (
<GridPage
key={index}
$height={rows * (maxGameHeight + spacing * 2)}
$width={columns * (maxGameWidth + spacing * 2)}
$height={rows * (gameHeight + spacing * 2)}
$width={columns * (gameWidth + spacing * 2)}
>
{page.map((games: Game) => {
const game = games[0]

return (
<ListItem
key={game.id}
$height={maxGameHeight}
$width={maxGameWidth}
$height={gameHeight}
$width={gameWidth}
$spacing={spacing}
>
<Game
cover={`coverArt/${game.oid.type}:${game.oid.id}`}
height={maxGameHeight}
width={maxGameWidth}
height={gameHeight}
width={gameWidth}
game={game}
/>
</ListItem>
Expand Down
2 changes: 1 addition & 1 deletion apps/playnite-web/src/components/GameListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FC } from 'react'
import { styled } from 'styled-components'
import type { Game } from '../api/types'
import type { Game } from '../api/playnite/types'

const Game = styled.section.attrs<{
$cover: string
Expand Down
8 changes: 4 additions & 4 deletions apps/playnite-web/src/routes/_index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import type { LoaderFunctionArgs } from '@remix-run/node'
import { json } from '@remix-run/node'
import { useLoaderData } from '@remix-run/react'
import { styled } from 'styled-components'
import PlayniteApi from '../api'
import type { Game, Playlist } from '../api/types'
import PlayniteApi from '../api/playnite'
import type { Game, Playlist } from '../api/playnite/types'
import GameList from '../components/GameList.js'
import GameListItem from '../components/GameListItem'

Expand Down Expand Up @@ -65,8 +65,8 @@ function Index() {
<GameList
Game={GameListItem}
games={games}
maxGameHeight={maxGameHeight - spacing * 2}
maxGameWidth={maxGameWidth - spacing * 2}
gameHeight={maxGameHeight - spacing * 2}
gameWidth={maxGameWidth - spacing * 2}
spacing={spacing}
/>
</PlaylistListItem>
Expand Down
22 changes: 15 additions & 7 deletions apps/playnite-web/src/routes/browse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import type { LoaderFunctionArgs } from '@remix-run/node'
import { json } from '@remix-run/node'
import { useLoaderData } from '@remix-run/react'
import { styled } from 'styled-components'
import PlayniteApi from '../api'
import { Game } from '../api/types'
import inferredLayout from '../api/layout'
import PlayniteApi from '../api/playnite'
import type { Game } from '../api/playnite/types'
import GameList from '../components/GameList'
import GameListItem from '../components/GameListItem'

Expand All @@ -23,8 +24,13 @@ async function loader({ request }: LoaderFunctionArgs) {
return 0
})

const [gameWidth, gameHeight] =
await inferredLayout.getGameDimensions(request)

return json({
games,
gameWidth,
gameHeight,
})
}

Expand All @@ -37,12 +43,14 @@ const Main = styled.main`
`

const spacing = 8
const maxGameWidth = 300
const maxGameHeight = (maxGameWidth * 4) / 3

function Index() {
const { games } = useLoaderData<typeof loader>() as unknown as {
const { games, gameWidth, gameHeight } = useLoaderData<
typeof loader
>() as unknown as {
games: Game[]
gameWidth: number
gameHeight: number
}

return (
Expand All @@ -51,8 +59,8 @@ function Index() {
<GameList
Game={GameListItem}
games={games}
maxGameHeight={maxGameHeight - spacing * 2}
maxGameWidth={maxGameWidth - spacing * 2}
gameHeight={gameHeight - spacing * 2}
gameWidth={gameWidth - spacing * 2}
spacing={spacing}
/>
</Main>
Expand Down
4 changes: 2 additions & 2 deletions apps/playnite-web/src/routes/coverArt.$oid.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { LoaderFunctionArgs } from '@remix-run/node'
import createDebugger from 'debug'
import { $params } from 'remix-routes'
import PlayniteApi from '../api'
import Oid from '../api/Oid'
import PlayniteApi from '../api/playnite'
import Oid from '../api/playnite/Oid'

const debug = createDebugger('playnite-web/route/coverArt')

Expand Down

0 comments on commit 7ce6c08

Please sign in to comment.