Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a16c804692 | ||
|
|
d08756c36f | ||
|
|
b42456f255 | ||
|
|
49ac5bef03 | ||
|
|
b9f4c12839 | ||
|
|
54c109ae3b | ||
|
|
d3bc93f6c9 | ||
|
|
0384f570c5 | ||
|
|
6925cd4e08 |
+3
-2
@@ -35,5 +35,6 @@ environment.go
|
|||||||
http-client.private.env.json
|
http-client.private.env.json
|
||||||
|
|
||||||
# Build artifacts
|
# Build artifacts
|
||||||
build/*.tar.gz
|
*.tar
|
||||||
AniTrack
|
*.tar.gz
|
||||||
|
/AniTrack
|
||||||
|
|||||||
+707
-202
@@ -74,37 +74,83 @@ func (a *App) GetAniListItem(aniId int, login bool) AniListGetSingleAnime {
|
|||||||
mediaId
|
mediaId
|
||||||
userId
|
userId
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
idMal
|
idMal
|
||||||
title {
|
title {
|
||||||
romaji
|
userPreferred
|
||||||
english
|
romaji
|
||||||
native
|
english
|
||||||
}
|
native
|
||||||
description
|
}
|
||||||
coverImage {
|
description
|
||||||
large
|
coverImage {
|
||||||
}
|
extraLarge
|
||||||
season
|
large
|
||||||
seasonYear
|
medium
|
||||||
status
|
color
|
||||||
episodes
|
}
|
||||||
nextAiringEpisode {
|
startDate {
|
||||||
airingAt
|
year
|
||||||
timeUntilAiring
|
month
|
||||||
episode
|
day
|
||||||
}
|
}
|
||||||
genres
|
endDate {
|
||||||
tags{
|
year
|
||||||
id
|
month
|
||||||
name
|
day
|
||||||
description
|
}
|
||||||
rank
|
bannerImage
|
||||||
isMediaSpoiler
|
format
|
||||||
isAdult
|
season
|
||||||
}
|
seasonYear
|
||||||
isAdult
|
status
|
||||||
}
|
episodes
|
||||||
|
duration
|
||||||
|
countryOfOrigin
|
||||||
|
source
|
||||||
|
synonyms
|
||||||
|
averageScore
|
||||||
|
meanScore
|
||||||
|
popularity
|
||||||
|
trending
|
||||||
|
favourites
|
||||||
|
isFavourite
|
||||||
|
relations {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
title {
|
||||||
|
userPreferred
|
||||||
|
romaji
|
||||||
|
english
|
||||||
|
native
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nextAiringEpisode {
|
||||||
|
airingAt
|
||||||
|
timeUntilAiring
|
||||||
|
episode
|
||||||
|
}
|
||||||
|
airingSchedule {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
airingAt
|
||||||
|
timeUntilAiring
|
||||||
|
episode
|
||||||
|
mediaId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genres
|
||||||
|
tags {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
rank
|
||||||
|
isMediaSpoiler
|
||||||
|
isAdult
|
||||||
|
}
|
||||||
|
isAdult
|
||||||
|
}
|
||||||
status
|
status
|
||||||
startedAt{
|
startedAt{
|
||||||
year
|
year
|
||||||
@@ -204,37 +250,84 @@ func (a *App) AniListSearch(query string) (interface{}, error) {
|
|||||||
perPage
|
perPage
|
||||||
}
|
}
|
||||||
media (search: $search, type: $listType) {
|
media (search: $search, type: $listType) {
|
||||||
id
|
id
|
||||||
idMal
|
idMal
|
||||||
title {
|
title {
|
||||||
|
userPreferred
|
||||||
|
romaji
|
||||||
|
english
|
||||||
|
native
|
||||||
|
}
|
||||||
|
description
|
||||||
|
coverImage {
|
||||||
|
extraLarge
|
||||||
|
large
|
||||||
|
medium
|
||||||
|
color
|
||||||
|
}
|
||||||
|
bannerImage
|
||||||
|
format
|
||||||
|
season
|
||||||
|
seasonYear
|
||||||
|
status
|
||||||
|
episodes
|
||||||
|
duration
|
||||||
|
countryOfOrigin
|
||||||
|
source
|
||||||
|
synonyms
|
||||||
|
averageScore
|
||||||
|
meanScore
|
||||||
|
popularity
|
||||||
|
trending
|
||||||
|
favourites
|
||||||
|
isFavourite
|
||||||
|
relations{
|
||||||
|
nodes{
|
||||||
|
id
|
||||||
|
title{
|
||||||
|
userPreferred
|
||||||
romaji
|
romaji
|
||||||
english
|
english
|
||||||
native
|
native
|
||||||
}
|
}
|
||||||
description
|
}
|
||||||
coverImage {
|
|
||||||
large
|
|
||||||
}
|
|
||||||
season
|
|
||||||
seasonYear
|
|
||||||
status
|
|
||||||
episodes
|
|
||||||
nextAiringEpisode{
|
|
||||||
airingAt
|
|
||||||
timeUntilAiring
|
|
||||||
episode
|
|
||||||
}
|
|
||||||
genres
|
|
||||||
tags{
|
|
||||||
id
|
|
||||||
name
|
|
||||||
description
|
|
||||||
rank
|
|
||||||
isMediaSpoiler
|
|
||||||
isAdult
|
|
||||||
}
|
|
||||||
isAdult
|
|
||||||
}
|
}
|
||||||
|
startDate{
|
||||||
|
year
|
||||||
|
month
|
||||||
|
day
|
||||||
|
}
|
||||||
|
endDate{
|
||||||
|
year
|
||||||
|
month
|
||||||
|
day
|
||||||
|
}
|
||||||
|
nextAiringEpisode{
|
||||||
|
airingAt
|
||||||
|
timeUntilAiring
|
||||||
|
episode
|
||||||
|
}
|
||||||
|
airingSchedule{
|
||||||
|
nodes{
|
||||||
|
id
|
||||||
|
airingAt
|
||||||
|
timeUntilAiring
|
||||||
|
episode
|
||||||
|
mediaId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genres
|
||||||
|
tags{
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
rank
|
||||||
|
isMediaSpoiler
|
||||||
|
isAdult
|
||||||
|
}
|
||||||
|
isAdult
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
@@ -271,93 +364,140 @@ func (a *App) GetAniListUserWatchingList(page int, perPage int, sort string) (An
|
|||||||
Variables Variables `json:"variables"`
|
Variables Variables `json:"variables"`
|
||||||
}{
|
}{
|
||||||
Query: `
|
Query: `
|
||||||
query(
|
query (
|
||||||
$page: Int
|
$page: Int
|
||||||
$perPage: Int
|
$perPage: Int
|
||||||
$userId: Int
|
$userId: Int
|
||||||
$listType: MediaType
|
$listType: MediaType
|
||||||
$status: MediaListStatus
|
$status: MediaListStatus
|
||||||
$sort:[MediaListSort]
|
$sort: [MediaListSort]
|
||||||
) {
|
) {
|
||||||
Page(page: $page, perPage: $perPage) {
|
Page(page: $page, perPage: $perPage) {
|
||||||
pageInfo {
|
pageInfo {
|
||||||
total
|
total
|
||||||
perPage
|
perPage
|
||||||
currentPage
|
currentPage
|
||||||
lastPage
|
lastPage
|
||||||
hasNextPage
|
hasNextPage
|
||||||
}
|
}
|
||||||
mediaList(userId: $userId, type: $listType, status: $status, sort: $sort) {
|
mediaList(userId: $userId, type: $listType, status: $status, sort: $sort) {
|
||||||
id
|
id
|
||||||
mediaId
|
mediaId
|
||||||
userId
|
userId
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
idMal
|
idMal
|
||||||
title {
|
title {
|
||||||
|
userPreferred
|
||||||
romaji
|
romaji
|
||||||
english
|
english
|
||||||
native
|
native
|
||||||
}
|
}
|
||||||
description
|
description
|
||||||
coverImage {
|
coverImage {
|
||||||
|
extraLarge
|
||||||
large
|
large
|
||||||
|
medium
|
||||||
|
color
|
||||||
}
|
}
|
||||||
|
bannerImage
|
||||||
|
format
|
||||||
season
|
season
|
||||||
seasonYear
|
seasonYear
|
||||||
status
|
status
|
||||||
episodes
|
episodes
|
||||||
|
duration
|
||||||
|
countryOfOrigin
|
||||||
|
source
|
||||||
|
synonyms
|
||||||
|
averageScore
|
||||||
|
meanScore
|
||||||
|
popularity
|
||||||
|
trending
|
||||||
|
favourites
|
||||||
|
isFavourite
|
||||||
|
relations{
|
||||||
|
nodes{
|
||||||
|
id
|
||||||
|
title{
|
||||||
|
userPreferred
|
||||||
|
romaji
|
||||||
|
english
|
||||||
|
native
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startDate{
|
||||||
|
year
|
||||||
|
month
|
||||||
|
day
|
||||||
|
}
|
||||||
|
endDate{
|
||||||
|
year
|
||||||
|
month
|
||||||
|
day
|
||||||
|
}
|
||||||
nextAiringEpisode{
|
nextAiringEpisode{
|
||||||
airingAt
|
airingAt
|
||||||
timeUntilAiring
|
timeUntilAiring
|
||||||
episode
|
episode
|
||||||
}
|
}
|
||||||
genres
|
airingSchedule{
|
||||||
tags{
|
nodes{
|
||||||
id
|
id
|
||||||
name
|
airingAt
|
||||||
description
|
timeUntilAiring
|
||||||
rank
|
episode
|
||||||
isMediaSpoiler
|
mediaId
|
||||||
isAdult
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
genres
|
||||||
|
tags{
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
rank
|
||||||
|
isMediaSpoiler
|
||||||
|
isAdult
|
||||||
|
}
|
||||||
|
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{
|
Variables: Variables{
|
||||||
Page: page,
|
Page: page,
|
||||||
@@ -424,86 +564,138 @@ func (a *App) AniListUpdateEntry(updateBody AniListUpdateVariables) AniListGetSi
|
|||||||
Variables AniListUpdateVariables `json:"variables"`
|
Variables AniListUpdateVariables `json:"variables"`
|
||||||
}{
|
}{
|
||||||
Query: `
|
Query: `
|
||||||
mutation(
|
mutation (
|
||||||
$mediaId:Int,
|
$mediaId: Int
|
||||||
$progress:Int,
|
$progress: Int
|
||||||
$status:MediaListStatus,
|
$status: MediaListStatus
|
||||||
$score:Float,
|
$score: Float
|
||||||
$repeat:Int,
|
$repeat: Int
|
||||||
$notes:String,
|
$notes: String
|
||||||
$startedAt:FuzzyDateInput,
|
$startedAt: FuzzyDateInput
|
||||||
$completedAt:FuzzyDateInput,
|
$completedAt: FuzzyDateInput
|
||||||
){
|
) {
|
||||||
SaveMediaListEntry(
|
SaveMediaListEntry(
|
||||||
mediaId:$mediaId,
|
mediaId: $mediaId
|
||||||
progress:$progress,
|
progress: $progress
|
||||||
status:$status,
|
status: $status
|
||||||
score:$score,
|
score: $score
|
||||||
repeat:$repeat,
|
repeat: $repeat
|
||||||
notes:$notes,
|
notes: $notes
|
||||||
startedAt:$startedAt
|
startedAt: $startedAt
|
||||||
completedAt:$completedAt
|
completedAt: $completedAt
|
||||||
){
|
) {
|
||||||
id
|
id
|
||||||
mediaId
|
idMal
|
||||||
userId
|
title {
|
||||||
media {
|
userPreferred
|
||||||
id
|
romaji
|
||||||
idMal
|
english
|
||||||
title {
|
native
|
||||||
romaji
|
}
|
||||||
english
|
description
|
||||||
native
|
coverImage {
|
||||||
}
|
extraLarge
|
||||||
description
|
large
|
||||||
coverImage {
|
medium
|
||||||
large
|
color
|
||||||
}
|
}
|
||||||
season
|
bannerImage
|
||||||
seasonYear
|
format
|
||||||
status
|
season
|
||||||
episodes
|
seasonYear
|
||||||
nextAiringEpisode {
|
status
|
||||||
airingAt
|
episodes
|
||||||
timeUntilAiring
|
duration
|
||||||
episode
|
countryOfOrigin
|
||||||
}
|
source
|
||||||
isAdult
|
synonyms
|
||||||
}
|
averageScore
|
||||||
status
|
meanScore
|
||||||
startedAt{
|
popularity
|
||||||
year
|
trending
|
||||||
month
|
favourites
|
||||||
day
|
isFavourite
|
||||||
}
|
relations {
|
||||||
completedAt{
|
nodes {
|
||||||
year
|
id
|
||||||
month
|
title {
|
||||||
day
|
userPreferred
|
||||||
}
|
romaji
|
||||||
notes
|
english
|
||||||
progress
|
native
|
||||||
score
|
}
|
||||||
repeat
|
}
|
||||||
user {
|
}
|
||||||
id
|
startDate {
|
||||||
name
|
year
|
||||||
avatar{
|
month
|
||||||
large
|
day
|
||||||
medium
|
}
|
||||||
}
|
endDate {
|
||||||
statistics{
|
year
|
||||||
anime{
|
month
|
||||||
count
|
day
|
||||||
statuses{
|
}
|
||||||
status
|
nextAiringEpisode {
|
||||||
count
|
airingAt
|
||||||
}
|
timeUntilAiring
|
||||||
}
|
episode
|
||||||
}
|
}
|
||||||
}
|
airingSchedule {
|
||||||
}
|
nodes {
|
||||||
}
|
id
|
||||||
|
airingAt
|
||||||
|
timeUntilAiring
|
||||||
|
episode
|
||||||
|
mediaId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genres
|
||||||
|
tags {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
rank
|
||||||
|
isMediaSpoiler
|
||||||
|
isAdult
|
||||||
|
}
|
||||||
|
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: updateBody,
|
Variables: updateBody,
|
||||||
}
|
}
|
||||||
@@ -558,3 +750,316 @@ func (a *App) AniListDeleteEntry(mediaListId int) DeleteAniListReturn {
|
|||||||
|
|
||||||
return post
|
return post
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) AniListBrowse(
|
||||||
|
page int,
|
||||||
|
perPage int,
|
||||||
|
id int,
|
||||||
|
isAdult bool,
|
||||||
|
search string,
|
||||||
|
format []string,
|
||||||
|
status string,
|
||||||
|
countryOfOrigin string,
|
||||||
|
source string,
|
||||||
|
season string,
|
||||||
|
seasonYear int,
|
||||||
|
year string,
|
||||||
|
onList bool,
|
||||||
|
yearLesser int,
|
||||||
|
yearGreater int,
|
||||||
|
episodeLesser int,
|
||||||
|
episodeGreater int,
|
||||||
|
durationLesser int,
|
||||||
|
durationGreater int,
|
||||||
|
chapterLesser int,
|
||||||
|
chapterGreater int,
|
||||||
|
volumeLesser int,
|
||||||
|
volumeGreater int,
|
||||||
|
licensedBy []int,
|
||||||
|
isLicensed bool,
|
||||||
|
genres []string,
|
||||||
|
excludedGenres []string,
|
||||||
|
tags []string,
|
||||||
|
excludedTags []string,
|
||||||
|
minimumTagRank int,
|
||||||
|
sort []string) (AniListCurrentUserWatchList, error) {
|
||||||
|
// user := a.GetAniListLoggedInUser()
|
||||||
|
type Variables struct {
|
||||||
|
Page int `json:"page"`
|
||||||
|
PerPage int `json:"perPage"`
|
||||||
|
Id int `json:"id"`
|
||||||
|
IsAdult bool `json:"isAdult"`
|
||||||
|
Search string `json:"search"`
|
||||||
|
Format []string `json:"format"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
CountryOfOrigin string `json:"countryOfOrigin"`
|
||||||
|
Source string `json:"source"`
|
||||||
|
Season string `json:"season"`
|
||||||
|
SeasonYear int `json:"seasonYear"`
|
||||||
|
Year string `json:"year"`
|
||||||
|
OnList bool `json:"onList"`
|
||||||
|
YearLesser int `json:"yearLesser"`
|
||||||
|
YearGreater int `json:"yearGreater"`
|
||||||
|
EpisodeLesser int `json:"episodeLesser"`
|
||||||
|
EpisodeGreater int `json:"episodeGreater"`
|
||||||
|
DurationLesser int `json:"durationLesser"`
|
||||||
|
DurationGreater int `json:"durationGreater"`
|
||||||
|
ChapterLesser int `json:"chapterLesser"`
|
||||||
|
ChapterGreater int `json:"chapterGreater"`
|
||||||
|
VolumeLesser int `json:"volumeLesser"`
|
||||||
|
VolumeGreater int `json:"volumeGreater"`
|
||||||
|
LicensedBy []int `json:"licensedBy"`
|
||||||
|
IsLicensed bool `json:"isLicensed"`
|
||||||
|
Genres []string `json:"genres"`
|
||||||
|
ExcludedGenres []string `json:"excludedGenres"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
ExcludedTags []string `json:"excludedTags"`
|
||||||
|
MinimumTagRank int `json:"minimumTagRank"`
|
||||||
|
Sort []string `json:"sort"`
|
||||||
|
}
|
||||||
|
body := struct {
|
||||||
|
Query string `json:"query"`
|
||||||
|
Variables Variables `json:"variables"`
|
||||||
|
}{
|
||||||
|
Query: `
|
||||||
|
query (
|
||||||
|
$page: Int = 1
|
||||||
|
$perPage: Int = 20
|
||||||
|
$id: Int
|
||||||
|
$isAdult: Boolean = false
|
||||||
|
$search: String
|
||||||
|
$format: [MediaFormat]
|
||||||
|
$status: MediaStatus
|
||||||
|
$countryOfOrigin: CountryCode
|
||||||
|
$source: MediaSource
|
||||||
|
$season: MediaSeason
|
||||||
|
$seasonYear: Int
|
||||||
|
$year: String
|
||||||
|
$onList: Boolean
|
||||||
|
$yearLesser: FuzzyDateInt
|
||||||
|
$yearGreater: FuzzyDateInt
|
||||||
|
$episodeLesser: Int
|
||||||
|
$episodeGreater: Int
|
||||||
|
$durationLesser: Int
|
||||||
|
$durationGreater: Int
|
||||||
|
$chapterLesser: Int
|
||||||
|
$chapterGreater: Int
|
||||||
|
$volumeLesser: Int
|
||||||
|
$volumeGreater: Int
|
||||||
|
$licensedBy: [Int]
|
||||||
|
$isLicensed: Boolean
|
||||||
|
$genres: [String]
|
||||||
|
$excludedGenres: [String]
|
||||||
|
$tags: [String]
|
||||||
|
$excludedTags: [String]
|
||||||
|
$minimumTagRank: Int
|
||||||
|
$sort: [MediaSort] = [POPULARITY_DESC, SCORE_DESC]
|
||||||
|
) {
|
||||||
|
Page(page: $page, perPage: $perPage) {
|
||||||
|
pageInfo {
|
||||||
|
total
|
||||||
|
perPage
|
||||||
|
currentPage
|
||||||
|
lastPage
|
||||||
|
hasNextPage
|
||||||
|
}
|
||||||
|
media(
|
||||||
|
id: $id
|
||||||
|
type: ANIME
|
||||||
|
season: $season
|
||||||
|
format_in: $format
|
||||||
|
status: $status
|
||||||
|
countryOfOrigin: $countryOfOrigin
|
||||||
|
source: $source
|
||||||
|
search: $search
|
||||||
|
onList: $onList
|
||||||
|
seasonYear: $seasonYear
|
||||||
|
startDate_like: $year
|
||||||
|
startDate_lesser: $yearLesser
|
||||||
|
startDate_greater: $yearGreater
|
||||||
|
episodes_lesser: $episodeLesser
|
||||||
|
episodes_greater: $episodeGreater
|
||||||
|
duration_lesser: $durationLesser
|
||||||
|
duration_greater: $durationGreater
|
||||||
|
chapters_lesser: $chapterLesser
|
||||||
|
chapters_greater: $chapterGreater
|
||||||
|
volumes_lesser: $volumeLesser
|
||||||
|
volumes_greater: $volumeGreater
|
||||||
|
licensedById_in: $licensedBy
|
||||||
|
isLicensed: $isLicensed
|
||||||
|
genre_in: $genres
|
||||||
|
genre_not_in: $excludedGenres
|
||||||
|
tag_in: $tags
|
||||||
|
tag_not_in: $excludedTags
|
||||||
|
minimumTagRank: $minimumTagRank
|
||||||
|
sort: $sort
|
||||||
|
isAdult: $isAdult
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
mediaId
|
||||||
|
userId
|
||||||
|
media {
|
||||||
|
id
|
||||||
|
idMal
|
||||||
|
title {
|
||||||
|
userPreferred
|
||||||
|
romaji
|
||||||
|
english
|
||||||
|
native
|
||||||
|
}
|
||||||
|
description
|
||||||
|
coverImage {
|
||||||
|
extraLarge
|
||||||
|
large
|
||||||
|
medium
|
||||||
|
color
|
||||||
|
}
|
||||||
|
bannerImage
|
||||||
|
format
|
||||||
|
season
|
||||||
|
seasonYear
|
||||||
|
status
|
||||||
|
episodes
|
||||||
|
duration
|
||||||
|
countryOfOrigin
|
||||||
|
source
|
||||||
|
synonyms
|
||||||
|
averageScore
|
||||||
|
meanScore
|
||||||
|
popularity
|
||||||
|
trending
|
||||||
|
favourites
|
||||||
|
isFavourite
|
||||||
|
relations {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
title {
|
||||||
|
userPreferred
|
||||||
|
romaji
|
||||||
|
english
|
||||||
|
native
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startDate {
|
||||||
|
year
|
||||||
|
month
|
||||||
|
day
|
||||||
|
}
|
||||||
|
endDate {
|
||||||
|
year
|
||||||
|
month
|
||||||
|
day
|
||||||
|
}
|
||||||
|
nextAiringEpisode {
|
||||||
|
airingAt
|
||||||
|
timeUntilAiring
|
||||||
|
episode
|
||||||
|
}
|
||||||
|
airingSchedule {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
airingAt
|
||||||
|
timeUntilAiring
|
||||||
|
episode
|
||||||
|
mediaId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genres
|
||||||
|
tags {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
rank
|
||||||
|
isMediaSpoiler
|
||||||
|
isAdult
|
||||||
|
}
|
||||||
|
isAdult
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
Variables: Variables{
|
||||||
|
Page: page,
|
||||||
|
PerPage: perPage,
|
||||||
|
Id: id,
|
||||||
|
IsAdult: isAdult,
|
||||||
|
Search: search,
|
||||||
|
Format: format,
|
||||||
|
Status: status,
|
||||||
|
CountryOfOrigin: countryOfOrigin,
|
||||||
|
Source: source,
|
||||||
|
Season: season,
|
||||||
|
SeasonYear: seasonYear,
|
||||||
|
Year: year,
|
||||||
|
OnList: onList,
|
||||||
|
YearLesser: yearLesser,
|
||||||
|
YearGreater: yearGreater,
|
||||||
|
EpisodeLesser: episodeLesser,
|
||||||
|
EpisodeGreater: episodeGreater,
|
||||||
|
DurationLesser: durationLesser,
|
||||||
|
DurationGreater: durationGreater,
|
||||||
|
ChapterLesser: chapterLesser,
|
||||||
|
ChapterGreater: chapterGreater,
|
||||||
|
VolumeLesser: volumeLesser,
|
||||||
|
VolumeGreater: volumeGreater,
|
||||||
|
LicensedBy: licensedBy,
|
||||||
|
IsLicensed: isLicensed,
|
||||||
|
Genres: genres,
|
||||||
|
ExcludedGenres: excludedGenres,
|
||||||
|
Tags: tags,
|
||||||
|
ExcludedTags: excludedTags,
|
||||||
|
MinimumTagRank: minimumTagRank,
|
||||||
|
Sort: sort,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
returnedBody, status := AniListQuery(body, true)
|
||||||
|
|
||||||
|
var badPost struct {
|
||||||
|
Errors []struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
Status int `json:"status"`
|
||||||
|
Locations []struct {
|
||||||
|
Line int `json:"line"`
|
||||||
|
Column int `json:"column"`
|
||||||
|
} `json:"locations"`
|
||||||
|
} `json:"errors"`
|
||||||
|
Data any `json:"data"`
|
||||||
|
}
|
||||||
|
var post AniListCurrentUserWatchList
|
||||||
|
if status == "200 OK" {
|
||||||
|
err := json.Unmarshal(returnedBody, &post)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed at unmarshal, %s\n", err)
|
||||||
|
}
|
||||||
|
// Getting the real total, finding the real last page and storing that in the Page info
|
||||||
|
statuses := post.Data.Page.MediaList[0].User.Statistics.Anime.Statuses
|
||||||
|
var total int
|
||||||
|
for _, status := range statuses {
|
||||||
|
if status.Status == "CURRENT" {
|
||||||
|
total = status.Count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPage := total / perPage
|
||||||
|
|
||||||
|
post.Data.Page.PageInfo.Total = total
|
||||||
|
post.Data.Page.PageInfo.LastPage = lastPage
|
||||||
|
}
|
||||||
|
|
||||||
|
if status == "403 Forbidden" {
|
||||||
|
err := json.Unmarshal(returnedBody, &badPost)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Failed at unmarshal, %s\n", err)
|
||||||
|
return post, fmt.Errorf("API authentication error")
|
||||||
|
}
|
||||||
|
return post, fmt.Errorf("AniList API error: %s", badPost.Errors[0].Message)
|
||||||
|
}
|
||||||
|
if status != "200 OK" {
|
||||||
|
return post, fmt.Errorf("API request failed with status: %s", status)
|
||||||
|
}
|
||||||
|
|
||||||
|
return post, nil
|
||||||
|
}
|
||||||
|
|||||||
+97
-35
@@ -37,6 +37,20 @@ type AniListCurrentUserWatchList struct {
|
|||||||
} `json:"data"`
|
} `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AniListBrowseList struct {
|
||||||
|
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"`
|
||||||
|
Media []Media `json:"mediaList"`
|
||||||
|
} `json:"Page"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
type AniListGetSingleAnime struct {
|
type AniListGetSingleAnime struct {
|
||||||
Data struct {
|
Data struct {
|
||||||
MediaList MediaList `json:"MediaList"`
|
MediaList MediaList `json:"MediaList"`
|
||||||
@@ -49,43 +63,91 @@ type AniListUpdateReturn struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Media struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
IDMal int `json:"idMal"`
|
||||||
|
Title struct {
|
||||||
|
UserPreferred string `json:"userPreferred"`
|
||||||
|
Romaji string `json:"romaji"`
|
||||||
|
English string `json:"english"`
|
||||||
|
Native string `json:"native"`
|
||||||
|
} `json:"title"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
CoverImage struct {
|
||||||
|
ExtraLarge string
|
||||||
|
Large string `json:"large"`
|
||||||
|
Medium string
|
||||||
|
Color string
|
||||||
|
} `json:"coverImage"`
|
||||||
|
BannerImage string
|
||||||
|
Format string
|
||||||
|
Season string `json:"season"`
|
||||||
|
SeasonYear int `json:"seasonYear"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Episodes int `json:"episodes"`
|
||||||
|
Duration int
|
||||||
|
CountryOfOrigin string
|
||||||
|
Source string
|
||||||
|
Synonyms []string
|
||||||
|
AverageScore int
|
||||||
|
MeanScore int
|
||||||
|
Popularity int
|
||||||
|
Trending int
|
||||||
|
Favourites int
|
||||||
|
isFavourite bool
|
||||||
|
Relations struct {
|
||||||
|
nodes struct {
|
||||||
|
id int
|
||||||
|
Title struct {
|
||||||
|
UserPreferred string `json:"userPreferred"`
|
||||||
|
Romaji string `json:"romaji"`
|
||||||
|
English string `json:"english"`
|
||||||
|
Native string `json:"native"`
|
||||||
|
} `json:"title"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StartDate struct {
|
||||||
|
Year int
|
||||||
|
Month int
|
||||||
|
Day int
|
||||||
|
}
|
||||||
|
EndDate struct {
|
||||||
|
Year int
|
||||||
|
Month int
|
||||||
|
Day int
|
||||||
|
}
|
||||||
|
NextAiringEpisode struct {
|
||||||
|
AiringAt int `json:"airingAt"`
|
||||||
|
TimeUntilAiring int `json:"timeUntilAiring"`
|
||||||
|
Episode int `json:"episode"`
|
||||||
|
} `json:"nextAiringEpisode"`
|
||||||
|
AiringSchedule struct {
|
||||||
|
Nodes struct {
|
||||||
|
Id int
|
||||||
|
AiringAt int
|
||||||
|
TimeUntilAiring int
|
||||||
|
Episode int
|
||||||
|
MediaId int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Genres []string `json:"genres"`
|
||||||
|
Tags []struct {
|
||||||
|
Id int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Rank int `json:"rank"`
|
||||||
|
IsMediaSpoiler bool `json:"isMediaSpoiler"`
|
||||||
|
IsAdult bool `json:"isAdult"`
|
||||||
|
} `json:"tags"`
|
||||||
|
IsAdult bool `json:"isAdult"`
|
||||||
|
}
|
||||||
|
|
||||||
type MediaList struct {
|
type MediaList struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id"`
|
||||||
MediaID int `json:"mediaId"`
|
MediaID int `json:"mediaId"`
|
||||||
UserID int `json:"userId"`
|
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"`
|
|
||||||
Genres []string `json:"genres"`
|
|
||||||
Tags []struct {
|
|
||||||
Id int `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Rank int `json:"rank"`
|
|
||||||
IsMediaSpoiler bool `json:"isMediaSpoiler"`
|
|
||||||
IsAdult bool `json:"isAdult"`
|
|
||||||
} `json:"tags"`
|
|
||||||
IsAdult bool `json:"isAdult"`
|
|
||||||
} `json:"media"`
|
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
|
Media Media `json:"media"`
|
||||||
StartedAt struct {
|
StartedAt struct {
|
||||||
Year int `json:"year"`
|
Year int `json:"year"`
|
||||||
Month int `json:"month"`
|
Month int `json:"month"`
|
||||||
|
|||||||
+30
-12
@@ -235,7 +235,7 @@ func getMyAnimeListAuthorizationToken(content string, verifier *CodeVerifier) My
|
|||||||
return post
|
return post
|
||||||
}
|
}
|
||||||
|
|
||||||
func refreshMyAnimeListAuthorizationToken() {
|
func refreshMyAnimeListAuthorizationToken() bool {
|
||||||
dataForURLs := struct {
|
dataForURLs := struct {
|
||||||
GrantType string `json:"grant_type"`
|
GrantType string `json:"grant_type"`
|
||||||
RefreshToken string `json:"refresh_token"`
|
RefreshToken string `json:"refresh_token"`
|
||||||
@@ -260,13 +260,15 @@ func refreshMyAnimeListAuthorizationToken() {
|
|||||||
response, err := http.NewRequest("POST", "https://myanimelist.net/v1/oauth2/token", strings.NewReader(data.Encode()))
|
response, err := http.NewRequest("POST", "https://myanimelist.net/v1/oauth2/token", strings.NewReader(data.Encode()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed at response, %s\n", err)
|
log.Printf("Failed at response, %s\n", err)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
response.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
response.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
res, resErr := client.Do(response)
|
res, resErr := client.Do(response)
|
||||||
if resErr != nil {
|
if resErr != nil {
|
||||||
log.Printf("Failed at res, %s\n", err)
|
log.Printf("Failed at res, %s\n", resErr)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
@@ -274,13 +276,22 @@ func refreshMyAnimeListAuthorizationToken() {
|
|||||||
returnedBody, err := io.ReadAll(res.Body)
|
returnedBody, err := io.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Could not read returned body, %s\n", err)
|
log.Printf("Could not read returned body, %s\n", err)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(returnedBody, &myAnimeListJwt)
|
var refreshed MyAnimeListJWT
|
||||||
|
err = json.Unmarshal(returnedBody, &refreshed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed at unmarshal, %s\n", err)
|
log.Printf("Failed at unmarshal, %s\n", err)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if refreshed.AccessToken == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
myAnimeListJwt = refreshed
|
||||||
|
|
||||||
_ = myAnimeListRing.Set(keyring.Item{
|
_ = myAnimeListRing.Set(keyring.Item{
|
||||||
Key: "MyAnimeListTokenType",
|
Key: "MyAnimeListTokenType",
|
||||||
Data: []byte(myAnimeListJwt.TokenType),
|
Data: []byte(myAnimeListJwt.TokenType),
|
||||||
@@ -297,26 +308,33 @@ func refreshMyAnimeListAuthorizationToken() {
|
|||||||
Key: "MyAnimeListRefreshToken",
|
Key: "MyAnimeListRefreshToken",
|
||||||
Data: []byte(myAnimeListJwt.RefreshToken),
|
Data: []byte(myAnimeListJwt.RefreshToken),
|
||||||
})
|
})
|
||||||
_, err = runtime.MessageDialog(*wailsContext, runtime.MessageDialogOptions{
|
return true
|
||||||
Title: "MyAnimeList Authorization",
|
|
||||||
Message: "It is now safe to close your browser tab",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) GetMyAnimeListLoggedInUser() MyAnimeListUser {
|
func (a *App) GetMyAnimeListLoggedInUser() MyAnimeListUser {
|
||||||
a.MyAnimeListLogin()
|
a.MyAnimeListLogin()
|
||||||
user := createUser()
|
user := createUser()
|
||||||
if user.Name == "" {
|
if user.Name == "" && !a.refreshMyAnimeListAndGetUser(&user) {
|
||||||
refreshMyAnimeListAuthorizationToken()
|
a.LogoutMyAnimeList()
|
||||||
|
a.MyAnimeListLogin()
|
||||||
user = createUser()
|
user = createUser()
|
||||||
}
|
}
|
||||||
|
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) refreshMyAnimeListAndGetUser(user *MyAnimeListUser) bool {
|
||||||
|
if !refreshMyAnimeListAuthorizationToken() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
freshUser := createUser()
|
||||||
|
if freshUser.Name == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
*user = freshUser
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func createUser() MyAnimeListUser {
|
func createUser() MyAnimeListUser {
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ headers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body:graphql {
|
body:graphql {
|
||||||
# Write your query or mutation here
|
|
||||||
query (
|
query (
|
||||||
$page: Int
|
$page: Int
|
||||||
$perPage: Int
|
$perPage: Int
|
||||||
@@ -41,23 +40,79 @@ body:graphql {
|
|||||||
id
|
id
|
||||||
idMal
|
idMal
|
||||||
title {
|
title {
|
||||||
|
userPreferred
|
||||||
romaji
|
romaji
|
||||||
english
|
english
|
||||||
native
|
native
|
||||||
}
|
}
|
||||||
description
|
description
|
||||||
coverImage {
|
coverImage {
|
||||||
|
extraLarge
|
||||||
large
|
large
|
||||||
|
medium
|
||||||
|
color
|
||||||
}
|
}
|
||||||
|
bannerImage
|
||||||
|
format
|
||||||
season
|
season
|
||||||
seasonYear
|
seasonYear
|
||||||
status
|
status
|
||||||
episodes
|
episodes
|
||||||
|
duration
|
||||||
|
countryOfOrigin
|
||||||
|
source
|
||||||
|
synonyms
|
||||||
|
averageScore
|
||||||
|
meanScore
|
||||||
|
popularity
|
||||||
|
trending
|
||||||
|
favourites
|
||||||
|
isFavourite
|
||||||
|
relations {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
title {
|
||||||
|
userPreferred
|
||||||
|
romaji
|
||||||
|
english
|
||||||
|
native
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startDate {
|
||||||
|
year
|
||||||
|
month
|
||||||
|
day
|
||||||
|
}
|
||||||
|
endDate {
|
||||||
|
year
|
||||||
|
month
|
||||||
|
day
|
||||||
|
}
|
||||||
nextAiringEpisode {
|
nextAiringEpisode {
|
||||||
airingAt
|
airingAt
|
||||||
timeUntilAiring
|
timeUntilAiring
|
||||||
episode
|
episode
|
||||||
}
|
}
|
||||||
|
airingSchedule {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
airingAt
|
||||||
|
timeUntilAiring
|
||||||
|
episode
|
||||||
|
mediaId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genres
|
||||||
|
tags {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
rank
|
||||||
|
isMediaSpoiler
|
||||||
|
isAdult
|
||||||
|
}
|
||||||
|
isAdult
|
||||||
}
|
}
|
||||||
status
|
status
|
||||||
startedAt {
|
startedAt {
|
||||||
|
|||||||
@@ -17,63 +17,161 @@ headers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body:graphql {
|
body:graphql {
|
||||||
mutation(
|
mutation (
|
||||||
$mediaId:Int,
|
$mediaId: Int
|
||||||
$progress:Int,
|
$progress: Int
|
||||||
$status:MediaListStatus,
|
$status: MediaListStatus
|
||||||
$score:Float,
|
$score: Float
|
||||||
$repeat:Int,
|
$repeat: Int
|
||||||
$notes:String,
|
$notes: String
|
||||||
$startedAt:FuzzyDateInput,
|
$startedAt: FuzzyDateInput
|
||||||
$completedAt:FuzzyDateInput,
|
$completedAt: FuzzyDateInput
|
||||||
){
|
) {
|
||||||
SaveMediaListEntry(
|
SaveMediaListEntry(
|
||||||
mediaId:$mediaId,
|
mediaId: $mediaId
|
||||||
progress:$progress,
|
progress: $progress
|
||||||
status:$status,
|
status: $status
|
||||||
score:$score,
|
score: $score
|
||||||
repeat:$repeat,
|
repeat: $repeat
|
||||||
notes:$notes,
|
notes: $notes
|
||||||
startedAt:$startedAt
|
startedAt: $startedAt
|
||||||
completedAt:$completedAt
|
completedAt: $completedAt
|
||||||
){
|
) {
|
||||||
mediaId
|
id
|
||||||
progress
|
mediaId
|
||||||
status
|
userId
|
||||||
score
|
media {
|
||||||
repeat
|
id
|
||||||
notes
|
idMal
|
||||||
startedAt{
|
title {
|
||||||
year
|
userPreferred
|
||||||
month
|
romaji
|
||||||
day
|
english
|
||||||
}
|
native
|
||||||
completedAt{
|
}
|
||||||
year
|
description
|
||||||
month
|
coverImage {
|
||||||
day
|
extraLarge
|
||||||
}
|
large
|
||||||
}
|
medium
|
||||||
}
|
color
|
||||||
|
}
|
||||||
|
bannerImage
|
||||||
|
format
|
||||||
|
season
|
||||||
|
seasonYear
|
||||||
|
status
|
||||||
|
episodes
|
||||||
|
duration
|
||||||
|
countryOfOrigin
|
||||||
|
source
|
||||||
|
synonyms
|
||||||
|
averageScore
|
||||||
|
meanScore
|
||||||
|
popularity
|
||||||
|
trending
|
||||||
|
favourites
|
||||||
|
isFavourite
|
||||||
|
relations {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
title {
|
||||||
|
userPreferred
|
||||||
|
romaji
|
||||||
|
english
|
||||||
|
native
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startDate {
|
||||||
|
year
|
||||||
|
month
|
||||||
|
day
|
||||||
|
}
|
||||||
|
endDate {
|
||||||
|
year
|
||||||
|
month
|
||||||
|
day
|
||||||
|
}
|
||||||
|
nextAiringEpisode {
|
||||||
|
airingAt
|
||||||
|
timeUntilAiring
|
||||||
|
episode
|
||||||
|
}
|
||||||
|
airingSchedule {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
airingAt
|
||||||
|
timeUntilAiring
|
||||||
|
episode
|
||||||
|
mediaId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genres
|
||||||
|
tags {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
rank
|
||||||
|
isMediaSpoiler
|
||||||
|
isAdult
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body:graphql:vars {
|
body:graphql:vars {
|
||||||
{
|
{
|
||||||
"mediaId":170998,
|
"mediaId": 170998,
|
||||||
"progress":5,
|
"progress": 5,
|
||||||
"status":"CURRENT",
|
"status": "CURRENT",
|
||||||
"score":9.0,
|
"score": 9,
|
||||||
"repeat":0,
|
"repeat": 0,
|
||||||
"notes":",malSync::eyJ1IjoiaHR0cHM6Ly93d3cuY3J1bmNoeXJvbGwuY29tL3Nlcmllcy9HVkRIWDg1Wk4vI3NlYXNvbj1HNjNWQzJHUUsiLCJwIjoiIn0=::",
|
"notes": ",malSync::eyJ1IjoiaHR0cHM6Ly93d3cuY3J1bmNoeXJvbGwuY29tL3Nlcmllcy9HVkRIWDg1Wk4vI3NlYXNvbj1HNjNWQzJHUUsiLCJwIjoiIn0=::",
|
||||||
"startedAt":{
|
"startedAt": {
|
||||||
"year":2024,
|
"year": 2024,
|
||||||
"month":7,
|
"month": 7,
|
||||||
"day":10
|
"day": 10
|
||||||
},
|
},
|
||||||
"completedAt":{
|
"completedAt": {
|
||||||
"year": 0,
|
"year": 0,
|
||||||
"month":0,
|
"month": 0,
|
||||||
"day":0
|
"day": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,191 @@
|
|||||||
|
meta {
|
||||||
|
name: SeasonBasedBrowse
|
||||||
|
type: graphql
|
||||||
|
seq: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
url: https://graphql.anilist.co
|
||||||
|
body: graphql
|
||||||
|
auth: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
body:graphql {
|
||||||
|
query (
|
||||||
|
$page: Int = 1
|
||||||
|
$perPage: Int = 20
|
||||||
|
$id: Int
|
||||||
|
$type: MediaType
|
||||||
|
$isAdult: Boolean = false
|
||||||
|
$search: String
|
||||||
|
$format: [MediaFormat]
|
||||||
|
$status: MediaStatus
|
||||||
|
$countryOfOrigin: CountryCode
|
||||||
|
$source: MediaSource
|
||||||
|
$season: MediaSeason
|
||||||
|
$seasonYear: Int
|
||||||
|
$year: String
|
||||||
|
$onList: Boolean
|
||||||
|
$yearLesser: FuzzyDateInt
|
||||||
|
$yearGreater: FuzzyDateInt
|
||||||
|
$episodeLesser: Int
|
||||||
|
$episodeGreater: Int
|
||||||
|
$durationLesser: Int
|
||||||
|
$durationGreater: Int
|
||||||
|
$chapterLesser: Int
|
||||||
|
$chapterGreater: Int
|
||||||
|
$volumeLesser: Int
|
||||||
|
$volumeGreater: Int
|
||||||
|
$licensedBy: [Int]
|
||||||
|
$isLicensed: Boolean
|
||||||
|
$genres: [String]
|
||||||
|
$excludedGenres: [String]
|
||||||
|
$tags: [String]
|
||||||
|
$excludedTags: [String]
|
||||||
|
$minimumTagRank: Int
|
||||||
|
$sort: [MediaSort] = [POPULARITY_DESC, SCORE_DESC]
|
||||||
|
) {
|
||||||
|
Page(page: $page, perPage: $perPage) {
|
||||||
|
pageInfo {
|
||||||
|
total
|
||||||
|
perPage
|
||||||
|
currentPage
|
||||||
|
lastPage
|
||||||
|
hasNextPage
|
||||||
|
}
|
||||||
|
media(
|
||||||
|
id: $id
|
||||||
|
type: $type
|
||||||
|
season: $season
|
||||||
|
format_in: $format
|
||||||
|
status: $status
|
||||||
|
countryOfOrigin: $countryOfOrigin
|
||||||
|
source: $source
|
||||||
|
search: $search
|
||||||
|
onList: $onList
|
||||||
|
seasonYear: $seasonYear
|
||||||
|
startDate_like: $year
|
||||||
|
startDate_lesser: $yearLesser
|
||||||
|
startDate_greater: $yearGreater
|
||||||
|
episodes_lesser: $episodeLesser
|
||||||
|
episodes_greater: $episodeGreater
|
||||||
|
duration_lesser: $durationLesser
|
||||||
|
duration_greater: $durationGreater
|
||||||
|
chapters_lesser: $chapterLesser
|
||||||
|
chapters_greater: $chapterGreater
|
||||||
|
volumes_lesser: $volumeLesser
|
||||||
|
volumes_greater: $volumeGreater
|
||||||
|
licensedById_in: $licensedBy
|
||||||
|
isLicensed: $isLicensed
|
||||||
|
genre_in: $genres
|
||||||
|
genre_not_in: $excludedGenres
|
||||||
|
tag_in: $tags
|
||||||
|
tag_not_in: $excludedTags
|
||||||
|
minimumTagRank: $minimumTagRank
|
||||||
|
sort: $sort
|
||||||
|
isAdult: $isAdult
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
idMal
|
||||||
|
title {
|
||||||
|
userPreferred
|
||||||
|
romaji
|
||||||
|
english
|
||||||
|
native
|
||||||
|
}
|
||||||
|
description
|
||||||
|
coverImage {
|
||||||
|
extraLarge
|
||||||
|
large
|
||||||
|
medium
|
||||||
|
color
|
||||||
|
}
|
||||||
|
startDate {
|
||||||
|
year
|
||||||
|
month
|
||||||
|
day
|
||||||
|
}
|
||||||
|
endDate {
|
||||||
|
year
|
||||||
|
month
|
||||||
|
day
|
||||||
|
}
|
||||||
|
bannerImage
|
||||||
|
format
|
||||||
|
season
|
||||||
|
seasonYear
|
||||||
|
status
|
||||||
|
episodes
|
||||||
|
duration
|
||||||
|
countryOfOrigin
|
||||||
|
source
|
||||||
|
synonyms
|
||||||
|
averageScore
|
||||||
|
meanScore
|
||||||
|
popularity
|
||||||
|
trending
|
||||||
|
favourites
|
||||||
|
isFavourite
|
||||||
|
relations {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
title {
|
||||||
|
userPreferred
|
||||||
|
romaji
|
||||||
|
english
|
||||||
|
native
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nextAiringEpisode {
|
||||||
|
airingAt
|
||||||
|
timeUntilAiring
|
||||||
|
episode
|
||||||
|
}
|
||||||
|
airingSchedule {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
airingAt
|
||||||
|
timeUntilAiring
|
||||||
|
episode
|
||||||
|
mediaId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genres
|
||||||
|
tags {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
rank
|
||||||
|
isMediaSpoiler
|
||||||
|
isAdult
|
||||||
|
}
|
||||||
|
isAdult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
body:graphql:vars {
|
||||||
|
{
|
||||||
|
"page": 1,
|
||||||
|
"perPage": 20,
|
||||||
|
"season": "SUMMER",
|
||||||
|
"seasonYear": 2026,
|
||||||
|
"type": "ANIME",
|
||||||
|
"excludedTags": [
|
||||||
|
"Ecchi",
|
||||||
|
"LGBTQ+ Themes",
|
||||||
|
"Yuri"
|
||||||
|
],
|
||||||
|
"excludedGenres": [
|
||||||
|
"Boy's Love"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
settings {
|
||||||
|
encodeUrl: true
|
||||||
|
timeout: 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
meta {
|
||||||
|
name: AniListCalendar
|
||||||
|
seq: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
auth {
|
||||||
|
mode: inherit
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
simklPrimary,
|
simklPrimary,
|
||||||
malWatchList,
|
malWatchList,
|
||||||
simklWatchList,
|
simklWatchList,
|
||||||
|
serviceLoggingIn,
|
||||||
} from "./helperModules/GlobalVariablesAndHelperFunctions.svelte";
|
} from "./helperModules/GlobalVariablesAndHelperFunctions.svelte";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import Router from "svelte-spa-router";
|
import Router from "svelte-spa-router";
|
||||||
@@ -35,6 +36,8 @@
|
|||||||
malLoggedIn.subscribe((value) => (isMALLoggedIn = value));
|
malLoggedIn.subscribe((value) => (isMALLoggedIn = value));
|
||||||
simklLoggedIn.subscribe((value) => (isSimklLoggedIn = value));
|
simklLoggedIn.subscribe((value) => (isSimklLoggedIn = value));
|
||||||
|
|
||||||
|
serviceLoggingIn.set(["anilist", "mal", "simkl"]);
|
||||||
|
|
||||||
!isAniListLoggedIn && (await CheckIfAniListLoggedInAndLoadWatchList());
|
!isAniListLoggedIn && (await CheckIfAniListLoggedInAndLoadWatchList());
|
||||||
!isMALLoggedIn && (await CheckIfMALLoggedInAndSetUser());
|
!isMALLoggedIn && (await CheckIfMALLoggedInAndSetUser());
|
||||||
!isSimklLoggedIn && (await CheckIfSimklLoggedInAndSetUser());
|
!isSimklLoggedIn && (await CheckIfSimklLoggedInAndSetUser());
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
logoutOfAniList,
|
logoutOfAniList,
|
||||||
logoutOfMAL,
|
logoutOfMAL,
|
||||||
logoutOfSimkl,
|
logoutOfSimkl,
|
||||||
|
serviceLoggingIn,
|
||||||
} from "../helperModules/GlobalVariablesAndHelperFunctions.svelte";
|
} from "../helperModules/GlobalVariablesAndHelperFunctions.svelte";
|
||||||
import * as runtime from "../../wailsjs/runtime";
|
import * as runtime from "../../wailsjs/runtime";
|
||||||
import type { MyAnimeListUser } from "../mal/types/MALTypes";
|
import type { MyAnimeListUser } from "../mal/types/MALTypes";
|
||||||
@@ -26,6 +27,7 @@
|
|||||||
let isAniListLoggedIn: boolean;
|
let isAniListLoggedIn: boolean;
|
||||||
let isSimklLoggedIn: boolean;
|
let isSimklLoggedIn: boolean;
|
||||||
let isMALLoggedIn: boolean;
|
let isMALLoggedIn: boolean;
|
||||||
|
let loggingIn: string[] = [];
|
||||||
|
|
||||||
aniListUser.subscribe((value) => (currentAniListUser = value));
|
aniListUser.subscribe((value) => (currentAniListUser = value));
|
||||||
malUser.subscribe((value) => (currentMALUser = value));
|
malUser.subscribe((value) => (currentMALUser = value));
|
||||||
@@ -33,6 +35,7 @@
|
|||||||
aniListLoggedIn.subscribe((value) => (isAniListLoggedIn = value));
|
aniListLoggedIn.subscribe((value) => (isAniListLoggedIn = value));
|
||||||
simklLoggedIn.subscribe((value) => (isSimklLoggedIn = value));
|
simklLoggedIn.subscribe((value) => (isSimklLoggedIn = value));
|
||||||
malLoggedIn.subscribe((value) => (isMALLoggedIn = value));
|
malLoggedIn.subscribe((value) => (isMALLoggedIn = value));
|
||||||
|
serviceLoggingIn.subscribe((value) => (loggingIn = value));
|
||||||
|
|
||||||
function dropdownUser(): void {
|
function dropdownUser(): void {
|
||||||
let dropdown = document.querySelector("#userDropdown");
|
let dropdown = document.querySelector("#userDropdown");
|
||||||
@@ -98,15 +101,24 @@
|
|||||||
</li>
|
</li>
|
||||||
{:else}
|
{:else}
|
||||||
<li>
|
<li>
|
||||||
<button
|
{#if loggingIn.includes("anilist")}
|
||||||
on:click={() => {
|
<span class="flex items-center px-4 py-2 w-full truncate">
|
||||||
dropdownUser();
|
<span
|
||||||
loginToAniList();
|
class="inline-block w-4 h-4 mr-4 border-2 border-gray-300 border-t-transparent rounded-full animate-spin"
|
||||||
}}
|
></span>
|
||||||
class="block px-4 py-2 w-full hover:bg-gray-600 truncate hover:text-white"
|
<span class="maple-font text-lg mr-4">A</span>Checking AniList
|
||||||
>
|
</span>
|
||||||
<span class="maple-font text-lg mr-4">A</span>Login to AniList
|
{:else}
|
||||||
</button>
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
dropdownUser();
|
||||||
|
loginToAniList();
|
||||||
|
}}
|
||||||
|
class="block px-4 py-2 w-full hover:bg-gray-600 truncate hover:text-white"
|
||||||
|
>
|
||||||
|
<span class="maple-font text-lg mr-4">A</span>Login to AniList
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
</li>
|
</li>
|
||||||
{/if}
|
{/if}
|
||||||
{#if isMALLoggedIn}
|
{#if isMALLoggedIn}
|
||||||
@@ -120,15 +132,24 @@
|
|||||||
</li>
|
</li>
|
||||||
{:else}
|
{:else}
|
||||||
<li>
|
<li>
|
||||||
<button
|
{#if loggingIn.includes("mal")}
|
||||||
on:click={() => {
|
<span class="flex items-center px-4 py-2 w-full truncate">
|
||||||
dropdownUser();
|
<span
|
||||||
loginToMAL();
|
class="inline-block w-4 h-4 mr-4 border-2 border-gray-300 border-t-transparent rounded-full animate-spin"
|
||||||
}}
|
></span>
|
||||||
class="block px-4 py-2 w-full hover:bg-gray-600 truncate hover:text-white"
|
<span class="maple-font text-lg mr-4">M</span>Checking MyAnimeList
|
||||||
>
|
</span>
|
||||||
<span class="maple-font text-lg mr-4">M</span>Login to MyAnimeList
|
{:else}
|
||||||
</button>
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
dropdownUser();
|
||||||
|
loginToMAL();
|
||||||
|
}}
|
||||||
|
class="block px-4 py-2 w-full hover:bg-gray-600 truncate hover:text-white"
|
||||||
|
>
|
||||||
|
<span class="maple-font text-lg mr-4">M</span>Login to MyAnimeList
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
</li>
|
</li>
|
||||||
{/if}
|
{/if}
|
||||||
{#if isSimklLoggedIn}
|
{#if isSimklLoggedIn}
|
||||||
@@ -143,15 +164,24 @@
|
|||||||
</li>
|
</li>
|
||||||
{:else}
|
{:else}
|
||||||
<li>
|
<li>
|
||||||
<button
|
{#if loggingIn.includes("simkl")}
|
||||||
on:click={() => {
|
<span class="flex items-center px-4 py-2 w-full truncate">
|
||||||
dropdownUser();
|
<span
|
||||||
loginToSimkl();
|
class="inline-block w-4 h-4 mr-4 border-2 border-gray-300 border-t-transparent rounded-full animate-spin"
|
||||||
}}
|
></span>
|
||||||
class="block px-4 py-2 w-full hover:bg-gray-600 truncate hover:text-white"
|
<span class="maple-font text-lg mr-4">S</span>Checking Simkl
|
||||||
>
|
</span>
|
||||||
<span class="maple-font text-lg mr-4">S</span>Login to Simkl
|
{:else}
|
||||||
</button>
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
dropdownUser();
|
||||||
|
loginToSimkl();
|
||||||
|
}}
|
||||||
|
class="block px-4 py-2 w-full hover:bg-gray-600 truncate hover:text-white"
|
||||||
|
>
|
||||||
|
<span class="maple-font text-lg mr-4">S</span>Login to Simkl
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
</li>
|
</li>
|
||||||
{/if}
|
{/if}
|
||||||
</ul>
|
</ul>
|
||||||
@@ -174,4 +204,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
loginToSimkl,
|
loginToSimkl,
|
||||||
malLoggedIn,
|
malLoggedIn,
|
||||||
simklLoggedIn,
|
simklLoggedIn,
|
||||||
|
serviceLoggingIn,
|
||||||
} from "../helperModules/GlobalVariablesAndHelperFunctions.svelte";
|
} from "../helperModules/GlobalVariablesAndHelperFunctions.svelte";
|
||||||
import AvatarMenu from "./AvatarMenu.svelte";
|
import AvatarMenu from "./AvatarMenu.svelte";
|
||||||
import logo from "../assets/images/AniTrackLogo.svg";
|
import logo from "../assets/images/AniTrackLogo.svg";
|
||||||
@@ -15,10 +16,12 @@
|
|||||||
let isAniListLoggedIn: boolean;
|
let isAniListLoggedIn: boolean;
|
||||||
let isSimklLoggedIn: boolean;
|
let isSimklLoggedIn: boolean;
|
||||||
let isMALLoggedIn: boolean;
|
let isMALLoggedIn: boolean;
|
||||||
|
let loggingIn: string[] = [];
|
||||||
|
|
||||||
aniListLoggedIn.subscribe((value) => (isAniListLoggedIn = value));
|
aniListLoggedIn.subscribe((value) => (isAniListLoggedIn = value));
|
||||||
simklLoggedIn.subscribe((value) => (isSimklLoggedIn = value));
|
simklLoggedIn.subscribe((value) => (isSimklLoggedIn = value));
|
||||||
malLoggedIn.subscribe((value) => (isMALLoggedIn = value));
|
malLoggedIn.subscribe((value) => (isMALLoggedIn = value));
|
||||||
|
serviceLoggingIn.subscribe((value) => (loggingIn = value));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<nav class="border-gray-200 bg-gray-900">
|
<nav class="border-gray-200 bg-gray-900">
|
||||||
@@ -74,23 +77,50 @@
|
|||||||
>
|
>
|
||||||
<li>
|
<li>
|
||||||
{#if !isAniListLoggedIn}
|
{#if !isAniListLoggedIn}
|
||||||
<button on:click={loginToAniList}>
|
<button
|
||||||
<!-- class="block py-2 px-3 w-full min-[950px]:w-auto rounded text-gray-300 min-[950px]:hover:text-blue-500 hover:bg-gray-700 hover:text-white min-[950px]:hover:bg-transparent border-gray-700">-->
|
disabled={loggingIn.includes("anilist")}
|
||||||
AniList Login
|
on:click={loginToAniList}
|
||||||
|
>
|
||||||
|
{#if loggingIn.includes("anilist")}
|
||||||
|
<span
|
||||||
|
class="inline-block w-4 h-4 mr-2 border-2 border-gray-300 border-t-transparent rounded-full animate-spin align-middle"
|
||||||
|
></span
|
||||||
|
>Checking AniList
|
||||||
|
{:else}
|
||||||
|
AniList Login
|
||||||
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
{#if !isMALLoggedIn}
|
{#if !isMALLoggedIn}
|
||||||
<button on:click={loginToMAL}>
|
<button
|
||||||
<!-- class="block py-2 px-3 w-full min-[950px]:w-auto rounded min-[950px]:p-0 text-gray-300 min-[950px]:hover:text-blue-500 hover:bg-gray-700 hover:text-white min-[950px]:hover:bg-transparent border-gray-700">-->
|
disabled={loggingIn.includes("mal")}
|
||||||
MyAnimeList Login
|
on:click={loginToMAL}
|
||||||
|
>
|
||||||
|
{#if loggingIn.includes("mal")}
|
||||||
|
<span
|
||||||
|
class="inline-block w-4 h-4 mr-2 border-2 border-gray-300 border-t-transparent rounded-full animate-spin align-middle"
|
||||||
|
></span
|
||||||
|
>Checking MAL
|
||||||
|
{:else}
|
||||||
|
MyAnimeList Login
|
||||||
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
{#if !isSimklLoggedIn}
|
{#if !isSimklLoggedIn}
|
||||||
<button on:click={loginToSimkl}>
|
<button
|
||||||
<!-- class="block py-2 px-3 w-full min-[950px]:w-auto rounded min-[950px]:p-0 text-gray-300 min-[950px]:hover:text-blue-500 hover:bg-gray-700 hover:text-white min-[950px]:hover:bg-transparent border-gray-700">-->
|
disabled={loggingIn.includes("simkl")}
|
||||||
Simkl Login
|
on:click={loginToSimkl}
|
||||||
|
>
|
||||||
|
{#if loggingIn.includes("simkl")}
|
||||||
|
<span
|
||||||
|
class="inline-block w-4 h-4 mr-2 border-2 border-gray-300 border-t-transparent rounded-full animate-spin align-middle"
|
||||||
|
></span
|
||||||
|
>Checking Simkl
|
||||||
|
{:else}
|
||||||
|
Simkl Login
|
||||||
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
aniListSort,
|
aniListSort,
|
||||||
clearApiError,
|
clearApiError,
|
||||||
setApiError,
|
setApiError,
|
||||||
|
serviceLoggingIn,
|
||||||
} from "./GlobalVariablesAndHelperFunctions.svelte";
|
} from "./GlobalVariablesAndHelperFunctions.svelte";
|
||||||
|
|
||||||
let isAniListPrimary: boolean;
|
let isAniListPrimary: boolean;
|
||||||
@@ -60,6 +61,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const CheckIfAniListLoggedInAndLoadWatchList = async () => {
|
export const CheckIfAniListLoggedInAndLoadWatchList = async () => {
|
||||||
|
serviceLoggingIn.update((s) => [...s, "anilist"]);
|
||||||
try {
|
try {
|
||||||
const loggedIn = await CheckIfAniListLoggedIn();
|
const loggedIn = await CheckIfAniListLoggedIn();
|
||||||
if (loggedIn) {
|
if (loggedIn) {
|
||||||
@@ -76,6 +78,8 @@
|
|||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
aniListLoggedIn.set(false);
|
aniListLoggedIn.set(false);
|
||||||
|
} finally {
|
||||||
|
serviceLoggingIn.update((s) => s.filter((item) => item !== "anilist"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,14 +1,21 @@
|
|||||||
<script lang="ts" context="module">
|
<script lang="ts" context="module">
|
||||||
import {CheckIfMyAnimeListLoggedIn, GetMyAnimeList, GetMyAnimeListLoggedInUser} from "../../wailsjs/go/main/App";
|
import {CheckIfMyAnimeListLoggedIn, GetMyAnimeList, GetMyAnimeListLoggedInUser} from "../../wailsjs/go/main/App";
|
||||||
import {malUser, malPrimary, malWatchList, malLoggedIn} from "./GlobalVariablesAndHelperFunctions.svelte"
|
import {malUser, malPrimary, malWatchList, malLoggedIn, serviceLoggingIn} from "./GlobalVariablesAndHelperFunctions.svelte"
|
||||||
|
import type { MyAnimeListUser } from "../mal/types/MALTypes";
|
||||||
|
|
||||||
let isMalPrimary: boolean
|
let isMalPrimary: boolean
|
||||||
malPrimary.subscribe(value => isMalPrimary = value)
|
malPrimary.subscribe(value => isMalPrimary = value)
|
||||||
|
|
||||||
export const CheckIfMALLoggedInAndSetUser = async () => {
|
export const CheckIfMALLoggedInAndSetUser = async () => {
|
||||||
|
serviceLoggingIn.update((s) => [...s, "mal"])
|
||||||
await CheckIfMyAnimeListLoggedIn().then(loggedIn => {
|
await CheckIfMyAnimeListLoggedIn().then(loggedIn => {
|
||||||
if (loggedIn) {
|
if (loggedIn) {
|
||||||
GetMyAnimeListLoggedInUser().then(user => {
|
GetMyAnimeListLoggedInUser().then(user => {
|
||||||
|
if (!user.name) {
|
||||||
|
malUser.set({} as MyAnimeListUser)
|
||||||
|
malLoggedIn.set(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
malUser.set(user)
|
malUser.set(user)
|
||||||
if (isMalPrimary) {
|
if (isMalPrimary) {
|
||||||
GetMyAnimeList(1000).then(watchList => {
|
GetMyAnimeList(1000).then(watchList => {
|
||||||
@@ -20,6 +27,8 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
serviceLoggingIn.update((s) => s.filter(item => item !== "mal"))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
<script lang="ts" context="module">
|
<script lang="ts" context="module">
|
||||||
import {CheckIfSimklLoggedIn, GetSimklLoggedInUser, SimklGetUserWatchlist} from "../../wailsjs/go/main/App";
|
import {CheckIfSimklLoggedIn, GetSimklLoggedInUser, SimklGetUserWatchlist} from "../../wailsjs/go/main/App";
|
||||||
import { simklLoggedIn, simklUser, simklPrimary, simklWatchList } from "./GlobalVariablesAndHelperFunctions.svelte";
|
import { simklLoggedIn, simklUser, simklPrimary, simklWatchList, serviceLoggingIn } from "./GlobalVariablesAndHelperFunctions.svelte";
|
||||||
|
|
||||||
let isSimklPrimary: boolean
|
let isSimklPrimary: boolean
|
||||||
simklPrimary.subscribe(value => isSimklPrimary = value)
|
simklPrimary.subscribe(value => isSimklPrimary = value)
|
||||||
|
|
||||||
export const CheckIfSimklLoggedInAndSetUser = async () => {
|
export const CheckIfSimklLoggedInAndSetUser = async () => {
|
||||||
|
serviceLoggingIn.update((s) => [...s, "simkl"])
|
||||||
await CheckIfSimklLoggedIn().then(loggedIn => {
|
await CheckIfSimklLoggedIn().then(loggedIn => {
|
||||||
if (loggedIn) {
|
if (loggedIn) {
|
||||||
GetSimklLoggedInUser().then(user => {
|
GetSimklLoggedInUser().then(user => {
|
||||||
@@ -24,6 +25,8 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
serviceLoggingIn.update((s) => s.filter(item => item !== "simkl"))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
export let aniListLoggedIn = writable(false);
|
export let aniListLoggedIn = writable(false);
|
||||||
export let simklLoggedIn = writable(false);
|
export let simklLoggedIn = writable(false);
|
||||||
export let malLoggedIn = writable(false);
|
export let malLoggedIn = writable(false);
|
||||||
|
export const serviceLoggingIn = writable([] as string[]);
|
||||||
export let simklWatchList = writable({} as SimklWatchList);
|
export let simklWatchList = writable({} as SimklWatchList);
|
||||||
export let aniListPrimary = writable(true);
|
export let aniListPrimary = writable(true);
|
||||||
export let simklPrimary = writable(false);
|
export let simklPrimary = writable(false);
|
||||||
@@ -148,39 +149,70 @@
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loginToSimkl(): void {
|
export function setServiceLoggingIn(service: string, isLoggingIn: boolean): void {
|
||||||
GetSimklLoggedInUser().then((user) => {
|
serviceLoggingIn.update((services) => {
|
||||||
if (Object.keys(user).length === 0) {
|
if (isLoggingIn) {
|
||||||
simklLoggedIn.set(false);
|
return services.includes(service) ? services : [...services, service];
|
||||||
} else {
|
|
||||||
simklUser.set(user);
|
|
||||||
SimklGetUserWatchlist().then((result) => {
|
|
||||||
simklWatchList.set(result);
|
|
||||||
simklLoggedIn.set(true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
return services.filter((s) => s !== service);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isServiceLoggingIn(service: string): boolean {
|
||||||
|
let loggingIn = false;
|
||||||
|
serviceLoggingIn.subscribe((services) => {
|
||||||
|
loggingIn = services.includes(service);
|
||||||
|
})();
|
||||||
|
return loggingIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loginToSimkl(): void {
|
||||||
|
setServiceLoggingIn("simkl", true);
|
||||||
|
GetSimklLoggedInUser()
|
||||||
|
.then((user) => {
|
||||||
|
if (Object.keys(user).length === 0) {
|
||||||
|
simklLoggedIn.set(false);
|
||||||
|
} else {
|
||||||
|
simklUser.set(user);
|
||||||
|
SimklGetUserWatchlist().then((result) => {
|
||||||
|
simklWatchList.set(result);
|
||||||
|
simklLoggedIn.set(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => setServiceLoggingIn("simkl", false));
|
||||||
|
}
|
||||||
|
|
||||||
export function loginToAniList(): void {
|
export function loginToAniList(): void {
|
||||||
GetAniListLoggedInUser().then((result) => {
|
setServiceLoggingIn("anilist", true);
|
||||||
aniListUser.set(result);
|
GetAniListLoggedInUser()
|
||||||
if (isAniListPrimary) {
|
.then((result) => {
|
||||||
GetAniListUserWatchingList(page, perPage, sort).then((result) => {
|
aniListUser.set(result);
|
||||||
aniListWatchlist.set(result);
|
if (isAniListPrimary) {
|
||||||
|
GetAniListUserWatchingList(page, perPage, sort).then((result) => {
|
||||||
|
aniListWatchlist.set(result);
|
||||||
|
aniListLoggedIn.set(true);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
aniListLoggedIn.set(true);
|
aniListLoggedIn.set(true);
|
||||||
});
|
}
|
||||||
} else {
|
})
|
||||||
aniListLoggedIn.set(true);
|
.finally(() => setServiceLoggingIn("anilist", false));
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loginToMAL(): void {
|
export function loginToMAL(): void {
|
||||||
GetMyAnimeListLoggedInUser().then((result) => {
|
setServiceLoggingIn("mal", true);
|
||||||
malUser.set(result);
|
GetMyAnimeListLoggedInUser()
|
||||||
malLoggedIn.set(true);
|
.then((result) => {
|
||||||
});
|
if (!result.name) {
|
||||||
|
malUser.set({} as MyAnimeListUser);
|
||||||
|
malLoggedIn.set(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
malUser.set(result);
|
||||||
|
malLoggedIn.set(true);
|
||||||
|
})
|
||||||
|
.finally(() => setServiceLoggingIn("mal", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function logoutOfAniList(): void {
|
export function logoutOfAniList(): void {
|
||||||
|
|||||||
Vendored
+2
@@ -2,6 +2,8 @@
|
|||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
import {main} from '../models';
|
import {main} from '../models';
|
||||||
|
|
||||||
|
export function AniListBrowse(arg1:number,arg2:number,arg3:number,arg4:boolean,arg5:string,arg6:Array<string>,arg7:string,arg8:string,arg9:string,arg10:string,arg11:number,arg12:string,arg13:boolean,arg14:number,arg15:number,arg16:number,arg17:number,arg18:number,arg19:number,arg20:number,arg21:number,arg22:number,arg23:number,arg24:Array<number>,arg25:boolean,arg26:Array<string>,arg27:Array<string>,arg28:Array<string>,arg29:Array<string>,arg30:number,arg31:Array<string>):Promise<main.AniListCurrentUserWatchList>;
|
||||||
|
|
||||||
export function AniListDeleteEntry(arg1:number):Promise<main.DeleteAniListReturn>;
|
export function AniListDeleteEntry(arg1:number):Promise<main.DeleteAniListReturn>;
|
||||||
|
|
||||||
export function AniListLogin():Promise<void>;
|
export function AniListLogin():Promise<void>;
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
export function AniListBrowse(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22, arg23, arg24, arg25, arg26, arg27, arg28, arg29, arg30, arg31) {
|
||||||
|
return window['go']['main']['App']['AniListBrowse'](arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22, arg23, arg24, arg25, arg26, arg27, arg28, arg29, arg30, arg31);
|
||||||
|
}
|
||||||
|
|
||||||
export function AniListDeleteEntry(arg1) {
|
export function AniListDeleteEntry(arg1) {
|
||||||
return window['go']['main']['App']['AniListDeleteEntry'](arg1);
|
return window['go']['main']['App']['AniListDeleteEntry'](arg1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -359,13 +359,125 @@ export namespace main {
|
|||||||
this.updated_at = source["updated_at"];
|
this.updated_at = source["updated_at"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export class {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
rank: number;
|
||||||
|
isMediaSpoiler: boolean;
|
||||||
|
isAdult: boolean;
|
||||||
|
|
||||||
|
static createFrom(source: any = {}) {
|
||||||
|
return new (source);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(source: any = {}) {
|
||||||
|
if ('string' === typeof source) source = JSON.parse(source);
|
||||||
|
this.id = source["id"];
|
||||||
|
this.name = source["name"];
|
||||||
|
this.description = source["description"];
|
||||||
|
this.rank = source["rank"];
|
||||||
|
this.isMediaSpoiler = source["isMediaSpoiler"];
|
||||||
|
this.isAdult = source["isAdult"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class Media {
|
||||||
|
id: number;
|
||||||
|
idMal: number;
|
||||||
|
// Go type: struct { UserPreferred string "json:\"userPreferred\""; Romaji string "json:\"romaji\""; English string "json:\"english\""; Native string "json:\"native\"" }
|
||||||
|
title: any;
|
||||||
|
description: string;
|
||||||
|
// Go type: struct { ExtraLarge string; Large string "json:\"large\""; Medium string; Color string }
|
||||||
|
coverImage: any;
|
||||||
|
BannerImage: string;
|
||||||
|
Format: string;
|
||||||
|
season: string;
|
||||||
|
seasonYear: number;
|
||||||
|
status: string;
|
||||||
|
episodes: number;
|
||||||
|
Duration: number;
|
||||||
|
CountryOfOrigin: string;
|
||||||
|
Source: string;
|
||||||
|
Synonyms: string[];
|
||||||
|
AverageScore: number;
|
||||||
|
MeanScore: number;
|
||||||
|
Popularity: number;
|
||||||
|
Trending: number;
|
||||||
|
Favourites: number;
|
||||||
|
// Go type: struct { nodes struct { id int; Title struct { UserPreferred string "json:\"userPreferred\""; Romaji string "json:\"romaji\""; English string "json:\"english\""; Native string "json:\"native\"" } "json:\"title\"" } }
|
||||||
|
Relations: any;
|
||||||
|
// Go type: struct { Year int; Month int; Day int }
|
||||||
|
StartDate: any;
|
||||||
|
// Go type: struct { Year int; Month int; Day int }
|
||||||
|
EndDate: any;
|
||||||
|
// Go type: struct { AiringAt int "json:\"airingAt\""; TimeUntilAiring int "json:\"timeUntilAiring\""; Episode int "json:\"episode\"" }
|
||||||
|
nextAiringEpisode: any;
|
||||||
|
// Go type: struct { Nodes struct { Id int; AiringAt int; TimeUntilAiring int; Episode int; MediaId int } }
|
||||||
|
AiringSchedule: any;
|
||||||
|
genres: string[];
|
||||||
|
tags: [];
|
||||||
|
isAdult: boolean;
|
||||||
|
|
||||||
|
static createFrom(source: any = {}) {
|
||||||
|
return new Media(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(source: any = {}) {
|
||||||
|
if ('string' === typeof source) source = JSON.parse(source);
|
||||||
|
this.id = source["id"];
|
||||||
|
this.idMal = source["idMal"];
|
||||||
|
this.title = this.convertValues(source["title"], Object);
|
||||||
|
this.description = source["description"];
|
||||||
|
this.coverImage = this.convertValues(source["coverImage"], Object);
|
||||||
|
this.BannerImage = source["BannerImage"];
|
||||||
|
this.Format = source["Format"];
|
||||||
|
this.season = source["season"];
|
||||||
|
this.seasonYear = source["seasonYear"];
|
||||||
|
this.status = source["status"];
|
||||||
|
this.episodes = source["episodes"];
|
||||||
|
this.Duration = source["Duration"];
|
||||||
|
this.CountryOfOrigin = source["CountryOfOrigin"];
|
||||||
|
this.Source = source["Source"];
|
||||||
|
this.Synonyms = source["Synonyms"];
|
||||||
|
this.AverageScore = source["AverageScore"];
|
||||||
|
this.MeanScore = source["MeanScore"];
|
||||||
|
this.Popularity = source["Popularity"];
|
||||||
|
this.Trending = source["Trending"];
|
||||||
|
this.Favourites = source["Favourites"];
|
||||||
|
this.Relations = this.convertValues(source["Relations"], Object);
|
||||||
|
this.StartDate = this.convertValues(source["StartDate"], Object);
|
||||||
|
this.EndDate = this.convertValues(source["EndDate"], Object);
|
||||||
|
this.nextAiringEpisode = this.convertValues(source["nextAiringEpisode"], Object);
|
||||||
|
this.AiringSchedule = this.convertValues(source["AiringSchedule"], Object);
|
||||||
|
this.genres = source["genres"];
|
||||||
|
this.tags = this.convertValues(source["tags"], );
|
||||||
|
this.isAdult = source["isAdult"];
|
||||||
|
}
|
||||||
|
|
||||||
|
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 MediaList {
|
export class MediaList {
|
||||||
id: number;
|
id: number;
|
||||||
mediaId: number;
|
mediaId: number;
|
||||||
userId: 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\""; Genres []string "json:\"genres\""; Tags []struct { Id int "json:\"id\""; Name string "json:\"name\""; Description string "json:\"description\""; Rank int "json:\"rank\""; IsMediaSpoiler bool "json:\"isMediaSpoiler\""; IsAdult bool "json:\"isAdult\"" } "json:\"tags\""; IsAdult bool "json:\"isAdult\"" }
|
|
||||||
media: any;
|
|
||||||
status: string;
|
status: string;
|
||||||
|
media: Media;
|
||||||
// Go type: struct { Year int "json:\"year\""; Month int "json:\"month\""; Day int "json:\"day\"" }
|
// Go type: struct { Year int "json:\"year\""; Month int "json:\"month\""; Day int "json:\"day\"" }
|
||||||
startedAt: any;
|
startedAt: any;
|
||||||
// Go type: struct { Year int "json:\"year\""; Month int "json:\"month\""; Day int "json:\"day\"" }
|
// Go type: struct { Year int "json:\"year\""; Month int "json:\"month\""; Day int "json:\"day\"" }
|
||||||
@@ -386,8 +498,8 @@ export namespace main {
|
|||||||
this.id = source["id"];
|
this.id = source["id"];
|
||||||
this.mediaId = source["mediaId"];
|
this.mediaId = source["mediaId"];
|
||||||
this.userId = source["userId"];
|
this.userId = source["userId"];
|
||||||
this.media = this.convertValues(source["media"], Object);
|
|
||||||
this.status = source["status"];
|
this.status = source["status"];
|
||||||
|
this.media = this.convertValues(source["media"], Media);
|
||||||
this.startedAt = this.convertValues(source["startedAt"], Object);
|
this.startedAt = this.convertValues(source["startedAt"], Object);
|
||||||
this.completedAt = this.convertValues(source["completedAt"], Object);
|
this.completedAt = this.convertValues(source["completedAt"], Object);
|
||||||
this.notes = source["notes"];
|
this.notes = source["notes"];
|
||||||
|
|||||||
+82
-1
@@ -246,4 +246,85 @@ export function OnFileDropOff() :void
|
|||||||
export function CanResolveFilePaths(): boolean;
|
export function CanResolveFilePaths(): boolean;
|
||||||
|
|
||||||
// Resolves file paths for an array of files
|
// Resolves file paths for an array of files
|
||||||
export function ResolveFilePaths(files: File[]): void
|
export function ResolveFilePaths(files: File[]): void
|
||||||
|
|
||||||
|
// Notification types
|
||||||
|
export interface NotificationOptions {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
subtitle?: string; // macOS and Linux only
|
||||||
|
body?: string;
|
||||||
|
categoryId?: string;
|
||||||
|
data?: { [key: string]: any };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NotificationAction {
|
||||||
|
id?: string;
|
||||||
|
title?: string;
|
||||||
|
destructive?: boolean; // macOS-specific
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NotificationCategory {
|
||||||
|
id?: string;
|
||||||
|
actions?: NotificationAction[];
|
||||||
|
hasReplyField?: boolean;
|
||||||
|
replyPlaceholder?: string;
|
||||||
|
replyButtonTitle?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [InitializeNotifications](https://wails.io/docs/reference/runtime/notification#initializenotifications)
|
||||||
|
// Initializes the notification service for the application.
|
||||||
|
// This must be called before sending any notifications.
|
||||||
|
export function InitializeNotifications(): Promise<void>;
|
||||||
|
|
||||||
|
// [CleanupNotifications](https://wails.io/docs/reference/runtime/notification#cleanupnotifications)
|
||||||
|
// Cleans up notification resources and releases any held connections.
|
||||||
|
export function CleanupNotifications(): Promise<void>;
|
||||||
|
|
||||||
|
// [IsNotificationAvailable](https://wails.io/docs/reference/runtime/notification#isnotificationavailable)
|
||||||
|
// Checks if notifications are available on the current platform.
|
||||||
|
export function IsNotificationAvailable(): Promise<boolean>;
|
||||||
|
|
||||||
|
// [RequestNotificationAuthorization](https://wails.io/docs/reference/runtime/notification#requestnotificationauthorization)
|
||||||
|
// Requests notification authorization from the user (macOS only).
|
||||||
|
export function RequestNotificationAuthorization(): Promise<boolean>;
|
||||||
|
|
||||||
|
// [CheckNotificationAuthorization](https://wails.io/docs/reference/runtime/notification#checknotificationauthorization)
|
||||||
|
// Checks the current notification authorization status (macOS only).
|
||||||
|
export function CheckNotificationAuthorization(): Promise<boolean>;
|
||||||
|
|
||||||
|
// [SendNotification](https://wails.io/docs/reference/runtime/notification#sendnotification)
|
||||||
|
// Sends a basic notification with the given options.
|
||||||
|
export function SendNotification(options: NotificationOptions): Promise<void>;
|
||||||
|
|
||||||
|
// [SendNotificationWithActions](https://wails.io/docs/reference/runtime/notification#sendnotificationwithactions)
|
||||||
|
// Sends a notification with action buttons. Requires a registered category.
|
||||||
|
export function SendNotificationWithActions(options: NotificationOptions): Promise<void>;
|
||||||
|
|
||||||
|
// [RegisterNotificationCategory](https://wails.io/docs/reference/runtime/notification#registernotificationcategory)
|
||||||
|
// Registers a notification category that can be used with SendNotificationWithActions.
|
||||||
|
export function RegisterNotificationCategory(category: NotificationCategory): Promise<void>;
|
||||||
|
|
||||||
|
// [RemoveNotificationCategory](https://wails.io/docs/reference/runtime/notification#removenotificationcategory)
|
||||||
|
// Removes a previously registered notification category.
|
||||||
|
export function RemoveNotificationCategory(categoryId: string): Promise<void>;
|
||||||
|
|
||||||
|
// [RemoveAllPendingNotifications](https://wails.io/docs/reference/runtime/notification#removeallpendingnotifications)
|
||||||
|
// Removes all pending notifications from the notification center.
|
||||||
|
export function RemoveAllPendingNotifications(): Promise<void>;
|
||||||
|
|
||||||
|
// [RemovePendingNotification](https://wails.io/docs/reference/runtime/notification#removependingnotification)
|
||||||
|
// Removes a specific pending notification by its identifier.
|
||||||
|
export function RemovePendingNotification(identifier: string): Promise<void>;
|
||||||
|
|
||||||
|
// [RemoveAllDeliveredNotifications](https://wails.io/docs/reference/runtime/notification#removealldeliverednotifications)
|
||||||
|
// Removes all delivered notifications from the notification center.
|
||||||
|
export function RemoveAllDeliveredNotifications(): Promise<void>;
|
||||||
|
|
||||||
|
// [RemoveDeliveredNotification](https://wails.io/docs/reference/runtime/notification#removedeliverednotification)
|
||||||
|
// Removes a specific delivered notification by its identifier.
|
||||||
|
export function RemoveDeliveredNotification(identifier: string): Promise<void>;
|
||||||
|
|
||||||
|
// [RemoveNotification](https://wails.io/docs/reference/runtime/notification#removenotification)
|
||||||
|
// Removes a notification by its identifier (cross-platform convenience function).
|
||||||
|
export function RemoveNotification(identifier: string): Promise<void>;
|
||||||
@@ -48,6 +48,10 @@ export function EventsOff(eventName, ...additionalEventNames) {
|
|||||||
return window.runtime.EventsOff(eventName, ...additionalEventNames);
|
return window.runtime.EventsOff(eventName, ...additionalEventNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function EventsOffAll() {
|
||||||
|
return window.runtime.EventsOffAll();
|
||||||
|
}
|
||||||
|
|
||||||
export function EventsOnce(eventName, callback) {
|
export function EventsOnce(eventName, callback) {
|
||||||
return EventsOnMultiple(eventName, callback, 1);
|
return EventsOnMultiple(eventName, callback, 1);
|
||||||
}
|
}
|
||||||
@@ -235,4 +239,60 @@ export function CanResolveFilePaths() {
|
|||||||
|
|
||||||
export function ResolveFilePaths(files) {
|
export function ResolveFilePaths(files) {
|
||||||
return window.runtime.ResolveFilePaths(files);
|
return window.runtime.ResolveFilePaths(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function InitializeNotifications() {
|
||||||
|
return window.runtime.InitializeNotifications();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CleanupNotifications() {
|
||||||
|
return window.runtime.CleanupNotifications();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function IsNotificationAvailable() {
|
||||||
|
return window.runtime.IsNotificationAvailable();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RequestNotificationAuthorization() {
|
||||||
|
return window.runtime.RequestNotificationAuthorization();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CheckNotificationAuthorization() {
|
||||||
|
return window.runtime.CheckNotificationAuthorization();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SendNotification(options) {
|
||||||
|
return window.runtime.SendNotification(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SendNotificationWithActions(options) {
|
||||||
|
return window.runtime.SendNotificationWithActions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RegisterNotificationCategory(category) {
|
||||||
|
return window.runtime.RegisterNotificationCategory(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RemoveNotificationCategory(categoryId) {
|
||||||
|
return window.runtime.RemoveNotificationCategory(categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RemoveAllPendingNotifications() {
|
||||||
|
return window.runtime.RemoveAllPendingNotifications();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RemovePendingNotification(identifier) {
|
||||||
|
return window.runtime.RemovePendingNotification(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RemoveAllDeliveredNotifications() {
|
||||||
|
return window.runtime.RemoveAllDeliveredNotifications();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RemoveDeliveredNotification(identifier) {
|
||||||
|
return window.runtime.RemoveDeliveredNotification(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RemoveNotification(identifier) {
|
||||||
|
return window.runtime.RemoveNotification(identifier);
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ go 1.25.0
|
|||||||
require (
|
require (
|
||||||
github.com/99designs/keyring v1.2.2
|
github.com/99designs/keyring v1.2.2
|
||||||
github.com/tidwall/gjson v1.19.0
|
github.com/tidwall/gjson v1.19.0
|
||||||
github.com/wailsapp/wails/v2 v2.12.0
|
github.com/wailsapp/wails/v2 v2.15.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -41,11 +41,11 @@ require (
|
|||||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||||
github.com/wailsapp/go-webview2 v1.0.23 // indirect
|
github.com/wailsapp/go-webview2 v1.0.23 // indirect
|
||||||
github.com/wailsapp/mimetype v1.4.1 // indirect
|
github.com/wailsapp/mimetype v1.4.1 // indirect
|
||||||
golang.org/x/crypto v0.52.0 // indirect
|
golang.org/x/crypto v0.53.0 // indirect
|
||||||
golang.org/x/net v0.55.0 // indirect
|
golang.org/x/net v0.56.0 // indirect
|
||||||
golang.org/x/sys v0.45.0 // indirect
|
golang.org/x/sys v0.46.0 // indirect
|
||||||
golang.org/x/term v0.43.0 // indirect
|
golang.org/x/term v0.44.0 // indirect
|
||||||
golang.org/x/text v0.37.0 // indirect
|
golang.org/x/text v0.39.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
// replace github.com/wailsapp/wails/v2 v2.9.1 => /home/nymusicman/go/pkg/mod
|
// replace github.com/wailsapp/wails/v2 v2.9.1 => /home/nymusicman/go/pkg/mod
|
||||||
|
|||||||
@@ -85,25 +85,25 @@ github.com/wailsapp/go-webview2 v1.0.23 h1:jmv8qhz1lHibCc79bMM/a/FqOnnzOGEisLav+
|
|||||||
github.com/wailsapp/go-webview2 v1.0.23/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc=
|
github.com/wailsapp/go-webview2 v1.0.23/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc=
|
||||||
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
||||||
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
||||||
github.com/wailsapp/wails/v2 v2.12.0 h1:BHO/kLNWFHYjCzucxbzAYZWUjub1Tvb4cSguQozHn5c=
|
github.com/wailsapp/wails/v2 v2.15.0 h1:u7cHK+UesZOlYxyJxfYLteaCPhws6UsZoDdqUejuX6Q=
|
||||||
github.com/wailsapp/wails/v2 v2.12.0/go.mod h1:mo1bzK1DEJrobt7YrBjgxvb5Sihb1mhAY09hppbibQg=
|
github.com/wailsapp/wails/v2 v2.15.0/go.mod h1:scxrgwfsv6yR6fE6cCF+Flfl+JeU+SR87T9x4kILJ6M=
|
||||||
golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
|
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
|
||||||
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
|
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
|
||||||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
|
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
|
||||||
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
|
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
|
||||||
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
|
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
||||||
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
|
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
|
||||||
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
|
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
|
golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus=
|
||||||
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
|
golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
|
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
|
||||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|||||||
Reference in New Issue
Block a user