adn login implementation and search not disappearing fix
This commit is contained in:
parent
f19189f1dc
commit
a4d3f8a34e
0
components/ADN/GetAnime.ts
Normal file
0
components/ADN/GetAnime.ts
Normal file
0
components/ADN/ListEpisodes.ts
Normal file
0
components/ADN/ListEpisodes.ts
Normal file
@ -19,7 +19,7 @@
|
|||||||
<option value="adn">ADN</option>
|
<option value="adn">ADN</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isLoggedInCR && service === 'crunchyroll' || !isLoggedInCR && service === 'adn'" class="relative flex flex-col">
|
<div v-if="isLoggedInCR && service === 'crunchyroll' || isLoggedInADN && service === 'adn'" class="relative flex flex-col">
|
||||||
<input
|
<input
|
||||||
v-model="search"
|
v-model="search"
|
||||||
@input="handleInputChange"
|
@input="handleInputChange"
|
||||||
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="searchActive"
|
v-if="searchActive"
|
||||||
class="absolute top-full left-0 h-60 w-full bg-[#868585] rounded-xl overflow-y-scroll grid grid-cols-2 gap-3 p-2 z-10"
|
class="absolute top-full left-0 h-40 w-full bg-[#868585] rounded-xl overflow-y-scroll grid grid-cols-2 gap-3 p-2 z-10"
|
||||||
style="-webkit-app-region: no-drag"
|
style="-webkit-app-region: no-drag"
|
||||||
>
|
>
|
||||||
<button v-for="result in crunchySearchResults" @click="selectShow(result)" class="flex flex-row gap-3 px-3 py-3 hover:bg-[#747474] rounded-xl">
|
<button v-for="result in crunchySearchResults" @click="selectShow(result)" class="flex flex-row gap-3 px-3 py-3 hover:bg-[#747474] rounded-xl">
|
||||||
@ -61,10 +61,10 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isLoggedInCR && service === 'crunchyroll'" class="relative flex flex-col">
|
<div v-if="isLoggedInCR && service === 'crunchyroll' || isLoggedInADN && service === 'adn'" class="relative flex flex-col">
|
||||||
<input v-model="url" type="text" name="text" placeholder="URL" class="bg-[#5c5b5b] focus:outline-none px-3 py-2 rounded-xl text-sm text-center" />
|
<input v-model="url" type="text" name="text" placeholder="URL" class="bg-[#5c5b5b] focus:outline-none px-3 py-2 rounded-xl text-sm text-center" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isLoggedInCR && service === 'crunchyroll'" class="relative flex flex-col">
|
<div v-if="isLoggedInCR && service === 'crunchyroll' || isLoggedInADN && service === 'adn'" class="relative flex flex-col">
|
||||||
<input
|
<input
|
||||||
@click="getFolderPath()"
|
@click="getFolderPath()"
|
||||||
v-model="path"
|
v-model="path"
|
||||||
@ -80,6 +80,11 @@
|
|||||||
class="bg-[#5c5b5b] focus:outline-none px-3 py-2 rounded-xl text-sm text-center cursor-pointer"
|
class="bg-[#5c5b5b] focus:outline-none px-3 py-2 rounded-xl text-sm text-center cursor-pointer"
|
||||||
>Click to Login</button>
|
>Click to Login</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="!isLoggedInADN && service === 'adn'" class="relative flex flex-col">
|
||||||
|
<button @click="openADNLogin"
|
||||||
|
class="bg-[#5c5b5b] focus:outline-none px-3 py-2 rounded-xl text-sm text-center cursor-pointer"
|
||||||
|
>Click to Login</button>
|
||||||
|
</div>
|
||||||
<div class="relative flex flex-col mt-auto">
|
<div class="relative flex flex-col mt-auto">
|
||||||
<button @click="switchToSeason" class="relative py-3 border-2 rounded-xl flex flex-row items-center justify-center">
|
<button @click="switchToSeason" class="relative py-3 border-2 rounded-xl flex flex-row items-center justify-center">
|
||||||
<div class="flex flex-row items-center justify-center transition-all" :class="isFetchingSeasons ? 'opacity-0' : 'opacity-100'">
|
<div class="flex flex-row items-center justify-center transition-all" :class="isFetchingSeasons ? 'opacity-0' : 'opacity-100'">
|
||||||
@ -91,7 +96,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- {{ searchresults }} -->
|
|
||||||
</div>
|
</div>
|
||||||
<div v-if="tab === 2" class="flex flex-col mt-5 gap-3.5 h-full" style="-webkit-app-region: no-drag">
|
<div v-if="tab === 2" class="flex flex-col mt-5 gap-3.5 h-full" style="-webkit-app-region: no-drag">
|
||||||
<div class="relative flex flex-col">
|
<div class="relative flex flex-col">
|
||||||
@ -282,7 +286,7 @@ const searchActive = ref<boolean>(false)
|
|||||||
const crunchySearchResults = ref<CrunchyrollSearchResults>()
|
const crunchySearchResults = ref<CrunchyrollSearchResults>()
|
||||||
const adnSearchResults = ref<ADNSearchResults>()
|
const adnSearchResults = ref<ADNSearchResults>()
|
||||||
const CRselectedShow = ref<CrunchyrollSearchResult | null>()
|
const CRselectedShow = ref<CrunchyrollSearchResult | null>()
|
||||||
const ADNselectedShow = ref<ADNSearchResult>()
|
const ADNselectedShow = ref<ADNSearchResult | null>()
|
||||||
const url = ref<string>('')
|
const url = ref<string>('')
|
||||||
const path = ref<string>()
|
const path = ref<string>()
|
||||||
const service = ref<'adn' | 'crunchyroll'>('crunchyroll')
|
const service = ref<'adn' | 'crunchyroll'>('crunchyroll')
|
||||||
@ -302,7 +306,9 @@ const isFetchingEpisodes = ref<number>(0)
|
|||||||
const isFetchingResults = ref<number>(0)
|
const isFetchingResults = ref<number>(0)
|
||||||
|
|
||||||
const isLoggedInCR = ref<boolean>(false)
|
const isLoggedInCR = ref<boolean>(false)
|
||||||
let interval: NodeJS.Timeout;
|
const isLoggedInADN = ref<boolean>(false)
|
||||||
|
let intervalcr: NodeJS.Timeout;
|
||||||
|
let intervaladn: NodeJS.Timeout;
|
||||||
|
|
||||||
const checkIfLoggedInCR = async () => {
|
const checkIfLoggedInCR = async () => {
|
||||||
const { data, error } = await checkAccount('CR')
|
const { data, error } = await checkAccount('CR')
|
||||||
@ -312,8 +318,8 @@ const checkIfLoggedInCR = async () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interval) {
|
if (intervalcr) {
|
||||||
clearInterval(interval)
|
clearInterval(intervalcr)
|
||||||
}
|
}
|
||||||
|
|
||||||
isLoggedInCR.value = true
|
isLoggedInCR.value = true
|
||||||
@ -328,10 +334,39 @@ const openCRLogin = () => {
|
|||||||
backgroundColor: "#111111"
|
backgroundColor: "#111111"
|
||||||
})
|
})
|
||||||
|
|
||||||
interval = setInterval(checkIfLoggedInCR, 1000)
|
intervalcr = setInterval(checkIfLoggedInCR, 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const checkIfLoggedInADN = async () => {
|
||||||
|
const { data, error } = await checkAccount('ADN')
|
||||||
|
|
||||||
|
if (error.value) {
|
||||||
|
isLoggedInADN.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intervaladn) {
|
||||||
|
clearInterval(intervaladn)
|
||||||
|
}
|
||||||
|
|
||||||
|
isLoggedInADN.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const openADNLogin = () => {
|
||||||
|
(window as any).myAPI.openWindow({
|
||||||
|
title: "ADN Login",
|
||||||
|
url: isProduction ? 'http://localhost:8079/adnlogin' : 'http://localhost:3000/adnlogin',
|
||||||
|
width: 600,
|
||||||
|
height: 300,
|
||||||
|
backgroundColor: "#111111"
|
||||||
|
})
|
||||||
|
|
||||||
|
intervalcr = setInterval(checkIfLoggedInADN, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
checkIfLoggedInCR()
|
checkIfLoggedInCR()
|
||||||
|
checkIfLoggedInADN()
|
||||||
|
|
||||||
const fetchSearch = async () => {
|
const fetchSearch = async () => {
|
||||||
if (!search.value || search.value.length === 0) {
|
if (!search.value || search.value.length === 0) {
|
||||||
@ -341,7 +376,9 @@ const fetchSearch = async () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isFetchingResults.value++
|
if (!isFetchingResults.value) {
|
||||||
|
isFetchingResults.value++
|
||||||
|
}
|
||||||
|
|
||||||
if (service.value === 'adn') {
|
if (service.value === 'adn') {
|
||||||
adnSearchResults.value = await searchADN(search.value)
|
adnSearchResults.value = await searchADN(search.value)
|
||||||
@ -351,7 +388,9 @@ const fetchSearch = async () => {
|
|||||||
crunchySearchResults.value = await searchCrunchy(search.value)
|
crunchySearchResults.value = await searchCrunchy(search.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
isFetchingResults.value--
|
if (isFetchingResults.value) {
|
||||||
|
isFetchingResults.value--
|
||||||
|
}
|
||||||
searchActive.value = true
|
searchActive.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,6 +406,12 @@ const handleInputChange = () => {
|
|||||||
debounceFetchSearch()
|
debounceFetchSearch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(url, () => {
|
||||||
|
if (url.value.length === 0 || !url.value) {
|
||||||
|
searchActive.value = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
;(window as any).myAPI.getFolder().then((result: any) => {
|
;(window as any).myAPI.getFolder().then((result: any) => {
|
||||||
path.value = result
|
path.value = result
|
||||||
@ -396,12 +441,21 @@ const selectShow = async (show: any) => {
|
|||||||
crunchySearchResults.value = []
|
crunchySearchResults.value = []
|
||||||
adnSearchResults.value = []
|
adnSearchResults.value = []
|
||||||
searchActive.value = false
|
searchActive.value = false
|
||||||
|
if (isFetchingResults.value) {
|
||||||
|
isFetchingResults.value--
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(selectedSeason, () => {
|
watch(selectedSeason, () => {
|
||||||
refetchEpisodes()
|
refetchEpisodes()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(service, () => {
|
||||||
|
url.value = "",
|
||||||
|
CRselectedShow.value = null,
|
||||||
|
ADNselectedShow.value = null
|
||||||
|
})
|
||||||
|
|
||||||
watch(selectedStartEpisode, () => {
|
watch(selectedStartEpisode, () => {
|
||||||
if (!selectedEndEpisode.value) return
|
if (!selectedEndEpisode.value) return
|
||||||
if (!episodes.value) return
|
if (!episodes.value) return
|
||||||
|
59
pages/adnlogin.vue
Normal file
59
pages/adnlogin.vue
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<template>
|
||||||
|
<div class="h-screen overflow-hidden bg-[#111111] flex flex-col p-5 text-white" style="-webkit-app-region: drag">
|
||||||
|
<div class="relative flex flex-row items-center justify-center">
|
||||||
|
<div class="text-2xl">ADN Login</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col mt-5 gap-3.5 h-full" style="-webkit-app-region: no-drag">
|
||||||
|
<div class="relative flex flex-col">
|
||||||
|
<input v-model="username" type="text" name="text" placeholder="Email" class="bg-[#5c5b5b] focus:outline-none px-3 py-2 rounded-xl text-sm text-center" />
|
||||||
|
</div>
|
||||||
|
<div class="relative flex flex-col">
|
||||||
|
<input v-model="password" type="password" name="text" placeholder="Password" class="bg-[#5c5b5b] focus:outline-none px-3 py-2 rounded-xl text-sm text-center" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="relative flex flex-col mt-auto">
|
||||||
|
<button @click="login" class="relative py-3 border-2 rounded-xl flex flex-row items-center justify-center" style="-webkit-app-region: no-drag">
|
||||||
|
<div class="flex flex-row items-center justify-center transition-all" :class="isLoggingIn ? 'opacity-0' : 'opacity-100'">
|
||||||
|
<div class="text-xl">Login</div>
|
||||||
|
</div>
|
||||||
|
<div class="absolute flex flex-row items-center justify-center gap-1 transition-all" :class="isLoggingIn ? 'opacity-100' : 'opacity-0'">
|
||||||
|
<Icon name="mdi:loading" class="h-6 w-6 animate-spin" />
|
||||||
|
<div class="text-xl">Logging in</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { loginAccount } from '~/components/Crunchyroll/Account'
|
||||||
|
const isProduction = process.env.NODE_ENV !== 'development'
|
||||||
|
|
||||||
|
const username = ref<string>()
|
||||||
|
const password = ref<string>()
|
||||||
|
|
||||||
|
const isLoggingIn = ref<number>(0)
|
||||||
|
|
||||||
|
const login = async () => {
|
||||||
|
isLoggingIn.value++
|
||||||
|
if (!username.value) {
|
||||||
|
isLoggingIn.value--
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!password.value) {
|
||||||
|
isLoggingIn.value--
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data, error } = await loginAccount(username.value, password.value, 'ADN')
|
||||||
|
|
||||||
|
if (error.value) {
|
||||||
|
isLoggingIn.value--
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isLoggingIn.value--
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
@ -378,92 +378,74 @@ import { useFetch } from '../useFetch'
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
export async function adnyLogin(user: string, passw: string) {
|
export async function adnLogin(user: string, passw: string) {
|
||||||
const cachedData:
|
const cachedData:
|
||||||
| {
|
| {
|
||||||
access_token: string
|
access_token: string
|
||||||
refresh_token: string
|
refresh_token: string
|
||||||
expires_in: number
|
expires_in: number
|
||||||
token_type: string
|
token_type: string
|
||||||
scope: string
|
scope: string
|
||||||
country: string
|
country: string
|
||||||
account_id: string
|
account_id: string
|
||||||
profile_id: string
|
profile_id: string
|
||||||
}
|
|
||||||
| undefined = server.CacheController.get('adntoken')
|
|
||||||
|
|
||||||
if (!cachedData) {
|
|
||||||
var { data, error } = await adnLoginFetch(user, passw)
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
messageBox(
|
|
||||||
'error',
|
|
||||||
['Cancel'],
|
|
||||||
2,
|
|
||||||
'Failed to login',
|
|
||||||
'Failed to login to ADN',
|
|
||||||
(error.error as string)
|
|
||||||
)
|
|
||||||
return { data: null, error: error.error }
|
|
||||||
}
|
}
|
||||||
|
| undefined = server.CacheController.get('adntoken')
|
||||||
|
|
||||||
if (!data) {
|
if (!cachedData) {
|
||||||
messageBox('error', ['Cancel'], 2, 'Failed to login', 'Failed to login to ADN', 'ADN returned null')
|
var { data, error } = await adnLoginFetch(user, passw)
|
||||||
return { data: null, error: 'ADN returned null' }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data.access_token) {
|
|
||||||
messageBox('error', ['Cancel'], 2, 'Failed to login', 'Failed to login to ADN', 'ADN returned malformed data')
|
|
||||||
return { data: null, error: 'ADN returned malformed data' }
|
|
||||||
}
|
|
||||||
|
|
||||||
server.CacheController.set('adntoken', data, data.expires_in - 30)
|
|
||||||
|
|
||||||
return { data: data, error: null }
|
|
||||||
}
|
|
||||||
|
|
||||||
return { data: cachedData, error: null }
|
|
||||||
}
|
|
||||||
|
|
||||||
async function adnLoginFetch(user: string, passw: string) {
|
|
||||||
const headers = {
|
|
||||||
Authorization: 'Basic dC1rZGdwMmg4YzNqdWI4Zm4wZnE6eWZMRGZNZnJZdktYaDRKWFMxTEVJMmNDcXUxdjVXYW4=',
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
'User-Agent': 'Crunchyroll/3.46.2 Android/13 okhttp/4.12.0'
|
|
||||||
}
|
|
||||||
|
|
||||||
const body: any = {
|
|
||||||
username: user,
|
|
||||||
password: passw,
|
|
||||||
grant_type: 'password',
|
|
||||||
scope: 'offline_access',
|
|
||||||
device_name: 'RMX2170',
|
|
||||||
device_type: 'realme RMX2170'
|
|
||||||
}
|
|
||||||
|
|
||||||
const { data, error } = await useFetch<{
|
|
||||||
access_token: string
|
|
||||||
refresh_token: string
|
|
||||||
expires_in: number
|
|
||||||
token_type: string
|
|
||||||
scope: string
|
|
||||||
country: string
|
|
||||||
account_id: string
|
|
||||||
profile_id: string
|
|
||||||
}>('https://beta-api.crunchyroll.com/auth/v1/token', {
|
|
||||||
type: 'POST',
|
|
||||||
body: new URLSearchParams(body).toString(),
|
|
||||||
header: headers,
|
|
||||||
credentials: 'same-origin'
|
|
||||||
})
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return { data: null, error: error }
|
messageBox('error', ['Cancel'], 2, 'Failed to login', 'Failed to login to ADN', error.error as string)
|
||||||
|
return { data: null, error: error.error }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return { data: null, error: null }
|
messageBox('error', ['Cancel'], 2, 'Failed to login', 'Failed to login to ADN', 'ADN returned null')
|
||||||
|
return { data: null, error: 'ADN returned null' }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!data.accessToken) {
|
||||||
|
messageBox('error', ['Cancel'], 2, 'Failed to login', 'Failed to login to ADN', 'ADN returned malformed data')
|
||||||
|
return { data: null, error: 'ADN returned malformed data' }
|
||||||
|
}
|
||||||
|
|
||||||
|
server.CacheController.set('adntoken', data, 300)
|
||||||
|
|
||||||
return { data: data, error: null }
|
return { data: data, error: null }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return { data: cachedData, error: null }
|
||||||
|
}
|
||||||
|
|
||||||
|
async function adnLoginFetch(user: string, passw: string) {
|
||||||
|
const headers = {
|
||||||
|
'x-target-distribution': 'de',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
username: user,
|
||||||
|
password: passw,
|
||||||
|
source: 'Web',
|
||||||
|
rememberMe: true
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data, error } = await useFetch<{
|
||||||
|
accessToken: string;
|
||||||
|
}>('https://gw.api.animationdigitalnetwork.fr/authentication/login', {
|
||||||
|
type: 'POST',
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
header: headers,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return { data: null, error: error }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return { data: null, error: null }
|
||||||
|
}
|
||||||
|
|
||||||
|
return { data: data, error: null }
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@ import { FastifyReply, FastifyRequest } from "fastify"
|
|||||||
import { crunchyLogin } from "../crunchyroll/crunchyroll.service"
|
import { crunchyLogin } from "../crunchyroll/crunchyroll.service"
|
||||||
import { addEpisodeToPlaylist, getDownloading, getPlaylist, loggedInCheck, safeLoginData } from "./service.service"
|
import { addEpisodeToPlaylist, getDownloading, getPlaylist, loggedInCheck, safeLoginData } from "./service.service"
|
||||||
import { CrunchyEpisodes } from "../../types/crunchyroll"
|
import { CrunchyEpisodes } from "../../types/crunchyroll"
|
||||||
|
import { adnLogin } from "../adn/adn.service"
|
||||||
|
|
||||||
export async function checkLoginController(request: FastifyRequest<{
|
export async function checkLoginController(request: FastifyRequest<{
|
||||||
Params: {
|
Params: {
|
||||||
@ -48,9 +49,9 @@ export async function loginController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (params.id === 'ADN') {
|
if (params.id === 'ADN') {
|
||||||
// const { data, error } = await adnLogin(body.user, body.password)
|
const { data, error } = await adnLogin(body.user, body.password)
|
||||||
// responseError = error,
|
responseError = error,
|
||||||
// responseData = data
|
responseData = data
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseError || !responseData) {
|
if (responseError || !responseData) {
|
||||||
|
Reference in New Issue
Block a user