Compare commits
10 Commits
4e11b218be
...
2be45caa21
Author | SHA1 | Date | |
---|---|---|---|
2be45caa21 | |||
55c73a84a3 | |||
cdf37707bf | |||
286ecbfddd | |||
d99f71e18c | |||
530a4bc3ff | |||
bcdccf8061 | |||
b6e06c1134 | |||
24a4d4e0d6 | |||
2dd0114cc3 |
@ -35,9 +35,11 @@ func AniListQuery(body interface{}, login bool) (json.RawMessage, string) {
|
||||
return returnedBody, ""
|
||||
}
|
||||
|
||||
func (a *App) GetAniListItem(aniId int) any {
|
||||
func (a *App) GetAniListItem(aniId int) AniListGetSingleAnime {
|
||||
var user = a.GetAniListLoggedInUserId()
|
||||
type Variables struct {
|
||||
ID int `json:"id"`
|
||||
UserId int `json:"userId"`
|
||||
MediaId int `json:"mediaId"`
|
||||
ListType string `json:"listType"`
|
||||
}
|
||||
body := struct {
|
||||
@ -45,43 +47,78 @@ func (a *App) GetAniListItem(aniId int) any {
|
||||
Variables Variables `json:"variables"`
|
||||
}{
|
||||
Query: `
|
||||
query ($id: Int!, $listType: MediaType) {
|
||||
Media (id: $id, type: $listType) {
|
||||
query($userId: Int, $mediaId: Int, $listType: MediaType) {
|
||||
MediaList(mediaId: $mediaId, userId: $userId, type: $listType) {
|
||||
id
|
||||
idMal
|
||||
title {
|
||||
mediaId
|
||||
userId
|
||||
media {
|
||||
id
|
||||
idMal
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
}
|
||||
description
|
||||
coverImage {
|
||||
medium
|
||||
native
|
||||
}
|
||||
description
|
||||
coverImage {
|
||||
large
|
||||
extraLarge
|
||||
color
|
||||
}
|
||||
season
|
||||
seasonYear
|
||||
status
|
||||
episodes
|
||||
nextAiringEpisode {
|
||||
airingAt
|
||||
timeUntilAiring
|
||||
episode
|
||||
}
|
||||
}
|
||||
tags {
|
||||
id
|
||||
name
|
||||
description
|
||||
category
|
||||
rank
|
||||
isGeneralSpoiler
|
||||
isMediaSpoiler
|
||||
isAdult
|
||||
status
|
||||
startedAt{
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
completedAt{
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
notes
|
||||
progress
|
||||
score
|
||||
repeat
|
||||
user {
|
||||
id
|
||||
name
|
||||
avatar {
|
||||
large
|
||||
medium
|
||||
}
|
||||
statistics {
|
||||
anime {
|
||||
count
|
||||
statuses {
|
||||
status
|
||||
count
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
Variables: Variables{
|
||||
ID: aniId,
|
||||
MediaId: aniId,
|
||||
UserId: user.Data.Viewer.ID,
|
||||
ListType: "ANIME",
|
||||
},
|
||||
}
|
||||
|
||||
returnedBody, _ := AniListQuery(body, false)
|
||||
|
||||
var post interface{}
|
||||
var post AniListGetSingleAnime
|
||||
err := json.Unmarshal(returnedBody, &post)
|
||||
if err != nil {
|
||||
log.Printf("Failed at unmarshal, %s\n", err)
|
||||
@ -110,18 +147,28 @@ func (a *App) AniListSearch(query string) any {
|
||||
perPage
|
||||
}
|
||||
media (search: $search, type: $listType) {
|
||||
id
|
||||
idMal
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
}
|
||||
coverImage {
|
||||
extraLarge
|
||||
color
|
||||
}
|
||||
id
|
||||
idMal
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
}
|
||||
description
|
||||
coverImage {
|
||||
large
|
||||
}
|
||||
season
|
||||
seasonYear
|
||||
status
|
||||
episodes
|
||||
nextAiringEpisode{
|
||||
airingAt
|
||||
timeUntilAiring
|
||||
episode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
Variables: Variables{
|
||||
@ -198,6 +245,16 @@ func (a *App) GetAniListUserWatchingList(page int, perPage int, sort string) Ani
|
||||
}
|
||||
}
|
||||
status
|
||||
startedAt {
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
completedAt {
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
notes
|
||||
progress
|
||||
score
|
||||
@ -257,3 +314,111 @@ func (a *App) GetAniListUserWatchingList(page int, perPage int, sort string) Ani
|
||||
|
||||
return post
|
||||
}
|
||||
|
||||
func (a *App) AniListUpdateEntry(
|
||||
mediaId int,
|
||||
progress string,
|
||||
status string,
|
||||
score float64,
|
||||
repeat int,
|
||||
notes string,
|
||||
startYear int,
|
||||
startMonth int,
|
||||
startDay int,
|
||||
completeYear int,
|
||||
completeMonth int,
|
||||
completeDay int,
|
||||
) interface{} {
|
||||
type StartedAt struct {
|
||||
Year int `json:"year"`
|
||||
Month int `json:"month"`
|
||||
Day int `json:"day"`
|
||||
}
|
||||
type CompletedAt struct {
|
||||
Year int `json:"year"`
|
||||
Month int `json:"month"`
|
||||
Day int `json:"day"`
|
||||
}
|
||||
type Variables struct {
|
||||
MediaId int `json:"mediaId"`
|
||||
Progress string `json:"progress"`
|
||||
Status string `json:"status"`
|
||||
Score float64 `json:"score"`
|
||||
Repeat int `json:"repeat"`
|
||||
Notes string `json:"notes"`
|
||||
StartedAt StartedAt `json:"startedAt"`
|
||||
CompletedAt CompletedAt `json:"completedAt"`
|
||||
}
|
||||
body := struct {
|
||||
Mutation string `json:"mutation"`
|
||||
Variables Variables `json:"variables"`
|
||||
}{
|
||||
Mutation: `
|
||||
mutation(
|
||||
$mediaId:Int,
|
||||
$progress:Int,
|
||||
$status:MediaListStatus,
|
||||
$score:Float,
|
||||
$repeat:Int,
|
||||
$notes:String,
|
||||
$startedAt:FuzzyDateInput,
|
||||
$completedAt:FuzzyDateInput,
|
||||
){
|
||||
SaveMediaListEntry(
|
||||
mediaId:$mediaId,
|
||||
progress:$progress,
|
||||
status:$status,
|
||||
score:$score,
|
||||
repeat:$repeat,
|
||||
notes:$notes,
|
||||
startedAt:$startedAt
|
||||
completedAt:$completedAt
|
||||
){
|
||||
mediaId
|
||||
progress
|
||||
status
|
||||
score
|
||||
repeat
|
||||
notes
|
||||
startedAt{
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
completedAt{
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
Variables: Variables{
|
||||
MediaId: mediaId,
|
||||
Progress: progress,
|
||||
Status: status,
|
||||
Score: score,
|
||||
Repeat: repeat,
|
||||
Notes: notes,
|
||||
StartedAt: StartedAt{
|
||||
Year: startYear,
|
||||
Month: startMonth,
|
||||
Day: startDay,
|
||||
},
|
||||
CompletedAt: CompletedAt{
|
||||
Year: completeYear,
|
||||
Month: completeMonth,
|
||||
Day: completeDay,
|
||||
},
|
||||
}}
|
||||
|
||||
returnedBody, _ := AniListQuery(body, true)
|
||||
|
||||
var post interface{}
|
||||
err := json.Unmarshal(returnedBody, &post)
|
||||
if err != nil {
|
||||
log.Printf("Failed at unmarshal, %s\n", err)
|
||||
}
|
||||
|
||||
return post
|
||||
}
|
||||
|
106
AniListTypes.go
106
AniListTypes.go
@ -26,59 +26,67 @@ type AniListCurrentUserWatchList struct {
|
||||
LastPage int `json:"lastPage"`
|
||||
HasNextPage bool `json:"hasNextPage"`
|
||||
} `json:"pageInfo"`
|
||||
MediaList []struct {
|
||||
ID int `json:"id"`
|
||||
MediaID int `json:"mediaId"`
|
||||
UserID int `json:"userId"`
|
||||
Media struct {
|
||||
ID int `json:"id"`
|
||||
IDMal int `json:"idMal"`
|
||||
Title struct {
|
||||
Romaji string `json:"romaji"`
|
||||
English string `json:"english"`
|
||||
Native string `json:"native"`
|
||||
} `json:"title"`
|
||||
Description string `json:"description"`
|
||||
CoverImage struct {
|
||||
Large string `json:"large"`
|
||||
} `json:"coverImage"`
|
||||
Season string `json:"season"`
|
||||
SeasonYear int `json:"seasonYear"`
|
||||
Status string `json:"status"`
|
||||
Episodes int `json:"episodes"`
|
||||
NextAiringEpisode struct {
|
||||
AiringAt int `json:"airingAt"`
|
||||
TimeUntilAiring int `json:"timeUntilAiring"`
|
||||
Episode int `json:"episode"`
|
||||
} `json:"nextAiringEpisode"`
|
||||
} `json:"media"`
|
||||
Status string `json:"status"`
|
||||
Notes string `json:"notes"`
|
||||
Progress int `json:"progress"`
|
||||
Score int `json:"score"`
|
||||
Repeat int `json:"repeat"`
|
||||
User struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Avatar struct {
|
||||
Large string `json:"large"`
|
||||
Medium string `json:"medium"`
|
||||
} `json:"avatar"`
|
||||
Statistics struct {
|
||||
Anime struct {
|
||||
Count int `json:"count"`
|
||||
Statuses []struct {
|
||||
Status string `json:"status"`
|
||||
Count int `json:"count"`
|
||||
} `json:"statuses"`
|
||||
} `json:"anime"`
|
||||
} `json:"statistics"`
|
||||
} `json:"user"`
|
||||
} `json:"mediaList"`
|
||||
MediaList []MediaList `json:"mediaList"`
|
||||
} `json:"Page"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
type AniListGetSingleAnime struct {
|
||||
Data struct {
|
||||
MediaList MediaList `json:"MediaList"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
type MediaList struct {
|
||||
ID int `json:"id"`
|
||||
MediaID int `json:"mediaId"`
|
||||
UserID int `json:"userId"`
|
||||
Media struct {
|
||||
ID int `json:"id"`
|
||||
IDMal int `json:"idMal"`
|
||||
Title struct {
|
||||
Romaji string `json:"romaji"`
|
||||
English string `json:"english"`
|
||||
Native string `json:"native"`
|
||||
} `json:"title"`
|
||||
Description string `json:"description"`
|
||||
CoverImage struct {
|
||||
Large string `json:"large"`
|
||||
} `json:"coverImage"`
|
||||
Season string `json:"season"`
|
||||
SeasonYear int `json:"seasonYear"`
|
||||
Status string `json:"status"`
|
||||
Episodes int `json:"episodes"`
|
||||
NextAiringEpisode struct {
|
||||
AiringAt int `json:"airingAt"`
|
||||
TimeUntilAiring int `json:"timeUntilAiring"`
|
||||
Episode int `json:"episode"`
|
||||
} `json:"nextAiringEpisode"`
|
||||
} `json:"media"`
|
||||
Status string `json:"status"`
|
||||
Notes string `json:"notes"`
|
||||
Progress int `json:"progress"`
|
||||
Score int `json:"score"`
|
||||
Repeat int `json:"repeat"`
|
||||
User struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Avatar struct {
|
||||
Large string `json:"large"`
|
||||
Medium string `json:"medium"`
|
||||
} `json:"avatar"`
|
||||
Statistics struct {
|
||||
Anime struct {
|
||||
Count int `json:"count"`
|
||||
Statuses []struct {
|
||||
Status string `json:"status"`
|
||||
Count int `json:"count"`
|
||||
} `json:"statuses"`
|
||||
} `json:"anime"`
|
||||
} `json:"statistics"`
|
||||
} `json:"user"`
|
||||
}
|
||||
|
||||
var MediaListSort = struct {
|
||||
MediaId string
|
||||
MediaIdDesc string
|
||||
|
@ -1,58 +0,0 @@
|
||||
meta {
|
||||
name: AniList Item
|
||||
type: graphql
|
||||
seq: 2
|
||||
}
|
||||
|
||||
post {
|
||||
url: https://graphql.anilist.co
|
||||
body: graphql
|
||||
auth: none
|
||||
}
|
||||
|
||||
headers {
|
||||
Content-Type: "application/json"
|
||||
Accept: "application/json"
|
||||
}
|
||||
|
||||
body:graphql {
|
||||
query ($id: Int, $listType: MediaType) {
|
||||
Media(id: $id, type: $listType) {
|
||||
id
|
||||
idMal
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
}
|
||||
description
|
||||
coverImage {
|
||||
large
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
body:graphql:vars {
|
||||
{
|
||||
"id": 157371,
|
||||
"listType": "ANIME"
|
||||
}
|
||||
}
|
||||
|
||||
docs {
|
||||
Title
|
||||
|
||||
Image
|
||||
|
||||
Description
|
||||
|
||||
Episodes
|
||||
|
||||
Status
|
||||
|
||||
Season
|
||||
|
||||
External & Streaming Links
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
meta {
|
||||
name: AniList MediaList User
|
||||
type: http
|
||||
seq: 5
|
||||
}
|
||||
|
||||
post {
|
||||
url: https://graphql.anilist.co
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
docs {
|
||||
Title
|
||||
Image
|
||||
Description
|
||||
Episodes
|
||||
Status
|
||||
Season
|
||||
External & Streaming Links
|
||||
|
||||
User Stuff Per Item
|
||||
Status
|
||||
Score
|
||||
Episode Progress
|
||||
Total Rewatches
|
||||
Notes
|
||||
}
|
105
bruno/AniTrack/Get Items/AniList Item.bru
Normal file
105
bruno/AniTrack/Get Items/AniList Item.bru
Normal file
@ -0,0 +1,105 @@
|
||||
meta {
|
||||
name: AniList Item
|
||||
type: graphql
|
||||
seq: 1
|
||||
}
|
||||
|
||||
post {
|
||||
url: https://graphql.anilist.co
|
||||
body: graphql
|
||||
auth: none
|
||||
}
|
||||
|
||||
headers {
|
||||
Content-Type: "application/json"
|
||||
Accept: "application/json"
|
||||
}
|
||||
|
||||
body:graphql {
|
||||
query($userId: Int, $mediaId: Int, $listType: MediaType) {
|
||||
MediaList(mediaId: $mediaId, userId: $userId, type: $listType) {
|
||||
id
|
||||
mediaId
|
||||
userId
|
||||
media {
|
||||
id
|
||||
idMal
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
}
|
||||
description
|
||||
coverImage {
|
||||
large
|
||||
}
|
||||
season
|
||||
seasonYear
|
||||
status
|
||||
episodes
|
||||
nextAiringEpisode {
|
||||
airingAt
|
||||
timeUntilAiring
|
||||
episode
|
||||
}
|
||||
}
|
||||
status
|
||||
startedAt{
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
completedAt{
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
notes
|
||||
progress
|
||||
score
|
||||
repeat
|
||||
user {
|
||||
id
|
||||
name
|
||||
avatar {
|
||||
large
|
||||
medium
|
||||
}
|
||||
statistics {
|
||||
anime {
|
||||
count
|
||||
statuses {
|
||||
status
|
||||
count
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
body:graphql:vars {
|
||||
{
|
||||
"userId": 413504,
|
||||
"mediaId": 157371,
|
||||
"listType": "ANIME"
|
||||
}
|
||||
}
|
||||
|
||||
docs {
|
||||
Title
|
||||
|
||||
Image
|
||||
|
||||
Description
|
||||
|
||||
Episodes
|
||||
|
||||
Status
|
||||
|
||||
Season
|
||||
|
||||
External & Streaming Links
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
meta {
|
||||
name: AniList MediaList User Query
|
||||
type: graphql
|
||||
seq: 6
|
||||
seq: 4
|
||||
}
|
||||
|
||||
post {
|
75
bruno/AniTrack/Get Items/AniList Search.bru
Normal file
75
bruno/AniTrack/Get Items/AniList Search.bru
Normal file
@ -0,0 +1,75 @@
|
||||
meta {
|
||||
name: AniList Search
|
||||
type: graphql
|
||||
seq: 2
|
||||
}
|
||||
|
||||
post {
|
||||
url: https://graphql.anilist.co
|
||||
body: graphql
|
||||
auth: none
|
||||
}
|
||||
|
||||
headers {
|
||||
Content-Type: "application/json"
|
||||
Accept: "application/json"
|
||||
}
|
||||
|
||||
body:graphql {
|
||||
query ($search: String!, $listType: MediaType) {
|
||||
Page (page: 1, perPage: 100) {
|
||||
pageInfo {
|
||||
total
|
||||
currentPage
|
||||
lastPage
|
||||
hasNextPage
|
||||
perPage
|
||||
}
|
||||
media (search: $search, type: $listType) {
|
||||
id
|
||||
idMal
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
}
|
||||
description
|
||||
coverImage {
|
||||
large
|
||||
}
|
||||
season
|
||||
seasonYear
|
||||
status
|
||||
episodes
|
||||
nextAiringEpisode{
|
||||
airingAt
|
||||
timeUntilAiring
|
||||
episode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body:graphql:vars {
|
||||
{
|
||||
"search": "frieren",
|
||||
"listType": "ANIME"
|
||||
}
|
||||
}
|
||||
|
||||
docs {
|
||||
Title
|
||||
|
||||
Image
|
||||
|
||||
Description
|
||||
|
||||
Episodes
|
||||
|
||||
Status
|
||||
|
||||
Season
|
||||
|
||||
External & Streaming Links
|
||||
}
|
125
bruno/AniTrack/Get Items/GetAniListUserWatchingList.bru
Normal file
125
bruno/AniTrack/Get Items/GetAniListUserWatchingList.bru
Normal file
@ -0,0 +1,125 @@
|
||||
meta {
|
||||
name: GetAniListUserWatchingList
|
||||
type: graphql
|
||||
seq: 3
|
||||
}
|
||||
|
||||
post {
|
||||
url: https://graphql.anilist.co
|
||||
body: graphql
|
||||
auth: none
|
||||
}
|
||||
|
||||
headers {
|
||||
Content-Type: "application/json"
|
||||
Accept: "application/json"
|
||||
}
|
||||
|
||||
body:graphql {
|
||||
# Write your query or mutation here
|
||||
query (
|
||||
$page: Int
|
||||
$perPage: Int
|
||||
$userId: Int
|
||||
$listType: MediaType
|
||||
$status: MediaListStatus
|
||||
$sort: [MediaListSort]
|
||||
) {
|
||||
Page(page: $page, perPage: $perPage) {
|
||||
pageInfo {
|
||||
total
|
||||
perPage
|
||||
currentPage
|
||||
lastPage
|
||||
hasNextPage
|
||||
}
|
||||
mediaList(userId: $userId, type: $listType, status: $status, sort: $sort) {
|
||||
id
|
||||
mediaId
|
||||
userId
|
||||
media {
|
||||
id
|
||||
idMal
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
}
|
||||
description
|
||||
coverImage {
|
||||
large
|
||||
}
|
||||
season
|
||||
seasonYear
|
||||
status
|
||||
episodes
|
||||
nextAiringEpisode {
|
||||
airingAt
|
||||
timeUntilAiring
|
||||
episode
|
||||
}
|
||||
}
|
||||
status
|
||||
startedAt {
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
completedAt {
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
notes
|
||||
progress
|
||||
score
|
||||
repeat
|
||||
user {
|
||||
id
|
||||
name
|
||||
avatar {
|
||||
large
|
||||
medium
|
||||
}
|
||||
statistics {
|
||||
anime {
|
||||
count
|
||||
statuses {
|
||||
status
|
||||
count
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
body:graphql:vars {
|
||||
{
|
||||
"page": 1,
|
||||
"perPage": 20,
|
||||
"userId": 413504,
|
||||
"listType": "ANIME",
|
||||
"status": "CURRENT",
|
||||
"sort": "UPDATED_TIME_DESC"
|
||||
}
|
||||
}
|
||||
|
||||
docs {
|
||||
Title
|
||||
|
||||
Image
|
||||
|
||||
Description
|
||||
|
||||
Episodes
|
||||
|
||||
Status
|
||||
|
||||
Season
|
||||
|
||||
External & Streaming Links
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
meta {
|
||||
name: GetAuthorizationToken
|
||||
type: http
|
||||
seq: 4
|
||||
seq: 2
|
||||
}
|
||||
|
||||
post {
|
||||
|
@ -1,7 +1,7 @@
|
||||
meta {
|
||||
name: Load AniList Oauth Page
|
||||
type: http
|
||||
seq: 3
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
|
48
bruno/AniTrack/Set Items/AniList Change Episode Watched.bru
Normal file
48
bruno/AniTrack/Set Items/AniList Change Episode Watched.bru
Normal file
@ -0,0 +1,48 @@
|
||||
meta {
|
||||
name: AniList Change Episode Watched
|
||||
type: graphql
|
||||
seq: 1
|
||||
}
|
||||
|
||||
post {
|
||||
url: https://graphql.anilist.co
|
||||
body: graphql
|
||||
auth: none
|
||||
}
|
||||
|
||||
headers {
|
||||
Authorization: Bearer {{process.env.ANILIST_ACCESS_TOKEN}}
|
||||
Content-Type: "application/json"
|
||||
Accept: "application/json"
|
||||
}
|
||||
|
||||
body:graphql {
|
||||
mutation($mediaId:Int, $progress:Int, $status:MediaListStatus){
|
||||
SaveMediaListEntry(mediaId:$mediaId, progress:$progress, status:$status){
|
||||
mediaId
|
||||
progress
|
||||
status
|
||||
score
|
||||
repeat
|
||||
notes
|
||||
startedAt{
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
completedAt{
|
||||
year
|
||||
month
|
||||
day
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body:graphql:vars {
|
||||
{
|
||||
"mediaId": 1,
|
||||
"progress": 26,
|
||||
"status":"COMPLETED"
|
||||
}
|
||||
}
|
33
bruno/AniTrack/Set Items/AniList Change Status.bru
Normal file
33
bruno/AniTrack/Set Items/AniList Change Status.bru
Normal file
@ -0,0 +1,33 @@
|
||||
meta {
|
||||
name: AniList Change Status
|
||||
type: graphql
|
||||
seq: 2
|
||||
}
|
||||
|
||||
post {
|
||||
url: https://graphql.anilist.co
|
||||
body: graphql
|
||||
auth: none
|
||||
}
|
||||
|
||||
headers {
|
||||
Authorization: Bearer {{process.env.ANILIST_ACCESS_TOKEN}}
|
||||
Content-Type: "application/json"
|
||||
Accept: "application/json"
|
||||
}
|
||||
|
||||
body:graphql {
|
||||
mutation($mediaId:Int, $status:MediaListStatus){
|
||||
SaveMediaListEntry(mediaId:$mediaId, status:$status){
|
||||
id
|
||||
status
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body:graphql:vars {
|
||||
{
|
||||
"mediaId": 1,
|
||||
"status": "CURRENT"
|
||||
}
|
||||
}
|
@ -17,12 +17,15 @@
|
||||
"svelte": "^3.49.0",
|
||||
"svelte-check": "^2.8.0",
|
||||
"svelte-preprocess": "^4.10.7",
|
||||
"tailwind-merge": "^2.4.0",
|
||||
"tailwindcss": "^3.4.6",
|
||||
"tslib": "^2.4.0",
|
||||
"typescript": "^4.6.4",
|
||||
"vite": "^3.0.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/aspect-ratio": "^0.4.2"
|
||||
"flowbite": "^2.4.1",
|
||||
"flowbite-svelte": "^0.46.15",
|
||||
"@popperjs/core": "^2.11.8"
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,32 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
AniListSearch,
|
||||
GetAniListItem,
|
||||
GetAniListLoggedInUserId,
|
||||
GetAniListUserWatchingList
|
||||
} from "../wailsjs/go/main/App";
|
||||
import {type AniListItem, type AniSearchList, MediaListSort} from "./anilist/types/AniListTypes";
|
||||
import {type AniSearchList, MediaListSort} from "./anilist/types/AniListTypes";
|
||||
import type {AniListCurrentUserWatchList} from "./anilist/types/AniListCurrentUserWatchListType"
|
||||
import Header from "./Header.svelte";
|
||||
import {Button, Modal} from "flowbite-svelte";
|
||||
import type {AniListGetSingleAnime} from "./anilist/types/AniListCurrentUserWatchListType.js";
|
||||
import {GetAniListItem} from "../wailsjs/go/main/App";
|
||||
import ChangeDataDialogue from "./ChangeDataDialogue.svelte";
|
||||
|
||||
let aniId = "157371"
|
||||
let aniSearch = ""
|
||||
let aniListItem: AniListItem
|
||||
let aniListSearch: AniSearchList
|
||||
let aniListSearchActive = false
|
||||
let aniListLoggedIn = false
|
||||
let aniListWatchlist: AniListCurrentUserWatchList
|
||||
let page = 1
|
||||
let perPage = 20
|
||||
|
||||
function getAniListitem(): void {
|
||||
GetAniListItem(Number(aniId)).then(result => aniListItem = result)
|
||||
}
|
||||
let anilistModal = false;
|
||||
let anime: AniListGetSingleAnime
|
||||
let title: string
|
||||
|
||||
function runAniListSearch(): void {
|
||||
AniListSearch(aniSearch).then(result => aniListSearch = result)
|
||||
AniListSearch(aniSearch).then(result => {
|
||||
aniListSearch = result
|
||||
aniListSearchActive = true
|
||||
})
|
||||
}
|
||||
|
||||
function anilistGetUserWatchlist(): void {
|
||||
@ -31,14 +35,50 @@
|
||||
aniListLoggedIn = true
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
function GetAniListSingleItemAndOpenModal(aniId: number): void {
|
||||
GetAniListItem(aniId).then(result => {
|
||||
anime = result
|
||||
title = anime.data.MediaList.media.title.english === "" ?
|
||||
anime.data.MediaList.media.title.romaji :
|
||||
anime.data.MediaList.media.title.english
|
||||
anilistModal = true
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<Header />
|
||||
|
||||
<main>
|
||||
<div class="input-box" id="aniSearch">
|
||||
<input autocomplete="off" bind:value={aniSearch} class="input" id="aniSearchInput" type="text"/>
|
||||
<button class="btn" on:click={runAniListSearch}>Search AniList</button>
|
||||
<input autocomplete="off" bind:value={aniSearch} class="input text-black" id="aniSearchInput" type="text"/>
|
||||
<button class="text-gray-800 dark:text-white hover:bg-gray-50 focus:ring-4 focus:ring-gray-300 font-medium rounded-lg text-sm px-4 lg:px-5 py-2 lg:py-2.5 mr-2 dark:hover:bg-gray-700 focus:outline-none dark:focus:ring-gray-800" on:click={runAniListSearch}>Search AniList</button>
|
||||
</div>
|
||||
|
||||
{#if aniListSearchActive}
|
||||
<div class="mx-auto max-w-2xl px-4 py-16 sm:px-6 sm:py-24 lg:max-w-7xl lg:px-8">
|
||||
<h1>Your Search Results</h1>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-6 gap-y-10 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 xl:gap-x-8">
|
||||
{#each aniListSearch.data.Page.media as media}
|
||||
<button on:click={() => GetAniListSingleItemAndOpenModal(media.id)} class="group">
|
||||
<!-- <div class="aspect-h-1 aspect-w-1 w-full overflow-hidden rounded-lg bg-gray-200 xl:aspect-h-8 xl:aspect-w-7">-->
|
||||
<div class="justify-center rounded-lg bg-gray-200">
|
||||
<img src={media.coverImage.large} alt="anime cover"/>
|
||||
</div>
|
||||
<h3 class="mt-4 text-sm text-white-700">{
|
||||
media.title.english === "" ?
|
||||
media.title.romaji :
|
||||
media.title.english
|
||||
}</h3>
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<button class="btn" on:click={anilistGetUserWatchlist}>Login to AniList</button>
|
||||
{#if aniListLoggedIn}
|
||||
<div>You are logged in {aniListWatchlist.data.Page.mediaList[0].user.name}!</div>
|
||||
@ -50,7 +90,7 @@
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-6 gap-y-10 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 xl:gap-x-8">
|
||||
{#each aniListWatchlist.data.Page.mediaList as media}
|
||||
<a href="#" class="group">
|
||||
<button on:click={() => GetAniListSingleItemAndOpenModal(media.media.id)} class="group">
|
||||
<!-- <div class="aspect-h-1 aspect-w-1 w-full overflow-hidden rounded-lg bg-gray-200 xl:aspect-h-8 xl:aspect-w-7">-->
|
||||
<div class="justify-center rounded-lg bg-gray-200">
|
||||
<img src={media.media.coverImage.large} alt="anime cover"/>
|
||||
@ -67,68 +107,13 @@
|
||||
<p class="mt-1 text-lg font-medium text-white-900">Total
|
||||
Episodes: {media.media.episodes}</p>
|
||||
{/if}
|
||||
</a>
|
||||
</button>
|
||||
<!-- <Button on:click={() => (anilistModal = true)}>Default modal</Button>-->
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<Modal title={title} bind:open={anilistModal} autoclose>
|
||||
<ChangeDataDialogue anime={anime} />
|
||||
</Modal>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
|
||||
#logo {
|
||||
display: block;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
margin: auto;
|
||||
padding: 10% 0 0;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-origin: content-box;
|
||||
}
|
||||
|
||||
.result {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
margin: 1.5rem auto;
|
||||
}
|
||||
|
||||
.input-box .btn {
|
||||
/*width: 60px;*/
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
border-radius: 3px;
|
||||
border: none;
|
||||
margin: 0 0 0 20px;
|
||||
padding: 0 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.input-box .btn:hover {
|
||||
background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%);
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.input-box .input {
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
outline: none;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding: 0 10px;
|
||||
background-color: rgba(240, 240, 240, 1);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.input-box .input:hover {
|
||||
border: none;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
.input-box .input:focus {
|
||||
border: none;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
32
frontend/src/ChangeDataDialogue.svelte
Normal file
32
frontend/src/ChangeDataDialogue.svelte
Normal file
@ -0,0 +1,32 @@
|
||||
<script lang="ts">
|
||||
import type {AniListGetSingleAnime} from "./anilist/types/AniListCurrentUserWatchListType";
|
||||
import {Button} from "flowbite-svelte";
|
||||
|
||||
export let anime: AniListGetSingleAnime
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
|
||||
|
||||
<form class="max-w-sm mx-auto">
|
||||
<label for="countries" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Select your
|
||||
country</label>
|
||||
<select id="countries"
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
|
||||
<option>United States</option>
|
||||
<option>Canada</option>
|
||||
<option>France</option>
|
||||
<option>Germany</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="bg-white rounded-lg shadow m-4 dark:bg-gray-800">
|
||||
<div class="w-full mx-auto max-w-screen-xl p-4 md:flex md:items-center md:justify-end">
|
||||
<Button class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800" on:click={() => alert('Handle "success"')}>Sync Changes</Button>
|
||||
<Button class="text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-100 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700">Cancel</Button>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
74
frontend/src/Header.svelte
Normal file
74
frontend/src/Header.svelte
Normal file
@ -0,0 +1,74 @@
|
||||
<script lang="ts">
|
||||
import logo from "./assets/images/AniTrackLogo.svg"
|
||||
import type {AniSearchList} from "./anilist/types/AniListTypes.js";
|
||||
import {AniListSearch} from "../wailsjs/go/main/App.js";
|
||||
|
||||
let aniSearch = ""
|
||||
let aniListSearch: AniSearchList
|
||||
let aniListSearchActive = false
|
||||
|
||||
function runAniListSearch(): void {
|
||||
AniListSearch(aniSearch).then(result => {
|
||||
aniListSearch = result
|
||||
aniListSearchActive = true
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<header class="mb-2">
|
||||
<nav class="bg-white border-gray-200 px-4 lg:px-6 py-2.5 dark:bg-gray-800">
|
||||
<div class="flex flex-wrap justify-between items-center mx-auto max-w-screen-xl">
|
||||
<a href="#" class="flex items-center">
|
||||
<img src={logo} class="mr-3 h-6 sm:h-9" alt="AniTrack Logo" />
|
||||
<!-- <span class="self-center text-xl font-semibold whitespace-nowrap dark:text-white">AniTrack</span>-->
|
||||
</a>
|
||||
<div class="flex items-center lg:order-2">
|
||||
|
||||
<form class="max-w-md mx-auto">
|
||||
<div class="flex">
|
||||
<label for="anime-search" class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Find Anime</label>
|
||||
<div class="relative w-full">
|
||||
<input type="search" id="anime-search" class="rounded-s-lg block p-2.5 w-full z-20 text-sm text-gray-900 bg-gray-50 rounded-e-lg border-s-gray-50 border-s-2 border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-s-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:border-blue-500" placeholder="Search for Anime" required />
|
||||
<button type="submit" class="absolute top-0 end-0 h-full p-2.5 text-sm font-medium text-white bg-blue-700 rounded-e-lg border border-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
|
||||
<svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"/>
|
||||
</svg>
|
||||
<span class="sr-only">Search</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<a href="#" class="text-gray-800 dark:text-white hover:bg-gray-50 focus:ring-4 focus:ring-gray-300 font-medium rounded-lg text-sm px-4 lg:px-5 py-2 lg:py-2.5 mr-2 dark:hover:bg-gray-700 focus:outline-none dark:focus:ring-gray-800">Log in AniList</a>
|
||||
<!-- <a href="#" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-4 lg:px-5 py-2 lg:py-2.5 mr-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">Get started</a>-->
|
||||
<button data-collapse-toggle="mobile-menu-2" type="button" class="inline-flex items-center p-2 ml-1 text-sm text-gray-500 rounded-lg lg:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600" aria-controls="mobile-menu-2" aria-expanded="false">
|
||||
<span class="sr-only">Open main menu</span>
|
||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clip-rule="evenodd"></path></svg>
|
||||
<svg class="hidden w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="hidden justify-between items-center w-full lg:flex lg:w-auto lg:order-1" id="mobile-menu-2">
|
||||
<ul class="flex flex-col mt-4 font-medium lg:flex-row lg:space-x-8 lg:mt-0">
|
||||
<li>
|
||||
<a href="#" class="block py-2 pr-4 pl-3 text-white rounded bg-blue-700 lg:bg-transparent lg:text-blue-700 lg:p-0 dark:text-white" aria-current="page">Home</a>
|
||||
</li>
|
||||
<!-- <li>-->
|
||||
<!-- <a href="#" class="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 lg:hover:bg-transparent lg:border-0 lg:hover:text-blue-700 lg:p-0 dark:text-gray-400 lg:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white lg:dark:hover:bg-transparent dark:border-gray-700">Company</a>-->
|
||||
<!-- </li>-->
|
||||
<!-- <li>-->
|
||||
<!-- <a href="#" class="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 lg:hover:bg-transparent lg:border-0 lg:hover:text-blue-700 lg:p-0 dark:text-gray-400 lg:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white lg:dark:hover:bg-transparent dark:border-gray-700">Marketplace</a>-->
|
||||
<!-- </li>-->
|
||||
<!-- <li>-->
|
||||
<!-- <a href="#" class="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 lg:hover:bg-transparent lg:border-0 lg:hover:text-blue-700 lg:p-0 dark:text-gray-400 lg:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white lg:dark:hover:bg-transparent dark:border-gray-700">Features</a>-->
|
||||
<!-- </li>-->
|
||||
<!-- <li>-->
|
||||
<!-- <a href="#" class="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 lg:hover:bg-transparent lg:border-0 lg:hover:text-blue-700 lg:p-0 dark:text-gray-400 lg:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white lg:dark:hover:bg-transparent dark:border-gray-700">Team</a>-->
|
||||
<!-- </li>-->
|
||||
<!-- <li>-->
|
||||
<!-- <a href="#" class="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 lg:hover:bg-transparent lg:border-0 lg:hover:text-blue-700 lg:p-0 dark:text-gray-400 lg:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white lg:dark:hover:bg-transparent dark:border-gray-700">Contact</a>-->
|
||||
<!-- </li>-->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
@ -1,88 +1,70 @@
|
||||
export interface AniListCurrentUserWatchList {
|
||||
data: Data
|
||||
data: {
|
||||
Page: {
|
||||
pageInfo: {
|
||||
total: number
|
||||
perPage: number
|
||||
currentPage: number
|
||||
lastPage: number
|
||||
hasNextPage: boolean
|
||||
},
|
||||
mediaList: MediaList[]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface Data {
|
||||
Page: Page
|
||||
}
|
||||
|
||||
export interface Page {
|
||||
pageInfo: PageInfo
|
||||
mediaList: MediaList[]
|
||||
}
|
||||
|
||||
export interface PageInfo {
|
||||
total: number
|
||||
perPage: number
|
||||
currentPage: number
|
||||
lastPage: number
|
||||
hasNextPage: boolean
|
||||
export interface AniListGetSingleAnime {
|
||||
data: {
|
||||
MediaList: MediaList
|
||||
}
|
||||
}
|
||||
|
||||
export interface MediaList {
|
||||
id: number
|
||||
mediaId: number
|
||||
userId: number
|
||||
media: Media
|
||||
media: {
|
||||
id: number
|
||||
idMal: number
|
||||
title: {
|
||||
romaji: string
|
||||
english?: string
|
||||
native: string
|
||||
}
|
||||
description: string
|
||||
coverImage: {
|
||||
large: string
|
||||
}
|
||||
season: string
|
||||
seasonYear: number
|
||||
status: string
|
||||
episodes?: number
|
||||
nextAiringEpisode?: {
|
||||
airingAt: number
|
||||
timeUntilAiring: number
|
||||
episode: number
|
||||
}
|
||||
}
|
||||
status: string
|
||||
notes?: string
|
||||
progress: number
|
||||
score: number
|
||||
repeat: number
|
||||
user: User
|
||||
}
|
||||
|
||||
export interface Media {
|
||||
id: number
|
||||
idMal: number
|
||||
title: Title
|
||||
description: string
|
||||
coverImage: CoverImage
|
||||
season: string
|
||||
seasonYear: number
|
||||
status: string
|
||||
episodes?: number
|
||||
nextAiringEpisode?: NextAiringEpisode
|
||||
}
|
||||
|
||||
export interface Title {
|
||||
romaji: string
|
||||
english?: string
|
||||
native: string
|
||||
}
|
||||
|
||||
export interface CoverImage {
|
||||
large: string
|
||||
}
|
||||
|
||||
export interface NextAiringEpisode {
|
||||
airingAt: number
|
||||
timeUntilAiring: number
|
||||
episode: number
|
||||
}
|
||||
|
||||
export interface User {
|
||||
id: number
|
||||
name: string
|
||||
avatar: Avatar
|
||||
statistics: Statistics
|
||||
}
|
||||
|
||||
export interface Avatar {
|
||||
large: string
|
||||
medium: string
|
||||
}
|
||||
|
||||
export interface Statistics {
|
||||
anime: Anime
|
||||
}
|
||||
|
||||
export interface Anime {
|
||||
count: number
|
||||
statuses: Status[]
|
||||
}
|
||||
|
||||
export interface Status {
|
||||
status: string
|
||||
count: number
|
||||
}
|
||||
user: {
|
||||
id: number
|
||||
name: string
|
||||
avatar: {
|
||||
large: string
|
||||
medium: string
|
||||
}
|
||||
statistics: {
|
||||
anime: {
|
||||
count: number
|
||||
statuses: [{
|
||||
status: string
|
||||
count: number
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,33 +1,3 @@
|
||||
export interface AniListItem {
|
||||
data: {
|
||||
Media: {
|
||||
id: number,
|
||||
idMal: number,
|
||||
title: {
|
||||
romaji: string,
|
||||
english: string,
|
||||
},
|
||||
description: string,
|
||||
coverImage: {
|
||||
medium: string,
|
||||
large: string,
|
||||
extraLarge: string,
|
||||
color: string,
|
||||
},
|
||||
tags: [{
|
||||
id: number,
|
||||
name: string,
|
||||
description: string,
|
||||
category: string,
|
||||
rank: number,
|
||||
isGeneralSpoiler: boolean,
|
||||
isMediaSpoiler: boolean,
|
||||
isAdult: boolean
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface AniSearchList {
|
||||
data: {
|
||||
Page: {
|
||||
@ -39,17 +9,26 @@ export interface AniSearchList {
|
||||
perPage: number
|
||||
},
|
||||
media: [{
|
||||
id: number,
|
||||
idMal: number,
|
||||
id: number
|
||||
idMal: number
|
||||
title: {
|
||||
romaji: string,
|
||||
english: string,
|
||||
native: string,
|
||||
},
|
||||
romaji: string
|
||||
english?: string
|
||||
native: string
|
||||
}
|
||||
description: string
|
||||
coverImage: {
|
||||
extraLarge: string,
|
||||
color: string,
|
||||
},
|
||||
large: string
|
||||
}
|
||||
season: string
|
||||
seasonYear: number
|
||||
status: string
|
||||
episodes?: number
|
||||
nextAiringEpisode?: {
|
||||
airingAt: number
|
||||
timeUntilAiring: number
|
||||
episode: number
|
||||
}
|
||||
}],
|
||||
},
|
||||
}
|
||||
|
BIN
frontend/src/assets/images/AniTrackLogo.png
Normal file
BIN
frontend/src/assets/images/AniTrackLogo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.6 KiB |
1
frontend/src/assets/images/AniTrackLogo.svg
Normal file
1
frontend/src/assets/images/AniTrackLogo.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
Before Width: | Height: | Size: 136 KiB |
@ -3,12 +3,22 @@ export default {
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src/**/*.{svelte,js,ts,jsx,tsx}",
|
||||
"./node_modules/flowbite/**/*.{html,js,svelte,ts}",
|
||||
"./node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}",
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [
|
||||
require('@tailwindcss/aspect-ratio'),
|
||||
require('flowbite/plugin')
|
||||
],
|
||||
|
||||
darkMode: 'media',
|
||||
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
// flowbite-svelte
|
||||
primary: { 50: '#FFF5F2', 100: '#FFF1EE', 200: '#FFE4DE', 300: '#FFD5CC', 400: '#FFBCAD', 500: '#FE795D', 600: '#EF562F', 700: '#EB4F27', 800: '#CC4522', 900: '#A5371B'},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
4
frontend/wailsjs/go/main/App.d.ts
vendored
4
frontend/wailsjs/go/main/App.d.ts
vendored
@ -6,7 +6,9 @@ export function AniListLogin():Promise<void>;
|
||||
|
||||
export function AniListSearch(arg1:string):Promise<any>;
|
||||
|
||||
export function GetAniListItem(arg1:number):Promise<any>;
|
||||
export function AniListUpdateEntry(arg1:number,arg2:string,arg3:string,arg4:number,arg5:number,arg6:string,arg7:number,arg8:number,arg9:number,arg10:number,arg11:number,arg12:number):Promise<any>;
|
||||
|
||||
export function GetAniListItem(arg1:number):Promise<main.AniListGetSingleAnime>;
|
||||
|
||||
export function GetAniListLoggedInUserId():Promise<main.AniListUser>;
|
||||
|
||||
|
@ -10,6 +10,10 @@ export function AniListSearch(arg1) {
|
||||
return window['go']['main']['App']['AniListSearch'](arg1);
|
||||
}
|
||||
|
||||
export function AniListUpdateEntry(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) {
|
||||
return window['go']['main']['App']['AniListUpdateEntry'](arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
|
||||
}
|
||||
|
||||
export function GetAniListItem(arg1) {
|
||||
return window['go']['main']['App']['GetAniListItem'](arg1);
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
export namespace main {
|
||||
|
||||
export class AniListCurrentUserWatchList {
|
||||
// Go type: struct { Page struct { PageInfo struct { Total int "json:\"total\""; PerPage int "json:\"perPage\""; CurrentPage int "json:\"currentPage\""; LastPage int "json:\"lastPage\""; HasNextPage bool "json:\"hasNextPage\"" } "json:\"pageInfo\""; MediaList []struct { ID int "json:\"id\""; MediaID int "json:\"mediaId\""; UserID int "json:\"userId\""; Media struct { ID int "json:\"id\""; IDMal int "json:\"idMal\""; Title struct { Romaji string "json:\"romaji\""; English string "json:\"english\""; Native string "json:\"native\"" } "json:\"title\""; Description string "json:\"description\""; CoverImage struct { Large string "json:\"large\"" } "json:\"coverImage\""; Season string "json:\"season\""; SeasonYear int "json:\"seasonYear\""; Status string "json:\"status\""; Episodes int "json:\"episodes\""; NextAiringEpisode struct { AiringAt int "json:\"airingAt\""; TimeUntilAiring int "json:\"timeUntilAiring\""; Episode int "json:\"episode\"" } "json:\"nextAiringEpisode\"" } "json:\"media\""; Status string "json:\"status\""; Notes string "json:\"notes\""; Progress int "json:\"progress\""; Score int "json:\"score\""; Repeat int "json:\"repeat\""; User struct { ID int "json:\"id\""; Name string "json:\"name\""; Avatar struct { Large string "json:\"large\""; Medium string "json:\"medium\"" } "json:\"avatar\""; Statistics struct { Anime struct { Count int "json:\"count\""; Statuses []struct { Status string "json:\"status\""; Count int "json:\"count\"" } "json:\"statuses\"" } "json:\"anime\"" } "json:\"statistics\"" } "json:\"user\"" } "json:\"mediaList\"" } "json:\"Page\"" }
|
||||
data: any;
|
||||
data: struct { Page struct { PageInfo struct { Total int "json:\"total\""; PerPage int "json:\"perPage\""; CurrentPage int "json:\"currentPage\""; LastPage int "json:\"lastPage\""; HasNextPage bool "json:\"hasNextPage\"" } "json:\"pageInfo\""; MediaList []main.;
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new AniListCurrentUserWatchList(source);
|
||||
@ -31,6 +30,36 @@ export namespace main {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
export class AniListGetSingleAnime {
|
||||
data: struct { MediaList main.;
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new AniListGetSingleAnime(source);
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) source = JSON.parse(source);
|
||||
this.data = this.convertValues(source["data"], Object);
|
||||
}
|
||||
|
||||
convertValues(a: any, classs: any, asMap: boolean = false): any {
|
||||
if (!a) {
|
||||
return a;
|
||||
}
|
||||
if (a.slice && a.map) {
|
||||
return (a as any[]).map(elem => this.convertValues(elem, classs));
|
||||
} else if ("object" === typeof a) {
|
||||
if (asMap) {
|
||||
for (const key of Object.keys(a)) {
|
||||
a[key] = new classs(a[key]);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
return new classs(a);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
}
|
||||
export class AniListUser {
|
||||
// Go type: struct { Viewer struct { ID int "json:\"id\""; Name string "json:\"name\"" } "json:\"Viewer\"" }
|
||||
data: any;
|
||||
@ -62,6 +91,91 @@ export namespace main {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
export class MediaList {
|
||||
id: number;
|
||||
mediaId: number;
|
||||
userId: number;
|
||||
// Go type: struct { ID int "json:\"id\""; IDMal int "json:\"idMal\""; Title struct { Romaji string "json:\"romaji\""; English string "json:\"english\""; Native string "json:\"native\"" } "json:\"title\""; Description string "json:\"description\""; CoverImage struct { Large string "json:\"large\"" } "json:\"coverImage\""; Season string "json:\"season\""; SeasonYear int "json:\"seasonYear\""; Status string "json:\"status\""; Episodes int "json:\"episodes\""; NextAiringEpisode struct { AiringAt int "json:\"airingAt\""; TimeUntilAiring int "json:\"timeUntilAiring\""; Episode int "json:\"episode\"" } "json:\"nextAiringEpisode\"" }
|
||||
media: any;
|
||||
status: string;
|
||||
notes: string;
|
||||
progress: number;
|
||||
score: number;
|
||||
repeat: number;
|
||||
// Go type: struct { ID int "json:\"id\""; Name string "json:\"name\""; Avatar struct { Large string "json:\"large\""; Medium string "json:\"medium\"" } "json:\"avatar\""; Statistics struct { Anime struct { Count int "json:\"count\""; Statuses []struct { Status string "json:\"status\""; Count int "json:\"count\"" } "json:\"statuses\"" } "json:\"anime\"" } "json:\"statistics\"" }
|
||||
user: any;
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new MediaList(source);
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) source = JSON.parse(source);
|
||||
this.id = source["id"];
|
||||
this.mediaId = source["mediaId"];
|
||||
this.userId = source["userId"];
|
||||
this.media = this.convertValues(source["media"], Object);
|
||||
this.status = source["status"];
|
||||
this.notes = source["notes"];
|
||||
this.progress = source["progress"];
|
||||
this.score = source["score"];
|
||||
this.repeat = source["repeat"];
|
||||
this.user = this.convertValues(source["user"], Object);
|
||||
}
|
||||
|
||||
convertValues(a: any, classs: any, asMap: boolean = false): any {
|
||||
if (!a) {
|
||||
return a;
|
||||
}
|
||||
if (a.slice && a.map) {
|
||||
return (a as any[]).map(elem => this.convertValues(elem, classs));
|
||||
} else if ("object" === typeof a) {
|
||||
if (asMap) {
|
||||
for (const key of Object.keys(a)) {
|
||||
a[key] = new classs(a[key]);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
return new classs(a);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export namespace struct { MediaList main {
|
||||
|
||||
export class {
|
||||
MediaList: main.MediaList;
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new (source);
|
||||
}
|
||||
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) source = JSON.parse(source);
|
||||
this.MediaList = this.convertValues(source["MediaList"], main.MediaList);
|
||||
}
|
||||
|
||||
convertValues(a: any, classs: any, asMap: boolean = false): any {
|
||||
if (!a) {
|
||||
return a;
|
||||
}
|
||||
if (a.slice && a.map) {
|
||||
return (a as any[]).map(elem => this.convertValues(elem, classs));
|
||||
} else if ("object" === typeof a) {
|
||||
if (asMap) {
|
||||
for (const key of Object.keys(a)) {
|
||||
a[key] = new classs(a[key]);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
return new classs(a);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user