mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-20 14:37:43 +01:00
Modal is almost ready after bookmark button
This commit is contained in:
commit
fae66c8db5
15 changed files with 1750 additions and 1479 deletions
|
@ -16,7 +16,7 @@
|
|||
|
||||
|
||||
## Referrers
|
||||
- [Priacy Subreddit Megathread](https://www.reddit.com/r/Piracy/s/iymSloEpXn)
|
||||
- [Piracy Subreddit Megathread](https://www.reddit.com/r/Piracy/s/iymSloEpXn)
|
||||
- [Toon's Instances](https://erynith.github.io/movie-web-instances)
|
||||
- [Sudo-Flix docs](https://sussy-code.github.io/docs)
|
||||
- [Sudo-Flix Discord](https://discord.gg/r5cYshWM4G)
|
||||
|
|
56
package.json
56
package.json
|
@ -41,15 +41,15 @@
|
|||
"@sozialhelden/ietf-language-tags": "^5.4.2",
|
||||
"@types/node-forge": "^1.3.11",
|
||||
"classnames": "^2.5.1",
|
||||
"core-js": "^3.37.0",
|
||||
"core-js": "^3.37.1",
|
||||
"detect-browser": "^5.3.0",
|
||||
"dompurify": "^3.1.1",
|
||||
"flag-icons": "^7.2.1",
|
||||
"dompurify": "^3.1.6",
|
||||
"flag-icons": "^7.2.3",
|
||||
"focus-trap-react": "^10.2.3",
|
||||
"fscreen": "^1.2.0",
|
||||
"fuse.js": "^7.0.0",
|
||||
"hls.js": "^1.5.8",
|
||||
"i18next": "^23.11.2",
|
||||
"hls.js": "^1.5.13",
|
||||
"i18next": "^23.11.5",
|
||||
"immer": "^10.1.1",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
|
@ -62,33 +62,33 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"react-ga4": "^2.1.0",
|
||||
"react-google-recaptcha-v3": "^1.10.1",
|
||||
"react-helmet-async": "^2.0.4",
|
||||
"react-i18next": "^14.1.1",
|
||||
"react-helmet-async": "^2.0.5",
|
||||
"react-i18next": "^14.1.2",
|
||||
"react-lazy-with-preload": "^2.2.1",
|
||||
"react-loading-skeleton": "^3.4.0",
|
||||
"react-router-dom": "^6.23.0",
|
||||
"react-router-dom": "^6.24.1",
|
||||
"react-sticky-el": "^2.1.0",
|
||||
"react-use": "^17.5.0",
|
||||
"semver": "^7.6.0",
|
||||
"semver": "^7.6.2",
|
||||
"slugify": "^1.6.6",
|
||||
"subsrt-ts": "^2.1.2",
|
||||
"zustand": "^4.5.2"
|
||||
"zustand": "^4.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.4",
|
||||
"@babel/preset-env": "^7.24.4",
|
||||
"@babel/preset-typescript": "^7.24.1",
|
||||
"@rollup/wasm-node": "^4.17.0",
|
||||
"@types/chromecast-caf-sender": "^1.0.9",
|
||||
"@babel/core": "^7.24.7",
|
||||
"@babel/preset-env": "^7.24.7",
|
||||
"@babel/preset-typescript": "^7.24.7",
|
||||
"@rollup/wasm-node": "^4.18.0",
|
||||
"@types/chromecast-caf-sender": "^1.0.10",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/dompurify": "^3.0.5",
|
||||
"@types/fscreen": "^1.0.4",
|
||||
"@types/lodash.isequal": "^4.5.8",
|
||||
"@types/lodash.merge": "^4.6.9",
|
||||
"@types/lodash.throttle": "^4.1.9",
|
||||
"@types/node": "^20.12.7",
|
||||
"@types/node": "^20.14.10",
|
||||
"@types/pako": "^2.0.3",
|
||||
"@types/react": "^18.3.1",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/react-helmet": "^6.1.11",
|
||||
"@types/react-lazy-load-image-component": "^1.6.4",
|
||||
|
@ -99,7 +99,7 @@
|
|||
"@types/semver": "^7.5.8",
|
||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||
"@typescript-eslint/parser": "^6.21.0",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.57.0",
|
||||
|
@ -107,30 +107,30 @@
|
|||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-jsx-a11y": "^6.8.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.9.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-react": "7.33.2",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"glob": "^10.3.12",
|
||||
"glob": "^10.4.3",
|
||||
"handlebars": "^4.7.8",
|
||||
"jsdom": "^23.2.0",
|
||||
"postcss": "^8.4.38",
|
||||
"postcss": "^8.4.39",
|
||||
"postcss-rtl": "^2.0.0",
|
||||
"postcss-rtlcss": "^4.0.9",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier": "^3.3.2",
|
||||
"prettier-plugin-tailwindcss": "^0.5.14",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"tailwind-scrollbar": "^3.1.0",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"tailwindcss": "^3.4.4",
|
||||
"tailwindcss-themer": "^4.0.0",
|
||||
"type-fest": "^4.17.0",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.2.10",
|
||||
"type-fest": "^4.21.0",
|
||||
"typescript": "^5.5.3",
|
||||
"vite": "^5.3.3",
|
||||
"vite-plugin-checker": "^0.6.4",
|
||||
"vite-plugin-package-version": "^1.1.0",
|
||||
"vite-plugin-pwa": "^0.17.5",
|
||||
"vite-plugin-static-copy": "^1.0.3",
|
||||
"vitest": "^1.5.2",
|
||||
"vite-plugin-static-copy": "^1.0.6",
|
||||
"vitest": "^1.6.0",
|
||||
"workbox-window": "^7.1.0"
|
||||
},
|
||||
"pnpm": {
|
||||
|
|
2364
pnpm-lock.yaml
2364
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -1,286 +1,359 @@
|
|||
{
|
||||
"about": {
|
||||
"description": "sudo-flix е уеб приложение, което търси в интернет за стриймове. Екипът се стреми към предимно минималистичен подход при консумирането на съдържание.",
|
||||
"faqTitle": "Общи въпроси",
|
||||
"q1": {
|
||||
"body": "sudo-flix не хоства никакво съдържание. Когато кликнете върху нещо, за да го гледате, се търси в интернет избраното медийно съдържание (На екрана за зареждане и в раздела \"Източници на видео\" можете да видите кой източник използвате). Медийното съдържание никога не се качва от sudo-flix, всичко става чрез този механизъм за търсене.",
|
||||
"title": "От къде идва съдържанието?"
|
||||
},
|
||||
"q2": {
|
||||
"body": "Невъзможно е да поискате сериал или филм, sudo-flix не управлява никакво съдържание. Всичко се гледа чрез източници в интернет.",
|
||||
"title": "Къде мога да поискам определен сериал или филм?"
|
||||
},
|
||||
"q3": {
|
||||
"body": "Резултатите от търсенето ни се поддържат от базата данни за филми (The Movie Database - TMDB) и се показват, независимо дали източниците ни реално разполагат със съдържанието.",
|
||||
"title": "Резултатите от търсенето показват сериала или филма, защо не мога да го пусна?"
|
||||
},
|
||||
"title": "Относно sudo-flix"
|
||||
},
|
||||
"actions": {
|
||||
"copied": "Копиране",
|
||||
"copy": "Копирай"
|
||||
},
|
||||
"auth": {
|
||||
"createAccount": "Все още нямате акаунт? <0>Създайте акаунт.</0>",
|
||||
"deviceNameLabel": "Име на устройството",
|
||||
"deviceNamePlaceholder": "Личен телефон",
|
||||
"generate": {
|
||||
"description": "Вашата паролна фраза служи като потребителско име и парола. Уверете се, че я пазите в безопасност, тъй като ще трябва да я въведете, за да влезете в своя акаунт.",
|
||||
"next": "Запазих паролната си фраза",
|
||||
"passphraseFrameLabel": "Паролна фраза",
|
||||
"title": "Вашата паролна фраза"
|
||||
},
|
||||
"hasAccount": "Вече имате акаунт? <0>Влезте тук.</0>",
|
||||
"login": {
|
||||
"description": "Моля, въведете своята паролна фраза, за да влезете в своя акаунт",
|
||||
"deviceLengthError": "Моля, въведете името на устройството",
|
||||
"passphraseLabel": "12-думена паролна фраза",
|
||||
"passphrasePlaceholder": "Паролна фраза",
|
||||
"submit": "Вход",
|
||||
"title": "Влезте в своя акаунт",
|
||||
"validationError": "Некоректна или непълна паролна фраза"
|
||||
},
|
||||
"register": {
|
||||
"information": {
|
||||
"color1": "Профилен цвят едно",
|
||||
"color2": "Профилен цвят две",
|
||||
"header": "Въведете име за устройството си и изберете цветове и потребителска икона по ваш избор",
|
||||
"icon": "Потребителска икона",
|
||||
"next": "Напред",
|
||||
"title": "Информация за акаунта"
|
||||
}
|
||||
},
|
||||
"trust": {
|
||||
"failed": {
|
||||
"text": "Конфигурирахте ли го правилно?",
|
||||
"title": "Неуспешно свързване със сървъра"
|
||||
},
|
||||
"host": "Вие се свързвате към <0>{{hostname}}</0> - моля, потвърдете, че му вярвате, преди да създадете акаунт",
|
||||
"no": "Върнете се назад",
|
||||
"title": "Вярвате ли на този сървър?",
|
||||
"yes": "Вярвам на този сървър"
|
||||
},
|
||||
"verify": {
|
||||
"description": "Моля, въведете паролната фраза от по-рано, за да потвърдите, че сте я запазили, и за да създадете своя акаунт",
|
||||
"invalidData": "Данните не са валидни",
|
||||
"noMatch": "Паролната фраза не съвпада",
|
||||
"passphraseLabel": "Вашата 12-думена паролна фраза",
|
||||
"recaptchaFailed": "Валидацията на ReCaptcha не беше успешна",
|
||||
"register": "Създаване на акаунт",
|
||||
"title": "Потвърдете вашата паролна фраза"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"badge": "Счупи се",
|
||||
"details": "Детайли за грешката",
|
||||
"reloadPage": "Презаредете страницата",
|
||||
"showError": "Покажи детайлите за грешката",
|
||||
"title": "Сблъскахме се с грешка!"
|
||||
},
|
||||
"footer": {
|
||||
"legal": {
|
||||
"disclaimer": "Внимание",
|
||||
"disclaimerText": "sudo-flix не хоства никакви файлове, а просто предоставя връзки към услуги от трета страна. Правните въпроси следва да се разглеждат с доставчиците на файлове. sudo-flix не носи отговорност за никакви медийни файлове, предоставени от видео доставчици."
|
||||
},
|
||||
"links": {
|
||||
"discord": "Discord",
|
||||
"dmca": "DMCA",
|
||||
"github": "Github"
|
||||
},
|
||||
"tagline": "Гледайте любимите си предавания и филми с това отворено-код стрийминг приложение."
|
||||
},
|
||||
"global": {
|
||||
"name": "sudo-flix",
|
||||
"pages": {
|
||||
"about": "За нас",
|
||||
"dmca": "DMCA",
|
||||
"login": "Вход",
|
||||
"pagetitle": "{{title}} - sudo-flix",
|
||||
"register": "Регистрация",
|
||||
"settings": "Настройки"
|
||||
}
|
||||
},
|
||||
"home": {
|
||||
"bookmarks": {
|
||||
"sectionTitle": "Отметки"
|
||||
},
|
||||
"continueWatching": {
|
||||
"sectionTitle": "Продължи гледането"
|
||||
},
|
||||
"mediaList": {
|
||||
"stopEditing": "Спри редактирането"
|
||||
},
|
||||
"search": {
|
||||
"allResults": "Това е всичко, което имаме!",
|
||||
"failed": "Неуспешно намиране на медия, опитайте отново!",
|
||||
"loading": "Зареждане...",
|
||||
"noResults": "Не успяхме да намерим нищо!",
|
||||
"placeholder": {
|
||||
"default": "Какво искате да гледате?",
|
||||
"extra": []
|
||||
},
|
||||
"sectionTitle": "Резултати от търсенето"
|
||||
},
|
||||
"titles": {
|
||||
"day": {
|
||||
"default": "Какво бихте искали да гледате този следобед?",
|
||||
"extra": [
|
||||
"Чувствате ли се авантюристично? \"Джурасик Парк\" може да бъде перфектният избор."
|
||||
]
|
||||
},
|
||||
"morning": {
|
||||
"default": "Какво бихте искали да гледате тази сутрин?",
|
||||
"extra": ["Чух, че Before Sunrise е добър"]
|
||||
},
|
||||
"night": {
|
||||
"default": "Какво бихте искали да гледате тази вечер?",
|
||||
"extra": ["Изморен? Чух, че Екзорсистът е добър."]
|
||||
}
|
||||
}
|
||||
},
|
||||
"media": {
|
||||
"episodeDisplay": "S{{season}} E{{episode}}",
|
||||
"types": {
|
||||
"movie": "Филм",
|
||||
"show": "Сериал"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"banner": {
|
||||
"offline": "Проверете вашата интернет връзка"
|
||||
},
|
||||
"menu": {
|
||||
"about": "За нас",
|
||||
"logout": "Излез",
|
||||
"register": "Синхронизиране с облак",
|
||||
"settings": "Настройки",
|
||||
"support": "поддържа"
|
||||
}
|
||||
},
|
||||
"notFound": {
|
||||
"badge": "Не е намерено",
|
||||
"goHome": "Обратно към началото",
|
||||
"message": "Търсихме навсякъде: под кошчетата, в килера, зад проксито, но в крайна сметка не успяхме да намерим страницата, която търсите.",
|
||||
"title": "Тази страница не можа да бъде намерена"
|
||||
},
|
||||
"overlays": {
|
||||
"close": "Затвори"
|
||||
},
|
||||
"player": {
|
||||
"back": {
|
||||
"default": "Обратно към началото",
|
||||
"short": "Назад"
|
||||
},
|
||||
"casting": {
|
||||
"enabled": "Предава се към устройството..."
|
||||
},
|
||||
"menus": {
|
||||
"downloads": {
|
||||
"disclaimer": "Изтеглянията се вземат директно от доставчика. sudo-flix няма контрол върху това как се предоставят изтеглянията.",
|
||||
"downloadSubtitle": "Изтеглете текущите субтитри",
|
||||
"downloadVideo": "Изтегляне на видео",
|
||||
"hlsDisclaimer": "Изтеглянията се вземат директно от доставчика. sudo-flix няма контрол върху това как се предоставят изтеглянията. Моля, имайте предвид, че изтегляте HLS плейлист, това е предназначено за потребители, запознати с усъвършенствано мултимедийно поточно предаване.",
|
||||
"onAndroid": {
|
||||
"1": "За да изтеглите на Android, щракнете върху бутона за изтегляне, след което на новата страница <bold>докоснете и задръжте</bold> видеоклипа, след което изберете <bold>запазване</bold>.",
|
||||
"shortTitle": "Изтегляне / Android",
|
||||
"title": "Изтегляне на Android"
|
||||
"about": {
|
||||
"description": "sudo-flix е уеб приложение, което търси в интернет за стриймове. Екипът се стреми към предимно минималистичен подход при консумирането на съдържание.",
|
||||
"faqTitle": "Общи въпроси",
|
||||
"q1": {
|
||||
"body": "sudo-flix не хоства никакво съдържание. Когато кликнете върху нещо, за да го гледате, се търси в интернет избраното медийно съдържание (На екрана за зареждане и в раздела \"Източници на видео\" можете да видите кой източник използвате). Медийното съдържание никога не се качва от sudo-flix, всичко става чрез този механизъм за търсене.",
|
||||
"title": "От къде идва съдържанието?"
|
||||
},
|
||||
"onIos": {
|
||||
"1": "За да изтеглите на iOS, щракнете върху бутона за изтегляне, след което на новата страница щракнете върху <bold><ios_share /></bold>, след което върху <bold>Запазване във файлове <ios_files /></bold>.",
|
||||
"shortTitle": "Изтегляне / iOS",
|
||||
"title": "Изтегляне на iOS"
|
||||
"q2": {
|
||||
"body": "Невъзможно е да поискате сериал или филм, sudo-flix не управлява никакво съдържание. Всичко се гледа чрез източници в интернет.",
|
||||
"title": "Къде мога да поискам определен сериал или филм?"
|
||||
},
|
||||
"onPc": {
|
||||
"1": "На компютър щракнете върху бутона за изтегляне, след което на новата страница щракнете с десния бутон върху видеоклипа и изберете <bold>Запазване на видеоклипа като</bold>",
|
||||
"shortTitle": "Изтегляне / компютър",
|
||||
"title": "Изтегляне на компютър"
|
||||
"q3": {
|
||||
"body": "Резултатите от търсенето ни се поддържат от базата данни за филми (The Movie Database - TMDB) и се показват, независимо дали източниците ни реално разполагат със съдържанието.",
|
||||
"title": "Резултатите от търсенето показват сериала или филма, защо не мога да го пусна?"
|
||||
},
|
||||
"title": "Изтегли"
|
||||
},
|
||||
"episodes": {
|
||||
"button": "епизоди",
|
||||
"emptyState": "Няма епизоди в този сезон, проверете отново по-късно!",
|
||||
"episodeBadge": "E{{episode}}",
|
||||
"loadingError": "Грешка при зареждането на сезона",
|
||||
"loadingList": "Зареждане...",
|
||||
"loadingTitle": "Зареждане..."
|
||||
},
|
||||
"playback": {
|
||||
"speedLabel": "Скорост на възпроизвеждане",
|
||||
"title": "Настройки за възпроизвеждане"
|
||||
},
|
||||
"quality": {
|
||||
"automaticLabel": "Автоматично качество",
|
||||
"hint": "Можете да опитате <0>да превключите източника</0>, за да получите различни опции за качество.",
|
||||
"iosNoQuality": "Поради ограниченията, определени от Apple, изборът на качество не е наличен в iOS за този източник. Можете да опитате <0>да превключите към друг източник</0>, за да получите различни опции за качество.",
|
||||
"title": "качество"
|
||||
},
|
||||
"settings": {
|
||||
"downloadItem": "Изтегли",
|
||||
"enableSubtitles": "включи субтитрите",
|
||||
"experienceSection": "Изживяване при гледане",
|
||||
"playbackItem": "Настройки за възпроизвеждане",
|
||||
"qualityItem": "качество",
|
||||
"sourceItem": "Видео източници",
|
||||
"subtitleItem": "Настройки на субтитрите",
|
||||
"videoSection": "Видео настройки"
|
||||
},
|
||||
"sources": {
|
||||
"failed": {
|
||||
"text": "Възникна грешка при опит за намиране на видеоклипове, моля, опитайте с друг източник.",
|
||||
"title": "Неуспешно изстъргване"
|
||||
"title": "Относно sudo-flix",
|
||||
"q5": {
|
||||
"title": "Как мога да разбера повече?",
|
||||
"body": "Е, sudo-flix има акаунт в Twitter, който може да бъде намерен в долния колонтитул на тази страница, както и връзка към изходния код в Github."
|
||||
},
|
||||
"noEmbeds": {
|
||||
"text": "Не можахме да намерим никакви вграждания, моля, опитайте с друг източник.",
|
||||
"title": "Няма намерени вграждания"
|
||||
},
|
||||
"noStream": {
|
||||
"text": "Този източник няма потоци за този филм или шоу.",
|
||||
"title": "Няма поток"
|
||||
},
|
||||
"title": "Източници",
|
||||
"unknownOption": "неизвестен"
|
||||
},
|
||||
"subtitles": {
|
||||
"customChoice": "Качете субтитри",
|
||||
"customizeLabel": "Персонализиране",
|
||||
"offChoice": "изключи",
|
||||
"settings": {
|
||||
"backlink": "Персонализирани субтитри",
|
||||
"delay": "Забавяне на субтитрите",
|
||||
"fixCapitals": "Коригиране на главни букви"
|
||||
},
|
||||
"title": "субтитри",
|
||||
"unknownLanguage": "неизвестен"
|
||||
}
|
||||
"q4": {
|
||||
"title": "Какво ще кажете за моите данни и други неща?",
|
||||
"body": "Всички данни се синхронизират със sudo-бекенда, който е различен от бекенда на общността и се хоства независимо от мен, всеки може да използва и това."
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"failed": {
|
||||
"badge": "Провал",
|
||||
"homeButton": "Обратно към началото",
|
||||
"text": "Неуспешно зареждане на метаданните на носителя от TMDB. Моля, проверете дали TMDB не работи или е блокиран във вашата интернет връзка.",
|
||||
"title": "Неуспешно зареждане на метаданните"
|
||||
},
|
||||
"notFound": {
|
||||
"actions": {
|
||||
"copied": "Копиране",
|
||||
"copy": "Копирай"
|
||||
},
|
||||
"auth": {
|
||||
"createAccount": "Все още нямате акаунт? <0>Създайте акаунт.</0>",
|
||||
"deviceNameLabel": "Име на устройството",
|
||||
"deviceNamePlaceholder": "Личен телефон",
|
||||
"generate": {
|
||||
"description": "Вашата паролна фраза служи като потребителско име и парола. Уверете се, че я пазите в безопасност, тъй като ще трябва да я въведете, за да влезете в своя акаунт.",
|
||||
"next": "Запазих паролната си фраза",
|
||||
"passphraseFrameLabel": "Паролна фраза",
|
||||
"title": "Вашата паролна фраза"
|
||||
},
|
||||
"hasAccount": "Вече имате акаунт? <0>Влезте тук.</0>",
|
||||
"login": {
|
||||
"description": "Моля, въведете своята паролна фраза, за да влезете в своя акаунт",
|
||||
"deviceLengthError": "Моля, въведете името на устройството",
|
||||
"passphraseLabel": "12-думена паролна фраза",
|
||||
"passphrasePlaceholder": "Паролна фраза",
|
||||
"submit": "Вход",
|
||||
"title": "Влезте в своя акаунт",
|
||||
"validationError": "Некоректна или непълна паролна фраза"
|
||||
},
|
||||
"register": {
|
||||
"information": {
|
||||
"color1": "Профилен цвят едно",
|
||||
"color2": "Профилен цвят две",
|
||||
"header": "Въведете име за устройството си и изберете цветове и потребителска икона по ваш избор",
|
||||
"icon": "Потребителска икона",
|
||||
"next": "Напред",
|
||||
"title": "Информация за акаунта"
|
||||
}
|
||||
},
|
||||
"trust": {
|
||||
"failed": {
|
||||
"text": "Конфигурирахте ли го правилно?",
|
||||
"title": "Неуспешно свързване със сървъра"
|
||||
},
|
||||
"host": "Вие се свързвате към <0>{{hostname}}</0> - моля, потвърдете, че му вярвате, преди да създадете акаунт",
|
||||
"no": "Върнете се назад",
|
||||
"title": "Вярвате ли на този сървър?",
|
||||
"yes": "Вярвам на този сървър",
|
||||
"noHostTitle": "Сървърът не е конфигуриран!",
|
||||
"noHost": "Сървърът не е конфигуриран, следователно не можете да създадете акаунт"
|
||||
},
|
||||
"verify": {
|
||||
"description": "Моля, въведете паролната фраза от по-рано, за да потвърдите, че сте я запазили, и за да създадете своя акаунт",
|
||||
"invalidData": "Данните не са валидни",
|
||||
"noMatch": "Паролната фраза не съвпада",
|
||||
"passphraseLabel": "Вашата 12-думена паролна фраза",
|
||||
"recaptchaFailed": "Валидацията на ReCaptcha не беше успешна",
|
||||
"register": "Създаване на акаунт",
|
||||
"title": "Потвърдете вашата паролна фраза"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"badge": "Счупи се",
|
||||
"details": "Детайли за грешката",
|
||||
"reloadPage": "Презаредете страницата",
|
||||
"showError": "Покажи детайлите за грешката",
|
||||
"title": "Сблъскахме се с грешка!"
|
||||
},
|
||||
"footer": {
|
||||
"legal": {
|
||||
"disclaimer": "Внимание",
|
||||
"disclaimerText": "sudo-flix не хоства никакви файлове, а просто предоставя връзки към услуги от трета страна. Правните въпроси следва да се разглеждат с доставчиците на файлове. sudo-flix не носи отговорност за никакви медийни файлове, предоставени от видео доставчици."
|
||||
},
|
||||
"links": {
|
||||
"discord": "Discord",
|
||||
"dmca": "DMCA",
|
||||
"github": "Github",
|
||||
"twitter": "Twitter"
|
||||
},
|
||||
"tagline": "Гледайте любимите си предавания и филми с това отворено-код стрийминг приложение."
|
||||
},
|
||||
"global": {
|
||||
"name": "sudo-flix",
|
||||
"pages": {
|
||||
"about": "За нас",
|
||||
"dmca": "DMCA",
|
||||
"login": "Вход",
|
||||
"pagetitle": "{{title}} - sudo-flix",
|
||||
"register": "Регистрация",
|
||||
"settings": "Настройки",
|
||||
"discover": "Открийте",
|
||||
"support": "поддържа",
|
||||
"onboarding": "Настройвам"
|
||||
}
|
||||
},
|
||||
"home": {
|
||||
"bookmarks": {
|
||||
"sectionTitle": "Отметки"
|
||||
},
|
||||
"continueWatching": {
|
||||
"sectionTitle": "Продължи гледането"
|
||||
},
|
||||
"mediaList": {
|
||||
"stopEditing": "Спри редактирането"
|
||||
},
|
||||
"search": {
|
||||
"allResults": "Това е всичко, което имаме!",
|
||||
"failed": "Неуспешно намиране на медия, опитайте отново!",
|
||||
"loading": "Зареждане...",
|
||||
"noResults": "Не успяхме да намерим нищо!",
|
||||
"placeholder": {
|
||||
"default": "Какво искате да гледате?",
|
||||
"extra": [
|
||||
"За какво имаш настроение?",
|
||||
"Трябва ли да изтрием историята на браузъра ви?",
|
||||
"Какво искате да предавате?",
|
||||
"Sudo-Flix е най-добрият сайт досега!",
|
||||
"Какво е в списъка ви за гледане днес?",
|
||||
"Как беше денят ти?",
|
||||
"Лошото ми е, че сайтът никога не работи...",
|
||||
"Не е ли sudo-flix най-добрият?",
|
||||
">ᴗ<"
|
||||
]
|
||||
},
|
||||
"sectionTitle": "Резултати от търсенето",
|
||||
"empty": {
|
||||
"default": "Добре дошли, намерете медии за гледане тук!",
|
||||
"extra": [
|
||||
"Тук няма нищо :(",
|
||||
"Толкова празно...",
|
||||
"Такава празнота.",
|
||||
"Здравей нов потребител :3"
|
||||
]
|
||||
},
|
||||
"discoverMore": "Открий повече",
|
||||
"discover": "Открийте"
|
||||
},
|
||||
"titles": {
|
||||
"day": {
|
||||
"default": "Какво бихте искали да гледате този следобед?",
|
||||
"extra": [
|
||||
"Viva la sudo-flix!"
|
||||
]
|
||||
},
|
||||
"morning": {
|
||||
"default": "Какво бихте искали да гледате тази сутрин?",
|
||||
"extra": [
|
||||
"Viva la sudo-flix!"
|
||||
]
|
||||
},
|
||||
"night": {
|
||||
"default": "Какво бихте искали да гледате тази вечер?",
|
||||
"extra": [
|
||||
"Viva la sudo-flix!"
|
||||
]
|
||||
},
|
||||
"69": {
|
||||
"default": "За нещо пикантно?",
|
||||
"extra": [
|
||||
"Честит 69 ден 😘!"
|
||||
]
|
||||
},
|
||||
"420": {
|
||||
"extra": [
|
||||
"Честит 4/20 🥳!"
|
||||
],
|
||||
"default": "Какво бихте искали да гледате този 4/20?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"media": {
|
||||
"episodeDisplay": "S{{season}} E{{episode}}",
|
||||
"types": {
|
||||
"movie": "Филм",
|
||||
"show": "Сериал"
|
||||
},
|
||||
"unreleased": "Неиздавана"
|
||||
},
|
||||
"navigation": {
|
||||
"banner": {
|
||||
"offline": "Проверете вашата интернет връзка"
|
||||
},
|
||||
"menu": {
|
||||
"about": "За нас",
|
||||
"logout": "Излез",
|
||||
"register": "Синхронизиране с облак",
|
||||
"settings": "Настройки",
|
||||
"support": "поддържа",
|
||||
"discover": "Открийте"
|
||||
}
|
||||
},
|
||||
"notFound": {
|
||||
"badge": "Не е намерено",
|
||||
"homeButton": "Обратно към началото",
|
||||
"text": "Не успяхме да намерим медията, която поискахте. Или е бил премахнат, или сте променили URL адреса.",
|
||||
"title": "Тази медия не можа да бъде намерена."
|
||||
}
|
||||
"goHome": "Обратно към началото",
|
||||
"message": "Търсихме навсякъде: под кошчетата, в килера, зад проксито, но в крайна сметка не успяхме да намерим страницата, която търсите. (ಥ﹏ಥ)",
|
||||
"title": "Тази страница не можа да бъде намерена",
|
||||
"reloadButton": "Опитай пак"
|
||||
},
|
||||
"nextEpisode": {
|
||||
"cancel": "Отказ",
|
||||
"next": "Следващ епизод"
|
||||
"overlays": {
|
||||
"close": "Затвори"
|
||||
},
|
||||
"playbackError": {
|
||||
"badge": "Грешка при възпроизвеждане",
|
||||
"errors": {
|
||||
"errorAborted": "Извличането на медията беше прекратено по искане на потребителя.",
|
||||
"errorDecode": "Въпреки че преди това беше определено като използваем, възникна грешка при опит за декодиране на медийния ресурс, което доведе до грешка.",
|
||||
"errorGenericMedia": "Възникна неизвестна медийна грешка.",
|
||||
"errorNetwork": "Възникна някакъв вид мрежова грешка, която попречи на медията да бъде успешно извлечена, въпреки че преди това е била достъпна.",
|
||||
"errorNotSupported": "Обектът медия или доставчик на медия не се поддържа."
|
||||
}
|
||||
"player": {
|
||||
"back": {
|
||||
"default": "Обратно към началото",
|
||||
"short": "Назад"
|
||||
},
|
||||
"casting": {
|
||||
"enabled": "Предава се към устройството..."
|
||||
},
|
||||
"menus": {
|
||||
"downloads": {
|
||||
"disclaimer": "Изтеглянията се вземат директно от доставчика. sudo-flix няма контрол върху това как се предоставят изтеглянията.",
|
||||
"downloadSubtitle": "Изтеглете текущите субтитри",
|
||||
"downloadVideo": "Изтегляне на видео",
|
||||
"hlsDisclaimer": "Изтеглянията се вземат директно от доставчика. sudo-flix няма контрол върху това как се предоставят изтеглянията. Моля, имайте предвид, че изтегляте HLS плейлист, това е предназначено за потребители, запознати с усъвършенствано мултимедийно поточно предаване.",
|
||||
"onAndroid": {
|
||||
"1": "За да изтеглите на Android, щракнете върху бутона за изтегляне, след което на новата страница <bold>докоснете и задръжте</bold> видеоклипа, след което изберете <bold>запазване</bold>.",
|
||||
"shortTitle": "Изтегляне / Android",
|
||||
"title": "Изтегляне на Android"
|
||||
},
|
||||
"onIos": {
|
||||
"1": "За да изтеглите на iOS, щракнете върху бутона за изтегляне, след което на новата страница щракнете върху <bold><ios_share /></bold>, след което върху <bold>Запазване във файлове <ios_files /></bold>.",
|
||||
"shortTitle": "Изтегляне / iOS",
|
||||
"title": "Изтегляне на iOS"
|
||||
},
|
||||
"onPc": {
|
||||
"1": "На компютър щракнете върху бутона за изтегляне, след което на новата страница щракнете с десния бутон върху видеоклипа и изберете <bold>Запазване на видеоклипа като</bold>",
|
||||
"shortTitle": "Изтегляне / компютър",
|
||||
"title": "Изтегляне на компютър"
|
||||
},
|
||||
"title": "Изтегли"
|
||||
},
|
||||
"episodes": {
|
||||
"button": "епизоди",
|
||||
"emptyState": "Няма епизоди в този сезон, проверете отново по-късно!",
|
||||
"episodeBadge": "E{{episode}}",
|
||||
"loadingError": "Грешка при зареждането на сезона",
|
||||
"loadingList": "Зареждане...",
|
||||
"loadingTitle": "Зареждане..."
|
||||
},
|
||||
"playback": {
|
||||
"speedLabel": "Скорост на възпроизвеждане",
|
||||
"title": "Настройки за възпроизвеждане"
|
||||
},
|
||||
"quality": {
|
||||
"automaticLabel": "Автоматично качество",
|
||||
"hint": "Можете да опитате <0>да превключите източника</0>, за да получите различни опции за качество.",
|
||||
"iosNoQuality": "Поради ограниченията, определени от Apple, изборът на качество не е наличен в iOS за този източник. Можете да опитате <0>да превключите към друг източник</0>, за да получите различни опции за качество.",
|
||||
"title": "качество"
|
||||
},
|
||||
"settings": {
|
||||
"downloadItem": "Изтегли",
|
||||
"enableSubtitles": "включи субтитрите",
|
||||
"experienceSection": "Изживяване при гледане",
|
||||
"playbackItem": "Настройки за възпроизвеждане",
|
||||
"qualityItem": "качество",
|
||||
"sourceItem": "Видео източници",
|
||||
"subtitleItem": "Настройки на субтитрите",
|
||||
"videoSection": "Видео настройки"
|
||||
},
|
||||
"sources": {
|
||||
"failed": {
|
||||
"text": "Възникна грешка при опит за намиране на видеоклипове, моля, опитайте с друг източник.",
|
||||
"title": "Неуспешно изстъргване"
|
||||
},
|
||||
"noEmbeds": {
|
||||
"text": "Не можахме да намерим никакви вграждания, моля, опитайте с друг източник.",
|
||||
"title": "Няма намерени вграждания"
|
||||
},
|
||||
"noStream": {
|
||||
"text": "Този източник няма потоци за този филм или шоу.",
|
||||
"title": "Няма поток"
|
||||
},
|
||||
"title": "Източници",
|
||||
"unknownOption": "неизвестен"
|
||||
},
|
||||
"subtitles": {
|
||||
"customChoice": "Качете субтитри",
|
||||
"customizeLabel": "Персонализиране",
|
||||
"offChoice": "изключи",
|
||||
"settings": {
|
||||
"backlink": "Персонализирани субтитри",
|
||||
"delay": "Забавяне на субтитрите",
|
||||
"fixCapitals": "Коригиране на главни букви"
|
||||
},
|
||||
"title": "субтитри",
|
||||
"unknownLanguage": "неизвестен"
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"failed": {
|
||||
"badge": "Провал",
|
||||
"homeButton": "Обратно към началото",
|
||||
"text": "Неуспешно зареждане на метаданните на носителя от TMDB. Моля, проверете дали TMDB не работи или е блокиран във вашата интернет връзка.",
|
||||
"title": "Неуспешно зареждане на метаданните"
|
||||
},
|
||||
"notFound": {
|
||||
"badge": "Не е намерено",
|
||||
"homeButton": "Обратно към началото",
|
||||
"text": "Не успяхме да намерим медията, която поискахте. Или е бил премахнат, или сте променили URL адреса.",
|
||||
"title": "Тази медия не можа да бъде намерена."
|
||||
}
|
||||
},
|
||||
"nextEpisode": {
|
||||
"cancel": "Отказ",
|
||||
"next": "Следващ епизод"
|
||||
},
|
||||
"playbackError": {
|
||||
"badge": "Грешка при възпроизвеждане",
|
||||
"errors": {
|
||||
"errorAborted": "Извличането на медията беше прекратено по искане на потребителя.",
|
||||
"errorDecode": "Въпреки че преди това беше определено като използваем, възникна грешка при опит за декодиране на медийния ресурс, което доведе до грешка.",
|
||||
"errorGenericMedia": "Възникна неизвестна медийна грешка.",
|
||||
"errorNetwork": "Възникна някакъв вид мрежова грешка, която попречи на медията да бъде успешно извлечена, въпреки че преди това е била достъпна.",
|
||||
"errorNotSupported": "Обектът медия или доставчик на медия не се поддържа."
|
||||
}
|
||||
}
|
||||
},
|
||||
"downtimeNotice": {
|
||||
"badge": "Проблеми",
|
||||
"goHome": "Прибирай се",
|
||||
"timeFrame": "<bold>March 31th 11:00 PM - 5:00 AM EST</bold>",
|
||||
"title": "Проблеми с доставчика",
|
||||
"message": "sudo-flix.lol отново има проблеми с някои доставчици, ако не можете да намерите или пуснете шоу, моля, променете източника. Очаквайте тази грешка да продължи през времената по-долу."
|
||||
},
|
||||
"onboarding": {
|
||||
"defaultConfirm": {
|
||||
"cancel": "Отказ",
|
||||
"confirm": "Използвайте настройките по подразбиране",
|
||||
"title": "Сигурен ли си?",
|
||||
"description": "Настройката по подразбиране няма най-добрите потоци и може да бъде непоносимо бавна. ( ͠° ͟ʖ ͡°)"
|
||||
},
|
||||
"extension": {
|
||||
"back": "Върни се",
|
||||
"explainer": "С помощта на разширението на браузъра можете да получите най-добрите потоци, които предлагаме. Само с проста инсталация. 👌"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -180,6 +180,12 @@
|
|||
"extra": [
|
||||
"Glædelig 4/20 🥳!"
|
||||
]
|
||||
},
|
||||
"69": {
|
||||
"default": "Har du lyst til at \"hygge\"?",
|
||||
"extra": [
|
||||
"Glædelig 69-dag 😘!"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -456,7 +462,7 @@
|
|||
"shortRemaining": "-{{timeLeft}}"
|
||||
},
|
||||
"turnstile": {
|
||||
"description": "Bevis at du er et menneske ved at udfylde Captcha'en til højre. Dette er for at holde sudo-flix.lol sikker!",
|
||||
"description": "Bevis at du er et menneske ved at udføre den hurtige opgave, det er for at holde sudo-flix sikker.",
|
||||
"verifyingHumanity": "Bekræfter at du er et menneske... (^▽^)👍",
|
||||
"title": "Er du en robot 🤖?",
|
||||
"error": "Kunne ikke bekræfte at du er et menneske! Prøv venligst igen."
|
||||
|
@ -544,7 +550,8 @@
|
|||
"default": "Standard",
|
||||
"gray": "Grå",
|
||||
"red": "Rød",
|
||||
"teal": "Blågrøn"
|
||||
"teal": "Blågrøn",
|
||||
"blck": "BLCK"
|
||||
},
|
||||
"title": "Udseende"
|
||||
},
|
||||
|
|
|
@ -14,7 +14,15 @@
|
|||
"body": "Nos résultats de recherche sont alimentés par The Movie Database (TMDB) et s'affichent indépendamment de la disponibilité réelle du contenu dans nos sources.",
|
||||
"title": "Les résultats de la recherche affichent la série ou le film, pourquoi ne puis-je pas le lire ?"
|
||||
},
|
||||
"title": "À propos de sudo-flix"
|
||||
"title": "À propos de sudo-flix",
|
||||
"q4": {
|
||||
"body": "La synchronisation de toutes les données se fait sur la sudo-backend, qui diffère de la backend de communauté et est hébergé indépendamment par moi. Tout le monde peut également l'utiliser.",
|
||||
"title": "Qu'en est-il de mes données ?"
|
||||
},
|
||||
"q5": {
|
||||
"body": "Sudo-flix possède un compte twitter qui peut être trouvé en bas de cette page ainsi qu'un lien vers le code source sur Github.",
|
||||
"title": "Comment puis-je en savoir plus ?"
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"copied": "Copié",
|
||||
|
@ -87,7 +95,8 @@
|
|||
"links": {
|
||||
"discord": "Discord",
|
||||
"dmca": "DMCA",
|
||||
"github": "GitHub"
|
||||
"github": "GitHub",
|
||||
"twitter": "Twitter"
|
||||
},
|
||||
"tagline": "Regardez vos séries et films préférés avec cette application de streaming open source."
|
||||
},
|
||||
|
@ -100,7 +109,9 @@
|
|||
"onboarding": "Mise en place",
|
||||
"pagetitle": "{{title}} - sudo-flix",
|
||||
"register": "Créer un compte",
|
||||
"settings": "Paramètres"
|
||||
"settings": "Paramètres",
|
||||
"discover": "Découvrir",
|
||||
"support": "Support"
|
||||
}
|
||||
},
|
||||
"home": {
|
||||
|
|
|
@ -29,6 +29,8 @@ export enum Icons {
|
|||
EXPAND = "expand",
|
||||
COMPRESS = "compress",
|
||||
VOLUME = "volume",
|
||||
VOLUME_MED = "volume_med",
|
||||
VOLUME_LOW = "volume_low",
|
||||
VOLUME_X = "volume_x",
|
||||
X = "x",
|
||||
EDIT = "edit",
|
||||
|
@ -102,7 +104,9 @@ const iconList: Record<Icons, string> = {
|
|||
expand: `<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="currentColor" d="M32 32C14.3 32 0 46.3 0 64v96c0 17.7 14.3 32 32 32s32-14.3 32-32V96h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H32zM64 352c0-17.7-14.3-32-32-32s-32 14.3-32 32v96c0 17.7 14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H64V352zM320 32c-17.7 0-32 14.3-32 32s14.3 32 32 32h64v64c0 17.7 14.3 32 32 32s32-14.3 32-32V64c0-17.7-14.3-32-32-32H320zM448 352c0-17.7-14.3-32-32-32s-32 14.3-32 32v64H320c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32V352z"/></svg>`,
|
||||
compress: `<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="currentColor" d="M160 64c0-17.7-14.3-32-32-32s-32 14.3-32 32v64H32c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32V64zM32 320c-17.7 0-32 14.3-32 32s14.3 32 32 32H96v64c0 17.7 14.3 32 32 32s32-14.3 32-32V352c0-17.7-14.3-32-32-32H32zM352 64c0-17.7-14.3-32-32-32s-32 14.3-32 32v96c0 17.7 14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H352V64zM320 320c-17.7 0-32 14.3-32 32v96c0 17.7 14.3 32 32 32s32-14.3 32-32V384h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H320z"/></svg>`,
|
||||
volume: `<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="currentColor" d="M533.6 32.5C598.5 85.3 640 165.8 640 256s-41.5 170.8-106.4 223.5c-10.3 8.4-25.4 6.8-33.8-3.5s-6.8-25.4 3.5-33.8C557.5 398.2 592 331.2 592 256s-34.5-142.2-88.7-186.3c-10.3-8.4-11.8-23.5-3.5-33.8s23.5-11.8 33.8-3.5zM473.1 107c43.2 35.2 70.9 88.9 70.9 149s-27.7 113.8-70.9 149c-10.3 8.4-25.4 6.8-33.8-3.5s-6.8-25.4 3.5-33.8C475.3 341.3 496 301.1 496 256s-20.7-85.3-53.2-111.8c-10.3-8.4-11.8-23.5-3.5-33.8s23.5-11.8 33.8-3.5zm-60.5 74.5C434.1 199.1 448 225.9 448 256s-13.9 56.9-35.4 74.5c-10.3 8.4-25.4 6.8-33.8-3.5s-6.8-25.4 3.5-33.8C393.1 284.4 400 271 400 256s-6.9-28.4-17.7-37.3c-10.3-8.4-11.8-23.5-3.5-33.8s23.5-11.8 33.8-3.5zM301.1 34.8C312.6 40 320 51.4 320 64V448c0 12.6-7.4 24-18.9 29.2s-25 3.1-34.4-5.3L131.8 352H64c-35.3 0-64-28.7-64-64V224c0-35.3 28.7-64 64-64h67.8L266.7 40.1c9.4-8.4 22.9-10.4 34.4-5.3z"/></svg>`,
|
||||
volume_x: `<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 576 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="currentColor" d="M301.1 34.8C312.6 40 320 51.4 320 64V448c0 12.6-7.4 24-18.9 29.2s-25 3.1-34.4-5.3L131.8 352H64c-35.3 0-64-28.7-64-64V224c0-35.3 28.7-64 64-64h67.8L266.7 40.1c9.4-8.4 22.9-10.4 34.4-5.3zM425 167l55 55 55-55c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-55 55 55 55c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-55-55-55 55c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l55-55-55-55c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0z"/></svg>`,
|
||||
volume_med: `<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="currentColor" d="M473.1 107c43.2 35.2 70.9 88.9 70.9 149s-27.7 113.8-70.9 149c-10.3 8.4-25.4 6.8-33.8-3.5s-6.8-25.4 3.5-33.8C475.3 341.3 496 301.1 496 256s-20.7-85.3-53.2-111.8c-10.3-8.4-11.8-23.5-3.5-33.8s23.5-11.8 33.8-3.5zm-60.5 74.5C434.1 199.1 448 225.9 448 256s-13.9 56.9-35.4 74.5c-10.3 8.4-25.4 6.8-33.8-3.5s-6.8-25.4 3.5-33.8C393.1 284.4 400 271 400 256s-6.9-28.4-17.7-37.3c-10.3-8.4-11.8-23.5-3.5-33.8s23.5-11.8 33.8-3.5zM301.1 34.8C312.6 40 320 51.4 320 64V448c0 12.6-7.4 24-18.9 29.2s-25 3.1-34.4-5.3L131.8 352H64c-35.3 0-64-28.7-64-64V224c0-35.3 28.7-64 64-64h67.8L266.7 40.1c9.4-8.4 22.9-10.4 34.4-5.3z"/></svg>`,
|
||||
volume_low: `<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="currentColor" d="M301.1 34.8C312.6 40 320 51.4 320 64V448c0 12.6-7.4 24-18.9 29.2s-25 3.1-34.4-5.3L131.8 352H64c-35.3 0-64-28.7-64-64V224c0-35.3 28.7-64 64-64h67.8L266.7 40.1c9.4-8.4 22.9-10.4 34.4-5.3zm105.5 145.2C434.1 199.1 448 225.9 448 256s-13.9 56.9-35.4 74.5c-10.3 8.4-25.4 6.8-33.8-3.5s-6.8-25.4 3.5-33.8C393.1 284.4 400 271 400 256s-6.9-28.4-17.7-37.3c-10.3-8.4-11.8-23.5-3.5-33.8s23.5-11.8 33.8-3.5z"/></svg>`,
|
||||
volume_x: `<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="currentColor" d="M301.1 34.8C312.6 40 320 51.4 320 64V448c0 12.6-7.4 24-18.9 29.2s-25 3.1-34.4-5.3L131.8 352H64c-35.3 0-64-28.7-64-64V224c0-35.3 28.7-64 64-64h67.8L266.7 40.1c9.4-8.4 22.9-10.4 34.4-5.3zM425 167l55 55 55-55c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-55 55 55 55c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-55-55-55 55c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l55-55-55-55c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0z"/></svg>`,
|
||||
x: `<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="currentColor" d="M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z"/></svg>`,
|
||||
edit: `<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="currentColor" d="M362.7 19.3L314.3 67.7 444.3 197.7l48.4-48.4c25-25 25-65.5 0-90.5L453.3 19.3c-25-25-65.5-25-90.5 0zm-71 71L58.6 323.5c-10.4 10.4-18 23.3-22.2 37.4L1 481.2C-1.5 489.7 .8 498.8 7 505s15.3 8.5 23.7 6.1l120.3-35.4c14.1-4.2 27-11.8 37.4-22.2L421.7 220.3 291.7 90.3z"/></svg>`,
|
||||
bookmark_outline: `<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="currentColor" d="M336 0h-288C21.49 0 0 21.49 0 48v431.9c0 24.7 26.79 40.08 48.12 27.64L192 423.6l143.9 83.93C357.2 519.1 384 504.6 384 479.9V48C384 21.49 362.5 0 336 0zM336 452L192 368l-144 84V54C48 50.63 50.63 48 53.1 48h276C333.4 48 336 50.63 336 54V452z"/></svg>`,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import classNames from "classnames";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { To, useNavigate } from "react-router-dom";
|
||||
|
||||
import { base64ToBuffer, decryptData } from "@/backend/accounts/crypto";
|
||||
import { UserAvatar } from "@/components/Avatar";
|
||||
|
@ -24,8 +24,12 @@ function GoToLink(props: {
|
|||
const navigate = useNavigate();
|
||||
|
||||
const goTo = (href: string) => {
|
||||
if (href.startsWith("http")) window.open(href, "_blank");
|
||||
else navigate(href);
|
||||
if (href.startsWith("http")) {
|
||||
window.open(href, "_blank");
|
||||
} else {
|
||||
window.scrollTo(0, 0);
|
||||
navigate(href);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import classNames from "classnames";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { Link, To, useNavigate } from "react-router-dom";
|
||||
|
||||
import { NoUserAvatar, UserAvatar } from "@/components/Avatar";
|
||||
import { IconPatch } from "@/components/buttons/IconPatch";
|
||||
|
@ -24,6 +24,11 @@ export function Navigation(props: NavigationProps) {
|
|||
const navigate = useNavigate();
|
||||
const { loggedIn } = useAuth();
|
||||
|
||||
const handleClick = (path: To) => {
|
||||
window.scrollTo(0, 0);
|
||||
navigate(path);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* lightbar */}
|
||||
|
@ -79,11 +84,12 @@ export function Navigation(props: NavigationProps) {
|
|||
}}
|
||||
>
|
||||
<div className={classNames("fixed left-0 right-0 flex items-center")}>
|
||||
<div className="px-7 py-5 relative z-[60] flex flex-1 items-center justify-between">
|
||||
<div className="px-7 py-3 relative z-[60] flex flex-1 items-center justify-between">
|
||||
<div className="flex items-center space-x-1.5 ssm:space-x-3 pointer-events-auto">
|
||||
<Link
|
||||
className="block tabbable rounded-full text-xs ssm:text-base"
|
||||
to="/"
|
||||
onClick={() => window.scrollTo(0, 0)}
|
||||
>
|
||||
<BrandPill clickable header />
|
||||
</Link>
|
||||
|
@ -104,7 +110,7 @@ export function Navigation(props: NavigationProps) {
|
|||
<IconPatch icon={Icons.GITHUB} clickable downsized />
|
||||
</a>
|
||||
<a
|
||||
onClick={() => navigate("/discover")}
|
||||
onClick={() => handleClick("/discover")}
|
||||
rel="noreferrer"
|
||||
className="text-xl text-white tabbable rounded-full"
|
||||
>
|
||||
|
|
|
@ -61,7 +61,7 @@ export function EpisodeSelector({
|
|||
|
||||
return (
|
||||
<div className="flex flex-row relative">
|
||||
<div className="w-24 sm:w-96 cursor-pointer overflow-y-auto overflow-x-hidden max-h-60 z-10">
|
||||
<div className="w-24 min-w-20 cursor-pointer overflow-y-auto overflow-x-hidden max-h-56 z-10 scrollbar-hide">
|
||||
{seasonsData.map((season) => (
|
||||
<div
|
||||
key={season.season_number}
|
||||
|
@ -79,8 +79,8 @@ export function EpisodeSelector({
|
|||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex-auto mt-4 sm:mt-0 sm:ml-4 cursor-pointer overflow-x-auto overflow-y-hidden sm:overflow-y-auto sm:overflow-x-hidden max-h-60 max-w-[70vw] z-0">
|
||||
<div className="flex sm:grid sm:grid-cols-3 sm:gap-2">
|
||||
<div className="flex-auto sm:mt-0 sm:ml-4 cursor-pointer overflow-x-auto overflow-y-hidden sm:overflow-y-auto sm:overflow-x-hidden max-h-56 max-w-[70vw]">
|
||||
<div className="flex sm:grid sm:grid-cols-3 sm:gap-2 gap-1">
|
||||
{selectedSeason ? (
|
||||
selectedSeason.episodes.map(
|
||||
(episode: {
|
||||
|
@ -92,11 +92,11 @@ export function EpisodeSelector({
|
|||
<Flare.Base
|
||||
key={episode.episode_number}
|
||||
onClick={() => {
|
||||
const navigateUrl = `/media/tmdb-tv-${tmdbId}-${mediaTitle}/${selectedSeason.id}/${episode.id}`;
|
||||
// console.log("Navigating to:", navigateUrl);
|
||||
navigate(navigateUrl);
|
||||
navigate(
|
||||
`/media/tmdb-tv-${tmdbId}-${mediaTitle}/${selectedSeason.id}/${episode.id}`,
|
||||
);
|
||||
}}
|
||||
className="group cursor-pointer rounded-xl relative p-[0.65em] bg-background-main transition-colors duration-[0.28s] flex-shrink-0 w-48 sm:w-auto mr-2 sm:mr-0"
|
||||
className="group cursor-pointer rounded-xl relative p-[0.6em] bg-background-secondary transition-colors duration-[0.25s] flex-shrink-0 w-44 max-h-48 sm:w-auto mr-2 sm:mr-0"
|
||||
>
|
||||
<Flare.Light
|
||||
flareSize={300}
|
||||
|
@ -109,9 +109,11 @@ export function EpisodeSelector({
|
|||
src={`https://image.tmdb.org/t/p/w500/${episode.still_path}`}
|
||||
className="w-full h-auto rounded"
|
||||
/>
|
||||
<p className="text-center text-[0.95em] mt-2">
|
||||
E{episode.episode_number}: {episode.name}
|
||||
</p>
|
||||
<div className="text-center my-2 overflow-hidden">
|
||||
<p className="text-[0.95em] overflow-ellipsis whitespace-wrap">
|
||||
E{episode.episode_number}: {episode.name}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Flare.Base>
|
||||
),
|
||||
|
|
|
@ -60,8 +60,6 @@ function formatRuntime(runtime: number) {
|
|||
export function PopupModal({
|
||||
isVisible,
|
||||
onClose,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
// idk just needed to add this line for commit
|
||||
playingTitle,
|
||||
media,
|
||||
}: PopupModalProps) {
|
||||
|
@ -171,28 +169,25 @@ export function PopupModal({
|
|||
|
||||
return (
|
||||
<div
|
||||
className="fixed inset-0 bg-black bg-opacity-40 flex justify-center items-center z-50 transition-opacity duration-100"
|
||||
className="fixed inset-0 flex justify-center items-center z-50 transition-opacity duration-100"
|
||||
style={{ opacity: style.opacity, visibility: style.visibility }}
|
||||
>
|
||||
<div
|
||||
ref={modalRef}
|
||||
className="rounded-xl bg-modal-background flex flex-col justify-center items-center transition-opacity duration-100 max-w-full sm:max-w-xl w-full sm:w-auto sm:h-auto overflow-y-auto p-4"
|
||||
style={{ opacity: style.opacity, maxHeight: "90vh", height: "auto" }}
|
||||
className="rounded-xl mx-4 min-w-[23em] overflow-x-hidden bg-modal-background flex flex-col justify-center items-center transition-opacity duration-100 sm:max-w-xl sm:w-auto sm:h-auto overflow-y-auto p-4"
|
||||
style={{ opacity: style.opacity, height: "auto" }}
|
||||
>
|
||||
<div className="aspect-w-16 aspect-h-9 w-full sm:w-auto">
|
||||
<div className="rounded-xl">
|
||||
{data?.backdrop_path ? (
|
||||
<img
|
||||
src={`https://image.tmdb.org/t/p/original/${data.backdrop_path}`}
|
||||
alt={media.poster ? "" : "failed to fetch :("}
|
||||
className="rounded-xl object-cover w-full h-full"
|
||||
loading="lazy"
|
||||
style={{ maxHeight: "60vh" }}
|
||||
/>
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</div>
|
||||
<div className="aspect-w-16 aspect-h-9 w-full sm:w-auto rounded-xl">
|
||||
{data?.backdrop_path ? (
|
||||
<img
|
||||
src={`https://image.tmdb.org/t/p/original/${data.backdrop_path}`}
|
||||
alt={media.poster ? "" : "failed to fetch :("}
|
||||
className="rounded-xl object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
<div className="flex pt-3 items-center gap-4">
|
||||
<h1 className="relative text-xl sm:text-2xl whitespace-normal font-bold text-white">
|
||||
{data?.title || data?.name ? (
|
||||
|
@ -262,22 +257,24 @@ export function PopupModal({
|
|||
</span>
|
||||
))}
|
||||
</div>
|
||||
{data?.genres && data.genres.length > 0
|
||||
? data.genres.map((genre: { name: string }) => (
|
||||
<div key={genre.name} className="inline-block">
|
||||
<div className="px-2 py-1 bg-mediaCard-hoverBackground rounded hover:bg-search-background cursor-default duration-200 transition-colors transform hover:scale-110">
|
||||
{genre.name}
|
||||
<div className="flex flex-row gap-3 flex-wrap">
|
||||
{data?.genres && data.genres.length > 0
|
||||
? data.genres.map((genre: { name: string }) => (
|
||||
<div key={genre.name}>
|
||||
<div className="px-2 py-1 text-[0.95em] bg-mediaCard-hoverBackground rounded hover:bg-search-background cursor-default duration-200 transition-colors transform hover:scale-110">
|
||||
{genre.name}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
: Array.from({ length: 3 }).map((_, idx) => (
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
<div className="inline-block" key={idx}>
|
||||
<Skeleton />
|
||||
</div>
|
||||
))}
|
||||
))
|
||||
: Array.from({ length: 3 }).map((_, idx) => (
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
<div key={idx}>
|
||||
<Skeleton />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative whitespace-normal font-medium overflow-y-auto max-h-32">
|
||||
<div className="relative whitespace-normal font-medium overflow-y-auto max-h-28">
|
||||
{data?.overview}
|
||||
</div>
|
||||
<div className="pt-3">
|
||||
|
@ -285,7 +282,7 @@ export function PopupModal({
|
|||
<EpisodeSelector tmdbId={media.id} mediaTitle={media.title} />
|
||||
) : null}
|
||||
</div>
|
||||
<div className="flex justify-center items-center mt-4 mb-1">
|
||||
<div className="flex justify-center items-center mt-3 mb-1">
|
||||
<Button
|
||||
theme="purple"
|
||||
onClick={() =>
|
||||
|
|
|
@ -62,6 +62,19 @@ export function Volume(props: Props) {
|
|||
[volume, setVolume],
|
||||
);
|
||||
|
||||
const getVolumeIcon = (volumeLevel: number) => {
|
||||
if (volumeLevel === 0) {
|
||||
return Icons.VOLUME_X;
|
||||
}
|
||||
if (volumeLevel > 0 && volumeLevel <= 0.33) {
|
||||
return Icons.VOLUME_LOW;
|
||||
}
|
||||
if (volumeLevel > 0.33 && volumeLevel <= 0.66) {
|
||||
return Icons.VOLUME_MED;
|
||||
}
|
||||
return Icons.VOLUME;
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={props.className}
|
||||
|
@ -71,7 +84,7 @@ export function Volume(props: Props) {
|
|||
>
|
||||
<div className="pointer-events-auto flex cursor-pointer items-center py-0 touch-none">
|
||||
<div className="px-4 text-2xl text-white" onClick={handleClick}>
|
||||
<Icon icon={percentage > 0 ? Icons.VOLUME : Icons.VOLUME_X} />
|
||||
<Icon icon={getVolumeIcon(percentage / 100)} />
|
||||
</div>
|
||||
<div
|
||||
className={`linear -ml-2 w-0 overflow-hidden transition-[width,opacity] duration-300 ${
|
||||
|
|
|
@ -118,10 +118,17 @@ export function KeyboardEvents() {
|
|||
|
||||
// Utils
|
||||
if (keyL === "f") dataRef.current.display?.toggleFullscreen();
|
||||
if (k === " " || keyL === "k")
|
||||
dataRef.current.display?.[
|
||||
dataRef.current.mediaPlaying.isPaused ? "play" : "pause"
|
||||
]();
|
||||
if (k === " " || keyL === "k") {
|
||||
if (
|
||||
evt.target &&
|
||||
(evt.target as HTMLInputElement).nodeName === "BUTTON"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const action = dataRef.current.mediaPlaying.isPaused ? "play" : "pause";
|
||||
dataRef.current.display?.[action]();
|
||||
}
|
||||
if (k === "Escape") dataRef.current.router.close();
|
||||
|
||||
// captions
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { To, useNavigate } from "react-router-dom";
|
||||
|
||||
import { WideContainer } from "@/components/layout/WideContainer";
|
||||
import { useDebounce } from "@/hooks/useDebounce";
|
||||
|
@ -48,6 +48,11 @@ export function HomePage() {
|
|||
const [showBookmarks, setShowBookmarks] = useState(false);
|
||||
const [showWatching, setShowWatching] = useState(false);
|
||||
|
||||
const handleClick = (path: To) => {
|
||||
window.scrollTo(0, 0);
|
||||
navigate(path);
|
||||
};
|
||||
|
||||
return (
|
||||
<HomeLayout showBg={showBg}>
|
||||
<div className="mb-16 sm:mb-24">
|
||||
|
@ -77,7 +82,7 @@ export function HomePage() {
|
|||
<p className="text-[18.5px] pb-3">{emptyText}</p>
|
||||
<Button
|
||||
className="px-py p-[0.35em] mt-3 rounded-xl text-type-dimmed box-content text-[18px] bg-largeCard-background text-buttons-secondaryText justify-center items-center"
|
||||
onClick={() => navigate("/discover")}
|
||||
onClick={() => handleClick("/discover")}
|
||||
>
|
||||
{t("home.search.discover")}
|
||||
</Button>
|
||||
|
|
|
@ -59,7 +59,7 @@ export default defineConfig(({ mode }) => {
|
|||
registerType: "autoUpdate",
|
||||
workbox: {
|
||||
maximumFileSizeToCacheInBytes: 4000000, // 4mb
|
||||
globIgnores: ["**ping.txt**"],
|
||||
globIgnores: ["!assets/**/*"],
|
||||
},
|
||||
includeAssets: [
|
||||
"favicon.ico",
|
||||
|
|
Loading…
Reference in a new issue