@playpilot/tpi 6.2.0 → 6.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/link-injections.js +8 -8
- package/package.json +1 -1
- package/src/lib/api/region.ts +6 -4
- package/src/lib/data/genres.json +0 -12
- package/src/routes/components/Explore/Empty.svelte +23 -0
- package/src/routes/components/Explore/Explore.svelte +11 -7
- package/src/routes/components/Explore/Filter/Filter.svelte +8 -5
- package/src/routes/components/TitlePoster.svelte +1 -1
- package/src/tests/lib/api/region.test.js +6 -0
- package/src/tests/routes/components/Explore/Explore.test.js +36 -0
- package/src/tests/routes/components/Explore/Filter/Filter.test.js +12 -0
package/package.json
CHANGED
package/src/lib/api/region.ts
CHANGED
|
@@ -10,12 +10,14 @@ export async function getRegionBasedOnIp(timeout = 5000): Promise<string> {
|
|
|
10
10
|
|
|
11
11
|
const data: { ip: string, country: string } = await response.json()
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
if (!
|
|
13
|
+
let region = data?.country?.toLowerCase()
|
|
14
|
+
if (!region) throw new Error('No country was returned by api.country.is')
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
if (region === 'gb') region = 'uk'
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
setSavedRegion(region)
|
|
19
|
+
|
|
20
|
+
return region
|
|
19
21
|
} catch (error: any) {
|
|
20
22
|
track(TrackingEvent.RegionRequestFailed, null, { message: error.message })
|
|
21
23
|
|
package/src/lib/data/genres.json
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<div class="empty">
|
|
2
|
+
<p>
|
|
3
|
+
<strong>No results were found</strong><br>
|
|
4
|
+
Sorry, we couldn't find anything matching your filter.
|
|
5
|
+
</p>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
<style lang="scss">
|
|
9
|
+
p {
|
|
10
|
+
margin: 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
strong {
|
|
14
|
+
font-size: theme(font-size-large);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.empty {
|
|
18
|
+
max-width: theme(explore-header-max-width, 600px);
|
|
19
|
+
padding: margin(2);
|
|
20
|
+
border-radius: theme(border-radius-large);
|
|
21
|
+
background: theme(lighter);
|
|
22
|
+
}
|
|
23
|
+
</style>
|
|
@@ -16,15 +16,16 @@
|
|
|
16
16
|
import ListTitleSkeleton from '../ListTitleSkeleton.svelte'
|
|
17
17
|
import Filter from './Filter/Filter.svelte'
|
|
18
18
|
import Search from './Filter/Search.svelte'
|
|
19
|
+
import Empty from './Empty.svelte'
|
|
19
20
|
|
|
20
21
|
const filter: ExploreFilter = $state({})
|
|
21
22
|
|
|
22
23
|
let element: HTMLElement | null = null
|
|
23
24
|
let titles: TitleData[] = $state([])
|
|
24
|
-
let page = 1
|
|
25
|
-
let searchQuery = ''
|
|
25
|
+
let page = $state(1)
|
|
26
26
|
let debounce: ReturnType<typeof setTimeout> | null = null
|
|
27
27
|
let latestRequestId = 0
|
|
28
|
+
let searchQuery = $state('')
|
|
28
29
|
let promise = $state(getTitlesForFilter())
|
|
29
30
|
let height: string | null = $state(null)
|
|
30
31
|
let width = $state(0)
|
|
@@ -70,8 +71,6 @@
|
|
|
70
71
|
|
|
71
72
|
const response = await fetchTitles(params)
|
|
72
73
|
|
|
73
|
-
if (!response?.results) throw new Error('Something went wrong when fetching titles in Explore')
|
|
74
|
-
|
|
75
74
|
if (requestId === latestRequestId) titles = [...titles, ...response.results]
|
|
76
75
|
|
|
77
76
|
return response
|
|
@@ -129,7 +128,7 @@
|
|
|
129
128
|
|
|
130
129
|
{#key grid}
|
|
131
130
|
<Search oninput={search} />
|
|
132
|
-
<Filter {filter} limit={!grid} onchange={setFilter} />
|
|
131
|
+
<Filter {filter} limit={!grid} onchange={setFilter} showSorting={!searchQuery} />
|
|
133
132
|
{/key}
|
|
134
133
|
</div>
|
|
135
134
|
|
|
@@ -155,8 +154,12 @@
|
|
|
155
154
|
<Button size="large" onclick={fetchMoreTitles}>Show more</Button>
|
|
156
155
|
</div>
|
|
157
156
|
{/if}
|
|
157
|
+
|
|
158
|
+
{#if !titles?.length && page === 1}
|
|
159
|
+
<Empty />
|
|
160
|
+
{/if}
|
|
158
161
|
{:catch}
|
|
159
|
-
Something went wrong
|
|
162
|
+
<p>Something went wrong</p>
|
|
160
163
|
{/await}
|
|
161
164
|
</div>
|
|
162
165
|
|
|
@@ -165,8 +168,9 @@
|
|
|
165
168
|
background: theme(explore-background, light);
|
|
166
169
|
border-radius: theme(border-radius-large);
|
|
167
170
|
max-width: theme(explore-max-width, 1200px);
|
|
171
|
+
min-height: 75vh;
|
|
168
172
|
margin: 0 auto;
|
|
169
|
-
padding: theme(explore-padding, margin(1) margin(1) margin(
|
|
173
|
+
padding: theme(explore-padding, margin(1) margin(1) margin(6));
|
|
170
174
|
overflow: auto;
|
|
171
175
|
font-family: theme(font-family);
|
|
172
176
|
font-family: theme(detail-font-family, font-family);
|
|
@@ -8,15 +8,16 @@
|
|
|
8
8
|
import Button from '../../Button.svelte'
|
|
9
9
|
import IconArrow from '../../Icons/IconArrow.svelte'
|
|
10
10
|
import IconFilter from '../../Icons/IconFilter.svelte'
|
|
11
|
-
import { scale } from 'svelte/transition'
|
|
11
|
+
import { fly, scale } from 'svelte/transition'
|
|
12
12
|
|
|
13
13
|
interface Props {
|
|
14
14
|
filter: ExploreFilter
|
|
15
15
|
onchange?: () => void
|
|
16
16
|
limit?: boolean
|
|
17
|
+
showSorting?: boolean
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
const { filter, onchange = () => null, limit = true }: Props = $props()
|
|
20
|
+
const { filter, onchange = () => null, limit = true, showSorting = true }: Props = $props()
|
|
20
21
|
|
|
21
22
|
const shownItemsLimit = 3
|
|
22
23
|
const items = [{
|
|
@@ -67,9 +68,11 @@
|
|
|
67
68
|
</Button>
|
|
68
69
|
{/if}
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
<
|
|
72
|
-
|
|
71
|
+
{#if showSorting}
|
|
72
|
+
<div class="sorting" transition:fly={{ x: 5, duration: 100 }}>
|
|
73
|
+
<FilterSorting {filter} {onchange} />
|
|
74
|
+
</div>
|
|
75
|
+
{/if}
|
|
73
76
|
</div>
|
|
74
77
|
</div>
|
|
75
78
|
|
|
@@ -87,4 +87,10 @@ describe('getRegionBasedOnIp', () => {
|
|
|
87
87
|
|
|
88
88
|
vi.useRealTimers()
|
|
89
89
|
})
|
|
90
|
+
|
|
91
|
+
it('Should use uk region when GB is returned by api endpoint', async () => {
|
|
92
|
+
fakeFetch({ response: { ip: '127.0.0.1', country: 'GB' } })
|
|
93
|
+
|
|
94
|
+
expect(await getRegionBasedOnIp()).toBe('uk')
|
|
95
|
+
})
|
|
90
96
|
})
|
|
@@ -172,4 +172,40 @@ describe('Explore.svelte', () => {
|
|
|
172
172
|
|
|
173
173
|
expect(fetchTitles).toHaveBeenCalledWith({ page: 1, page_size: 24, ordering: '-new' })
|
|
174
174
|
})
|
|
175
|
+
|
|
176
|
+
it('Should show empty message if no titles are returned for first page', async () => {
|
|
177
|
+
vi.mocked(fetchTitles).mockResolvedValue({ results: [], next: null, previous: null })
|
|
178
|
+
|
|
179
|
+
const { getByText } = render(Explore)
|
|
180
|
+
|
|
181
|
+
await waitFor(() => {
|
|
182
|
+
expect(getByText('No results were found')).toBeTruthy()
|
|
183
|
+
})
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it('Should not show empty message if no titles are returned for pages past the first page', async () => {
|
|
187
|
+
vi.mocked(fetchTitles).mockResolvedValue({ results: [title], next: 'truthy', previous: null })
|
|
188
|
+
|
|
189
|
+
const { getByText, queryByText } = render(Explore)
|
|
190
|
+
|
|
191
|
+
await waitFor(() => getByText('Show more'))
|
|
192
|
+
|
|
193
|
+
vi.mocked(fetchTitles).mockResolvedValue({ results: [], next: null, previous: null })
|
|
194
|
+
|
|
195
|
+
await fireEvent.click(getByText('Show more'))
|
|
196
|
+
|
|
197
|
+
await waitFor(() => {
|
|
198
|
+
expect(queryByText('No results were found')).not.toBeTruthy()
|
|
199
|
+
})
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('Should show error message if api responded with error', async () => {
|
|
203
|
+
vi.mocked(fetchTitles).mockRejectedValueOnce(null)
|
|
204
|
+
|
|
205
|
+
const { getByText } = render(Explore)
|
|
206
|
+
|
|
207
|
+
await waitFor(() => {
|
|
208
|
+
expect(getByText('Something went wrong')).toBeTruthy()
|
|
209
|
+
})
|
|
210
|
+
})
|
|
175
211
|
})
|
|
@@ -55,4 +55,16 @@ describe('Filter.svelte', () => {
|
|
|
55
55
|
|
|
56
56
|
expect(fetchProviders).toHaveBeenCalled()
|
|
57
57
|
})
|
|
58
|
+
|
|
59
|
+
it('Should not show sortings when showSortings is false', () => {
|
|
60
|
+
const { container } = render(Filter, { filter: {}, showSorting: false })
|
|
61
|
+
|
|
62
|
+
expect(container.querySelector('.sorting')).not.toBeTruthy()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('Should show sortings when showSortings is true', () => {
|
|
66
|
+
const { container } = render(Filter, { filter: {}, showSorting: true })
|
|
67
|
+
|
|
68
|
+
expect(container.querySelector('.sorting')).toBeTruthy()
|
|
69
|
+
})
|
|
58
70
|
})
|