import 'package:pixes/appdata.dart'; class Account { String accessToken; String refreshToken; final User user; Account(this.accessToken, this.refreshToken, this.user); Account.fromJson(Map json) : accessToken = json['access_token'], refreshToken = json['refresh_token'], user = User.fromJson(json['user']); Map toJson() => { 'access_token': accessToken, 'refresh_token': refreshToken, 'user': user.toJson() }; } class User { String profile; final String id; String name; String account; String email; bool isPremium; User(this.profile, this.id, this.name, this.account, this.email, this.isPremium); User.fromJson(Map json) : profile = json['profile_image_urls']['px_170x170'], id = json['id'], name = json['name'], account = json['account'], email = json['mail_address'], isPremium = json['is_premium']; Map toJson() => { 'profile_image_urls': {'px_170x170': profile}, 'id': id, 'name': name, 'account': account, 'mail_address': email, 'is_premium': isPremium }; } class UserDetails { final int id; final String name; final String account; final String avatar; final String comment; bool isFollowed; final bool isBlocking; final String? webpage; final String gender; final String birth; final String region; final String job; final int totalFollowUsers; final int myPixivUsers; final int totalIllusts; final int totalMangas; final int totalNovels; final int totalIllustBookmarks; final String? backgroundImage; final String? twitterUrl; final bool isPremium; final String? pawooUrl; UserDetails( this.id, this.name, this.account, this.avatar, this.comment, this.isFollowed, this.isBlocking, this.webpage, this.gender, this.birth, this.region, this.job, this.totalFollowUsers, this.myPixivUsers, this.totalIllusts, this.totalMangas, this.totalNovels, this.totalIllustBookmarks, this.backgroundImage, this.twitterUrl, this.isPremium, this.pawooUrl); UserDetails.fromJson(Map json) : id = json['user']['id'], name = json['user']['name'], account = json['user']['account'], avatar = json['user']['profile_image_urls']['medium'], comment = json['user']['comment'], isFollowed = json['user']['is_followed'], isBlocking = json['user']['is_access_blocking_user'], webpage = json['profile']['webpage'], gender = json['profile']['gender'], birth = json['profile']['birth'], region = json['profile']['region'], job = json['profile']['job'], totalFollowUsers = json['profile']['total_follow_users'], myPixivUsers = json['profile']['total_mypixiv_users'], totalIllusts = json['profile']['total_illusts'], totalMangas = json['profile']['total_manga'], totalNovels = json['profile']['total_novels'], totalIllustBookmarks = json['profile']['total_illust_bookmarks_public'], backgroundImage = json['profile']['background_image_url'], twitterUrl = json['profile']['twitter_url'], isPremium = json['profile']['is_premium'], pawooUrl = json['profile']['pawoo_url']; } class IllustAuthor { final int id; final String name; final String account; final String avatar; bool isFollowed; IllustAuthor( this.id, this.name, this.account, this.avatar, this.isFollowed); } class Tag { final String name; final String? translatedName; const Tag(this.name, this.translatedName); @override String toString() { return "$name${translatedName == null ? "" : "($translatedName)"}"; } @override bool operator ==(Object other) { if (other is Tag) { return name == other.name; } return false; } @override int get hashCode => name.hashCode; } class IllustImage { final String squareMedium; final String medium; final String large; final String original; const IllustImage(this.squareMedium, this.medium, this.large, this.original); } class Illust { final int id; final String title; final String type; final List images; final String caption; final int restrict; final IllustAuthor author; final List tags; final DateTime createDate; final int pageCount; final int width; final int height; final int totalView; final int totalBookmarks; bool isBookmarked; final bool isAi; final bool isUgoira; bool get isR18 => tags.contains(const Tag("R-18", null)); bool get isR18G => tags.contains(const Tag("R-18G", null)); Illust.fromJson(Map json) : id = json['id'], title = json['title'], type = json['type'], images = (() { List images = []; for (var i in json['meta_pages']) { images.add(IllustImage( i['image_urls']['square_medium'], i['image_urls']['medium'], i['image_urls']['large'], i['image_urls']['original'])); } if (images.isEmpty) { images.add(IllustImage( json['image_urls']['square_medium'], json['image_urls']['medium'], json['image_urls']['large'], json['meta_single_page']['original_image_url'])); } return images; }()), caption = json['caption'], restrict = json['restrict'], author = IllustAuthor( json['user']['id'], json['user']['name'], json['user']['account'], json['user']['profile_image_urls']['medium'], json['user']['is_followed'] ?? false), tags = (json['tags'] as List) .map((e) => Tag(e['name'], e['translated_name'])) .toList(), createDate = DateTime.parse(json['create_date']), pageCount = json['page_count'], width = json['width'], height = json['height'], totalView = json['total_view'], totalBookmarks = json['total_bookmarks'], isBookmarked = json['is_bookmarked'], isAi = json['illust_ai_type'] == 2, isUgoira = json['type'] == "ugoira"; } class TrendingTag { final Tag tag; final Illust illust; TrendingTag(this.tag, this.illust); } enum KeywordMatchType { tagsPartialMatches("Tags partial match"), tagsExactMatch("Tags exact match"), titleOrDescriptionSearch("Title or description search"); final String text; const KeywordMatchType(this.text); @override toString() => text; String toParam() => switch(this) { KeywordMatchType.tagsPartialMatches => "partial_match_for_tags", KeywordMatchType.tagsExactMatch => "exact_match_for_tags", KeywordMatchType.titleOrDescriptionSearch => "title_and_caption" }; } enum FavoriteNumber { unlimited(-1), f500(500), f1000(1000), f2000(2000), f5000(5000), f7500(7500), f10000(10000), f20000(20000), f50000(50000), f100000(100000); final int number; const FavoriteNumber(this.number); @override toString() => this == FavoriteNumber.unlimited ? "Unlimited" : "$number Bookmarks"; String toParam() => this == FavoriteNumber.unlimited ? "" : " ${number}users入り"; } enum SearchSort { newToOld, oldToNew, popular, popularMale, popularFemale; bool get isPremium => appdata.account?.user.isPremium == true; static List get availableValues => [ SearchSort.newToOld, SearchSort.oldToNew, SearchSort.popular, if(appdata.account?.user.isPremium == true) SearchSort.popularMale, if(appdata.account?.user.isPremium == true) SearchSort.popularFemale ]; @override toString() { if(this == SearchSort.popular) { return isPremium ? "Popular" : "Popular(limited)"; } else if(this == SearchSort.newToOld) { return "New to old"; } else if(this == SearchSort.oldToNew){ return "Old to new"; } else if(this == SearchSort.popularMale){ return "Popular(Male)"; } else { return "Popular(Female)"; } } String toParam() => switch(this) { SearchSort.newToOld => "date_desc", SearchSort.oldToNew => "date_asc", SearchSort.popular => "popular_desc", SearchSort.popularMale => "popular_male_desc", SearchSort.popularFemale => "popular_female_desc", }; } enum AgeLimit { unlimited("Unlimited"), allAges("All ages"), r18("R18"); final String text; const AgeLimit(this.text); @override toString() => text; String toParam() => switch(this) { AgeLimit.unlimited => "", AgeLimit.allAges => " -R-18", AgeLimit.r18 => "R-18", }; } class SearchOptions { KeywordMatchType matchType = KeywordMatchType.tagsPartialMatches; FavoriteNumber favoriteNumber = FavoriteNumber.unlimited; SearchSort sort = SearchSort.newToOld; DateTime? startTime; DateTime? endTime; AgeLimit ageLimit = AgeLimit.unlimited; } /* json: { "id": 20542044, "name": "vocaloidhm01", "account": "vocaloidhm01", "profile_image_urls": { "medium": "https://i.pximg.net/user-profile/img/2023/04/28/00/21/54/24348957_c74a61e78ddccb467417be7c37b5d463_170.jpg" }, "is_followed": false, "is_access_blocking_user": false } */ class UserPreview { final int id; final String name; final String account; final String avatar; bool isFollowed; final bool isBlocking; UserPreview(this.id, this.name, this.account, this.avatar, this.isFollowed, this.isBlocking); UserPreview.fromJson(Map json) : id = json['id'], name = json['name'], account = json['account'], avatar = json['profile_image_urls']['medium'], isFollowed = json['is_followed'], isBlocking = json['is_access_blocking_user'] ?? false; } /* { "id": 176418447, "comment": "", "date": "2024-05-13T19:28:13+09:00", "user": { "id": 54898889, "name": "Rorigod", "account": "user_gjzr2787", "profile_image_urls": { "medium": "https://i.pximg.net/user-profile/img/2021/09/01/00/46/58/21334581_94fac3456245d2b680ecf1c60aba2c95_170.png" } }, "has_replies": false, "stamp": { "stamp_id": 407, "stamp_url": "https://s.pximg.net/common/images/stamp/generated-stamps/407_s.jpg?20180605" } } */ class Comment{ final String id; final String comment; final DateTime date; final String uid; final String name; final String avatar; final bool hasReplies; final String? stampUrl; Comment.fromJson(Map json) : id = json['id'].toString(), comment = json['comment'], date = DateTime.parse(json['date']), uid = json['user']['id'].toString(), name = json['user']['name'], avatar = json['user']['profile_image_urls']['medium'], hasReplies = json['has_replies'], stampUrl = json['stamp']?['stamp_url']; }