Compare commits
9 Commits
v1.32.1
...
feat/reque
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92c7ac3906 | ||
|
|
d954328911 | ||
|
|
3e43586acc | ||
|
|
7040da1334 | ||
|
|
9d10e6a88c | ||
|
|
8942eb8b7c | ||
|
|
51b05cd8fb | ||
|
|
374c78c989 | ||
|
|
507693881b |
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -94,9 +94,9 @@ jobs:
|
||||
run: |
|
||||
failures=(neutral, skipped, timed_out, action_required)
|
||||
if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then
|
||||
echo ::set-output name=status::failure
|
||||
echo "status=failure" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo ::set-output name=status::$WORKFLOW_CONCLUSION
|
||||
echo "status=$WORKFLOW_CONCLUSION" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Post Status to Discord
|
||||
uses: sarisia/actions-status-discord@v1
|
||||
|
||||
2
.github/workflows/preview.yml
vendored
2
.github/workflows/preview.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/}
|
||||
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
|
||||
11
.github/workflows/release.yml
vendored
11
.github/workflows/release.yml
vendored
@@ -67,9 +67,9 @@ jobs:
|
||||
run: |
|
||||
git fetch --prune --tags
|
||||
if [[ $GITHUB_REF == refs/tags/* || $GITHUB_REF == refs/heads/master ]]; then
|
||||
echo ::set-output name=RELEASE::stable
|
||||
echo "RELEASE=stable" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo ::set-output name=RELEASE::edge
|
||||
echo "RELEASE=edge" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Set Up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
@@ -91,8 +91,9 @@ jobs:
|
||||
snap: ${{ steps.build.outputs.snap }}
|
||||
- name: Publish Snap Package
|
||||
uses: snapcore/action-publish@v1
|
||||
env:
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_LOGIN }}
|
||||
with:
|
||||
store_login: ${{ secrets.SNAP_LOGIN }}
|
||||
snap: ${{ steps.build.outputs.snap }}
|
||||
release: ${{ steps.prepare.outputs.RELEASE }}
|
||||
|
||||
@@ -109,9 +110,9 @@ jobs:
|
||||
run: |
|
||||
failures=(neutral, skipped, timed_out, action_required)
|
||||
if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then
|
||||
echo ::set-output name=status::failure
|
||||
echo "status=failure" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo ::set-output name=status::$WORKFLOW_CONCLUSION
|
||||
echo "status=$WORKFLOW_CONCLUSION" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Post Status to Discord
|
||||
uses: sarisia/actions-status-discord@v1
|
||||
|
||||
11
.github/workflows/snap.yaml
vendored
11
.github/workflows/snap.yaml
vendored
@@ -35,9 +35,9 @@ jobs:
|
||||
run: |
|
||||
git fetch --prune --unshallow --tags
|
||||
if [[ $GITHUB_REF == refs/tags/* || $GITHUB_REF == refs/heads/master ]]; then
|
||||
echo ::set-output name=RELEASE::stable
|
||||
echo "RELEASE=stable" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo ::set-output name=RELEASE::edge
|
||||
echo "RELEASE=edge" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Set Up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
@@ -57,8 +57,9 @@ jobs:
|
||||
snap: ${{ steps.build.outputs.snap }}
|
||||
- name: Publish Snap Package
|
||||
uses: snapcore/action-publish@v1
|
||||
env:
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_LOGIN }}
|
||||
with:
|
||||
store_login: ${{ secrets.SNAP_LOGIN }}
|
||||
snap: ${{ steps.build.outputs.snap }}
|
||||
release: ${{ steps.prepare.outputs.RELEASE }}
|
||||
|
||||
@@ -75,9 +76,9 @@ jobs:
|
||||
run: |
|
||||
failures=(neutral, skipped, timed_out, action_required)
|
||||
if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then
|
||||
echo ::set-output name=status::failure
|
||||
echo "status=failure" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo ::set-output name=status::$WORKFLOW_CONCLUSION
|
||||
echo "status=$WORKFLOW_CONCLUSION" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Post Status to Discord
|
||||
uses: sarisia/actions-status-discord@v1
|
||||
|
||||
@@ -4418,7 +4418,7 @@ paths:
|
||||
- in: query
|
||||
name: genre
|
||||
schema:
|
||||
type: number
|
||||
type: string
|
||||
example: 18
|
||||
- in: query
|
||||
name: network
|
||||
@@ -4900,6 +4900,7 @@ paths:
|
||||
approved,
|
||||
available,
|
||||
pending,
|
||||
requested,
|
||||
processing,
|
||||
unavailable,
|
||||
failed,
|
||||
|
||||
@@ -226,12 +226,13 @@ class PlexAPI {
|
||||
id: string,
|
||||
options: { addedAt: number } = {
|
||||
addedAt: Date.now() - 1000 * 60 * 60,
|
||||
}
|
||||
},
|
||||
mediaType: 'movie' | 'show'
|
||||
): Promise<PlexLibraryItem[]> {
|
||||
const response = await this.plexClient.query<PlexLibraryResponse>({
|
||||
uri: `/library/sections/${id}/all?sort=addedAt%3Adesc&addedAt>>=${Math.floor(
|
||||
options.addedAt / 1000
|
||||
)}`,
|
||||
uri: `/library/sections/${id}/all?type=${
|
||||
mediaType === 'show' ? '4' : '1'
|
||||
}&sort=addedAt%3Adesc&addedAt>>=${Math.floor(options.addedAt / 1000)}`,
|
||||
extraHeaders: {
|
||||
'X-Plex-Container-Start': `0`,
|
||||
'X-Plex-Container-Size': `500`,
|
||||
|
||||
@@ -85,7 +85,7 @@ interface DiscoverTvOptions {
|
||||
voteAverageLte?: string;
|
||||
includeEmptyReleaseDate?: boolean;
|
||||
originalLanguage?: string;
|
||||
genre?: number;
|
||||
genre?: string;
|
||||
network?: number;
|
||||
keywords?: string;
|
||||
sortBy?: SortOptions;
|
||||
|
||||
@@ -96,7 +96,8 @@ class PlexScanner
|
||||
// We remove 10 minutes from the last scan as a buffer
|
||||
addedAt: library.lastScan - 1000 * 60 * 10,
|
||||
}
|
||||
: undefined
|
||||
: undefined,
|
||||
library.type
|
||||
);
|
||||
|
||||
// Bundle items up by rating keys
|
||||
|
||||
@@ -356,7 +356,7 @@ discoverRoutes.get('/tv', async (req, res, next) => {
|
||||
page: Number(query.page),
|
||||
sortBy: query.sortBy as SortOptions,
|
||||
language: req.locale ?? query.language,
|
||||
genre: query.genre ? Number(query.genre) : undefined,
|
||||
genre: query.genre,
|
||||
network: query.network ? Number(query.network) : undefined,
|
||||
firstAirDateLte: query.firstAirDateLte
|
||||
? new Date(query.firstAirDateLte).toISOString().split('T')[0]
|
||||
@@ -491,7 +491,7 @@ discoverRoutes.get<{ genreId: string }>(
|
||||
const data = await tmdb.getDiscoverTv({
|
||||
page: Number(req.query.page),
|
||||
language: req.locale ?? (req.query.language as string),
|
||||
genre: Number(req.params.genreId),
|
||||
genre: req.params.genreId,
|
||||
});
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
@@ -770,7 +770,9 @@ discoverRoutes.get<{ language: string }, GenreSliderItem[]>(
|
||||
|
||||
await Promise.all(
|
||||
genres.map(async (genre) => {
|
||||
const genreData = await tmdb.getDiscoverTv({ genre: genre.id });
|
||||
const genreData = await tmdb.getDiscoverTv({
|
||||
genre: genre.id.toString(),
|
||||
});
|
||||
|
||||
mappedGenres.push({
|
||||
id: genre.id,
|
||||
|
||||
@@ -70,6 +70,9 @@ requestRoutes.get<Record<string, unknown>, RequestResultsResponse>(
|
||||
case 'available':
|
||||
mediaStatusFilter = [MediaStatus.AVAILABLE];
|
||||
break;
|
||||
case 'requested':
|
||||
mediaStatusFilter = [MediaStatus.PROCESSING];
|
||||
break;
|
||||
case 'processing':
|
||||
case 'unavailable':
|
||||
mediaStatusFilter = [
|
||||
|
||||
@@ -37,6 +37,7 @@ const AirDateBadge = ({ airDate }: AirDateBadgeProps) => {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
timeZone: 'UTC',
|
||||
})}
|
||||
</Badge>
|
||||
{showRelative && (
|
||||
|
||||
@@ -91,10 +91,10 @@ const DiscoverTv = () => {
|
||||
<option value={SortOptions.PopularityAsc}>
|
||||
{intl.formatMessage(messages.sortPopularityAsc)}
|
||||
</option>
|
||||
<option value={SortOptions.ReleaseDateDesc}>
|
||||
<option value={SortOptions.FirstAirDateDesc}>
|
||||
{intl.formatMessage(messages.sortFirstAirDateDesc)}
|
||||
</option>
|
||||
<option value={SortOptions.ReleaseDateAsc}>
|
||||
<option value={SortOptions.FirstAirDateAsc}>
|
||||
{intl.formatMessage(messages.sortFirstAirDateAsc)}
|
||||
</option>
|
||||
<option value={SortOptions.TmdbRatingDesc}>
|
||||
|
||||
@@ -167,27 +167,29 @@ const MobileMenu = () => {
|
||||
</Transition>
|
||||
<div className="padding-bottom-safe border-t border-gray-600 bg-gray-800 bg-opacity-90 backdrop-blur">
|
||||
<div className="flex h-full items-center justify-between px-6 py-4 text-gray-100">
|
||||
{filteredLinks.slice(0, 4).map((link) => {
|
||||
const isActive =
|
||||
router.pathname.match(link.activeRegExp) && !isOpen;
|
||||
return (
|
||||
<Link key={`mobile-menu-link-${link.href}`} href={link.href}>
|
||||
<a
|
||||
className={`flex flex-col items-center space-y-1 ${
|
||||
isActive ? 'text-indigo-500' : ''
|
||||
}`}
|
||||
>
|
||||
{cloneElement(
|
||||
isActive ? link.svgIconSelected : link.svgIcon,
|
||||
{
|
||||
className: 'h-6 w-6',
|
||||
}
|
||||
)}
|
||||
</a>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
{filteredLinks.length > 4 && (
|
||||
{filteredLinks
|
||||
.slice(0, filteredLinks.length === 5 ? 5 : 4)
|
||||
.map((link) => {
|
||||
const isActive =
|
||||
router.pathname.match(link.activeRegExp) && !isOpen;
|
||||
return (
|
||||
<Link key={`mobile-menu-link-${link.href}`} href={link.href}>
|
||||
<a
|
||||
className={`flex flex-col items-center space-y-1 ${
|
||||
isActive ? 'text-indigo-500' : ''
|
||||
}`}
|
||||
>
|
||||
{cloneElement(
|
||||
isActive ? link.svgIconSelected : link.svgIcon,
|
||||
{
|
||||
className: 'h-6 w-6',
|
||||
}
|
||||
)}
|
||||
</a>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
{filteredLinks.length > 4 && filteredLinks.length !== 5 && (
|
||||
<button
|
||||
className={`flex flex-col items-center space-y-1 ${
|
||||
isOpen ? 'text-indigo-500' : ''
|
||||
|
||||
@@ -621,6 +621,7 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
timeZone: 'UTC',
|
||||
})}
|
||||
</span>
|
||||
</span>
|
||||
@@ -640,6 +641,7 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
timeZone: 'UTC',
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -91,11 +91,13 @@ const PersonDetails = () => {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
timeZone: 'UTC',
|
||||
}),
|
||||
deathdate: intl.formatDate(data.deathday, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
timeZone: 'UTC',
|
||||
}),
|
||||
})
|
||||
);
|
||||
@@ -106,6 +108,7 @@ const PersonDetails = () => {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
timeZone: 'UTC',
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
@@ -31,6 +31,7 @@ enum Filter {
|
||||
PENDING = 'pending',
|
||||
APPROVED = 'approved',
|
||||
PROCESSING = 'processing',
|
||||
REQUESTED = 'requested',
|
||||
AVAILABLE = 'available',
|
||||
UNAVAILABLE = 'unavailable',
|
||||
FAILED = 'failed',
|
||||
@@ -165,6 +166,9 @@ const RequestList = () => {
|
||||
<option value="approved">
|
||||
{intl.formatMessage(globalMessages.approved)}
|
||||
</option>
|
||||
<option value="requested">
|
||||
{intl.formatMessage(globalMessages.requested)}
|
||||
</option>
|
||||
<option value="processing">
|
||||
{intl.formatMessage(globalMessages.processing)}
|
||||
</option>
|
||||
|
||||
@@ -844,6 +844,7 @@ const TvDetails = ({ tv }: TvDetailsProps) => {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
timeZone: 'UTC',
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
@@ -858,6 +859,7 @@ const TvDetails = ({ tv }: TvDetailsProps) => {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
timeZone: 'UTC',
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -453,7 +453,15 @@
|
||||
}
|
||||
|
||||
input[type='range']::-webkit-slider-thumb {
|
||||
@apply rounded-full bg-indigo-500;
|
||||
@apply rounded-full border-0 bg-indigo-500;
|
||||
pointer-events: all;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
input[type='range']::-moz-range-thumb {
|
||||
@apply rounded-full border-0 bg-indigo-500;
|
||||
pointer-events: all;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
||||
Reference in New Issue
Block a user