fix: profiles

This commit is contained in:
RockinChaos 2024-08-27 17:28:16 -07:00
parent 65b7e614f0
commit 196ba8be55
4 changed files with 76 additions and 55 deletions

View file

@ -1,7 +1,7 @@
<script context='module'>
import { generateRandomString } from "@/modules/util.js"
import { get, writable } from 'simple-store-svelte'
import { swapProfiles, alToken, malToken } from '@/modules/settings.js'
import { swapProfiles, alToken, malToken, profiles } from '@/modules/settings.js'
import { platformMap } from '@/views/Settings/Settings.svelte'
import { clientID } from "@/modules/myanimelist.js"
import { click } from '@/modules/click.js'
@ -12,7 +12,10 @@
export const profileView = writable(false)
const profileAdd = writable(false)
const currentProfile = writable(alToken || malToken)
const profiles = writable(JSON.parse(localStorage.getItem('profiles')) || [])
profiles.subscribe(() => {
currentProfile.set(alToken || malToken)
})
function isAniProfile (profile) {
return profile.viewer?.data?.Viewer?.avatar
@ -25,9 +28,7 @@
function dropProfile (profile) {
profiles.update(profiles => {
const updatedProfiles = profiles.filter(p => p.viewer.data.Viewer.id !== profile.viewer?.data?.Viewer.id)
localStorage.setItem('profiles', JSON.stringify(updatedProfiles))
return updatedProfiles
return profiles.filter(p => p.viewer.data.Viewer.id !== profile.viewer?.data?.Viewer.id)
})
}
@ -43,14 +44,12 @@
localStorage.setItem(isAniProfile(mainProfile) ? 'ALviewer' : 'MALviewer', JSON.stringify(mainProfile))
} else {
profiles.update(profiles => {
const updatedProfiles = profiles.map(p => {
return profiles.map(p => {
if (p.viewer.data.Viewer.id === profile.viewer.data.Viewer.id) {
p.viewer.data.Viewer.sync = !p.viewer.data.Viewer.sync
}
return p
})
localStorage.setItem('profiles', JSON.stringify(updatedProfiles))
return updatedProfiles
})
}
}

View file

@ -2,7 +2,9 @@ import { alToken, malToken, isAuthorized } from '@/modules/settings.js'
import { anilistClient, codes } from '@/modules/anilist.js'
import { malClient } from '@/modules/myanimelist.js'
import { malDubs } from "@/modules/animedubs.js"
import { profiles } from '@/modules/settings.js'
import { toast } from 'svelte-sonner'
import { get } from 'svelte/store'
import Fuse from 'fuse.js'
import Debug from 'debug'
@ -178,7 +180,7 @@ export default class Helper {
*/
static async fillEntry(media) {
if (this.isMalAuth()) {
debug(`Filling myanimelist entry data for ${media.id}`)
debug(`Filling MyAnimeList entry data for ${media?.id} (AniList)`)
const userLists = await malClient.userLists.value
const malEntry = userLists.data.MediaList.find(({ node }) => node.id === media.idMal)
if (malEntry) {
@ -212,9 +214,9 @@ export default class Helper {
// check if values exist
if (filemedia.media && this.isAuthorized()) {
const { media, failed } = filemedia
debug(`Checking entry for ${media.title.userPreferred}`)
debug(`Checking entry for ${media?.title?.userPreferred}`)
debug(`Media viability: ${media.status}, Is from failed resolve: ${failed}`)
debug(`Media viability: ${media?.status}, Is from failed resolve: ${failed}`)
if (failed) return
if (media.status !== 'FINISHED' && media.status !== 'RELEASING') return
@ -264,10 +266,9 @@ export default class Helper {
}
this.listToast(res, description, false)
if (this.getUser().sync) { // handle profile syncing
if (this.getUser().sync) { // handle profile entry syncing
const mediaId = media.id
const profiles = JSON.parse(localStorage.getItem('profiles')) || []
for (const profile of profiles) {
for (const profile of get(profiles)) {
if (profile.viewer?.data?.Viewer.sync) {
let res
if (profile.viewer?.data?.Viewer?.avatar) {

View file

@ -1,4 +1,4 @@
import { writable } from 'simple-store-svelte'
import { get, writable } from 'simple-store-svelte'
import { defaults } from './util.js'
import IPC from '@/modules/ipc.js'
import { toast } from 'svelte-sonner'
@ -6,6 +6,7 @@ import Debug from 'debug'
const debug = Debug('ui:anilist')
export let profiles = writable(JSON.parse(localStorage.getItem('profiles')) || [])
/** @type {{viewer: import('./al').Query<{Viewer: import('./al').Viewer}>, token: string} | null} */
export let alToken = JSON.parse(localStorage.getItem('ALviewer')) || null
/** @type {{viewer: import('./mal').Query<{Viewer: import('./mal').Viewer}>, token: string} | null} */
@ -36,6 +37,10 @@ settings.subscribe(value => {
localStorage.setItem('settings', JSON.stringify(value))
})
profiles.subscribe(value => {
localStorage.setItem('profiles', JSON.stringify(value))
})
export function resetSettings () {
settings.value = { ...defaults, ...scopedDefaults }
}
@ -125,49 +130,55 @@ async function handleMalToken (code, state) {
export async function refreshMalToken (token) {
const { clientID } = await import('./myanimelist.js')
const response = await fetch('https://myanimelist.net/v1/oauth2/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
client_id: clientID,
grant_type: 'refresh_token',
refresh_token: malToken.refresh
const refresh = malToken?.token === token ? malToken.refresh : get(profiles).find(profile => profile.token === token)?.refresh
let response
if (!refresh || !(refresh.length > 0)) {
response = await fetch('https://myanimelist.net/v1/oauth2/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
client_id: clientID,
grant_type: 'refresh_token',
refresh_token: refresh
})
})
})
if (!response.ok) {
}
if (!refresh || !(refresh.length > 0) || !response.ok) {
toast.error('Failed to re-authenticate with MyAnimeList. You will need to log in again.', { description: JSON.stringify(response.status) })
debug(`Failed to refresh MyAnimeList User Token: ${JSON.stringify(response)}`)
if (malToken.token === token) {
debug(`Failed to refresh MyAnimeList User Token ${ !refresh || !(refresh.length > 0) ? 'as the refresh token could not be fetched!' : ': ' + JSON.stringify(response)}`)
if (malToken?.token === token) {
swapProfiles(null)
location.reload()
} else {
const profiles = JSON.parse(localStorage.getItem('profiles')) || []
localStorage.setItem('profiles', JSON.stringify(profiles.filter(profile => profile.token !== token)))
profiles.update(profiles =>
profiles.filter(profile => profile.token !== token)
)
}
return
}
const oauth = await response.json()
if (malToken.token === token) {
if (malToken?.token === token) {
const viewer = malToken.viewer
malToken = { token: oauth.access_token, refresh:oauth.refresh_token, viewer: viewer }
malToken = { token: oauth.access_token, refresh: oauth.refresh_token, viewer: viewer }
localStorage.setItem('MALviewer', JSON.stringify({ token: oauth.access_token, refresh: oauth.refresh_token, viewer }))
} else {
let profiles = JSON.parse(localStorage.getItem('profiles')) || []
profiles = profiles.map(profile => {
if (profile.token === token) {
return {...profile, token: oauth.access_token, refresh: oauth.refresh_token}
}
return profile
})
localStorage.setItem('profiles', JSON.stringify(profiles))
profiles.update(profiles =>
profiles.map(profile => {
if (profile.token === token) {
return { ...profile, token: oauth.access_token, refresh: oauth.refresh_token }
}
return profile
})
)
}
return oauth
}
export function swapProfiles(profile) {
let profiles = JSON.parse(localStorage.getItem('profiles')) || []
const currentProfile = isAuthorized()
const newProfile = profile !== null && !profiles.some(p => p.viewer?.data?.Viewer?.id === currentProfile?.viewer?.data?.Viewer?.id)
const newProfile = profile !== null && !get(profiles).some(p => p.viewer?.data?.Viewer?.id === currentProfile?.viewer?.data?.Viewer?.id)
if (currentProfile) {
const torrent = localStorage.getItem('torrent')
@ -176,26 +187,30 @@ export function swapProfiles(profile) {
if (torrent) currentProfile.viewer.data.Viewer.torrent = torrent
if (lastFinished) currentProfile.viewer.data.Viewer.lastFinished = lastFinished
if (settings) currentProfile.viewer.data.Viewer.settings = settings
if (newProfile) profiles.unshift(currentProfile)
if (newProfile) profiles.update(currentProfiles => [currentProfile, ...currentProfiles])
}
localStorage.removeItem(alToken ? 'ALviewer' : 'MALviewer')
if (profile === null && profiles.length > 0) {
const firstProfile = profiles.shift()
setViewer(firstProfile)
if (profile === null && get(profiles).length > 0) {
let firstProfile
profiles.update(profiles => {
firstProfile = profiles[0]
setViewer(firstProfile)
return profiles.slice(1)
})
} else if (profile !== null) {
profiles = profiles.filter(p => p.viewer?.data?.Viewer?.id !== profile.viewer?.data?.Viewer?.id)
setViewer(profile)
profiles.update(profiles =>
profiles.filter(p => p.viewer?.data?.Viewer?.id !== profile.viewer?.data?.Viewer?.id)
)
} else {
alToken = null
malToken = null
}
localStorage.setItem('profiles', JSON.stringify(profiles))
}
function setViewer (profile) {
const { torrent, lastFinished, settings } = profile.viewer?.data?.Viewer
const { torrent, lastFinished, settings } = profile?.viewer?.data?.Viewer
if (torrent) {
localStorage.setItem('torrent', torrent)
} else if (isAuthorized()) {
@ -211,5 +226,12 @@ function setViewer (profile) {
} else if (isAuthorized()) {
localStorage.setItem('settings', writable({ ...defaults, ...scopedDefaults}))
}
if (profile?.viewer?.data?.Viewer?.avatar) {
alToken = profile
malToken = null
} else {
malToken = profile
alToken = null
}
localStorage.setItem(profile.viewer?.data?.Viewer?.avatar ? 'ALviewer' : 'MALviewer', JSON.stringify(profile))
}

View file

@ -1,7 +1,8 @@
<script>
import { anilistClient, codes } from '@/modules/anilist.js'
import { profiles } from '@/modules/settings.js'
import { click } from '@/modules/click.js'
import { writable } from 'svelte/store'
import { get, writable } from 'svelte/store'
import { toast } from 'svelte-sonner'
import { Bookmark, PencilLine } from 'lucide-svelte'
import Helper from '@/modules/helper.js'
@ -67,8 +68,7 @@
if (Helper.getUser().sync) { // handle profile syncing
const mediaId = media.id
const profiles = JSON.parse(localStorage.getItem('profiles')) || []
for (const profile of profiles) {
for (const profile of get(profiles)) {
if (profile.viewer?.data?.Viewer.sync) {
const anilist = profile.viewer?.data?.Viewer?.avatar
const listId = (anilist ? {id: (await anilistClient.getUserLists({userID: profile.viewer.data.Viewer.id, token: profile.token}))?.data?.MediaListCollection?.lists?.flatMap(list => list.entries).find(({ media }) => media.id === mediaId)?.media?.mediaListEntry?.id} : {idMal: media.idMal})
@ -107,8 +107,7 @@
printToast(res, description, true, false)
if (Helper.getUser().sync) { // handle profile syncing
const mediaId = media.id
const profiles = JSON.parse(localStorage.getItem('profiles')) || []
for (const profile of profiles) {
for (const profile of get(profiles)) {
if (profile.viewer?.data?.Viewer.sync) {
const anilist = profile.viewer?.data?.Viewer?.avatar
const currentLists = (anilist ? (await anilistClient.getUserLists({userID: profile.viewer.data.Viewer.id, token: profile.token}))?.data?.MediaListCollection?.lists?.flatMap(list => list.entries).find(({ media }) => media.id === mediaId)?.media?.mediaListEntry?.customLists?.filter(list => list.enabled).map(list => list.name) || [] : lists)