diff --git a/.all-contributorsrc b/.all-contributorsrc index faa3f7534..3202486cc 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -755,6 +755,42 @@ "contributions": [ "doc" ] + }, + { + "login": "ceptonit", + "name": "ceptonit", + "avatar_url": "https://avatars.githubusercontent.com/u/12678743?v=4", + "profile": "https://github.com/ceptonit", + "contributions": [ + "doc" + ] + }, + { + "login": "aedelbro", + "name": "aedelbro", + "avatar_url": "https://avatars.githubusercontent.com/u/36162221?v=4", + "profile": "https://github.com/aedelbro", + "contributions": [ + "code" + ] + }, + { + "login": "lunks", + "name": "Pedro Nascimento", + "avatar_url": "https://avatars.githubusercontent.com/u/91118?v=4", + "profile": "http://twitter.com/lunks/", + "contributions": [ + "code" + ] + }, + { + "login": "owenvoke", + "name": "Owen Voke", + "avatar_url": "https://avatars.githubusercontent.com/u/1899334?v=4", + "profile": "https://voke.dev", + "contributions": [ + "code" + ] } ], "badgeTemplate": "-orange.svg\"/>", diff --git a/.github/holopin.yml b/.github/holopin.yml new file mode 100644 index 000000000..ee4edc81b --- /dev/null +++ b/.github/holopin.yml @@ -0,0 +1,5 @@ +organization: overseerr +defaultSticker: clcyagj1j329008l468ya8pu2 +stickers: + - id: clcyagj1j329008l468ya8pu2 + alias: overseerr-contributor diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05db03e1b..8c670f6b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..10926bbd9 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,41 @@ +name: 'CodeQL' + +on: + push: + branches: ['develop'] + pull_request: + branches: ['develop'] + schedule: + - cron: '50 7 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [javascript] + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + queries: +security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: '/language:${{ matrix.language }}' diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 6e0d8f3d8..e1e93de02 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -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 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 839b2245c..22c815138 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -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 diff --git a/.github/workflows/snap.yaml b/.github/workflows/snap.yaml index bf00e04d7..880c1d9e7 100644 --- a/.github/workflows/snap.yaml +++ b/.github/workflows/snap.yaml @@ -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 diff --git a/README.md b/README.md index d81193a2a..a17dad138 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,9 @@ - - +
@@ -76,110 +75,116 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d(
ref?: React.Ref (
break;
case 'ghost':
buttonStyle.push(
- 'text-white bg-transaprent border-gray-600 hover:border-gray-200 focus:border-gray-100 active:border-gray-100'
+ 'text-white bg-transparent border-gray-600 hover:border-gray-200 focus:border-gray-100 active:border-gray-100'
);
break;
case 'plex':
diff --git a/src/components/Common/ButtonWithDropdown/index.tsx b/src/components/Common/ButtonWithDropdown/index.tsx
index be6815b94..b5bc0cb64 100644
--- a/src/components/Common/ButtonWithDropdown/index.tsx
+++ b/src/components/Common/ButtonWithDropdown/index.tsx
@@ -1,7 +1,7 @@
import useClickOutside from '@app/hooks/useClickOutside';
import { withProperties } from '@app/utils/typeHelpers';
import { Transition } from '@headlessui/react';
-import { ChevronDownIcon } from '@heroicons/react/solid';
+import { ChevronDownIcon } from '@heroicons/react/24/solid';
import type { AnchorHTMLAttributes, ButtonHTMLAttributes } from 'react';
import { Fragment, useRef, useState } from 'react';
diff --git a/src/components/Common/ConfirmButton/index.tsx b/src/components/Common/ConfirmButton/index.tsx
index 1f5756cb9..4234da68a 100644
--- a/src/components/Common/ConfirmButton/index.tsx
+++ b/src/components/Common/ConfirmButton/index.tsx
@@ -1,6 +1,6 @@
import Button from '@app/components/Common/Button';
import useClickOutside from '@app/hooks/useClickOutside';
-import { useRef, useState } from 'react';
+import { forwardRef, useRef, useState } from 'react';
interface ConfirmButtonProps {
onClick: () => void;
@@ -9,50 +9,51 @@ interface ConfirmButtonProps {
children: React.ReactNode;
}
-const ConfirmButton = ({
- onClick,
- children,
- confirmText,
- className,
-}: ConfirmButtonProps) => {
- const ref = useRef(null);
- useClickOutside(ref, () => setIsClicked(false));
- const [isClicked, setIsClicked] = useState(false);
- return (
-
+ );
+ }
+);
+
+ConfirmButton.displayName = 'ConfirmButton';
export default ConfirmButton;
diff --git a/src/components/Common/MultiRangeSlider/index.tsx b/src/components/Common/MultiRangeSlider/index.tsx
new file mode 100644
index 000000000..c3da2b577
--- /dev/null
+++ b/src/components/Common/MultiRangeSlider/index.tsx
@@ -0,0 +1,113 @@
+import Tooltip from '@app/components/Common/Tooltip';
+import useDebouncedState from '@app/hooks/useDebouncedState';
+import { useEffect, useRef } from 'react';
+
+type MultiRangeSliderProps = {
+ min: number;
+ max: number;
+ defaultMinValue?: number;
+ defaultMaxValue?: number;
+ subText?: string;
+ onUpdateMin: (min: number) => void;
+ onUpdateMax: (max: number) => void;
+};
+
+const MultiRangeSlider = ({
+ min,
+ max,
+ defaultMinValue,
+ defaultMaxValue,
+ subText,
+ onUpdateMin,
+ onUpdateMax,
+}: MultiRangeSliderProps) => {
+ const touched = useRef(false);
+ const [valueMin, finalValueMin, setValueMin] = useDebouncedState(
+ defaultMinValue ?? min
+ );
+ const [valueMax, finalValueMax, setValueMax] = useDebouncedState(
+ defaultMaxValue ?? max
+ );
+
+ const minThumb = ((valueMin - min) / (max - min)) * 100;
+ const maxThumb = ((valueMax - min) / (max - min)) * 100;
+
+ useEffect(() => {
+ if (touched.current) {
+ onUpdateMin(finalValueMin);
+ }
+ }, [finalValueMin, onUpdateMin]);
+
+ useEffect(() => {
+ if (touched.current) {
+ onUpdateMax(finalValueMax);
+ }
+ }, [finalValueMax, onUpdateMax]);
+
+ useEffect(() => {
+ touched.current = false;
+ setValueMax(defaultMaxValue ?? max);
+ setValueMin(defaultMinValue ?? min);
+ }, [defaultMinValue, defaultMaxValue, setValueMax, setValueMin, min, max]);
+
+ return (
+
@@ -83,7 +83,7 @@ const SlideOver = ({
className="text-gray-200 transition duration-150 ease-in-out hover:text-white"
onClick={() => onClose()}
>
-
{data.mediaInfo?.downloadStatus?.map((status, index) => (
-