diff --git a/android/app/build.gradle b/android/app/build.gradle index 9f31c37..3370f63 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -86,8 +86,8 @@ android { applicationId "com.vega" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 80 - versionName "2.5.5" + versionCode 82 + versionName "2.5.6" } signingConfigs { release { diff --git a/app.json b/app.json index be3770a..de4e9e0 100644 --- a/app.json +++ b/app.json @@ -21,12 +21,12 @@ ] ], "slug": "vega", - "version": "2.5.5", + "version": "2.5.6", "sdkVersion": "51.0.0", "android": { "minSdkVersion": 24, "package": "com.vega", - "versionCode": 80 + "versionCode": 82 }, "platforms": ["ios", "android"] } diff --git a/package-lock.json b/package-lock.json index 577471e..571649b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,14 @@ { "name": "vega", - "version": "2.5.4", + "version": "2.5.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "vega", - "version": "2.5.4", + "version": "2.5.5", "dependencies": { - "@8man/react-native-media-console": "^2.2.4-alpha.14", + "@8man/react-native-media-console": "^2.2.4-alpha.16", "@dominicvonk/react-native-apk-installer": "^2.2.2", "@gorhom/bottom-sheet": "^4.6.4", "@notifee/react-native": "^7.8.2", @@ -76,9 +76,9 @@ } }, "node_modules/@8man/react-native-media-console": { - "version": "2.2.4-alpha.14", - "resolved": "https://registry.npmjs.org/@8man/react-native-media-console/-/react-native-media-console-2.2.4-alpha.14.tgz", - "integrity": "sha512-larW7yJixgJT7LEMPDMYFGXQXdVLRz2JaRg8mkYOUp1PzAm2CayA9mp3L4ApX64XHjUZ0+UcrOEDZIUr+QL2HA==", + "version": "2.2.4-alpha.16", + "resolved": "https://registry.npmjs.org/@8man/react-native-media-console/-/react-native-media-console-2.2.4-alpha.16.tgz", + "integrity": "sha512-n+X1savxnHpg88edc5X1Vsv+cvstx+3wig9cpEQWp+lbMapchDNOoI+Ozal/6cr4+JFuGM77GwNu2ny3/eBlyA==", "license": "MIT", "peerDependencies": { "react-native": ">=0.46.0" diff --git a/package.json b/package.json index 053c925..4bde132 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vega", - "version": "2.5.5", + "version": "2.5.6", "private": true, "scripts": { "android": "react-native run-android", @@ -10,7 +10,7 @@ "test": "jest" }, "dependencies": { - "@8man/react-native-media-console": "^2.2.4-alpha.14", + "@8man/react-native-media-console": "^2.2.4-alpha.16", "@dominicvonk/react-native-apk-installer": "^2.2.2", "@gorhom/bottom-sheet": "^4.6.4", "@notifee/react-native": "^7.8.2", diff --git a/src/components/SeasonList.tsx b/src/components/SeasonList.tsx index cc4644f..5d4ec49 100644 --- a/src/components/SeasonList.tsx +++ b/src/components/SeasonList.tsx @@ -415,7 +415,7 @@ const SeasonList = ({ )} {LinkList?.length === 0 && ( - No streams found + No stream found )} diff --git a/src/lib/Manifest.ts b/src/lib/Manifest.ts index b1cc9c4..e6ea5af 100644 --- a/src/lib/Manifest.ts +++ b/src/lib/Manifest.ts @@ -29,6 +29,8 @@ import {cinemaLuxe} from './providers/cinemaLuxe'; import {animeRulzProvider} from './providers/animeRulz'; import {moviesApi} from './providers/moviesApi'; import {guardahd} from './providers/guardahd'; +import {toonstream} from './providers/toonstream'; +import {ridoMovies} from './providers/ridoMovies'; export interface ProviderType { searchFilter?: string; @@ -90,4 +92,6 @@ export const manifest: Manifest = { animeRulz: animeRulzProvider, moviesApi: moviesApi, guardahd: guardahd, + toonstream: toonstream, + ridoMovies: ridoMovies, }; diff --git a/src/lib/constants.ts b/src/lib/constants.ts index f64b2ab..824f8e8 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -50,7 +50,7 @@ export const providersList: ProvidersList[] = [ flag: '🌏', }, { - name: 'ModMovies', + name: 'MoviesMod', value: 'mod', type: 'global', flag: '🌏', @@ -92,11 +92,23 @@ export const providersList: ProvidersList[] = [ flag: '🌏', }, // { + // name: 'ToonStream', + // value: 'toonstream', + // type: 'global', + // flag: '🌏', + // }, + // { // name: 'MoviesApi', // value: 'moviesApi', // type: 'english', // flag: '🇬🇧', // }, + { + name: 'RidoMovies', + value: 'ridoMovies', + type: 'english', + flag: '🇬🇧', + }, { name: 'FlixHQ', value: 'flixhq', @@ -158,7 +170,7 @@ export const providersList: ProvidersList[] = [ flag: '🇮🇳', }, { - name: 'LuxMovies', + name: 'RogMovies', value: 'lux', type: 'india', flag: '🇮🇳', diff --git a/src/lib/providers/guardahd/guardahdGetPosts.ts b/src/lib/providers/guardahd/guardahdGetPosts.ts new file mode 100644 index 0000000..e90f09e --- /dev/null +++ b/src/lib/providers/guardahd/guardahdGetPosts.ts @@ -0,0 +1,39 @@ +import axios from 'axios'; +import {headers} from '../headers'; +import {Post} from '../types'; + +export const guardahdGetSearchPosts = async function ( + searchQuery: string, + page: number, + providerValue: string, + signal: AbortSignal, +): Promise { + try { + if (page > 1) { + return []; + } + const catalog: Post[] = []; + const url2 = `https://v3-cinemeta.strem.io/catalog/movie/top/search=${encodeURI( + searchQuery, + )}.json`; + const res2 = await axios.get(url2, {headers, signal}); + const data2 = res2.data; + data2?.metas.map((result: any) => { + const title = result?.name || ''; + const id = result?.imdb_id || result?.id; + const image = result?.poster; + const type = result?.type; + if (id) { + catalog.push({ + title: title, + link: `https://v3-cinemeta.strem.io/meta/${type}/${id}.json`, + image: image, + }); + } + }); + return catalog; + } catch (err) { + console.error('AutoEmbed error ', err); + return []; + } +}; diff --git a/src/lib/providers/guardahd/index.ts b/src/lib/providers/guardahd/index.ts index 86c30b1..a9ced4b 100644 --- a/src/lib/providers/guardahd/index.ts +++ b/src/lib/providers/guardahd/index.ts @@ -1,6 +1,7 @@ import {guardahdCatalog, guardahdGenresList} from './guardahdCatalog'; import {allGetInfo} from '../autoEmbed/allGetInfo'; -import {allGetPost, allGetSearchPosts} from '../autoEmbed/allGetPost'; +import {allGetPost} from '../autoEmbed/allGetPost'; +import {guardahdGetSearchPosts} from './guardahdGetPosts'; import {ProviderType} from '../../Manifest'; import {GuardahdGetStream} from './GetGuardahdStream'; @@ -10,5 +11,5 @@ export const guardahd: ProviderType = { GetMetaData: allGetInfo, GetHomePosts: allGetPost, GetStream: GuardahdGetStream, - GetSearchPosts: allGetSearchPosts, + GetSearchPosts: guardahdGetSearchPosts, }; diff --git a/src/lib/providers/luxMovies/headers.ts b/src/lib/providers/luxMovies/headers.ts index 75f73bd..29c1559 100644 --- a/src/lib/providers/luxMovies/headers.ts +++ b/src/lib/providers/luxMovies/headers.ts @@ -13,7 +13,7 @@ export const headers = { 'Sec-Fetch-Site': 'none', 'Sec-Fetch-User': '?1', Cookie: - 'cf_clearance=zre97fLPyk9GTUfuqbfZvXPU5zDN4BE3nnkMxE7767Y-1723609417-1.0.1.1-YD4.GJqqAhcctS4bOpgW8ZmD9pLzASAaHbUl9ROEN.SmbMhisTm8nf8PO6T9wfy59UE0ozdWr0BGTF7F7UdvrA', + 'ext_name=ojplmecpdpgccookcobabopnaifgidhf; cf_clearance=gaIhTNzqSvp27JCVf7qiEUfYRfwyj0Jx9rcsn774BbE-1732694853-1.2.1.1-QKgYJvmrEz08gM9qbAp70diztE2.hseO2NNi.0imIUk_gkuWUcr7U8t5Zn_z4Ov30sIGPBES1PBgMUEa.s8e8QTkQoZjgziFmoC7YdX7s2Jnt.tYCxE_s5mMLQQBYbz_94A89IYe93Y6kyLQm_L.dvUKPPiGjn_sH3qRD0g4p9oOl0SPvH0T2W_EaD0r6mVBasbgro9dAROt_6CxshXOEGeMOnoWR.ID699FKldjMUhbXJbATAffdOY6kf2sD_iwrSl4bcetTlDHd4gusTVfxSS1pL5qNjyTU9wa38soPl1wZoqFHkEGOPWz6S7FD5ikHxX0bArFem9hiDeJXctYfWz5e_Lkc6lH7nW0Rm2XS3gxCadQSg21RkSReN6kDAEecqjgJSE4zUomkWAxFZ98TSShgGWC0ridPTpdQizPDZQ; _lscache_vary=c1d682536aea2d88fbb2574666e1f0aa', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0', diff --git a/src/lib/providers/mod/modGetStream.ts b/src/lib/providers/mod/modGetStream.ts index d925faf..e9b6b66 100644 --- a/src/lib/providers/mod/modGetStream.ts +++ b/src/lib/providers/mod/modGetStream.ts @@ -122,7 +122,7 @@ export const modGetStream = async ( const $cfWorkers = cheerio.load(cfWorkersHtml); const cfWorkersStream = $cfWorkers('.btn-success'); cfWorkersStream.each((i, el) => { - const link = $(el).attr('href'); + const link = el.attribs.href; if (link) { servers.push({ server: 'Cf Worker 1.' + i, @@ -143,7 +143,7 @@ export const modGetStream = async ( const $cfWorkers = cheerio.load(cfWorkersHtml); const cfWorkersStream = $cfWorkers('.btn-success'); cfWorkersStream.each((i, el) => { - const link = $(el).attr('href'); + const link = el.attribs.href; if (link) { servers.push({ server: 'Cf Worker 2.' + i, diff --git a/src/lib/providers/multi/multiGetStream.ts b/src/lib/providers/multi/multiGetStream.ts index e40130d..467dbe4 100644 --- a/src/lib/providers/multi/multiGetStream.ts +++ b/src/lib/providers/multi/multiGetStream.ts @@ -46,7 +46,7 @@ export const multiGetStream = async ( const $$ = cheerio.load(iframeRes.data); let newIframeUrl = $$('.linkserver').first().attr('data-video') || - $$('#videoLinks').children().first().attr('data-link'); + $$('[data-sourcekey=smwh]').attr('data-link'); console.log('newIframeUrl', newIframeUrl); if (newIframeUrl) { ifameUrl = newIframeUrl; diff --git a/src/lib/providers/netflixMirror/nfGetCookie.ts b/src/lib/providers/netflixMirror/nfGetCookie.ts index 5767520..effbad0 100644 --- a/src/lib/providers/netflixMirror/nfGetCookie.ts +++ b/src/lib/providers/netflixMirror/nfGetCookie.ts @@ -92,7 +92,7 @@ export class NetMirrorCookieFetcher { ): Promise { try { await fetch( - `https://userverify.netmirror.app/verify?dp1=${addhash}&a=y&t=${Math.random()}`, + `https://userverify.netmirror.app/verify?vhfd=${addhash}&a=y&t=${Math.random()}`, {credentials: 'omit'}, ); } catch (err) { diff --git a/src/lib/providers/ridoMovies/index.ts b/src/lib/providers/ridoMovies/index.ts new file mode 100644 index 0000000..92112ea --- /dev/null +++ b/src/lib/providers/ridoMovies/index.ts @@ -0,0 +1,15 @@ +import {ProviderType} from '../../Manifest'; +import {guardahdCatalog, guardahdGenresList} from '../guardahd/guardahdCatalog'; +import {allGetPost} from '../autoEmbed/allGetPost'; +import {guardahdGetSearchPosts} from '../guardahd/guardahdGetPosts'; +import {ridoGetInfo} from './ridoGetMeta'; +import {ridoGetStream} from './ridoGetSream'; + +export const ridoMovies: ProviderType = { + catalog: guardahdCatalog, + genres: guardahdGenresList, + GetMetaData: ridoGetInfo, + GetHomePosts: allGetPost, + GetStream: ridoGetStream, + GetSearchPosts: guardahdGetSearchPosts, +}; diff --git a/src/lib/providers/ridoMovies/ridoGetMeta.ts b/src/lib/providers/ridoMovies/ridoGetMeta.ts new file mode 100644 index 0000000..0e41af0 --- /dev/null +++ b/src/lib/providers/ridoMovies/ridoGetMeta.ts @@ -0,0 +1,112 @@ +import axios from 'axios'; +import {EpisodeLink, Info, Link} from '../types'; +import {getBaseUrl} from '../getBaseUrl'; + +export const ridoGetInfo = async function (link: string): Promise { + try { + console.log('all', link); + const res = await axios.get(link); + const data = res.data; + const meta = { + title: '', + synopsis: '', + image: '', + imdbId: data?.meta?.imdb_id || '', + type: data?.meta?.type || 'movie', + }; + + const baseUrl = await getBaseUrl('ridomovies'); + let slug = ''; + try { + const res2 = await axios.get( + baseUrl + '/core/api/search?q=' + meta.imdbId, + ); + const data2 = res2.data; + console.log('all', data2); + slug = data2?.data?.items[0]?.fullSlug; + if (!slug || meta?.type === 'series') { + return { + title: '', + synopsis: '', + image: '', + imdbId: data?.meta?.imdb_id || '', + type: meta?.type || 'movie', + linkList: [], + }; + } + } catch (err) { + console.error('ridoGetInfo', err); + return { + title: '', + synopsis: '', + image: '', + imdbId: meta?.imdbId || '', + type: meta?.type || 'movie', + linkList: [], + }; + } + + const links: Link[] = []; + let directLinks: EpisodeLink[] = []; + let season = new Map(); + if (meta.type === 'series') { + data?.meta?.videos?.map((video: any) => { + if (video?.season <= 0) return; + if (!season.has(video?.season)) { + season.set(video?.season, []); + } + + season.get(video?.season).push({ + title: 'Episode ' + video?.episode, + type: 'series', + link: JSON.stringify({ + season: video?.id?.split(':')[1], + episode: video?.id?.split(':')[2], + type: data?.meta?.type, + slug: slug, + baseUrl: baseUrl, + }), + }); + }); + const keys = Array.from(season.keys()); + keys.sort(); + keys.map(key => { + directLinks = season.get(key); + links.push({ + title: `Season ${key}`, + directLinks: directLinks, + }); + }); + } else { + console.log('all meta Mv🔥🔥', meta); + links.push({ + title: data?.meta?.name as string, + directLinks: [ + { + title: 'Movie', + type: 'movie', + link: JSON.stringify({ + type: data?.meta?.type, + slug: slug, + baseUrl: baseUrl, + }), + }, + ], + }); + } + return { + ...meta, + linkList: links, + }; + } catch (err) { + console.error('ridoGetInfo', err); + return { + title: '', + synopsis: '', + image: '', + imdbId: '', + type: 'movie', + linkList: [], + }; + } +}; diff --git a/src/lib/providers/ridoMovies/ridoGetSream.ts b/src/lib/providers/ridoMovies/ridoGetSream.ts new file mode 100644 index 0000000..31d924e --- /dev/null +++ b/src/lib/providers/ridoMovies/ridoGetSream.ts @@ -0,0 +1,71 @@ +import axios from 'axios'; +import * as cheerio from 'cheerio'; +import {Stream} from '../types'; +import {headers} from '../headers'; + +export const ridoGetStream = async (data: string): Promise => { + try { + const streamData = JSON.parse(data); + const streamLinks: Stream[] = []; + + // const path = + // streamData?.type === 'movie' + // ? `/${streamData?.slug}` + // : `/${streamData?.slug}/season-${streamData?.season}/episode-${streamData?.episode}`; + // const url = streamData?.baseUrl + path; + // console.log('all', url); + // const res = await axios.get(url, {headers}); + // const postId = res.data.split('\\"postid\\":\\"')[1].split('\\"')[0]; + // console.log('rido post id', postId); + + const url = streamData?.baseUrl + '/api/' + streamData?.slug; + console.log('rido url', url); + + const res = await axios.get(url, {headers}); + const iframe = res.data.data?.[0]?.url; + + console.log('rido data', iframe); + const iframeUrl = iframe.split('src="')[1].split('"')[0]; + console.log('rido iframeUrl', iframeUrl); + const iframeRes = await axios.get(iframeUrl, { + headers: { + ...headers, + Referer: streamData?.baseUrl, + }, + }); + const $ = cheerio.load(iframeRes.data); + const script = $('script:contains("eval")').html(); + if (!script) { + throw new Error('Unable to find script'); + } + // console.log('rido script', script); + const srcUrl = unpackJavaScript(script.trim()); + console.log('rido srcUrl', srcUrl); + + streamLinks.push({ + link: srcUrl, + server: 'rido', + type: 'm3u8', + headers: { + Referer: iframeUrl, + }, + }); + + return streamLinks; + } catch (e) { + console.log('rido get stream err', e); + return []; + } +}; + +function unpackJavaScript(packedCode: string): string { + const encodedString = packedCode.split('|aHR')[1].split('|')[0]; + const base64Url = 'aHR' + encodedString; + function addPadding(base64: string) { + return base64 + '='.repeat((4 - (base64.length % 4)) % 4); + } + + console.log('rido base64Url', base64Url); + const unpackedCode = atob(addPadding(base64Url)); + return unpackedCode; +} diff --git a/src/lib/providers/toonstream/index.ts b/src/lib/providers/toonstream/index.ts new file mode 100644 index 0000000..b000040 --- /dev/null +++ b/src/lib/providers/toonstream/index.ts @@ -0,0 +1,15 @@ +import {ProviderType} from '../../Manifest'; +import {toonCatalog, toonGenresList} from './toonCatalog'; +import {toonGetInfo} from './toonGetInfo'; +import {toonGetPosts, toonGetPostsSearch} from './toonGetPosts'; +import {toonGetEpisodeLinks} from './toonGetEpisodes'; + +export const toonstream: ProviderType = { + catalog: toonCatalog, + genres: toonGenresList, + GetMetaData: toonGetInfo, + GetHomePosts: toonGetPosts, + GetStream: toonGetInfo, + GetSearchPosts: toonGetPostsSearch, + GetEpisodeLinks: toonGetEpisodeLinks, +}; diff --git a/src/lib/providers/toonstream/toonCatalog.ts b/src/lib/providers/toonstream/toonCatalog.ts new file mode 100644 index 0000000..638436c --- /dev/null +++ b/src/lib/providers/toonstream/toonCatalog.ts @@ -0,0 +1,20 @@ +export const toonCatalog = [ + { + title: 'Latest Series', + filter: '/series/', + }, + { + title: 'Latest Movies', + filter: '/movies/', + }, + { + title: 'Anime', + filter: '/category/anime/', + }, + { + title: 'Cartoons', + filter: '/category/cartoon/', + }, +]; + +export const toonGenresList = []; diff --git a/src/lib/providers/toonstream/toonGetEpisodes.ts b/src/lib/providers/toonstream/toonGetEpisodes.ts new file mode 100644 index 0000000..13c3819 --- /dev/null +++ b/src/lib/providers/toonstream/toonGetEpisodes.ts @@ -0,0 +1,40 @@ +import axios from 'axios'; +import * as cheerio from 'cheerio'; +import {EpisodeLink} from '../types'; + +export const toonGetEpisodeLinks = async function ( + data: string, +): Promise { + try { + const seasonData = JSON.parse(data); + const url = `https://toonstream.co/wp-admin/admin-ajax.php`; + const formData = new FormData(); + formData.append('action', 'action_select_season'); + formData.append('season', seasonData.season); + formData.append('post', seasonData.postid); + + const res = await fetch(url, { + method: 'POST', + body: formData, + }); + const html = await res.text(); + const $ = cheerio.load(html); + const episodeLinks: EpisodeLink[] = []; + $('.post').map((i, element) => { + const title = + 'Episode' + $(element).find('.num-epi').text().split('x')[1]; + const link = $(element).find('a').attr('href'); + if (title && link) { + episodeLinks.push({ + title: title, + link: link, + }); + } + }); + console.log('toonstream episodeLinks', episodeLinks); + return episodeLinks; + } catch (err) { + console.error('Error in toonGetEpisodeLinks:', err); + return []; + } +}; diff --git a/src/lib/providers/toonstream/toonGetInfo.ts b/src/lib/providers/toonstream/toonGetInfo.ts new file mode 100644 index 0000000..fc50d9f --- /dev/null +++ b/src/lib/providers/toonstream/toonGetInfo.ts @@ -0,0 +1,77 @@ +import axios from 'axios'; +import * as cheerio from 'cheerio'; +import {headers} from '../headers'; +import {Info, Link} from '../types'; + +export const toonGetInfo = async function (link: string): Promise { + try { + const url = link; + // console.log('url', url); + const res = await axios.get(url, {headers}); + const data = res.data; + const $ = cheerio.load(data); + const type = url.includes('tvshows') ? 'series' : 'movie'; + const imdbId = ''; + const title = $('.entry-title').first().text() || ''; + const image = $('.post-thumbnail.alg-ss') + .find('img') + .attr('data-src') + ?.includes('https') + ? $('.post-thumbnail.alg-ss').find('img').attr('data-src') + : 'https:' + $('.post-thumbnail.alg-ss').find('img').attr('data-src'); + const synopsis = $('.description').find('p').first().text() || ''; + const tags = $('.genres') + .find('a') + .slice(0, 2) + .map((i, element) => { + return $(element).text(); + }) + .get(); + const rating = Math.floor(Number($('.num').text())).toString(); + const cast = $('.loadactor') + .find('a') + .map((i, element) => { + return $(element).text(); + }) + .get(); + + // console.log(title, image, synopsis); + + // Links + const links: Link[] = []; + const seasons = $('.aa-cnt.sub-menu').children(); + seasons.map((i, element) => { + const title = $(element).find('a').text(); + const data = JSON.stringify({ + season: $(element).find('a').attr('data-season'), + postid: $(element).find('a').attr('data-post'), + }); + links.push({ + title, + episodesLink: data, + }); + }); + + return { + title, + tags, + synopsis, + image, + imdbId, + cast, + rating, + type, + linkList: links, + }; + } catch (err) { + console.error(err); + return { + title: '', + synopsis: '', + image: '', + imdbId: '', + type: 'movie', + linkList: [], + }; + } +}; diff --git a/src/lib/providers/toonstream/toonGetPosts.ts b/src/lib/providers/toonstream/toonGetPosts.ts new file mode 100644 index 0000000..fc127c7 --- /dev/null +++ b/src/lib/providers/toonstream/toonGetPosts.ts @@ -0,0 +1,62 @@ +import axios from 'axios'; +import * as cheerio from 'cheerio'; +import {headers} from '../headers'; +import {Post} from '../types'; +import {getBaseUrl} from '../getBaseUrl'; + +export const toonGetPosts = async function ( + filter: string, + page: number, + providerValue: string, + signal: AbortSignal, +): Promise { + const baseUrl = 'https://toonstream.co'; + const url = `${baseUrl + filter}/page/${page}/`; + + return posts(url, signal); +}; + +export const toonGetPostsSearch = async function ( + searchQuery: string, + page: number, + providerValue: string, + signal: AbortSignal, +): Promise { + const baseUrl = 'https://toonstream.co'; + const url = `${baseUrl}/page/${page}/?s=${searchQuery}`; + return posts(url, signal); +}; + +async function posts(url: string, signal: AbortSignal): Promise { + try { + const res = await axios.get(url, {headers, signal}); + const data = res.data; + const $ = cheerio.load(data); + const catalog: Post[] = []; + $('ul.post-lst') + .first() + .children() + .map((i, element) => { + const title = $(element).find('.entry-title').text(); + const link = $(element).find('a').attr('href'); + const image = + $(element).find('img').attr('data-src') || + $(element).find('img').attr('src') || + ''; + + console.log('toonstream image', image); + if (title && link) { + catalog.push({ + title: title, + link: link, + image: image.includes('https') ? image : 'https:' + image, + }); + } + }); + console.log('toonstream catalog', catalog); + return catalog; + } catch (err) { + console.error('toonstream error ', err); + return []; + } +} diff --git a/src/lib/providers/uhd/uhdGetStream.ts b/src/lib/providers/uhd/uhdGetStream.ts index c146cad..f40bd0f 100644 --- a/src/lib/providers/uhd/uhdGetStream.ts +++ b/src/lib/providers/uhd/uhdGetStream.ts @@ -4,10 +4,7 @@ import * as cheerio from 'cheerio'; import {Stream} from '../types'; import {headers} from './header'; -export const uhdGetStream = async ( - url: string, - type: string, -): Promise => { +export const uhdGetStream = async (url: string): Promise => { try { const wpHttp = url.split('sid=')[1]; var bodyFormData0 = new FormData(); @@ -121,7 +118,7 @@ export const uhdGetStream = async ( const $cfWorkers = cheerio.load(cfWorkersHtml); const cfWorkersStream = $cfWorkers('.btn-success'); cfWorkersStream.each((i, el) => { - const link = $(el).attr('href'); + const link = el.attribs.href; if (link) { ServerLinks.push({ server: 'Cf Worker 1.' + i, @@ -142,7 +139,7 @@ export const uhdGetStream = async ( const $cfWorkers = cheerio.load(cfWorkersHtml); const cfWorkersStream = $cfWorkers('.btn-success'); cfWorkersStream.each((i, el) => { - const link = $(el).attr('href'); + const link = el.attribs.href; if (link) { ServerLinks.push({ server: 'Cf Worker 2.' + i, diff --git a/src/screens/home/Info.tsx b/src/screens/home/Info.tsx index da0dba0..d195647 100644 --- a/src/screens/home/Info.tsx +++ b/src/screens/home/Info.tsx @@ -9,7 +9,6 @@ import { TouchableOpacity, Modal, Pressable, - ScrollView, } from 'react-native'; import React, {useEffect, useRef, useState} from 'react'; import { @@ -43,6 +42,7 @@ export default function Info({route, navigation}: Props): React.JSX.Element { const [refreshing, setRefreshing] = useState(false); const [threeDotsMenuOpen, setThreeDotsMenuOpen] = useState(false); + const [readMore, setReadMore] = useState(false); const [menuPosition, setMenuPosition] = useState({top: -1000, right: 0}); const threeDotsRef = useRef(); @@ -103,10 +103,6 @@ export default function Info({route, navigation}: Props): React.JSX.Element { route.params.provider || provider.value ].GetMetaData(route.params.link, provider); - if (data.linkList?.length === 0) { - setInfoLoading(false); - return; - } try { const metaRes = await axios.get( `https://v3-cinemeta.strem.io/meta/${data?.type}/${data?.imdbId}.json`, @@ -121,6 +117,10 @@ export default function Info({route, navigation}: Props): React.JSX.Element { } catch (e) { console.log('meta error', e); } + if (data.linkList?.length === 0) { + setInfoLoading(false); + return; + } setInfo(data); MmmkvCache.setString(route.params.link, JSON.stringify(data)); setInfoLoading(false); @@ -163,6 +163,9 @@ export default function Info({route, navigation}: Props): React.JSX.Element { MMKV.setArray('watchlist', newLibrary); setInLibrary(false); }; + const synopsis = meta?.description + ? meta?.description + : info?.synopsis || 'No synopsis available'; return ( + {/* open in web */} { + setThreeDotsMenuOpen(false); navigation.navigate('Webview', { link: route.params.link, }); @@ -404,6 +409,7 @@ export default function Info({route, navigation}: Props): React.JSX.Element { Open in Web + {/* search */} { @@ -431,21 +437,24 @@ export default function Info({route, navigation}: Props): React.JSX.Element { } - + - {meta?.description - ? meta?.description.length > 180 - ? meta?.description.slice(0, 180) + '...' - : meta?.description - : info?.synopsis?.length! > 180 - ? info?.synopsis.slice(0, 180) + '...' - : info?.synopsis || 'No synopsis available'} + {synopsis.length > 180 && !readMore + ? synopsis.slice(0, 180) + '... ' + : synopsis} + {synopsis.length > 180 && !readMore && ( + setReadMore(!readMore)} + className="text-white font-extrabold text-xs px-2 bg-tertiary rounded-md"> + read more + + )} {/* cast */} - {infoLoading || !info?.linkList ? ( + {infoLoading ? ( { // search subtitles const [searchQuery, setSearchQuery] = useState(''); - const [showMediaControls] = useState( - MMKV.getBool('showMediaControls') || true, - ); - const [playbackRate, setPlaybackRate] = useState(1); // constants - const playbacks = [0.25, 0.5, 1, 1.25, 1.5, 1.75, 2]; + const playbacks = [0.25, 0.5, 1, 1.25, 1.35, 1.5, 1.75, 2]; const settings: | { title: string; @@ -133,6 +129,10 @@ const Player = ({route}: Props): React.JSX.Element => { const excludedQualities = MMKV.getArray('ExcludedQualities') || []; const hideSeekButtons = MMKV.getBool('hideSeekButtons') || false; const enable2xGesture = MMKV.getBool('enable2xGesture') || false; + const enableSwipeGesture = + MMKV.getBool('enableSwipeGesture') === false ? false : true; + const showMediaControls = + MMKV.getBool('showMediaControls') === false ? false : true; const watchedDuration = MmmkvCache.getString(activeEpisode?.link) ? JSON.parse(MmmkvCache.getString(activeEpisode?.link) as string).position @@ -307,6 +307,7 @@ const Player = ({route}: Props): React.JSX.Element => { {/* // video player */} { transition={{type: 'timing', duration: 190}} className="absolute top-5 right-20 flex-row items-center"> )} diff --git a/src/screens/settings/Preference.tsx b/src/screens/settings/Preference.tsx index a45a453..51f96d4 100644 --- a/src/screens/settings/Preference.tsx +++ b/src/screens/settings/Preference.tsx @@ -35,7 +35,7 @@ const Preferences = () => { ); const [showMediaControls, setShowMediaControls] = useState( - MMKV.getBool('showMediaControls') || true, + MMKV.getBool('showMediaControls') === false ? false : true, ); const [showHamburgerMenu, setShowHamburgerMenu] = useState( @@ -49,6 +49,11 @@ const Preferences = () => { MMKV.getBool('enable2xGesture') || false, ); + const [enableSwipeGesture, setEnableSwipeGesture] = useState( + MMKV.getBool('enableSwipeGesture') === false ? false : true, + ); + console.log('gesture', enableSwipeGesture); + return ( @@ -235,6 +240,22 @@ const Preferences = () => { /> + {/* enable volume and brightness gesture */} + + + Enable Swipe Gestures + + + { + MMKV.setBool('enableSwipeGesture', !enableSwipeGesture); + setEnableSwipeGesture(!enableSwipeGesture); + }} + /> + + {/* enable 2x gesture */} diff --git a/yarn.lock b/yarn.lock index 46aa144..5b11c39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@8man/react-native-media-console@^2.2.4-alpha.14": - version "2.2.4-alpha.14" - resolved "https://registry.npmjs.org/@8man/react-native-media-console/-/react-native-media-console-2.2.4-alpha.14.tgz" - integrity sha512-larW7yJixgJT7LEMPDMYFGXQXdVLRz2JaRg8mkYOUp1PzAm2CayA9mp3L4ApX64XHjUZ0+UcrOEDZIUr+QL2HA== +"@8man/react-native-media-console@^2.2.4-alpha.16": + version "2.2.4-alpha.16" + resolved "https://registry.npmjs.org/@8man/react-native-media-console/-/react-native-media-console-2.2.4-alpha.16.tgz" + integrity sha512-n+X1savxnHpg88edc5X1Vsv+cvstx+3wig9cpEQWp+lbMapchDNOoI+Ozal/6cr4+JFuGM77GwNu2ny3/eBlyA== "@aashutoshrathi/word-wrap@^1.2.3": version "1.2.6"