Compare commits
28 Commits
514e4b5015
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 7c4e23e32c | |||
| d569623dfe | |||
| eccdd418b7 | |||
| 3a977688c8 | |||
|
|
a837c38732 | ||
| 2d8862c512 | |||
|
6375fb32a5
|
|||
| 7dd53baf06 | |||
| 33fab699d4 | |||
| ebacb533bc | |||
|
|
edbd229211 | ||
| fc304edc31 | |||
| 415aa098af | |||
| 95b56ecac6 | |||
|
|
1c49c2a299 | ||
| 6d3367c1cc | |||
| 037fab6409 | |||
| 286f705c41 | |||
| 2c0611cb9e | |||
| 7b1ad49e4d | |||
| a01e8602e5 | |||
| f081bd7c43 | |||
| 1481841009 | |||
| 918e42b424 | |||
| 9fed2116b1 | |||
| fbe72d1232 | |||
|
|
a6caeec383 | ||
| b76e1e9a24 |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -43,6 +43,12 @@ app.*.map.json
|
|||||||
/android/app/profile
|
/android/app/profile
|
||||||
/android/app/release
|
/android/app/release
|
||||||
|
|
||||||
|
# Ignore built translations
|
||||||
|
lib/i18n/
|
||||||
|
|
||||||
# NixOS
|
# NixOS
|
||||||
.direnv
|
.direnv
|
||||||
.envrc
|
.envrc
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
release-*/
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
plugins {
|
||||||
|
id "com.android.application"
|
||||||
|
id "kotlin-android"
|
||||||
|
id "dev.flutter.flutter-gradle-plugin"
|
||||||
|
}
|
||||||
|
|
||||||
def localProperties = new Properties()
|
def localProperties = new Properties()
|
||||||
def localPropertiesFile = rootProject.file('local.properties')
|
def localPropertiesFile = rootProject.file('local.properties')
|
||||||
if (localPropertiesFile.exists()) {
|
if (localPropertiesFile.exists()) {
|
||||||
@@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
|
||||||
if (flutterRoot == null) {
|
|
||||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
|
||||||
}
|
|
||||||
|
|
||||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||||
if (flutterVersionCode == null) {
|
if (flutterVersionCode == null) {
|
||||||
flutterVersionCode = '1'
|
flutterVersionCode = '1'
|
||||||
@@ -21,12 +22,8 @@ if (flutterVersionName == null) {
|
|||||||
flutterVersionName = '1.0'
|
flutterVersionName = '1.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
|
||||||
apply plugin: 'kotlin-android'
|
|
||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 33
|
compileSdkVersion 34
|
||||||
ndkVersion flutter.ndkVersion
|
ndkVersion flutter.ndkVersion
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
@@ -43,7 +40,6 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
|
||||||
applicationId "me.polynom.anitrack"
|
applicationId "me.polynom.anitrack"
|
||||||
// You can update the following values to match your application needs.
|
// You can update the following values to match your application needs.
|
||||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
||||||
@@ -55,9 +51,7 @@ android {
|
|||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
// TODO: Add your own signing config for the release build.
|
signingConfig null
|
||||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
|
||||||
signingConfig signingConfigs.debug
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,7 +59,3 @@ android {
|
|||||||
flutter {
|
flutter {
|
||||||
source '../..'
|
source '../..'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -30,7 +30,12 @@
|
|||||||
<meta-data
|
<meta-data
|
||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="io.flutter.embedding.android.EnableImpeller"
|
||||||
|
android:value="true" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -1,16 +1,3 @@
|
|||||||
buildscript {
|
|
||||||
ext.kotlin_version = '1.6.10'
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
classpath 'com.android.tools.build:gradle:7.1.2'
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
@@ -26,6 +13,6 @@ subprojects {
|
|||||||
project.evaluationDependsOn(':app')
|
project.evaluationDependsOn(':app')
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
tasks.register("clean", Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
|
||||||
|
|||||||
@@ -1,11 +1,25 @@
|
|||||||
include ':app'
|
pluginManagement {
|
||||||
|
def flutterSdkPath = {
|
||||||
|
def properties = new Properties()
|
||||||
|
file("local.properties").withInputStream { properties.load(it) }
|
||||||
|
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||||
|
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||||
|
return flutterSdkPath
|
||||||
|
}()
|
||||||
|
|
||||||
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
|
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||||
def properties = new Properties()
|
|
||||||
|
|
||||||
assert localPropertiesFile.exists()
|
repositories {
|
||||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
plugins {
|
||||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||||
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
id "com.android.application" version "7.3.0" apply false
|
||||||
|
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
|
||||||
|
}
|
||||||
|
|
||||||
|
include ":app"
|
||||||
|
|||||||
@@ -9,15 +9,26 @@
|
|||||||
"title": "Einstellungen",
|
"title": "Einstellungen",
|
||||||
"invalidAnimeListBody": "Die ausgewählte Datei ist keine gültige MAL Animeliste, da die Dateiendung nicht \".xml.gz\" ist.",
|
"invalidAnimeListBody": "Die ausgewählte Datei ist keine gültige MAL Animeliste, da die Dateiendung nicht \".xml.gz\" ist.",
|
||||||
"invalidMangaListBody": "Die ausgewählte Datei ist keine MAL Mangaliste, da die Dateiendung nicht \".xml.gz\" ist.",
|
"invalidMangaListBody": "Die ausgewählte Datei ist keine MAL Mangaliste, da die Dateiendung nicht \".xml.gz\" ist.",
|
||||||
"importIndicator": "$current von $total"
|
"importIndicator": "$current von $total",
|
||||||
|
"importData": "Daten importieren",
|
||||||
|
"dataExportSuccess": "Daten erfolgreich exportiert",
|
||||||
|
"dataImportSuccess": "Daten erfolgreich importiert",
|
||||||
|
"importInvalidData": {
|
||||||
|
"content": "Die ausgewählte Datei ist nicht ein AniTrack-Datenexport, da die Dateiendung \".json.gz\" fehlt.",
|
||||||
|
"title": "Ungültige AniTrack-Daten"
|
||||||
|
},
|
||||||
|
"exportData": "Daten exportieren"
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"title": "Über",
|
"title": "Über",
|
||||||
"source": "Quellcode"
|
"source": "Quellcode",
|
||||||
|
"license": "Lizenz",
|
||||||
|
"close": "Schließen"
|
||||||
},
|
},
|
||||||
"content": {
|
"content": {
|
||||||
"anime": "Anime",
|
"anime": "Anime",
|
||||||
"manga": "Manga"
|
"manga": "Manga",
|
||||||
|
"list": "Liste"
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"anime": "Animesuche",
|
"anime": "Animesuche",
|
||||||
@@ -52,5 +63,18 @@
|
|||||||
},
|
},
|
||||||
"tooltips": {
|
"tooltips": {
|
||||||
"addNewItem": "Neuen Eintrag erstellen"
|
"addNewItem": "Neuen Eintrag erstellen"
|
||||||
|
},
|
||||||
|
"calendar": {
|
||||||
|
"calendar": "Kalender",
|
||||||
|
"days": {
|
||||||
|
"monday": "Montag",
|
||||||
|
"tuesday": "Dienstag",
|
||||||
|
"wednesday": "Mittwoch",
|
||||||
|
"thursday": "Donnerstag",
|
||||||
|
"friday": "Freitag",
|
||||||
|
"saturday": "Samstag",
|
||||||
|
"sunday": "Sonntag",
|
||||||
|
"unknown": "Unbekannt"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,16 +9,27 @@
|
|||||||
"importMangaDesc": "Import manga list exported from MyAnimeList.",
|
"importMangaDesc": "Import manga list exported from MyAnimeList.",
|
||||||
"invalidMangaListTitle": "Invalid manga list",
|
"invalidMangaListTitle": "Invalid manga list",
|
||||||
"invalidMangaListBody": "The selected file is not a MAL manga list. It lacks the \".xml.gz\" suffix.",
|
"invalidMangaListBody": "The selected file is not a MAL manga list. It lacks the \".xml.gz\" suffix.",
|
||||||
"importIndicator": "$current of $total"
|
"importIndicator": "$current of $total",
|
||||||
|
"exportData": "Export data",
|
||||||
|
"importData": "Import data",
|
||||||
|
"dataExportSuccess": "Data successfully exported",
|
||||||
|
"dataImportSuccess": "Data successfully imported",
|
||||||
|
"importInvalidData": {
|
||||||
|
"title": "Invalid AniTrack Data",
|
||||||
|
"content": "The selected file is not an AniTrack data export. It lacks the \".json.gz\" suffix."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"title": "About",
|
"title": "About",
|
||||||
"source": "Source code"
|
"source": "Source code",
|
||||||
|
"license": "License",
|
||||||
|
"close": "Close"
|
||||||
},
|
},
|
||||||
"tooltips": {
|
"tooltips": {
|
||||||
"addNewItem": "Add new item"
|
"addNewItem": "Add new item"
|
||||||
},
|
},
|
||||||
"content": {
|
"content": {
|
||||||
|
"list": "List",
|
||||||
"anime": "Anime",
|
"anime": "Anime",
|
||||||
"manga": "Manga"
|
"manga": "Manga"
|
||||||
},
|
},
|
||||||
@@ -39,6 +50,19 @@
|
|||||||
"chapters": "Chapters",
|
"chapters": "Chapters",
|
||||||
"volumesOwned": "Volumes owned"
|
"volumesOwned": "Volumes owned"
|
||||||
},
|
},
|
||||||
|
"calendar": {
|
||||||
|
"calendar": "Calendar",
|
||||||
|
"days": {
|
||||||
|
"monday": "Monday",
|
||||||
|
"tuesday": "Tuesday",
|
||||||
|
"wednesday": "Wednesday",
|
||||||
|
"thursday": "Thursday",
|
||||||
|
"friday": "Friday",
|
||||||
|
"saturday": "Saturday",
|
||||||
|
"sunday": "Sunday",
|
||||||
|
"unknown": "Unknown"
|
||||||
|
}
|
||||||
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"ongoing": {
|
"ongoing": {
|
||||||
"anime": "Watching",
|
"anime": "Watching",
|
||||||
|
|||||||
80
assets/i18n/strings_nl.i18n.json
Normal file
80
assets/i18n/strings_nl.i18n.json
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"settings": {
|
||||||
|
"title": "Instellingen",
|
||||||
|
"importAnime": "Animelijst importeren",
|
||||||
|
"importAnimeDesc": "Importeer een animelijst van MyAnimeList.",
|
||||||
|
"invalidAnimeListTitle": "Ongeldige animelijst",
|
||||||
|
"invalidAnimeListBody": "Het gekozen bestand is geen MAL-lijst: de ‘.xml.gz’-extensie ontbreekt.",
|
||||||
|
"importManga": "Mangalijst importeren",
|
||||||
|
"importMangaDesc": "Importeer een mangalijst van MyAnimeList.",
|
||||||
|
"invalidMangaListTitle": "Ongeldige mangalijst",
|
||||||
|
"invalidMangaListBody": "Het gekozen bestand is geen MAL-lijst; het achtervoegsel ‘.xml.gz’ ontbreekt.",
|
||||||
|
"importIndicator": "$current van $total",
|
||||||
|
"exportData": "Gegevens exporteren",
|
||||||
|
"importData": "Gegevens importeren",
|
||||||
|
"dataExportSuccess": "De gegevens zijn geëxporteerd",
|
||||||
|
"dataImportSuccess": "De gegevens zijn geïmporteerd",
|
||||||
|
"importInvalidData": {
|
||||||
|
"title": "De AniTrack-gegevens zijn ongeldig",
|
||||||
|
"content": "Het gekozen bestand is geen AniTrack-gegevensexport: de ‘.json.gz’-extensie ontbreekt."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"about": {
|
||||||
|
"title": "Over",
|
||||||
|
"source": "Broncode",
|
||||||
|
"close": "Sluiten",
|
||||||
|
"license": "Licentie"
|
||||||
|
},
|
||||||
|
"tooltips": {
|
||||||
|
"addNewItem": "Item toevoegen"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"anime": "Anime",
|
||||||
|
"manga": "Manga",
|
||||||
|
"list": "Lijst"
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"anime": "Zoeken naar anime",
|
||||||
|
"manga": "Zoeken naar manga",
|
||||||
|
"query": "Zoekopdracht"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"title": "Details",
|
||||||
|
"removeBody": "Weet je zeker dat je ‘$title’ van de lijst wilt verwijderen?",
|
||||||
|
"removeButton": "Verwijderen",
|
||||||
|
"cancelButton": "Annuleren",
|
||||||
|
"removeTitle": "‘$title’ verwijderen?",
|
||||||
|
"watchState": "Kijkstatus",
|
||||||
|
"readState": "Leesstatus",
|
||||||
|
"episodes": "Afleveringen",
|
||||||
|
"chapters": "Hoofdstukken",
|
||||||
|
"volumesOwned": "Aantal edities in bezit"
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"ongoing": {
|
||||||
|
"anime": "Aan het kijken",
|
||||||
|
"manga": "Aan het lezen"
|
||||||
|
},
|
||||||
|
"completed": "Afgerond",
|
||||||
|
"planned": {
|
||||||
|
"anime": "Wil ik kijken",
|
||||||
|
"manga": "Wil ik lezen"
|
||||||
|
},
|
||||||
|
"dropped": "Gestopt",
|
||||||
|
"paused": "Onderbroken",
|
||||||
|
"all": "Alles"
|
||||||
|
},
|
||||||
|
"calendar": {
|
||||||
|
"calendar": "Kalender",
|
||||||
|
"days": {
|
||||||
|
"monday": "maandag",
|
||||||
|
"tuesday": "dinsdag",
|
||||||
|
"wednesday": "woensdag",
|
||||||
|
"thursday": "donderdag",
|
||||||
|
"friday": "vrijdag",
|
||||||
|
"saturday": "zaterdag",
|
||||||
|
"sunday": "zondag",
|
||||||
|
"unknown": "Onbekend"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
80
assets/i18n/strings_zh_Hans.i18n.json
Normal file
80
assets/i18n/strings_zh_Hans.i18n.json
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"settings": {
|
||||||
|
"importAnime": "导入动画列表",
|
||||||
|
"title": "设置",
|
||||||
|
"importManga": "导入漫画列表",
|
||||||
|
"importMangaDesc": "导入从 MyAnimeList 导出的漫画列表。",
|
||||||
|
"invalidMangaListTitle": "漫画列表无效",
|
||||||
|
"importIndicator": "$current / $total",
|
||||||
|
"exportData": "导出数据",
|
||||||
|
"importData": "导入数据",
|
||||||
|
"dataExportSuccess": "数据已成功导出",
|
||||||
|
"dataImportSuccess": "数据已成功导入",
|
||||||
|
"importInvalidData": {
|
||||||
|
"title": "AniTrack 数据无效",
|
||||||
|
"content": "所选文件不是 AniTrack 导出的数据。它缺少“.json.gz”后缀。"
|
||||||
|
},
|
||||||
|
"importAnimeDesc": "导入从 MyAnimeList 导出的动画列表。",
|
||||||
|
"invalidAnimeListTitle": "动画列表无效",
|
||||||
|
"invalidAnimeListBody": "所选文件不是 MyAnimeList 动画列表。它缺少“.xml.gz”后缀。",
|
||||||
|
"invalidMangaListBody": "所选文件不是 MyAnimeList 漫画列表。它缺少“.xml.gz”后缀。"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"removeTitle": "移除 $title?",
|
||||||
|
"title": "详情",
|
||||||
|
"removeBody": "是否确定要从列表中移除“$title”?",
|
||||||
|
"removeButton": "移除",
|
||||||
|
"cancelButton": "取消",
|
||||||
|
"watchState": "观看状态",
|
||||||
|
"episodes": "剧集",
|
||||||
|
"chapters": "章节",
|
||||||
|
"volumesOwned": "拥有的卷",
|
||||||
|
"readState": "阅读状态"
|
||||||
|
},
|
||||||
|
"calendar": {
|
||||||
|
"days": {
|
||||||
|
"monday": "星期一",
|
||||||
|
"tuesday": "星期二",
|
||||||
|
"wednesday": "星期三",
|
||||||
|
"thursday": "星期四",
|
||||||
|
"friday": "星期五",
|
||||||
|
"saturday": "星期六",
|
||||||
|
"sunday": "星期日",
|
||||||
|
"unknown": "未知"
|
||||||
|
},
|
||||||
|
"calendar": "日历"
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"planned": {
|
||||||
|
"manga": "计划阅读",
|
||||||
|
"anime": "计划观看"
|
||||||
|
},
|
||||||
|
"completed": "已完成",
|
||||||
|
"paused": "已暂停",
|
||||||
|
"all": "全部",
|
||||||
|
"ongoing": {
|
||||||
|
"anime": "正在观看",
|
||||||
|
"manga": "正在阅读"
|
||||||
|
},
|
||||||
|
"dropped": "已丢弃"
|
||||||
|
},
|
||||||
|
"about": {
|
||||||
|
"title": "关于",
|
||||||
|
"source": "源代码",
|
||||||
|
"license": "许可证",
|
||||||
|
"close": "关闭"
|
||||||
|
},
|
||||||
|
"tooltips": {
|
||||||
|
"addNewItem": "添加新项目"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"list": "列表",
|
||||||
|
"anime": "动画",
|
||||||
|
"manga": "漫画"
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"anime": "动画搜索",
|
||||||
|
"manga": "漫画搜索",
|
||||||
|
"query": "搜索查询"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,3 +5,5 @@ targets:
|
|||||||
options:
|
options:
|
||||||
input_directory: assets/i18n
|
input_directory: assets/i18n
|
||||||
output_directory: lib/i18n
|
output_directory: lib/i18n
|
||||||
|
fallback_strategy: base_locale
|
||||||
|
base_locale: en
|
||||||
|
|||||||
189
flake.lock
generated
189
flake.lock
generated
@@ -1,6 +1,100 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"android-nixpkgs": {
|
||||||
|
"inputs": {
|
||||||
|
"devshell": "devshell",
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1689798050,
|
||||||
|
"narHash": "sha256-ZyFPra7N0MF803o55dYQQyX9b/BmXr6QTCyN7slRThY=",
|
||||||
|
"owner": "tadfisher",
|
||||||
|
"repo": "android-nixpkgs",
|
||||||
|
"rev": "9aa0e2990da86de8ca203af313668851dcb9ea6e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "tadfisher",
|
||||||
|
"repo": "android-nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bab": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils_2",
|
||||||
|
"nixpkgs": "nixpkgs_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1689978337,
|
||||||
|
"narHash": "sha256-d4Rn+YtBrs6NpQobODZYUeVqsTS+WCiGih+WOt+gazA=",
|
||||||
|
"ref": "refs/heads/master",
|
||||||
|
"rev": "92687b6513492c6fdc839f313d14da632c9d2767",
|
||||||
|
"revCount": 1,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://codeberg.org/PapaTutuWawa/bits-and-bytes.git"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://codeberg.org/PapaTutuWawa/bits-and-bytes.git"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"devshell": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": ["android-nixpkgs", "nixpkgs"],
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1688380630,
|
||||||
|
"narHash": "sha256-8ilApWVb1mAi4439zS3iFeIT0ODlbrifm/fegWwgHjA=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "devshell",
|
||||||
|
"rev": "f9238ec3d75cefbb2b42a44948c4e8fb1ae9a205",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "devshell",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1689068808,
|
||||||
|
"narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils_2": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems_3"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1689068808,
|
||||||
|
"narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils_3": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1667395993,
|
"lastModified": 1667395993,
|
||||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||||
@@ -17,24 +111,103 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1676076353,
|
"lastModified": 1689679375,
|
||||||
"narHash": "sha256-mdUtE8Tp40cZETwcq5tCwwLqkJVV1ULJQ5GKRtbshag=",
|
"narHash": "sha256-LHUC52WvyVDi9PwyL1QCpaxYWBqp4ir4iL6zgOkmcb8=",
|
||||||
"owner": "AtaraxiaSjel",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "5deb99bdccbbb97e7562dee4ba8a3ee3021688e6",
|
"rev": "684c17c429c42515bafb3ad775d2a710947f3d67",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "AtaraxiaSjel",
|
"owner": "NixOS",
|
||||||
"ref": "update/flutter",
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1689935543,
|
||||||
|
"narHash": "sha256-6GQ9ib4dA/r1leC5VUpsBo0BmDvNxLjKrX1iyL+h8mc=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "e43e2448161c0a2c4928abec4e16eae1516571bc",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1727586919,
|
||||||
|
"narHash": "sha256-e/YXG0tO5GWHDS8QQauj8aj4HhXEm602q9swrrlTlKQ=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "2dcd9c55e8914017226f5948ac22c53872a13ee2",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils",
|
"android-nixpkgs": "android-nixpkgs",
|
||||||
"nixpkgs": "nixpkgs"
|
"bab": "bab",
|
||||||
|
"flake-utils": "flake-utils_3",
|
||||||
|
"nixpkgs": "nixpkgs_3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
85
flake.nix
85
flake.nix
@@ -1,11 +1,13 @@
|
|||||||
{
|
{
|
||||||
description = "AniTrack";
|
description = "AniTrack";
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:AtaraxiaSjel/nixpkgs/update/flutter";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
android-nixpkgs.url = "github:tadfisher/android-nixpkgs";
|
||||||
|
bab.url = "git+https://codeberg.org/PapaTutuWawa/bits-and-bytes.git";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: let
|
outputs = { self, nixpkgs, android-nixpkgs, flake-utils, bab }: flake-utils.lib.eachDefaultSystem (system: let
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
config = {
|
config = {
|
||||||
@@ -13,36 +15,73 @@
|
|||||||
allowUnfree = true;
|
allowUnfree = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
android = pkgs.androidenv.composeAndroidPackages {
|
lib = pkgs.lib;
|
||||||
# TODO: Find a way to pin these
|
babPkgs = bab.packages."${system}";
|
||||||
#toolsVersion = "26.1.1";
|
|
||||||
#platformToolsVersion = "31.0.3";
|
|
||||||
#buildToolsVersions = [ "31.0.0" ];
|
|
||||||
#includeEmulator = true;
|
|
||||||
#emulatorVersion = "30.6.3";
|
|
||||||
platformVersions = [ "28" ];
|
|
||||||
includeSources = false;
|
|
||||||
includeSystemImages = true;
|
|
||||||
systemImageTypes = [ "default" ];
|
|
||||||
abiVersions = [ "x86_64" ];
|
|
||||||
includeNDK = false;
|
|
||||||
useGoogleAPIs = false;
|
|
||||||
useGoogleTVAddOns = false;
|
|
||||||
};
|
|
||||||
pinnedJDK = pkgs.jdk17;
|
pinnedJDK = pkgs.jdk17;
|
||||||
|
|
||||||
pythonEnv = pkgs.python3.withPackages (ps: with ps; [
|
# Everything to make Flutter happy
|
||||||
requests pyyaml # For the build scripts
|
sdk = android-nixpkgs.sdk.${system} (sdkPkgs: with sdkPkgs; [
|
||||||
|
cmdline-tools-latest
|
||||||
|
build-tools-30-0-3
|
||||||
|
build-tools-33-0-2
|
||||||
|
build-tools-34-0-0
|
||||||
|
platform-tools
|
||||||
|
emulator
|
||||||
|
patcher-v4
|
||||||
|
#platforms-android-30
|
||||||
|
platforms-android-31
|
||||||
|
platforms-android-33
|
||||||
|
platforms-android-34
|
||||||
]);
|
]);
|
||||||
in {
|
in {
|
||||||
devShell = pkgs.mkShell {
|
devShell = pkgs.mkShell {
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
flutter pinnedJDK android.platform-tools dart scrcpy # Flutter/Android
|
# Android
|
||||||
gitlint jq # Code hygiene
|
sdk
|
||||||
ripgrep # General utilities
|
|
||||||
|
# Flutter
|
||||||
|
flutter dart scrcpy pinnedJDK
|
||||||
|
|
||||||
|
# Code hygiene
|
||||||
|
gitlint
|
||||||
];
|
];
|
||||||
|
|
||||||
JAVA_HOME = pinnedJDK;
|
JAVA_HOME = pinnedJDK;
|
||||||
|
ANDROID_HOME = "${sdk}/share/android-sdk";
|
||||||
|
ANDROID_SDK_ROOT = "${sdk}/share/android-sdk";
|
||||||
|
|
||||||
|
# Fix an issue with Flutter using an older version of aapt2, which does not know
|
||||||
|
# an used parameter.
|
||||||
|
GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${sdk}/share/android-sdk/build-tools/34.0.0/aapt2";
|
||||||
|
};
|
||||||
|
|
||||||
|
apps = let
|
||||||
|
providerArg = pkgs.writeText "provider-arg.cfg" ''
|
||||||
|
name = OpenSC-PKCS11
|
||||||
|
description = SunPKCS11 via OpenSC
|
||||||
|
library = ${pkgs.opensc}/lib/opensc-pkcs11.so
|
||||||
|
slotListIndex = 0
|
||||||
|
'';
|
||||||
|
mkBuildScript = skipBuild: pkgs.writeShellScript "build-anitrack.sh" ''
|
||||||
|
${babPkgs.flutter-build}/bin/flutter-build \
|
||||||
|
--name AniTrack \
|
||||||
|
--not-signed \
|
||||||
|
--zipalign ${sdk}/share/android-sdk/build-tools/34.0.0/zipalign \
|
||||||
|
--apksigner ${sdk}/share/android-sdk/build-tools/34.0.0/apksigner \
|
||||||
|
--provider-config ${providerArg} ${lib.optionalString skipBuild "--skip-build"}
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
# Skip the build and just sign
|
||||||
|
onlySign = {
|
||||||
|
type = "app";
|
||||||
|
program = "${mkBuildScript true}";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Build everything and sign
|
||||||
|
build = {
|
||||||
|
type = "app";
|
||||||
|
program = "${mkBuildScript false}";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,322 +0,0 @@
|
|||||||
/// Generated file. Do not edit.
|
|
||||||
///
|
|
||||||
/// Locales: 1
|
|
||||||
/// Strings: 36
|
|
||||||
///
|
|
||||||
/// Built on 2023-06-21 at 20:15 UTC
|
|
||||||
|
|
||||||
// coverage:ignore-file
|
|
||||||
// ignore_for_file: type=lint
|
|
||||||
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:slang/builder/model/node.dart';
|
|
||||||
import 'package:slang_flutter/slang_flutter.dart';
|
|
||||||
export 'package:slang_flutter/slang_flutter.dart';
|
|
||||||
|
|
||||||
const AppLocale _baseLocale = AppLocale.en;
|
|
||||||
|
|
||||||
/// Supported locales, see extension methods below.
|
|
||||||
///
|
|
||||||
/// Usage:
|
|
||||||
/// - LocaleSettings.setLocale(AppLocale.en) // set locale
|
|
||||||
/// - Locale locale = AppLocale.en.flutterLocale // get flutter locale from enum
|
|
||||||
/// - if (LocaleSettings.currentLocale == AppLocale.en) // locale check
|
|
||||||
enum AppLocale with BaseAppLocale<AppLocale, _StringsEn> {
|
|
||||||
en(languageCode: 'en', build: _StringsEn.build);
|
|
||||||
|
|
||||||
const AppLocale({required this.languageCode, this.scriptCode, this.countryCode, required this.build}); // ignore: unused_element
|
|
||||||
|
|
||||||
@override final String languageCode;
|
|
||||||
@override final String? scriptCode;
|
|
||||||
@override final String? countryCode;
|
|
||||||
@override final TranslationBuilder<AppLocale, _StringsEn> build;
|
|
||||||
|
|
||||||
/// Gets current instance managed by [LocaleSettings].
|
|
||||||
_StringsEn get translations => LocaleSettings.instance.translationMap[this]!;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Method A: Simple
|
|
||||||
///
|
|
||||||
/// No rebuild after locale change.
|
|
||||||
/// Translation happens during initialization of the widget (call of t).
|
|
||||||
/// Configurable via 'translate_var'.
|
|
||||||
///
|
|
||||||
/// Usage:
|
|
||||||
/// String a = t.someKey.anotherKey;
|
|
||||||
/// String b = t['someKey.anotherKey']; // Only for edge cases!
|
|
||||||
_StringsEn get t => LocaleSettings.instance.currentTranslations;
|
|
||||||
|
|
||||||
/// Method B: Advanced
|
|
||||||
///
|
|
||||||
/// All widgets using this method will trigger a rebuild when locale changes.
|
|
||||||
/// Use this if you have e.g. a settings page where the user can select the locale during runtime.
|
|
||||||
///
|
|
||||||
/// Step 1:
|
|
||||||
/// wrap your App with
|
|
||||||
/// TranslationProvider(
|
|
||||||
/// child: MyApp()
|
|
||||||
/// );
|
|
||||||
///
|
|
||||||
/// Step 2:
|
|
||||||
/// final t = Translations.of(context); // Get t variable.
|
|
||||||
/// String a = t.someKey.anotherKey; // Use t variable.
|
|
||||||
/// String b = t['someKey.anotherKey']; // Only for edge cases!
|
|
||||||
class Translations {
|
|
||||||
Translations._(); // no constructor
|
|
||||||
|
|
||||||
static _StringsEn of(BuildContext context) => InheritedLocaleData.of<AppLocale, _StringsEn>(context).translations;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The provider for method B
|
|
||||||
class TranslationProvider extends BaseTranslationProvider<AppLocale, _StringsEn> {
|
|
||||||
TranslationProvider({required super.child}) : super(settings: LocaleSettings.instance);
|
|
||||||
|
|
||||||
static InheritedLocaleData<AppLocale, _StringsEn> of(BuildContext context) => InheritedLocaleData.of<AppLocale, _StringsEn>(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Method B shorthand via [BuildContext] extension method.
|
|
||||||
/// Configurable via 'translate_var'.
|
|
||||||
///
|
|
||||||
/// Usage (e.g. in a widget's build method):
|
|
||||||
/// context.t.someKey.anotherKey
|
|
||||||
extension BuildContextTranslationsExtension on BuildContext {
|
|
||||||
_StringsEn get t => TranslationProvider.of(this).translations;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Manages all translation instances and the current locale
|
|
||||||
class LocaleSettings extends BaseFlutterLocaleSettings<AppLocale, _StringsEn> {
|
|
||||||
LocaleSettings._() : super(utils: AppLocaleUtils.instance);
|
|
||||||
|
|
||||||
static final instance = LocaleSettings._();
|
|
||||||
|
|
||||||
// static aliases (checkout base methods for documentation)
|
|
||||||
static AppLocale get currentLocale => instance.currentLocale;
|
|
||||||
static Stream<AppLocale> getLocaleStream() => instance.getLocaleStream();
|
|
||||||
static AppLocale setLocale(AppLocale locale, {bool? listenToDeviceLocale = false}) => instance.setLocale(locale, listenToDeviceLocale: listenToDeviceLocale);
|
|
||||||
static AppLocale setLocaleRaw(String rawLocale, {bool? listenToDeviceLocale = false}) => instance.setLocaleRaw(rawLocale, listenToDeviceLocale: listenToDeviceLocale);
|
|
||||||
static AppLocale useDeviceLocale() => instance.useDeviceLocale();
|
|
||||||
@Deprecated('Use [AppLocaleUtils.supportedLocales]') static List<Locale> get supportedLocales => instance.supportedLocales;
|
|
||||||
@Deprecated('Use [AppLocaleUtils.supportedLocalesRaw]') static List<String> get supportedLocalesRaw => instance.supportedLocalesRaw;
|
|
||||||
static void setPluralResolver({String? language, AppLocale? locale, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) => instance.setPluralResolver(
|
|
||||||
language: language,
|
|
||||||
locale: locale,
|
|
||||||
cardinalResolver: cardinalResolver,
|
|
||||||
ordinalResolver: ordinalResolver,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provides utility functions without any side effects.
|
|
||||||
class AppLocaleUtils extends BaseAppLocaleUtils<AppLocale, _StringsEn> {
|
|
||||||
AppLocaleUtils._() : super(baseLocale: _baseLocale, locales: AppLocale.values);
|
|
||||||
|
|
||||||
static final instance = AppLocaleUtils._();
|
|
||||||
|
|
||||||
// static aliases (checkout base methods for documentation)
|
|
||||||
static AppLocale parse(String rawLocale) => instance.parse(rawLocale);
|
|
||||||
static AppLocale parseLocaleParts({required String languageCode, String? scriptCode, String? countryCode}) => instance.parseLocaleParts(languageCode: languageCode, scriptCode: scriptCode, countryCode: countryCode);
|
|
||||||
static AppLocale findDeviceLocale() => instance.findDeviceLocale();
|
|
||||||
static List<Locale> get supportedLocales => instance.supportedLocales;
|
|
||||||
static List<String> get supportedLocalesRaw => instance.supportedLocalesRaw;
|
|
||||||
}
|
|
||||||
|
|
||||||
// translations
|
|
||||||
|
|
||||||
// Path: <root>
|
|
||||||
class _StringsEn implements BaseTranslations<AppLocale, _StringsEn> {
|
|
||||||
|
|
||||||
/// You can call this constructor and build your own translation instance of this locale.
|
|
||||||
/// Constructing via the enum [AppLocale.build] is preferred.
|
|
||||||
_StringsEn.build({Map<String, Node>? overrides, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver})
|
|
||||||
: assert(overrides == null, 'Set "translation_overrides: true" in order to enable this feature.'),
|
|
||||||
$meta = TranslationMetadata(
|
|
||||||
locale: AppLocale.en,
|
|
||||||
overrides: overrides ?? {},
|
|
||||||
cardinalResolver: cardinalResolver,
|
|
||||||
ordinalResolver: ordinalResolver,
|
|
||||||
) {
|
|
||||||
$meta.setFlatMapFunction(_flatMapFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Metadata for the translations of <en>.
|
|
||||||
@override final TranslationMetadata<AppLocale, _StringsEn> $meta;
|
|
||||||
|
|
||||||
/// Access flat map
|
|
||||||
dynamic operator[](String key) => $meta.getTranslation(key);
|
|
||||||
|
|
||||||
late final _StringsEn _root = this; // ignore: unused_field
|
|
||||||
|
|
||||||
// Translations
|
|
||||||
late final _StringsSettingsEn settings = _StringsSettingsEn._(_root);
|
|
||||||
late final _StringsAboutEn about = _StringsAboutEn._(_root);
|
|
||||||
late final _StringsTooltipsEn tooltips = _StringsTooltipsEn._(_root);
|
|
||||||
late final _StringsContentEn content = _StringsContentEn._(_root);
|
|
||||||
late final _StringsSearchEn search = _StringsSearchEn._(_root);
|
|
||||||
late final _StringsDetailsEn details = _StringsDetailsEn._(_root);
|
|
||||||
late final _StringsDataEn data = _StringsDataEn._(_root);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path: settings
|
|
||||||
class _StringsSettingsEn {
|
|
||||||
_StringsSettingsEn._(this._root);
|
|
||||||
|
|
||||||
final _StringsEn _root; // ignore: unused_field
|
|
||||||
|
|
||||||
// Translations
|
|
||||||
String get title => 'Settings';
|
|
||||||
String get importAnime => 'Import anime list';
|
|
||||||
String get importAnimeDesc => 'Import anime list exported from MyAnimeList.';
|
|
||||||
String get invalidAnimeListTitle => 'Invalid anime list';
|
|
||||||
String get invalidAnimeListBody => 'The selected file is not a MAL anime list. It lacks the ".xml.gz" suffix.';
|
|
||||||
String get importManga => 'Import manga list';
|
|
||||||
String get importMangaDesc => 'Import manga list exported from MyAnimeList.';
|
|
||||||
String get invalidMangaListTitle => 'Invalid manga list';
|
|
||||||
String get invalidMangaListBody => 'The selected file is not a MAL manga list. It lacks the ".xml.gz" suffix.';
|
|
||||||
String importIndicator({required Object current, required Object total}) => '${current} of ${total}';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path: about
|
|
||||||
class _StringsAboutEn {
|
|
||||||
_StringsAboutEn._(this._root);
|
|
||||||
|
|
||||||
final _StringsEn _root; // ignore: unused_field
|
|
||||||
|
|
||||||
// Translations
|
|
||||||
String get title => 'About';
|
|
||||||
String get source => 'Source code';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path: tooltips
|
|
||||||
class _StringsTooltipsEn {
|
|
||||||
_StringsTooltipsEn._(this._root);
|
|
||||||
|
|
||||||
final _StringsEn _root; // ignore: unused_field
|
|
||||||
|
|
||||||
// Translations
|
|
||||||
String get addNewItem => 'Add new item';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path: content
|
|
||||||
class _StringsContentEn {
|
|
||||||
_StringsContentEn._(this._root);
|
|
||||||
|
|
||||||
final _StringsEn _root; // ignore: unused_field
|
|
||||||
|
|
||||||
// Translations
|
|
||||||
String get anime => 'Anime';
|
|
||||||
String get manga => 'Manga';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path: search
|
|
||||||
class _StringsSearchEn {
|
|
||||||
_StringsSearchEn._(this._root);
|
|
||||||
|
|
||||||
final _StringsEn _root; // ignore: unused_field
|
|
||||||
|
|
||||||
// Translations
|
|
||||||
String get anime => 'Anime search';
|
|
||||||
String get manga => 'Manga search';
|
|
||||||
String get query => 'Search query';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path: details
|
|
||||||
class _StringsDetailsEn {
|
|
||||||
_StringsDetailsEn._(this._root);
|
|
||||||
|
|
||||||
final _StringsEn _root; // ignore: unused_field
|
|
||||||
|
|
||||||
// Translations
|
|
||||||
String get title => 'Details';
|
|
||||||
String removeTitle({required Object title}) => 'Remove ${title}?';
|
|
||||||
String removeBody({required Object title}) => 'Are you sure you want to remove "${title}" from the list?';
|
|
||||||
String get removeButton => 'Remove';
|
|
||||||
String get cancelButton => 'Cancel';
|
|
||||||
String get watchState => 'Watch state';
|
|
||||||
String get readState => 'Read state';
|
|
||||||
String get episodes => 'Episodes';
|
|
||||||
String get chapters => 'Chapters';
|
|
||||||
String get volumesOwned => 'Volumes owned';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path: data
|
|
||||||
class _StringsDataEn {
|
|
||||||
_StringsDataEn._(this._root);
|
|
||||||
|
|
||||||
final _StringsEn _root; // ignore: unused_field
|
|
||||||
|
|
||||||
// Translations
|
|
||||||
late final _StringsDataOngoingEn ongoing = _StringsDataOngoingEn._(_root);
|
|
||||||
String get completed => 'Completed';
|
|
||||||
late final _StringsDataPlannedEn planned = _StringsDataPlannedEn._(_root);
|
|
||||||
String get dropped => 'Dropped';
|
|
||||||
String get paused => 'Paused';
|
|
||||||
String get all => 'All';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path: data.ongoing
|
|
||||||
class _StringsDataOngoingEn {
|
|
||||||
_StringsDataOngoingEn._(this._root);
|
|
||||||
|
|
||||||
final _StringsEn _root; // ignore: unused_field
|
|
||||||
|
|
||||||
// Translations
|
|
||||||
String get anime => 'Watching';
|
|
||||||
String get manga => 'Reading';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path: data.planned
|
|
||||||
class _StringsDataPlannedEn {
|
|
||||||
_StringsDataPlannedEn._(this._root);
|
|
||||||
|
|
||||||
final _StringsEn _root; // ignore: unused_field
|
|
||||||
|
|
||||||
// Translations
|
|
||||||
String get anime => 'Plan to watch';
|
|
||||||
String get manga => 'Plan to read';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Flat map(s) containing all translations.
|
|
||||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
|
||||||
|
|
||||||
extension on _StringsEn {
|
|
||||||
dynamic _flatMapFunction(String path) {
|
|
||||||
switch (path) {
|
|
||||||
case 'settings.title': return 'Settings';
|
|
||||||
case 'settings.importAnime': return 'Import anime list';
|
|
||||||
case 'settings.importAnimeDesc': return 'Import anime list exported from MyAnimeList.';
|
|
||||||
case 'settings.invalidAnimeListTitle': return 'Invalid anime list';
|
|
||||||
case 'settings.invalidAnimeListBody': return 'The selected file is not a MAL anime list. It lacks the ".xml.gz" suffix.';
|
|
||||||
case 'settings.importManga': return 'Import manga list';
|
|
||||||
case 'settings.importMangaDesc': return 'Import manga list exported from MyAnimeList.';
|
|
||||||
case 'settings.invalidMangaListTitle': return 'Invalid manga list';
|
|
||||||
case 'settings.invalidMangaListBody': return 'The selected file is not a MAL manga list. It lacks the ".xml.gz" suffix.';
|
|
||||||
case 'settings.importIndicator': return ({required Object current, required Object total}) => '${current} of ${total}';
|
|
||||||
case 'about.title': return 'About';
|
|
||||||
case 'about.source': return 'Source code';
|
|
||||||
case 'tooltips.addNewItem': return 'Add new item';
|
|
||||||
case 'content.anime': return 'Anime';
|
|
||||||
case 'content.manga': return 'Manga';
|
|
||||||
case 'search.anime': return 'Anime search';
|
|
||||||
case 'search.manga': return 'Manga search';
|
|
||||||
case 'search.query': return 'Search query';
|
|
||||||
case 'details.title': return 'Details';
|
|
||||||
case 'details.removeTitle': return ({required Object title}) => 'Remove ${title}?';
|
|
||||||
case 'details.removeBody': return ({required Object title}) => 'Are you sure you want to remove "${title}" from the list?';
|
|
||||||
case 'details.removeButton': return 'Remove';
|
|
||||||
case 'details.cancelButton': return 'Cancel';
|
|
||||||
case 'details.watchState': return 'Watch state';
|
|
||||||
case 'details.readState': return 'Read state';
|
|
||||||
case 'details.episodes': return 'Episodes';
|
|
||||||
case 'details.chapters': return 'Chapters';
|
|
||||||
case 'details.volumesOwned': return 'Volumes owned';
|
|
||||||
case 'data.ongoing.anime': return 'Watching';
|
|
||||||
case 'data.ongoing.manga': return 'Reading';
|
|
||||||
case 'data.completed': return 'Completed';
|
|
||||||
case 'data.planned.anime': return 'Plan to watch';
|
|
||||||
case 'data.planned.manga': return 'Plan to read';
|
|
||||||
case 'data.dropped': return 'Dropped';
|
|
||||||
case 'data.paused': return 'Paused';
|
|
||||||
case 'data.all': return 'All';
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -86,7 +86,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
'Provides encoders and decoders for various archive and compression formats such as zip, tar, bzip2, gzip, and zlib.',
|
'Provides encoders and decoders for various archive and compression formats such as zip, tar, bzip2, gzip, and zlib.',
|
||||||
repository: 'https://github.com/brendan-duncan/archive',
|
repository: 'https://github.com/brendan-duncan/archive',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '3.3.6',
|
version: '3.3.7',
|
||||||
license: '''The MIT License
|
license: '''The MIT License
|
||||||
|
|
||||||
Copyright (c) 2013-2021 Brendan Duncan.
|
Copyright (c) 2013-2021 Brendan Duncan.
|
||||||
@@ -111,7 +111,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||||||
THE SOFTWARE.''',
|
THE SOFTWARE.''',
|
||||||
isMarkdown: false,
|
isMarkdown: false,
|
||||||
isSdk: false,
|
isSdk: false,
|
||||||
isDirectDependency: false,
|
isDirectDependency: true,
|
||||||
),
|
),
|
||||||
Package(
|
Package(
|
||||||
name: 'args',
|
name: 'args',
|
||||||
@@ -157,7 +157,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
'Utility functions and classes related to the \'dart:async\' library.',
|
'Utility functions and classes related to the \'dart:async\' library.',
|
||||||
repository: 'https://github.com/dart-lang/async',
|
repository: 'https://github.com/dart-lang/async',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '2.9.0',
|
version: '2.10.0',
|
||||||
license: '''Copyright 2015, the Dart project authors.
|
license: '''Copyright 2015, the Dart project authors.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -226,10 +226,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.''',
|
|||||||
name: 'boolean_selector',
|
name: 'boolean_selector',
|
||||||
description:
|
description:
|
||||||
'A flexible syntax for boolean expressions, based on a simplified version of Dart\'s expression syntax.',
|
'A flexible syntax for boolean expressions, based on a simplified version of Dart\'s expression syntax.',
|
||||||
homepage: 'https://github.com/dart-lang/boolean_selector',
|
repository: 'https://github.com/dart-lang/boolean_selector',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '2.1.0',
|
version: '2.1.1',
|
||||||
license: '''Copyright 2016, the Dart project authors. All rights reserved.
|
license: '''Copyright 2016, the Dart project authors.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
met:
|
met:
|
||||||
@@ -240,7 +241,7 @@ met:
|
|||||||
copyright notice, this list of conditions and the following
|
copyright notice, this list of conditions and the following
|
||||||
disclaimer in the documentation and/or other materials provided
|
disclaimer in the documentation and/or other materials provided
|
||||||
with the distribution.
|
with the distribution.
|
||||||
* Neither the name of Google Inc. nor the names of its
|
* Neither the name of Google LLC nor the names of its
|
||||||
contributors may be used to endorse or promote products derived
|
contributors may be used to endorse or promote products derived
|
||||||
from this software without specific prior written permission.
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
@@ -1062,7 +1063,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
'Collections and utilities functions and classes related to collections.',
|
'Collections and utilities functions and classes related to collections.',
|
||||||
repository: 'https://github.com/dart-lang/collection',
|
repository: 'https://github.com/dart-lang/collection',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '1.16.0',
|
version: '1.17.0',
|
||||||
license: '''Copyright 2015, the Dart project authors.
|
license: '''Copyright 2015, the Dart project authors.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -1092,7 +1093,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
||||||
isMarkdown: false,
|
isMarkdown: false,
|
||||||
isSdk: false,
|
isSdk: false,
|
||||||
isDirectDependency: false,
|
isDirectDependency: true,
|
||||||
),
|
),
|
||||||
Package(
|
Package(
|
||||||
name: 'convert',
|
name: 'convert',
|
||||||
@@ -1170,6 +1171,39 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
isSdk: false,
|
isSdk: false,
|
||||||
isDirectDependency: false,
|
isDirectDependency: false,
|
||||||
),
|
),
|
||||||
|
Package(
|
||||||
|
name: 'csv',
|
||||||
|
description: '''A codec to transform between a string and a list of values.
|
||||||
|
|
||||||
|
The string must be comma (configurable) separated values.''',
|
||||||
|
homepage: 'https://github.com/close2/csv',
|
||||||
|
authors: [],
|
||||||
|
version: '5.0.2',
|
||||||
|
license: '''The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Christian Loitsch
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.''',
|
||||||
|
isMarkdown: false,
|
||||||
|
isSdk: false,
|
||||||
|
isDirectDependency: false,
|
||||||
|
),
|
||||||
Package(
|
Package(
|
||||||
name: 'cupertino_icons',
|
name: 'cupertino_icons',
|
||||||
description:
|
description:
|
||||||
@@ -1561,6 +1595,39 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
isSdk: false,
|
isSdk: false,
|
||||||
isDirectDependency: false,
|
isDirectDependency: false,
|
||||||
),
|
),
|
||||||
|
Package(
|
||||||
|
name: 'file_picker',
|
||||||
|
description:
|
||||||
|
'A package that allows you to use a native file explorer to pick single or multiple absolute file paths, with extension filtering support.',
|
||||||
|
homepage: 'https://github.com/miguelpruivo/plugins_flutter_file_picker',
|
||||||
|
repository: 'https://github.com/miguelpruivo/flutter_file_picker',
|
||||||
|
authors: [],
|
||||||
|
version: '5.2.8',
|
||||||
|
license: '''MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Miguel Ruivo
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.''',
|
||||||
|
isMarkdown: false,
|
||||||
|
isSdk: false,
|
||||||
|
isDirectDependency: true,
|
||||||
|
),
|
||||||
Package(
|
Package(
|
||||||
name: 'fixnum',
|
name: 'fixnum',
|
||||||
description:
|
description:
|
||||||
@@ -1604,7 +1671,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
description: 'A framework for writing Flutter applications',
|
description: 'A framework for writing Flutter applications',
|
||||||
homepage: 'https://flutter.dev',
|
homepage: 'https://flutter.dev',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '3.3.8',
|
version: '3.7.3',
|
||||||
license: '''Copyright 2014 The Flutter Authors. All rights reserved.
|
license: '''Copyright 2014 The Flutter Authors. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -1837,6 +1904,75 @@ SOFTWARE.''',
|
|||||||
isSdk: false,
|
isSdk: false,
|
||||||
isDirectDependency: false,
|
isDirectDependency: false,
|
||||||
),
|
),
|
||||||
|
Package(
|
||||||
|
name: 'flutter_plugin_android_lifecycle',
|
||||||
|
description:
|
||||||
|
'Flutter plugin for accessing an Android Lifecycle within other plugins.',
|
||||||
|
repository:
|
||||||
|
'https://github.com/flutter/packages/tree/main/packages/flutter_plugin_android_lifecycle',
|
||||||
|
authors: [],
|
||||||
|
version: '2.0.9',
|
||||||
|
license: '''Copyright 2013 The Flutter Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials provided
|
||||||
|
with the distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
||||||
|
isMarkdown: false,
|
||||||
|
isSdk: false,
|
||||||
|
isDirectDependency: false,
|
||||||
|
),
|
||||||
|
Package(
|
||||||
|
name: 'fluttertoast',
|
||||||
|
description:
|
||||||
|
'Toast Library for Flutter, Easily create toast messages in single line of code',
|
||||||
|
homepage: 'https://github.com/PonnamKarthik/FlutterToast',
|
||||||
|
authors: [],
|
||||||
|
version: '8.2.2',
|
||||||
|
license: '''MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Karthik Ponnam
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.''',
|
||||||
|
isMarkdown: false,
|
||||||
|
isSdk: false,
|
||||||
|
isDirectDependency: true,
|
||||||
|
),
|
||||||
Package(
|
Package(
|
||||||
name: 'freezed',
|
name: 'freezed',
|
||||||
description:
|
description:
|
||||||
@@ -2273,9 +2409,9 @@ SOFTWARE.''',
|
|||||||
name: 'js',
|
name: 'js',
|
||||||
description:
|
description:
|
||||||
'Annotations to create static Dart interfaces for JavaScript APIs.',
|
'Annotations to create static Dart interfaces for JavaScript APIs.',
|
||||||
homepage: 'https://github.com/dart-lang/sdk/tree/master/pkg/js',
|
repository: 'https://github.com/dart-lang/sdk/tree/main/pkg/js',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '0.6.4',
|
version: '0.6.5',
|
||||||
license: '''Copyright 2012, the Dart project authors.
|
license: '''Copyright 2012, the Dart project authors.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -2307,6 +2443,39 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
isSdk: false,
|
isSdk: false,
|
||||||
isDirectDependency: false,
|
isDirectDependency: false,
|
||||||
),
|
),
|
||||||
|
Package(
|
||||||
|
name: 'json2yaml',
|
||||||
|
description:
|
||||||
|
'''Dart package to render JSON data to YAML with built-in automatic beautifier and
|
||||||
|
support for Dart pubspec.yaml and pubspec.lock conventions''',
|
||||||
|
homepage: 'https://github.com/alexei-sintotski/json2yaml',
|
||||||
|
authors: [],
|
||||||
|
version: '3.0.1',
|
||||||
|
license: '''MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Alexei Sintotski
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.''',
|
||||||
|
isMarkdown: false,
|
||||||
|
isSdk: false,
|
||||||
|
isDirectDependency: false,
|
||||||
|
),
|
||||||
Package(
|
Package(
|
||||||
name: 'json_annotation',
|
name: 'json_annotation',
|
||||||
description:
|
description:
|
||||||
@@ -2466,7 +2635,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
'Support for specifying test expectations via an extensible Matcher class. Also includes a number of built-in Matcher implementations for common cases.',
|
'Support for specifying test expectations via an extensible Matcher class. Also includes a number of built-in Matcher implementations for common cases.',
|
||||||
repository: 'https://github.com/dart-lang/matcher',
|
repository: 'https://github.com/dart-lang/matcher',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '0.12.12',
|
version: '0.12.13',
|
||||||
license: '''Copyright 2014, the Dart project authors.
|
license: '''Copyright 2014, the Dart project authors.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -2501,11 +2670,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
Package(
|
Package(
|
||||||
name: 'material_color_utilities',
|
name: 'material_color_utilities',
|
||||||
description:
|
description:
|
||||||
'Algorithms and utilities that power the Material Design 3 (M3) color system, including choosing theme colors from images and creating tones of colors; all in a new color space.',
|
'Algorithms and utilities that power the Material Design 3 color system, including choosing theme colors from images and creating tones of colors; all in a new color space.',
|
||||||
repository:
|
repository:
|
||||||
'https://github.com/material-foundation/material-color-utilities',
|
'https://github.com/material-foundation/material-color-utilities/tree/main/dart',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '0.1.5',
|
version: '0.2.0',
|
||||||
license: '''Apache License
|
license: '''Apache License
|
||||||
Version 2.0, January 2004
|
Version 2.0, January 2004
|
||||||
http://www.apache.org/licenses/
|
http://www.apache.org/licenses/
|
||||||
@@ -2925,7 +3094,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
||||||
isMarkdown: false,
|
isMarkdown: false,
|
||||||
isSdk: false,
|
isSdk: false,
|
||||||
isDirectDependency: false,
|
isDirectDependency: true,
|
||||||
),
|
),
|
||||||
Package(
|
Package(
|
||||||
name: 'path_provider',
|
name: 'path_provider',
|
||||||
@@ -3181,6 +3350,167 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
isSdk: false,
|
isSdk: false,
|
||||||
isDirectDependency: false,
|
isDirectDependency: false,
|
||||||
),
|
),
|
||||||
|
Package(
|
||||||
|
name: 'permission_handler',
|
||||||
|
description:
|
||||||
|
'Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.',
|
||||||
|
repository: 'https://github.com/baseflow/flutter-permission-handler',
|
||||||
|
authors: [],
|
||||||
|
version: '10.4.3',
|
||||||
|
license: '''MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Baseflow
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.''',
|
||||||
|
isMarkdown: false,
|
||||||
|
isSdk: false,
|
||||||
|
isDirectDependency: true,
|
||||||
|
),
|
||||||
|
Package(
|
||||||
|
name: 'permission_handler_android',
|
||||||
|
description:
|
||||||
|
'Permission plugin for Flutter. This plugin provides the Android API to request and check permissions.',
|
||||||
|
homepage: 'https://github.com/baseflow/flutter-permission-handler',
|
||||||
|
authors: [],
|
||||||
|
version: '10.3.2',
|
||||||
|
license: '''MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Baseflow
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.''',
|
||||||
|
isMarkdown: false,
|
||||||
|
isSdk: false,
|
||||||
|
isDirectDependency: false,
|
||||||
|
),
|
||||||
|
Package(
|
||||||
|
name: 'permission_handler_apple',
|
||||||
|
description:
|
||||||
|
'Permission plugin for Flutter. This plugin provides the iOS API to request and check permissions.',
|
||||||
|
repository: 'https://github.com/baseflow/flutter-permission-handler',
|
||||||
|
authors: [],
|
||||||
|
version: '9.1.4',
|
||||||
|
license: '''MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Baseflow
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.''',
|
||||||
|
isMarkdown: false,
|
||||||
|
isSdk: false,
|
||||||
|
isDirectDependency: false,
|
||||||
|
),
|
||||||
|
Package(
|
||||||
|
name: 'permission_handler_platform_interface',
|
||||||
|
description:
|
||||||
|
'A common platform interface for the permission_handler plugin.',
|
||||||
|
homepage:
|
||||||
|
'https://github.com/baseflow/flutter-permission-handler/tree/master/permission_handler_platform_interface',
|
||||||
|
authors: [],
|
||||||
|
version: '3.11.3',
|
||||||
|
license: '''MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Baseflow
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.''',
|
||||||
|
isMarkdown: false,
|
||||||
|
isSdk: false,
|
||||||
|
isDirectDependency: false,
|
||||||
|
),
|
||||||
|
Package(
|
||||||
|
name: 'permission_handler_windows',
|
||||||
|
description:
|
||||||
|
'Permission plugin for Flutter. This plugin provides the Windows API to request and check permissions.',
|
||||||
|
homepage: 'https://github.com/baseflow/flutter-permission-handler',
|
||||||
|
authors: [],
|
||||||
|
version: '0.1.3',
|
||||||
|
license: '''MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Baseflow
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.''',
|
||||||
|
isMarkdown: false,
|
||||||
|
isSdk: false,
|
||||||
|
isDirectDependency: false,
|
||||||
|
),
|
||||||
Package(
|
Package(
|
||||||
name: 'petitparser',
|
name: 'petitparser',
|
||||||
description:
|
description:
|
||||||
@@ -3604,6 +3934,102 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
isSdk: false,
|
isSdk: false,
|
||||||
isDirectDependency: false,
|
isDirectDependency: false,
|
||||||
),
|
),
|
||||||
|
Package(
|
||||||
|
name: 'slang',
|
||||||
|
description:
|
||||||
|
'Localization / Internationalization (i18n) solution. Use JSON, YAML or CSV files to create typesafe translations via source generation.',
|
||||||
|
repository: 'https://github.com/Tienisto/slang',
|
||||||
|
authors: [],
|
||||||
|
version: '3.19.0',
|
||||||
|
license: '''MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020-2023 Tien Do Nam
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.''',
|
||||||
|
isMarkdown: false,
|
||||||
|
isSdk: false,
|
||||||
|
isDirectDependency: true,
|
||||||
|
),
|
||||||
|
Package(
|
||||||
|
name: 'slang_build_runner',
|
||||||
|
description:
|
||||||
|
'build_runner integration for slang. This library ensures that slang is recognized by build_runner.',
|
||||||
|
repository: 'https://github.com/Tienisto/slang',
|
||||||
|
authors: [],
|
||||||
|
version: '3.19.0',
|
||||||
|
license: '''MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020-2023 Tien Do Nam
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.''',
|
||||||
|
isMarkdown: false,
|
||||||
|
isSdk: false,
|
||||||
|
isDirectDependency: false,
|
||||||
|
),
|
||||||
|
Package(
|
||||||
|
name: 'slang_flutter',
|
||||||
|
description:
|
||||||
|
'Flutter support for slang. This library provides helpful Flutter API.',
|
||||||
|
repository: 'https://github.com/Tienisto/slang',
|
||||||
|
authors: [],
|
||||||
|
version: '3.19.0',
|
||||||
|
license: '''MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020-2023 Tien Do Nam
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.''',
|
||||||
|
isMarkdown: false,
|
||||||
|
isSdk: false,
|
||||||
|
isDirectDependency: true,
|
||||||
|
),
|
||||||
Package(
|
Package(
|
||||||
name: 'source_gen',
|
name: 'source_gen',
|
||||||
description:
|
description:
|
||||||
@@ -3858,9 +4284,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
Package(
|
Package(
|
||||||
name: 'source_span',
|
name: 'source_span',
|
||||||
description: 'A library for identifying source spans and locations.',
|
description: 'A library for identifying source spans and locations.',
|
||||||
homepage: 'https://github.com/dart-lang/source_span',
|
repository: 'https://github.com/dart-lang/source_span',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '1.9.0',
|
version: '1.9.1',
|
||||||
license: '''Copyright 2014, the Dart project authors.
|
license: '''Copyright 2014, the Dart project authors.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -3968,10 +4394,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
name: 'stack_trace',
|
name: 'stack_trace',
|
||||||
description:
|
description:
|
||||||
'A package for manipulating stack traces and printing them readably.',
|
'A package for manipulating stack traces and printing them readably.',
|
||||||
homepage: 'https://github.com/dart-lang/stack_trace',
|
repository: 'https://github.com/dart-lang/stack_trace',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '1.10.0',
|
version: '1.11.0',
|
||||||
license: '''Copyright 2014, the Dart project authors. All rights reserved.
|
license: '''Copyright 2014, the Dart project authors.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
met:
|
met:
|
||||||
@@ -3982,7 +4409,7 @@ met:
|
|||||||
copyright notice, this list of conditions and the following
|
copyright notice, this list of conditions and the following
|
||||||
disclaimer in the documentation and/or other materials provided
|
disclaimer in the documentation and/or other materials provided
|
||||||
with the distribution.
|
with the distribution.
|
||||||
* Neither the name of Google Inc. nor the names of its
|
* Neither the name of Google LLC nor the names of its
|
||||||
contributors may be used to endorse or promote products derived
|
contributors may be used to endorse or promote products derived
|
||||||
from this software without specific prior written permission.
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
@@ -4005,10 +4432,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
name: 'stream_channel',
|
name: 'stream_channel',
|
||||||
description:
|
description:
|
||||||
'An abstraction for two-way communication channels based on the Dart Stream class.',
|
'An abstraction for two-way communication channels based on the Dart Stream class.',
|
||||||
homepage: 'https://github.com/dart-lang/stream_channel',
|
repository: 'https://github.com/dart-lang/stream_channel',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '2.1.0',
|
version: '2.1.1',
|
||||||
license: '''Copyright 2015, the Dart project authors. All rights reserved.
|
license: '''Copyright 2015, the Dart project authors.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
met:
|
met:
|
||||||
@@ -4019,7 +4447,7 @@ met:
|
|||||||
copyright notice, this list of conditions and the following
|
copyright notice, this list of conditions and the following
|
||||||
disclaimer in the documentation and/or other materials provided
|
disclaimer in the documentation and/or other materials provided
|
||||||
with the distribution.
|
with the distribution.
|
||||||
* Neither the name of Google Inc. nor the names of its
|
* Neither the name of Google LLC nor the names of its
|
||||||
contributors may be used to endorse or promote products derived
|
contributors may be used to endorse or promote products derived
|
||||||
from this software without specific prior written permission.
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
@@ -4081,7 +4509,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
description: 'A class for parsing strings using a sequence of patterns.',
|
description: 'A class for parsing strings using a sequence of patterns.',
|
||||||
repository: 'https://github.com/dart-lang/string_scanner',
|
repository: 'https://github.com/dart-lang/string_scanner',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '1.1.1',
|
version: '1.2.0',
|
||||||
license: '''Copyright 2014, the Dart project authors.
|
license: '''Copyright 2014, the Dart project authors.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -4225,10 +4653,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
),
|
),
|
||||||
Package(
|
Package(
|
||||||
name: 'test_api',
|
name: 'test_api',
|
||||||
description: 'A library for writing Dart tests.',
|
description:
|
||||||
|
'The user facing API for structuring Dart tests and checking expectations.',
|
||||||
repository: 'https://github.com/dart-lang/test/tree/master/pkgs/test_api',
|
repository: 'https://github.com/dart-lang/test/tree/master/pkgs/test_api',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '0.4.12',
|
version: '0.4.16',
|
||||||
license: '''Copyright 2018, the Dart project authors.
|
license: '''Copyright 2018, the Dart project authors.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -4855,7 +5284,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||||||
description: 'A Vector Math library for 2D and 3D applications.',
|
description: 'A Vector Math library for 2D and 3D applications.',
|
||||||
repository: 'https://github.com/google/vector_math.dart',
|
repository: 'https://github.com/google/vector_math.dart',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '2.1.2',
|
version: '2.1.4',
|
||||||
license: '''Copyright 2015, Google Inc. All rights reserved.
|
license: '''Copyright 2015, Google Inc. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -5096,7 +5525,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.''',
|
|||||||
'A lightweight library for parsing, traversing, querying, transforming and building XML documents.',
|
'A lightweight library for parsing, traversing, querying, transforming and building XML documents.',
|
||||||
homepage: 'https://github.com/renggli/dart-xml',
|
homepage: 'https://github.com/renggli/dart-xml',
|
||||||
authors: [],
|
authors: [],
|
||||||
version: '6.1.0',
|
version: '6.2.2',
|
||||||
license: '''The MIT License
|
license: '''The MIT License
|
||||||
|
|
||||||
Copyright (c) 2006-2022 Lukas Renggli.
|
Copyright (c) 2006-2022 Lukas Renggli.
|
||||||
@@ -5121,7 +5550,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||||||
THE SOFTWARE.''',
|
THE SOFTWARE.''',
|
||||||
isMarkdown: false,
|
isMarkdown: false,
|
||||||
isSdk: false,
|
isSdk: false,
|
||||||
isDirectDependency: false,
|
isDirectDependency: true,
|
||||||
),
|
),
|
||||||
Package(
|
Package(
|
||||||
name: 'yaml',
|
name: 'yaml',
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:anitrack/i18n/strings.g.dart';
|
|||||||
import 'package:anitrack/src/service/database.dart';
|
import 'package:anitrack/src/service/database.dart';
|
||||||
import 'package:anitrack/src/ui/bloc/anime_list_bloc.dart';
|
import 'package:anitrack/src/ui/bloc/anime_list_bloc.dart';
|
||||||
import 'package:anitrack/src/ui/bloc/anime_search_bloc.dart';
|
import 'package:anitrack/src/ui/bloc/anime_search_bloc.dart';
|
||||||
|
import 'package:anitrack/src/ui/bloc/calendar_bloc.dart';
|
||||||
import 'package:anitrack/src/ui/bloc/details_bloc.dart';
|
import 'package:anitrack/src/ui/bloc/details_bloc.dart';
|
||||||
import 'package:anitrack/src/ui/bloc/navigation_bloc.dart';
|
import 'package:anitrack/src/ui/bloc/navigation_bloc.dart';
|
||||||
import 'package:anitrack/src/ui/bloc/settings_bloc.dart';
|
import 'package:anitrack/src/ui/bloc/settings_bloc.dart';
|
||||||
@@ -9,6 +10,7 @@ import 'package:anitrack/src/ui/constants.dart';
|
|||||||
import 'package:anitrack/src/ui/pages/about.dart';
|
import 'package:anitrack/src/ui/pages/about.dart';
|
||||||
import 'package:anitrack/src/ui/pages/anime_list.dart';
|
import 'package:anitrack/src/ui/pages/anime_list.dart';
|
||||||
import 'package:anitrack/src/ui/pages/anime_search.dart';
|
import 'package:anitrack/src/ui/pages/anime_search.dart';
|
||||||
|
import 'package:anitrack/src/ui/pages/calendar.dart';
|
||||||
import 'package:anitrack/src/ui/pages/details.dart';
|
import 'package:anitrack/src/ui/pages/details.dart';
|
||||||
import 'package:anitrack/src/ui/pages/settings.dart';
|
import 'package:anitrack/src/ui/pages/settings.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -32,6 +34,7 @@ void main() async {
|
|||||||
GetIt.I.registerSingleton<DetailsBloc>(DetailsBloc());
|
GetIt.I.registerSingleton<DetailsBloc>(DetailsBloc());
|
||||||
GetIt.I.registerSingleton<NavigationBloc>(NavigationBloc(navKey));
|
GetIt.I.registerSingleton<NavigationBloc>(NavigationBloc(navKey));
|
||||||
GetIt.I.registerSingleton<SettingsBloc>(SettingsBloc());
|
GetIt.I.registerSingleton<SettingsBloc>(SettingsBloc());
|
||||||
|
GetIt.I.registerSingleton<CalendarBloc>(CalendarBloc());
|
||||||
|
|
||||||
// Load animes
|
// Load animes
|
||||||
GetIt.I.get<AnimeListBloc>().add(
|
GetIt.I.get<AnimeListBloc>().add(
|
||||||
@@ -59,6 +62,9 @@ void main() async {
|
|||||||
BlocProvider<SettingsBloc>(
|
BlocProvider<SettingsBloc>(
|
||||||
create: (_) => GetIt.I.get<SettingsBloc>(),
|
create: (_) => GetIt.I.get<SettingsBloc>(),
|
||||||
),
|
),
|
||||||
|
BlocProvider<CalendarBloc>(
|
||||||
|
create: (_) => GetIt.I.get<CalendarBloc>(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
child: MyApp(navKey),
|
child: MyApp(navKey),
|
||||||
),
|
),
|
||||||
@@ -95,6 +101,8 @@ class MyApp extends StatelessWidget {
|
|||||||
return AnimeListPage.route;
|
return AnimeListPage.route;
|
||||||
case animeSearchRoute:
|
case animeSearchRoute:
|
||||||
return AnimeSearchPage.route;
|
return AnimeSearchPage.route;
|
||||||
|
case calendarRoute:
|
||||||
|
return CalendarPage.route;
|
||||||
case detailsRoute:
|
case detailsRoute:
|
||||||
return DetailsPage.route;
|
return DetailsPage.route;
|
||||||
case aboutRoute:
|
case aboutRoute:
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
import 'package:anitrack/src/data/type.dart';
|
import 'package:anitrack/src/data/type.dart';
|
||||||
|
import 'package:anitrack/src/service/database.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
part 'anime.freezed.dart';
|
part 'anime.freezed.dart';
|
||||||
part 'anime.g.dart';
|
part 'anime.g.dart';
|
||||||
|
|
||||||
|
class BoolConverter implements JsonConverter<bool, int> {
|
||||||
|
const BoolConverter();
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool fromJson(int json) => json.toBool();
|
||||||
|
|
||||||
|
@override
|
||||||
|
int toJson(bool object) => object.toInt();
|
||||||
|
}
|
||||||
|
|
||||||
/// Data about a tracked anime
|
/// Data about a tracked anime
|
||||||
@freezed
|
@freezed
|
||||||
class AnimeTrackingData with _$AnimeTrackingData, TrackingMedium {
|
class AnimeTrackingData with _$AnimeTrackingData, TrackingMedium {
|
||||||
@@ -25,6 +36,12 @@ class AnimeTrackingData with _$AnimeTrackingData, TrackingMedium {
|
|||||||
|
|
||||||
/// URL to the thumbnail/cover art for the anime.
|
/// URL to the thumbnail/cover art for the anime.
|
||||||
String thumbnailUrl,
|
String thumbnailUrl,
|
||||||
|
|
||||||
|
/// Flag whether the anime is airing
|
||||||
|
@BoolConverter() bool airing,
|
||||||
|
|
||||||
|
/// The day of the week the anime is airing
|
||||||
|
String? broadcastDay,
|
||||||
) = _AnimeTrackingData;
|
) = _AnimeTrackingData;
|
||||||
|
|
||||||
/// JSON
|
/// JSON
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
part of 'anime.dart';
|
part of 'anime.dart';
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ part of 'anime.dart';
|
|||||||
T _$identity<T>(T value) => value;
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
final _privateConstructorUsedError = UnsupportedError(
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
AnimeTrackingData _$AnimeTrackingDataFromJson(Map<String, dynamic> json) {
|
AnimeTrackingData _$AnimeTrackingDataFromJson(Map<String, dynamic> json) {
|
||||||
return _AnimeTrackingData.fromJson(json);
|
return _AnimeTrackingData.fromJson(json);
|
||||||
@@ -39,8 +39,19 @@ mixin _$AnimeTrackingData {
|
|||||||
/// URL to the thumbnail/cover art for the anime.
|
/// URL to the thumbnail/cover art for the anime.
|
||||||
String get thumbnailUrl => throw _privateConstructorUsedError;
|
String get thumbnailUrl => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Flag whether the anime is airing
|
||||||
|
@BoolConverter()
|
||||||
|
bool get airing => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// The day of the week the anime is airing
|
||||||
|
String? get broadcastDay => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this AnimeTrackingData to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of AnimeTrackingData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$AnimeTrackingDataCopyWith<AnimeTrackingData> get copyWith =>
|
$AnimeTrackingDataCopyWith<AnimeTrackingData> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -49,136 +60,173 @@ mixin _$AnimeTrackingData {
|
|||||||
abstract class $AnimeTrackingDataCopyWith<$Res> {
|
abstract class $AnimeTrackingDataCopyWith<$Res> {
|
||||||
factory $AnimeTrackingDataCopyWith(
|
factory $AnimeTrackingDataCopyWith(
|
||||||
AnimeTrackingData value, $Res Function(AnimeTrackingData) then) =
|
AnimeTrackingData value, $Res Function(AnimeTrackingData) then) =
|
||||||
_$AnimeTrackingDataCopyWithImpl<$Res>;
|
_$AnimeTrackingDataCopyWithImpl<$Res, AnimeTrackingData>;
|
||||||
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{String id,
|
{String id,
|
||||||
@MediumTrackingStateConverter() MediumTrackingState state,
|
@MediumTrackingStateConverter() MediumTrackingState state,
|
||||||
String title,
|
String title,
|
||||||
int episodesWatched,
|
int episodesWatched,
|
||||||
int? episodesTotal,
|
int? episodesTotal,
|
||||||
String thumbnailUrl});
|
String thumbnailUrl,
|
||||||
|
@BoolConverter() bool airing,
|
||||||
|
String? broadcastDay});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$AnimeTrackingDataCopyWithImpl<$Res>
|
class _$AnimeTrackingDataCopyWithImpl<$Res, $Val extends AnimeTrackingData>
|
||||||
implements $AnimeTrackingDataCopyWith<$Res> {
|
implements $AnimeTrackingDataCopyWith<$Res> {
|
||||||
_$AnimeTrackingDataCopyWithImpl(this._value, this._then);
|
_$AnimeTrackingDataCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
final AnimeTrackingData _value;
|
|
||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function(AnimeTrackingData) _then;
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of AnimeTrackingData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? id = freezed,
|
Object? id = null,
|
||||||
Object? state = freezed,
|
Object? state = null,
|
||||||
Object? title = freezed,
|
Object? title = null,
|
||||||
Object? episodesWatched = freezed,
|
Object? episodesWatched = null,
|
||||||
Object? episodesTotal = freezed,
|
Object? episodesTotal = freezed,
|
||||||
Object? thumbnailUrl = freezed,
|
Object? thumbnailUrl = null,
|
||||||
|
Object? airing = null,
|
||||||
|
Object? broadcastDay = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
id: id == freezed
|
id: null == id
|
||||||
? _value.id
|
? _value.id
|
||||||
: id // ignore: cast_nullable_to_non_nullable
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
state: state == freezed
|
state: null == state
|
||||||
? _value.state
|
? _value.state
|
||||||
: state // ignore: cast_nullable_to_non_nullable
|
: state // ignore: cast_nullable_to_non_nullable
|
||||||
as MediumTrackingState,
|
as MediumTrackingState,
|
||||||
title: title == freezed
|
title: null == title
|
||||||
? _value.title
|
? _value.title
|
||||||
: title // ignore: cast_nullable_to_non_nullable
|
: title // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
episodesWatched: episodesWatched == freezed
|
episodesWatched: null == episodesWatched
|
||||||
? _value.episodesWatched
|
? _value.episodesWatched
|
||||||
: episodesWatched // ignore: cast_nullable_to_non_nullable
|
: episodesWatched // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
episodesTotal: episodesTotal == freezed
|
episodesTotal: freezed == episodesTotal
|
||||||
? _value.episodesTotal
|
? _value.episodesTotal
|
||||||
: episodesTotal // ignore: cast_nullable_to_non_nullable
|
: episodesTotal // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
thumbnailUrl: thumbnailUrl == freezed
|
thumbnailUrl: null == thumbnailUrl
|
||||||
? _value.thumbnailUrl
|
? _value.thumbnailUrl
|
||||||
: thumbnailUrl // ignore: cast_nullable_to_non_nullable
|
: thumbnailUrl // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
));
|
airing: null == airing
|
||||||
|
? _value.airing
|
||||||
|
: airing // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
broadcastDay: freezed == broadcastDay
|
||||||
|
? _value.broadcastDay
|
||||||
|
: broadcastDay // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class _$$_AnimeTrackingDataCopyWith<$Res>
|
abstract class _$$AnimeTrackingDataImplCopyWith<$Res>
|
||||||
implements $AnimeTrackingDataCopyWith<$Res> {
|
implements $AnimeTrackingDataCopyWith<$Res> {
|
||||||
factory _$$_AnimeTrackingDataCopyWith(_$_AnimeTrackingData value,
|
factory _$$AnimeTrackingDataImplCopyWith(_$AnimeTrackingDataImpl value,
|
||||||
$Res Function(_$_AnimeTrackingData) then) =
|
$Res Function(_$AnimeTrackingDataImpl) then) =
|
||||||
__$$_AnimeTrackingDataCopyWithImpl<$Res>;
|
__$$AnimeTrackingDataImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{String id,
|
{String id,
|
||||||
@MediumTrackingStateConverter() MediumTrackingState state,
|
@MediumTrackingStateConverter() MediumTrackingState state,
|
||||||
String title,
|
String title,
|
||||||
int episodesWatched,
|
int episodesWatched,
|
||||||
int? episodesTotal,
|
int? episodesTotal,
|
||||||
String thumbnailUrl});
|
String thumbnailUrl,
|
||||||
|
@BoolConverter() bool airing,
|
||||||
|
String? broadcastDay});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class __$$_AnimeTrackingDataCopyWithImpl<$Res>
|
class __$$AnimeTrackingDataImplCopyWithImpl<$Res>
|
||||||
extends _$AnimeTrackingDataCopyWithImpl<$Res>
|
extends _$AnimeTrackingDataCopyWithImpl<$Res, _$AnimeTrackingDataImpl>
|
||||||
implements _$$_AnimeTrackingDataCopyWith<$Res> {
|
implements _$$AnimeTrackingDataImplCopyWith<$Res> {
|
||||||
__$$_AnimeTrackingDataCopyWithImpl(
|
__$$AnimeTrackingDataImplCopyWithImpl(_$AnimeTrackingDataImpl _value,
|
||||||
_$_AnimeTrackingData _value, $Res Function(_$_AnimeTrackingData) _then)
|
$Res Function(_$AnimeTrackingDataImpl) _then)
|
||||||
: super(_value, (v) => _then(v as _$_AnimeTrackingData));
|
: super(_value, _then);
|
||||||
|
|
||||||
@override
|
|
||||||
_$_AnimeTrackingData get _value => super._value as _$_AnimeTrackingData;
|
|
||||||
|
|
||||||
|
/// Create a copy of AnimeTrackingData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? id = freezed,
|
Object? id = null,
|
||||||
Object? state = freezed,
|
Object? state = null,
|
||||||
Object? title = freezed,
|
Object? title = null,
|
||||||
Object? episodesWatched = freezed,
|
Object? episodesWatched = null,
|
||||||
Object? episodesTotal = freezed,
|
Object? episodesTotal = freezed,
|
||||||
Object? thumbnailUrl = freezed,
|
Object? thumbnailUrl = null,
|
||||||
|
Object? airing = null,
|
||||||
|
Object? broadcastDay = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$_AnimeTrackingData(
|
return _then(_$AnimeTrackingDataImpl(
|
||||||
id == freezed
|
null == id
|
||||||
? _value.id
|
? _value.id
|
||||||
: id // ignore: cast_nullable_to_non_nullable
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
state == freezed
|
null == state
|
||||||
? _value.state
|
? _value.state
|
||||||
: state // ignore: cast_nullable_to_non_nullable
|
: state // ignore: cast_nullable_to_non_nullable
|
||||||
as MediumTrackingState,
|
as MediumTrackingState,
|
||||||
title == freezed
|
null == title
|
||||||
? _value.title
|
? _value.title
|
||||||
: title // ignore: cast_nullable_to_non_nullable
|
: title // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
episodesWatched == freezed
|
null == episodesWatched
|
||||||
? _value.episodesWatched
|
? _value.episodesWatched
|
||||||
: episodesWatched // ignore: cast_nullable_to_non_nullable
|
: episodesWatched // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
episodesTotal == freezed
|
freezed == episodesTotal
|
||||||
? _value.episodesTotal
|
? _value.episodesTotal
|
||||||
: episodesTotal // ignore: cast_nullable_to_non_nullable
|
: episodesTotal // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
thumbnailUrl == freezed
|
null == thumbnailUrl
|
||||||
? _value.thumbnailUrl
|
? _value.thumbnailUrl
|
||||||
: thumbnailUrl // ignore: cast_nullable_to_non_nullable
|
: thumbnailUrl // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
|
null == airing
|
||||||
|
? _value.airing
|
||||||
|
: airing // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
freezed == broadcastDay
|
||||||
|
? _value.broadcastDay
|
||||||
|
: broadcastDay // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$_AnimeTrackingData implements _AnimeTrackingData {
|
class _$AnimeTrackingDataImpl implements _AnimeTrackingData {
|
||||||
_$_AnimeTrackingData(this.id, @MediumTrackingStateConverter() this.state,
|
_$AnimeTrackingDataImpl(
|
||||||
this.title, this.episodesWatched, this.episodesTotal, this.thumbnailUrl);
|
this.id,
|
||||||
|
@MediumTrackingStateConverter() this.state,
|
||||||
|
this.title,
|
||||||
|
this.episodesWatched,
|
||||||
|
this.episodesTotal,
|
||||||
|
this.thumbnailUrl,
|
||||||
|
@BoolConverter() this.airing,
|
||||||
|
this.broadcastDay);
|
||||||
|
|
||||||
factory _$_AnimeTrackingData.fromJson(Map<String, dynamic> json) =>
|
factory _$AnimeTrackingDataImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$_AnimeTrackingDataFromJson(json);
|
_$$AnimeTrackingDataImplFromJson(json);
|
||||||
|
|
||||||
/// The ID of the anime
|
/// The ID of the anime
|
||||||
@override
|
@override
|
||||||
@@ -205,47 +253,56 @@ class _$_AnimeTrackingData implements _AnimeTrackingData {
|
|||||||
@override
|
@override
|
||||||
final String thumbnailUrl;
|
final String thumbnailUrl;
|
||||||
|
|
||||||
|
/// Flag whether the anime is airing
|
||||||
|
@override
|
||||||
|
@BoolConverter()
|
||||||
|
final bool airing;
|
||||||
|
|
||||||
|
/// The day of the week the anime is airing
|
||||||
|
@override
|
||||||
|
final String? broadcastDay;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AnimeTrackingData(id: $id, state: $state, title: $title, episodesWatched: $episodesWatched, episodesTotal: $episodesTotal, thumbnailUrl: $thumbnailUrl)';
|
return 'AnimeTrackingData(id: $id, state: $state, title: $title, episodesWatched: $episodesWatched, episodesTotal: $episodesTotal, thumbnailUrl: $thumbnailUrl, airing: $airing, broadcastDay: $broadcastDay)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(dynamic other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _$_AnimeTrackingData &&
|
other is _$AnimeTrackingDataImpl &&
|
||||||
const DeepCollectionEquality().equals(other.id, id) &&
|
(identical(other.id, id) || other.id == id) &&
|
||||||
const DeepCollectionEquality().equals(other.state, state) &&
|
(identical(other.state, state) || other.state == state) &&
|
||||||
const DeepCollectionEquality().equals(other.title, title) &&
|
(identical(other.title, title) || other.title == title) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.episodesWatched, episodesWatched) ||
|
||||||
.equals(other.episodesWatched, episodesWatched) &&
|
other.episodesWatched == episodesWatched) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.episodesTotal, episodesTotal) ||
|
||||||
.equals(other.episodesTotal, episodesTotal) &&
|
other.episodesTotal == episodesTotal) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.thumbnailUrl, thumbnailUrl) ||
|
||||||
.equals(other.thumbnailUrl, thumbnailUrl));
|
other.thumbnailUrl == thumbnailUrl) &&
|
||||||
|
(identical(other.airing, airing) || other.airing == airing) &&
|
||||||
|
(identical(other.broadcastDay, broadcastDay) ||
|
||||||
|
other.broadcastDay == broadcastDay));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(runtimeType, id, state, title,
|
||||||
runtimeType,
|
episodesWatched, episodesTotal, thumbnailUrl, airing, broadcastDay);
|
||||||
const DeepCollectionEquality().hash(id),
|
|
||||||
const DeepCollectionEquality().hash(state),
|
|
||||||
const DeepCollectionEquality().hash(title),
|
|
||||||
const DeepCollectionEquality().hash(episodesWatched),
|
|
||||||
const DeepCollectionEquality().hash(episodesTotal),
|
|
||||||
const DeepCollectionEquality().hash(thumbnailUrl));
|
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of AnimeTrackingData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
_$$_AnimeTrackingDataCopyWith<_$_AnimeTrackingData> get copyWith =>
|
@pragma('vm:prefer-inline')
|
||||||
__$$_AnimeTrackingDataCopyWithImpl<_$_AnimeTrackingData>(
|
_$$AnimeTrackingDataImplCopyWith<_$AnimeTrackingDataImpl> get copyWith =>
|
||||||
|
__$$AnimeTrackingDataImplCopyWithImpl<_$AnimeTrackingDataImpl>(
|
||||||
this, _$identity);
|
this, _$identity);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return _$$_AnimeTrackingDataToJson(
|
return _$$AnimeTrackingDataImplToJson(
|
||||||
this,
|
this,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -258,38 +315,51 @@ abstract class _AnimeTrackingData implements AnimeTrackingData {
|
|||||||
final String title,
|
final String title,
|
||||||
final int episodesWatched,
|
final int episodesWatched,
|
||||||
final int? episodesTotal,
|
final int? episodesTotal,
|
||||||
final String thumbnailUrl) = _$_AnimeTrackingData;
|
final String thumbnailUrl,
|
||||||
|
@BoolConverter() final bool airing,
|
||||||
|
final String? broadcastDay) = _$AnimeTrackingDataImpl;
|
||||||
|
|
||||||
factory _AnimeTrackingData.fromJson(Map<String, dynamic> json) =
|
factory _AnimeTrackingData.fromJson(Map<String, dynamic> json) =
|
||||||
_$_AnimeTrackingData.fromJson;
|
_$AnimeTrackingDataImpl.fromJson;
|
||||||
|
|
||||||
@override
|
|
||||||
|
|
||||||
/// The ID of the anime
|
/// The ID of the anime
|
||||||
String get id;
|
|
||||||
@override
|
@override
|
||||||
|
String get id;
|
||||||
|
|
||||||
/// The state of the anime
|
/// The state of the anime
|
||||||
|
@override
|
||||||
@MediumTrackingStateConverter()
|
@MediumTrackingStateConverter()
|
||||||
MediumTrackingState get state;
|
MediumTrackingState get state;
|
||||||
@override
|
|
||||||
|
|
||||||
/// The title of the anime
|
/// The title of the anime
|
||||||
String get title;
|
|
||||||
@override
|
@override
|
||||||
|
String get title;
|
||||||
|
|
||||||
/// Episodes in total.
|
/// Episodes in total.
|
||||||
int get episodesWatched;
|
|
||||||
@override
|
@override
|
||||||
|
int get episodesWatched;
|
||||||
|
|
||||||
/// Episodes watched.
|
/// Episodes watched.
|
||||||
int? get episodesTotal;
|
|
||||||
@override
|
@override
|
||||||
|
int? get episodesTotal;
|
||||||
|
|
||||||
/// URL to the thumbnail/cover art for the anime.
|
/// URL to the thumbnail/cover art for the anime.
|
||||||
String get thumbnailUrl;
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
String get thumbnailUrl;
|
||||||
_$$_AnimeTrackingDataCopyWith<_$_AnimeTrackingData> get copyWith =>
|
|
||||||
|
/// Flag whether the anime is airing
|
||||||
|
@override
|
||||||
|
@BoolConverter()
|
||||||
|
bool get airing;
|
||||||
|
|
||||||
|
/// The day of the week the anime is airing
|
||||||
|
@override
|
||||||
|
String? get broadcastDay;
|
||||||
|
|
||||||
|
/// Create a copy of AnimeTrackingData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$AnimeTrackingDataImplCopyWith<_$AnimeTrackingDataImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,18 +6,22 @@ part of 'anime.dart';
|
|||||||
// JsonSerializableGenerator
|
// JsonSerializableGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
_$_AnimeTrackingData _$$_AnimeTrackingDataFromJson(Map<String, dynamic> json) =>
|
_$AnimeTrackingDataImpl _$$AnimeTrackingDataImplFromJson(
|
||||||
_$_AnimeTrackingData(
|
Map<String, dynamic> json) =>
|
||||||
|
_$AnimeTrackingDataImpl(
|
||||||
json['id'] as String,
|
json['id'] as String,
|
||||||
const MediumTrackingStateConverter().fromJson(json['state'] as int),
|
const MediumTrackingStateConverter()
|
||||||
|
.fromJson((json['state'] as num).toInt()),
|
||||||
json['title'] as String,
|
json['title'] as String,
|
||||||
json['episodesWatched'] as int,
|
(json['episodesWatched'] as num).toInt(),
|
||||||
json['episodesTotal'] as int?,
|
(json['episodesTotal'] as num?)?.toInt(),
|
||||||
json['thumbnailUrl'] as String,
|
json['thumbnailUrl'] as String,
|
||||||
|
const BoolConverter().fromJson((json['airing'] as num).toInt()),
|
||||||
|
json['broadcastDay'] as String?,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$_AnimeTrackingDataToJson(
|
Map<String, dynamic> _$$AnimeTrackingDataImplToJson(
|
||||||
_$_AnimeTrackingData instance) =>
|
_$AnimeTrackingDataImpl instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'id': instance.id,
|
'id': instance.id,
|
||||||
'state': const MediumTrackingStateConverter().toJson(instance.state),
|
'state': const MediumTrackingStateConverter().toJson(instance.state),
|
||||||
@@ -25,4 +29,6 @@ Map<String, dynamic> _$$_AnimeTrackingDataToJson(
|
|||||||
'episodesWatched': instance.episodesWatched,
|
'episodesWatched': instance.episodesWatched,
|
||||||
'episodesTotal': instance.episodesTotal,
|
'episodesTotal': instance.episodesTotal,
|
||||||
'thumbnailUrl': instance.thumbnailUrl,
|
'thumbnailUrl': instance.thumbnailUrl,
|
||||||
|
'airing': const BoolConverter().toJson(instance.airing),
|
||||||
|
'broadcastDay': instance.broadcastDay,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
part of 'manga.dart';
|
part of 'manga.dart';
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ part of 'manga.dart';
|
|||||||
T _$identity<T>(T value) => value;
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
final _privateConstructorUsedError = UnsupportedError(
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
MangaTrackingData _$MangaTrackingDataFromJson(Map<String, dynamic> json) {
|
MangaTrackingData _$MangaTrackingDataFromJson(Map<String, dynamic> json) {
|
||||||
return _MangaTrackingData.fromJson(json);
|
return _MangaTrackingData.fromJson(json);
|
||||||
@@ -42,8 +42,12 @@ mixin _$MangaTrackingData {
|
|||||||
/// URL to the thumbnail/cover art for the manga.
|
/// URL to the thumbnail/cover art for the manga.
|
||||||
String get thumbnailUrl => throw _privateConstructorUsedError;
|
String get thumbnailUrl => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Serializes this MangaTrackingData to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
|
||||||
|
/// Create a copy of MangaTrackingData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$MangaTrackingDataCopyWith<MangaTrackingData> get copyWith =>
|
$MangaTrackingDataCopyWith<MangaTrackingData> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -52,7 +56,8 @@ mixin _$MangaTrackingData {
|
|||||||
abstract class $MangaTrackingDataCopyWith<$Res> {
|
abstract class $MangaTrackingDataCopyWith<$Res> {
|
||||||
factory $MangaTrackingDataCopyWith(
|
factory $MangaTrackingDataCopyWith(
|
||||||
MangaTrackingData value, $Res Function(MangaTrackingData) then) =
|
MangaTrackingData value, $Res Function(MangaTrackingData) then) =
|
||||||
_$MangaTrackingDataCopyWithImpl<$Res>;
|
_$MangaTrackingDataCopyWithImpl<$Res, MangaTrackingData>;
|
||||||
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{String id,
|
{String id,
|
||||||
@MediumTrackingStateConverter() MediumTrackingState state,
|
@MediumTrackingStateConverter() MediumTrackingState state,
|
||||||
@@ -64,64 +69,69 @@ abstract class $MangaTrackingDataCopyWith<$Res> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$MangaTrackingDataCopyWithImpl<$Res>
|
class _$MangaTrackingDataCopyWithImpl<$Res, $Val extends MangaTrackingData>
|
||||||
implements $MangaTrackingDataCopyWith<$Res> {
|
implements $MangaTrackingDataCopyWith<$Res> {
|
||||||
_$MangaTrackingDataCopyWithImpl(this._value, this._then);
|
_$MangaTrackingDataCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
final MangaTrackingData _value;
|
|
||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function(MangaTrackingData) _then;
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of MangaTrackingData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? id = freezed,
|
Object? id = null,
|
||||||
Object? state = freezed,
|
Object? state = null,
|
||||||
Object? title = freezed,
|
Object? title = null,
|
||||||
Object? chaptersRead = freezed,
|
Object? chaptersRead = null,
|
||||||
Object? volumesOwned = freezed,
|
Object? volumesOwned = null,
|
||||||
Object? chaptersTotal = freezed,
|
Object? chaptersTotal = freezed,
|
||||||
Object? thumbnailUrl = freezed,
|
Object? thumbnailUrl = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
id: id == freezed
|
id: null == id
|
||||||
? _value.id
|
? _value.id
|
||||||
: id // ignore: cast_nullable_to_non_nullable
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
state: state == freezed
|
state: null == state
|
||||||
? _value.state
|
? _value.state
|
||||||
: state // ignore: cast_nullable_to_non_nullable
|
: state // ignore: cast_nullable_to_non_nullable
|
||||||
as MediumTrackingState,
|
as MediumTrackingState,
|
||||||
title: title == freezed
|
title: null == title
|
||||||
? _value.title
|
? _value.title
|
||||||
: title // ignore: cast_nullable_to_non_nullable
|
: title // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
chaptersRead: chaptersRead == freezed
|
chaptersRead: null == chaptersRead
|
||||||
? _value.chaptersRead
|
? _value.chaptersRead
|
||||||
: chaptersRead // ignore: cast_nullable_to_non_nullable
|
: chaptersRead // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
volumesOwned: volumesOwned == freezed
|
volumesOwned: null == volumesOwned
|
||||||
? _value.volumesOwned
|
? _value.volumesOwned
|
||||||
: volumesOwned // ignore: cast_nullable_to_non_nullable
|
: volumesOwned // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
chaptersTotal: chaptersTotal == freezed
|
chaptersTotal: freezed == chaptersTotal
|
||||||
? _value.chaptersTotal
|
? _value.chaptersTotal
|
||||||
: chaptersTotal // ignore: cast_nullable_to_non_nullable
|
: chaptersTotal // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
thumbnailUrl: thumbnailUrl == freezed
|
thumbnailUrl: null == thumbnailUrl
|
||||||
? _value.thumbnailUrl
|
? _value.thumbnailUrl
|
||||||
: thumbnailUrl // ignore: cast_nullable_to_non_nullable
|
: thumbnailUrl // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
));
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class _$$_MangaTrackingDataCopyWith<$Res>
|
abstract class _$$MangaTrackingDataImplCopyWith<$Res>
|
||||||
implements $MangaTrackingDataCopyWith<$Res> {
|
implements $MangaTrackingDataCopyWith<$Res> {
|
||||||
factory _$$_MangaTrackingDataCopyWith(_$_MangaTrackingData value,
|
factory _$$MangaTrackingDataImplCopyWith(_$MangaTrackingDataImpl value,
|
||||||
$Res Function(_$_MangaTrackingData) then) =
|
$Res Function(_$MangaTrackingDataImpl) then) =
|
||||||
__$$_MangaTrackingDataCopyWithImpl<$Res>;
|
__$$MangaTrackingDataImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{String id,
|
{String id,
|
||||||
@MediumTrackingStateConverter() MediumTrackingState state,
|
@MediumTrackingStateConverter() MediumTrackingState state,
|
||||||
@@ -133,52 +143,52 @@ abstract class _$$_MangaTrackingDataCopyWith<$Res>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class __$$_MangaTrackingDataCopyWithImpl<$Res>
|
class __$$MangaTrackingDataImplCopyWithImpl<$Res>
|
||||||
extends _$MangaTrackingDataCopyWithImpl<$Res>
|
extends _$MangaTrackingDataCopyWithImpl<$Res, _$MangaTrackingDataImpl>
|
||||||
implements _$$_MangaTrackingDataCopyWith<$Res> {
|
implements _$$MangaTrackingDataImplCopyWith<$Res> {
|
||||||
__$$_MangaTrackingDataCopyWithImpl(
|
__$$MangaTrackingDataImplCopyWithImpl(_$MangaTrackingDataImpl _value,
|
||||||
_$_MangaTrackingData _value, $Res Function(_$_MangaTrackingData) _then)
|
$Res Function(_$MangaTrackingDataImpl) _then)
|
||||||
: super(_value, (v) => _then(v as _$_MangaTrackingData));
|
: super(_value, _then);
|
||||||
|
|
||||||
@override
|
|
||||||
_$_MangaTrackingData get _value => super._value as _$_MangaTrackingData;
|
|
||||||
|
|
||||||
|
/// Create a copy of MangaTrackingData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? id = freezed,
|
Object? id = null,
|
||||||
Object? state = freezed,
|
Object? state = null,
|
||||||
Object? title = freezed,
|
Object? title = null,
|
||||||
Object? chaptersRead = freezed,
|
Object? chaptersRead = null,
|
||||||
Object? volumesOwned = freezed,
|
Object? volumesOwned = null,
|
||||||
Object? chaptersTotal = freezed,
|
Object? chaptersTotal = freezed,
|
||||||
Object? thumbnailUrl = freezed,
|
Object? thumbnailUrl = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$_MangaTrackingData(
|
return _then(_$MangaTrackingDataImpl(
|
||||||
id == freezed
|
null == id
|
||||||
? _value.id
|
? _value.id
|
||||||
: id // ignore: cast_nullable_to_non_nullable
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
state == freezed
|
null == state
|
||||||
? _value.state
|
? _value.state
|
||||||
: state // ignore: cast_nullable_to_non_nullable
|
: state // ignore: cast_nullable_to_non_nullable
|
||||||
as MediumTrackingState,
|
as MediumTrackingState,
|
||||||
title == freezed
|
null == title
|
||||||
? _value.title
|
? _value.title
|
||||||
: title // ignore: cast_nullable_to_non_nullable
|
: title // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
chaptersRead == freezed
|
null == chaptersRead
|
||||||
? _value.chaptersRead
|
? _value.chaptersRead
|
||||||
: chaptersRead // ignore: cast_nullable_to_non_nullable
|
: chaptersRead // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
volumesOwned == freezed
|
null == volumesOwned
|
||||||
? _value.volumesOwned
|
? _value.volumesOwned
|
||||||
: volumesOwned // ignore: cast_nullable_to_non_nullable
|
: volumesOwned // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
chaptersTotal == freezed
|
freezed == chaptersTotal
|
||||||
? _value.chaptersTotal
|
? _value.chaptersTotal
|
||||||
: chaptersTotal // ignore: cast_nullable_to_non_nullable
|
: chaptersTotal // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,
|
as int?,
|
||||||
thumbnailUrl == freezed
|
null == thumbnailUrl
|
||||||
? _value.thumbnailUrl
|
? _value.thumbnailUrl
|
||||||
: thumbnailUrl // ignore: cast_nullable_to_non_nullable
|
: thumbnailUrl // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
@@ -188,8 +198,8 @@ class __$$_MangaTrackingDataCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$_MangaTrackingData implements _MangaTrackingData {
|
class _$MangaTrackingDataImpl implements _MangaTrackingData {
|
||||||
_$_MangaTrackingData(
|
_$MangaTrackingDataImpl(
|
||||||
this.id,
|
this.id,
|
||||||
@MediumTrackingStateConverter() this.state,
|
@MediumTrackingStateConverter() this.state,
|
||||||
this.title,
|
this.title,
|
||||||
@@ -198,8 +208,8 @@ class _$_MangaTrackingData implements _MangaTrackingData {
|
|||||||
this.chaptersTotal,
|
this.chaptersTotal,
|
||||||
this.thumbnailUrl);
|
this.thumbnailUrl);
|
||||||
|
|
||||||
factory _$_MangaTrackingData.fromJson(Map<String, dynamic> json) =>
|
factory _$MangaTrackingDataImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$_MangaTrackingDataFromJson(json);
|
_$$MangaTrackingDataImplFromJson(json);
|
||||||
|
|
||||||
/// The ID of the manga
|
/// The ID of the manga
|
||||||
@override
|
@override
|
||||||
@@ -236,44 +246,40 @@ class _$_MangaTrackingData implements _MangaTrackingData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(dynamic other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _$_MangaTrackingData &&
|
other is _$MangaTrackingDataImpl &&
|
||||||
const DeepCollectionEquality().equals(other.id, id) &&
|
(identical(other.id, id) || other.id == id) &&
|
||||||
const DeepCollectionEquality().equals(other.state, state) &&
|
(identical(other.state, state) || other.state == state) &&
|
||||||
const DeepCollectionEquality().equals(other.title, title) &&
|
(identical(other.title, title) || other.title == title) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.chaptersRead, chaptersRead) ||
|
||||||
.equals(other.chaptersRead, chaptersRead) &&
|
other.chaptersRead == chaptersRead) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.volumesOwned, volumesOwned) ||
|
||||||
.equals(other.volumesOwned, volumesOwned) &&
|
other.volumesOwned == volumesOwned) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.chaptersTotal, chaptersTotal) ||
|
||||||
.equals(other.chaptersTotal, chaptersTotal) &&
|
other.chaptersTotal == chaptersTotal) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.thumbnailUrl, thumbnailUrl) ||
|
||||||
.equals(other.thumbnailUrl, thumbnailUrl));
|
other.thumbnailUrl == thumbnailUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(runtimeType, id, state, title, chaptersRead,
|
||||||
runtimeType,
|
volumesOwned, chaptersTotal, thumbnailUrl);
|
||||||
const DeepCollectionEquality().hash(id),
|
|
||||||
const DeepCollectionEquality().hash(state),
|
|
||||||
const DeepCollectionEquality().hash(title),
|
|
||||||
const DeepCollectionEquality().hash(chaptersRead),
|
|
||||||
const DeepCollectionEquality().hash(volumesOwned),
|
|
||||||
const DeepCollectionEquality().hash(chaptersTotal),
|
|
||||||
const DeepCollectionEquality().hash(thumbnailUrl));
|
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of MangaTrackingData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
_$$_MangaTrackingDataCopyWith<_$_MangaTrackingData> get copyWith =>
|
@pragma('vm:prefer-inline')
|
||||||
__$$_MangaTrackingDataCopyWithImpl<_$_MangaTrackingData>(
|
_$$MangaTrackingDataImplCopyWith<_$MangaTrackingDataImpl> get copyWith =>
|
||||||
|
__$$MangaTrackingDataImplCopyWithImpl<_$MangaTrackingDataImpl>(
|
||||||
this, _$identity);
|
this, _$identity);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return _$$_MangaTrackingDataToJson(
|
return _$$MangaTrackingDataImplToJson(
|
||||||
this,
|
this,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -287,42 +293,44 @@ abstract class _MangaTrackingData implements MangaTrackingData {
|
|||||||
final int chaptersRead,
|
final int chaptersRead,
|
||||||
final int volumesOwned,
|
final int volumesOwned,
|
||||||
final int? chaptersTotal,
|
final int? chaptersTotal,
|
||||||
final String thumbnailUrl) = _$_MangaTrackingData;
|
final String thumbnailUrl) = _$MangaTrackingDataImpl;
|
||||||
|
|
||||||
factory _MangaTrackingData.fromJson(Map<String, dynamic> json) =
|
factory _MangaTrackingData.fromJson(Map<String, dynamic> json) =
|
||||||
_$_MangaTrackingData.fromJson;
|
_$MangaTrackingDataImpl.fromJson;
|
||||||
|
|
||||||
@override
|
|
||||||
|
|
||||||
/// The ID of the manga
|
/// The ID of the manga
|
||||||
String get id;
|
|
||||||
@override
|
@override
|
||||||
|
String get id;
|
||||||
|
|
||||||
/// The state of the manga
|
/// The state of the manga
|
||||||
|
@override
|
||||||
@MediumTrackingStateConverter()
|
@MediumTrackingStateConverter()
|
||||||
MediumTrackingState get state;
|
MediumTrackingState get state;
|
||||||
@override
|
|
||||||
|
|
||||||
/// The title of the manga
|
/// The title of the manga
|
||||||
|
@override
|
||||||
String get title;
|
String get title;
|
||||||
@override
|
|
||||||
|
|
||||||
/// Chapters read.
|
/// Chapters read.
|
||||||
|
@override
|
||||||
int get chaptersRead;
|
int get chaptersRead;
|
||||||
@override
|
|
||||||
|
|
||||||
/// Chapters read.
|
/// Chapters read.
|
||||||
int get volumesOwned;
|
|
||||||
@override
|
@override
|
||||||
|
int get volumesOwned;
|
||||||
|
|
||||||
/// Episodes watched.
|
/// Episodes watched.
|
||||||
int? get chaptersTotal;
|
|
||||||
@override
|
@override
|
||||||
|
int? get chaptersTotal;
|
||||||
|
|
||||||
/// URL to the thumbnail/cover art for the manga.
|
/// URL to the thumbnail/cover art for the manga.
|
||||||
String get thumbnailUrl;
|
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
String get thumbnailUrl;
|
||||||
_$$_MangaTrackingDataCopyWith<_$_MangaTrackingData> get copyWith =>
|
|
||||||
|
/// Create a copy of MangaTrackingData
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$MangaTrackingDataImplCopyWith<_$MangaTrackingDataImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,19 +6,21 @@ part of 'manga.dart';
|
|||||||
// JsonSerializableGenerator
|
// JsonSerializableGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
_$_MangaTrackingData _$$_MangaTrackingDataFromJson(Map<String, dynamic> json) =>
|
_$MangaTrackingDataImpl _$$MangaTrackingDataImplFromJson(
|
||||||
_$_MangaTrackingData(
|
Map<String, dynamic> json) =>
|
||||||
|
_$MangaTrackingDataImpl(
|
||||||
json['id'] as String,
|
json['id'] as String,
|
||||||
const MediumTrackingStateConverter().fromJson(json['state'] as int),
|
const MediumTrackingStateConverter()
|
||||||
|
.fromJson((json['state'] as num).toInt()),
|
||||||
json['title'] as String,
|
json['title'] as String,
|
||||||
json['chaptersRead'] as int,
|
(json['chaptersRead'] as num).toInt(),
|
||||||
json['volumesOwned'] as int,
|
(json['volumesOwned'] as num).toInt(),
|
||||||
json['chaptersTotal'] as int?,
|
(json['chaptersTotal'] as num?)?.toInt(),
|
||||||
json['thumbnailUrl'] as String,
|
json['thumbnailUrl'] as String,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$_MangaTrackingDataToJson(
|
Map<String, dynamic> _$$MangaTrackingDataImplToJson(
|
||||||
_$_MangaTrackingData instance) =>
|
_$MangaTrackingDataImpl instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'id': instance.id,
|
'id': instance.id,
|
||||||
'state': const MediumTrackingStateConverter().toJson(instance.state),
|
'state': const MediumTrackingStateConverter().toJson(instance.state),
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ class SearchResult {
|
|||||||
this.total,
|
this.total,
|
||||||
this.thumbnailUrl,
|
this.thumbnailUrl,
|
||||||
this.description,
|
this.description,
|
||||||
|
this.isAiring,
|
||||||
|
this.broadcastDay,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// The title of the anime.
|
/// The title of the anime.
|
||||||
@@ -22,4 +24,10 @@ class SearchResult {
|
|||||||
|
|
||||||
/// The description of the anime
|
/// The description of the anime
|
||||||
final String description;
|
final String description;
|
||||||
|
|
||||||
|
/// Flag whether the anime is airing.
|
||||||
|
final bool isAiring;
|
||||||
|
|
||||||
|
/// The day of the week the anime is airing.
|
||||||
|
final String? broadcastDay;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,62 +10,46 @@ enum TrackingMediumType {
|
|||||||
/// The state of the medium we're tracking, i.e. reading/watching, dropped, ...
|
/// The state of the medium we're tracking, i.e. reading/watching, dropped, ...
|
||||||
enum MediumTrackingState {
|
enum MediumTrackingState {
|
||||||
/// Currently watching or reading
|
/// Currently watching or reading
|
||||||
ongoing,
|
ongoing(0),
|
||||||
|
|
||||||
/// Done
|
/// Done
|
||||||
completed,
|
completed(1),
|
||||||
|
|
||||||
/// Plan to watch or read
|
/// Plan to watch or read
|
||||||
planned,
|
planned(2),
|
||||||
|
|
||||||
/// Dropped
|
/// Dropped
|
||||||
dropped,
|
dropped(3),
|
||||||
|
|
||||||
/// Paused
|
/// Paused
|
||||||
paused,
|
paused(4),
|
||||||
|
|
||||||
/// Meta state
|
/// Meta state
|
||||||
all,
|
all(-1);
|
||||||
}
|
|
||||||
|
|
||||||
/// Interface for the Anime and Manga data classes
|
const MediumTrackingState(this.id);
|
||||||
abstract class TrackingMedium {
|
|
||||||
/// The ID of the medium
|
|
||||||
final String id = '';
|
|
||||||
|
|
||||||
/// The title of the medium
|
factory MediumTrackingState.fromInt(int id) {
|
||||||
final String title = '';
|
switch (id) {
|
||||||
|
case 0:
|
||||||
/// The URL of the cover image.
|
return MediumTrackingState.ongoing;
|
||||||
final String thumbnailUrl = '';
|
case 1:
|
||||||
|
return MediumTrackingState.completed;
|
||||||
/// The tracking state
|
case 2:
|
||||||
final MediumTrackingState state = MediumTrackingState.planned;
|
return MediumTrackingState.planned;
|
||||||
}
|
case 3:
|
||||||
|
return MediumTrackingState.dropped;
|
||||||
extension MediumStateExtension on MediumTrackingState {
|
case 4:
|
||||||
int toInteger() {
|
return MediumTrackingState.paused;
|
||||||
assert(
|
|
||||||
this != MediumTrackingState.all,
|
|
||||||
'MediumTrackingState.all must not be serialized',
|
|
||||||
);
|
|
||||||
switch (this) {
|
|
||||||
case MediumTrackingState.ongoing:
|
|
||||||
return 0;
|
|
||||||
case MediumTrackingState.completed:
|
|
||||||
return 1;
|
|
||||||
case MediumTrackingState.planned:
|
|
||||||
return 2;
|
|
||||||
case MediumTrackingState.dropped:
|
|
||||||
return 3;
|
|
||||||
case MediumTrackingState.paused:
|
|
||||||
return 4;
|
|
||||||
case MediumTrackingState.all:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String toNameString(TrackingMediumType type) {
|
return MediumTrackingState.planned;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The id of the value.
|
||||||
|
final int id;
|
||||||
|
|
||||||
|
String getName(TrackingMediumType type) {
|
||||||
assert(
|
assert(
|
||||||
this != MediumTrackingState.all,
|
this != MediumTrackingState.all,
|
||||||
'MediumTrackingState.all must not be stringified',
|
'MediumTrackingState.all must not be stringified',
|
||||||
@@ -98,28 +82,28 @@ extension MediumStateExtension on MediumTrackingState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Interface for the Anime and Manga data classes
|
||||||
|
mixin TrackingMedium {
|
||||||
|
/// The ID of the medium
|
||||||
|
final String id = '';
|
||||||
|
|
||||||
|
/// The title of the medium
|
||||||
|
final String title = '';
|
||||||
|
|
||||||
|
/// The URL of the cover image.
|
||||||
|
final String thumbnailUrl = '';
|
||||||
|
|
||||||
|
/// The tracking state
|
||||||
|
final MediumTrackingState state = MediumTrackingState.planned;
|
||||||
|
}
|
||||||
|
|
||||||
class MediumTrackingStateConverter
|
class MediumTrackingStateConverter
|
||||||
implements JsonConverter<MediumTrackingState, int> {
|
implements JsonConverter<MediumTrackingState, int> {
|
||||||
const MediumTrackingStateConverter();
|
const MediumTrackingStateConverter();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MediumTrackingState fromJson(int json) {
|
MediumTrackingState fromJson(int json) => MediumTrackingState.fromInt(json);
|
||||||
switch (json) {
|
|
||||||
case 0:
|
|
||||||
return MediumTrackingState.ongoing;
|
|
||||||
case 1:
|
|
||||||
return MediumTrackingState.completed;
|
|
||||||
case 2:
|
|
||||||
return MediumTrackingState.planned;
|
|
||||||
case 3:
|
|
||||||
return MediumTrackingState.dropped;
|
|
||||||
case 4:
|
|
||||||
return MediumTrackingState.paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MediumTrackingState.planned;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int toJson(MediumTrackingState state) => state.toInteger();
|
int toJson(MediumTrackingState state) => state.id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,24 @@
|
|||||||
import 'package:anitrack/src/data/anime.dart';
|
import 'package:anitrack/src/data/anime.dart';
|
||||||
import 'package:anitrack/src/data/manga.dart';
|
import 'package:anitrack/src/data/manga.dart';
|
||||||
|
import 'package:anitrack/src/service/migrations/0000_airing.dart';
|
||||||
import 'package:anitrack/src/service/migrations/0000_score.dart';
|
import 'package:anitrack/src/service/migrations/0000_score.dart';
|
||||||
import 'package:sqflite/sqflite.dart';
|
import 'package:sqflite/sqflite.dart';
|
||||||
|
|
||||||
const animeTable = 'Anime';
|
const animeTable = 'Anime';
|
||||||
const mangaTable = 'Manga';
|
const mangaTable = 'Manga';
|
||||||
|
|
||||||
|
extension BoolToInt on bool {
|
||||||
|
int toInt() {
|
||||||
|
return this ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension IntToBool on int {
|
||||||
|
bool toBool() {
|
||||||
|
return this == 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _createDatabase(Database db, int version) async {
|
Future<void> _createDatabase(Database db, int version) async {
|
||||||
await db.execute(
|
await db.execute(
|
||||||
'''
|
'''
|
||||||
@@ -16,7 +29,9 @@ Future<void> _createDatabase(Database db, int version) async {
|
|||||||
episodesWatched INTEGER NOT NULL,
|
episodesWatched INTEGER NOT NULL,
|
||||||
thumbnailUrl TEXT NOT NULL,
|
thumbnailUrl TEXT NOT NULL,
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
score INTEGER
|
score INTEGER,
|
||||||
|
airing INTEGER NOT NULL,
|
||||||
|
broadcastDay TEXT
|
||||||
)''',
|
)''',
|
||||||
);
|
);
|
||||||
await db.execute(
|
await db.execute(
|
||||||
@@ -40,7 +55,7 @@ class DatabaseService {
|
|||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
_db = await openDatabase(
|
_db = await openDatabase(
|
||||||
'anitrack.db',
|
'anitrack.db',
|
||||||
version: 2,
|
version: 3,
|
||||||
onConfigure: (db) async {
|
onConfigure: (db) async {
|
||||||
// In order to do schema changes during database upgrades, we disable foreign
|
// In order to do schema changes during database upgrades, we disable foreign
|
||||||
// keys in the onConfigure phase, but re-enable them here.
|
// keys in the onConfigure phase, but re-enable them here.
|
||||||
@@ -56,6 +71,9 @@ class DatabaseService {
|
|||||||
if (oldVersion < 2) {
|
if (oldVersion < 2) {
|
||||||
await migrateFromV1ToV2(db);
|
await migrateFromV1ToV2(db);
|
||||||
}
|
}
|
||||||
|
if (oldVersion < 3) {
|
||||||
|
await migrateFromV2ToV3(db);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
11
lib/src/service/migrations/0000_airing.dart
Normal file
11
lib/src/service/migrations/0000_airing.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import 'package:anitrack/src/service/database.dart';
|
||||||
|
import 'package:sqflite/sqflite.dart';
|
||||||
|
|
||||||
|
Future<void> migrateFromV2ToV3(Database db) async {
|
||||||
|
await db.execute(
|
||||||
|
'ALTER TABLE $animeTable ADD COLUMN airing INTEGER NOT NULL DEFAULT ${true.toInt()};',
|
||||||
|
);
|
||||||
|
await db.execute(
|
||||||
|
'ALTER TABLE $animeTable ADD COLUMN broadcastDay TEXT;',
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ import 'package:anitrack/src/data/manga.dart';
|
|||||||
import 'package:anitrack/src/data/type.dart';
|
import 'package:anitrack/src/data/type.dart';
|
||||||
import 'package:anitrack/src/service/database.dart';
|
import 'package:anitrack/src/service/database.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
|
|
||||||
@@ -35,6 +36,8 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
final List<MangaTrackingData> _mangas =
|
final List<MangaTrackingData> _mangas =
|
||||||
List<MangaTrackingData>.empty(growable: true);
|
List<MangaTrackingData>.empty(growable: true);
|
||||||
|
|
||||||
|
List<AnimeTrackingData> get unfilteredAnime => _animes;
|
||||||
|
|
||||||
List<AnimeTrackingData> _getFilteredAnime({
|
List<AnimeTrackingData> _getFilteredAnime({
|
||||||
MediumTrackingState? trackingState,
|
MediumTrackingState? trackingState,
|
||||||
}) {
|
}) {
|
||||||
@@ -63,7 +66,16 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
await GetIt.I.get<DatabaseService>().addAnime(event.data);
|
await GetIt.I.get<DatabaseService>().addAnime(event.data);
|
||||||
|
|
||||||
// Add it to the cache
|
// Add it to the cache
|
||||||
|
if (event.checkIfExists) {
|
||||||
|
final shouldAdd =
|
||||||
|
_animes.firstWhereOrNull((element) => element.id == event.data.id) ==
|
||||||
|
null;
|
||||||
|
if (shouldAdd) {
|
||||||
_animes.add(event.data);
|
_animes.add(event.data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_animes.add(event.data);
|
||||||
|
}
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
@@ -80,7 +92,17 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
await GetIt.I.get<DatabaseService>().addManga(event.data);
|
await GetIt.I.get<DatabaseService>().addManga(event.data);
|
||||||
|
|
||||||
// Add it to the cache
|
// Add it to the cache
|
||||||
|
// Add it to the cache
|
||||||
|
if (event.checkIfExists) {
|
||||||
|
final shouldAdd =
|
||||||
|
_mangas.firstWhereOrNull((element) => element.id == event.data.id) ==
|
||||||
|
null;
|
||||||
|
if (shouldAdd) {
|
||||||
_mangas.add(event.data);
|
_mangas.add(event.data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_mangas.add(event.data);
|
||||||
|
}
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
@@ -270,6 +292,8 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
animes: _getFilteredAnime(),
|
animes: _getFilteredAnime(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await GetIt.I.get<DatabaseService>().updateAnime(event.anime);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onMangaUpdated(
|
Future<void> _onMangaUpdated(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
part of 'anime_list_bloc.dart';
|
part of 'anime_list_bloc.dart';
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ part of 'anime_list_bloc.dart';
|
|||||||
T _$identity<T>(T value) => value;
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
final _privateConstructorUsedError = UnsupportedError(
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$AnimeListState {
|
mixin _$AnimeListState {
|
||||||
@@ -25,7 +25,9 @@ mixin _$AnimeListState {
|
|||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
TrackingMediumType get trackingType => throw _privateConstructorUsedError;
|
TrackingMediumType get trackingType => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of AnimeListState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$AnimeListStateCopyWith<AnimeListState> get copyWith =>
|
$AnimeListStateCopyWith<AnimeListState> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -34,7 +36,8 @@ mixin _$AnimeListState {
|
|||||||
abstract class $AnimeListStateCopyWith<$Res> {
|
abstract class $AnimeListStateCopyWith<$Res> {
|
||||||
factory $AnimeListStateCopyWith(
|
factory $AnimeListStateCopyWith(
|
||||||
AnimeListState value, $Res Function(AnimeListState) then) =
|
AnimeListState value, $Res Function(AnimeListState) then) =
|
||||||
_$AnimeListStateCopyWithImpl<$Res>;
|
_$AnimeListStateCopyWithImpl<$Res, AnimeListState>;
|
||||||
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{bool buttonVisibility,
|
{bool buttonVisibility,
|
||||||
List<AnimeTrackingData> animes,
|
List<AnimeTrackingData> animes,
|
||||||
@@ -45,59 +48,64 @@ abstract class $AnimeListStateCopyWith<$Res> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$AnimeListStateCopyWithImpl<$Res>
|
class _$AnimeListStateCopyWithImpl<$Res, $Val extends AnimeListState>
|
||||||
implements $AnimeListStateCopyWith<$Res> {
|
implements $AnimeListStateCopyWith<$Res> {
|
||||||
_$AnimeListStateCopyWithImpl(this._value, this._then);
|
_$AnimeListStateCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
final AnimeListState _value;
|
|
||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function(AnimeListState) _then;
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of AnimeListState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? buttonVisibility = freezed,
|
Object? buttonVisibility = null,
|
||||||
Object? animes = freezed,
|
Object? animes = null,
|
||||||
Object? mangas = freezed,
|
Object? mangas = null,
|
||||||
Object? animeFilterState = freezed,
|
Object? animeFilterState = null,
|
||||||
Object? mangaFilterState = freezed,
|
Object? mangaFilterState = null,
|
||||||
Object? trackingType = freezed,
|
Object? trackingType = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
buttonVisibility: buttonVisibility == freezed
|
buttonVisibility: null == buttonVisibility
|
||||||
? _value.buttonVisibility
|
? _value.buttonVisibility
|
||||||
: buttonVisibility // ignore: cast_nullable_to_non_nullable
|
: buttonVisibility // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
animes: animes == freezed
|
animes: null == animes
|
||||||
? _value.animes
|
? _value.animes
|
||||||
: animes // ignore: cast_nullable_to_non_nullable
|
: animes // ignore: cast_nullable_to_non_nullable
|
||||||
as List<AnimeTrackingData>,
|
as List<AnimeTrackingData>,
|
||||||
mangas: mangas == freezed
|
mangas: null == mangas
|
||||||
? _value.mangas
|
? _value.mangas
|
||||||
: mangas // ignore: cast_nullable_to_non_nullable
|
: mangas // ignore: cast_nullable_to_non_nullable
|
||||||
as List<MangaTrackingData>,
|
as List<MangaTrackingData>,
|
||||||
animeFilterState: animeFilterState == freezed
|
animeFilterState: null == animeFilterState
|
||||||
? _value.animeFilterState
|
? _value.animeFilterState
|
||||||
: animeFilterState // ignore: cast_nullable_to_non_nullable
|
: animeFilterState // ignore: cast_nullable_to_non_nullable
|
||||||
as MediumTrackingState,
|
as MediumTrackingState,
|
||||||
mangaFilterState: mangaFilterState == freezed
|
mangaFilterState: null == mangaFilterState
|
||||||
? _value.mangaFilterState
|
? _value.mangaFilterState
|
||||||
: mangaFilterState // ignore: cast_nullable_to_non_nullable
|
: mangaFilterState // ignore: cast_nullable_to_non_nullable
|
||||||
as MediumTrackingState,
|
as MediumTrackingState,
|
||||||
trackingType: trackingType == freezed
|
trackingType: null == trackingType
|
||||||
? _value.trackingType
|
? _value.trackingType
|
||||||
: trackingType // ignore: cast_nullable_to_non_nullable
|
: trackingType // ignore: cast_nullable_to_non_nullable
|
||||||
as TrackingMediumType,
|
as TrackingMediumType,
|
||||||
));
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class _$$_AnimeListStateCopyWith<$Res>
|
abstract class _$$AnimeListStateImplCopyWith<$Res>
|
||||||
implements $AnimeListStateCopyWith<$Res> {
|
implements $AnimeListStateCopyWith<$Res> {
|
||||||
factory _$$_AnimeListStateCopyWith(
|
factory _$$AnimeListStateImplCopyWith(_$AnimeListStateImpl value,
|
||||||
_$_AnimeListState value, $Res Function(_$_AnimeListState) then) =
|
$Res Function(_$AnimeListStateImpl) then) =
|
||||||
__$$_AnimeListStateCopyWithImpl<$Res>;
|
__$$AnimeListStateImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{bool buttonVisibility,
|
{bool buttonVisibility,
|
||||||
List<AnimeTrackingData> animes,
|
List<AnimeTrackingData> animes,
|
||||||
@@ -108,47 +116,47 @@ abstract class _$$_AnimeListStateCopyWith<$Res>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class __$$_AnimeListStateCopyWithImpl<$Res>
|
class __$$AnimeListStateImplCopyWithImpl<$Res>
|
||||||
extends _$AnimeListStateCopyWithImpl<$Res>
|
extends _$AnimeListStateCopyWithImpl<$Res, _$AnimeListStateImpl>
|
||||||
implements _$$_AnimeListStateCopyWith<$Res> {
|
implements _$$AnimeListStateImplCopyWith<$Res> {
|
||||||
__$$_AnimeListStateCopyWithImpl(
|
__$$AnimeListStateImplCopyWithImpl(
|
||||||
_$_AnimeListState _value, $Res Function(_$_AnimeListState) _then)
|
_$AnimeListStateImpl _value, $Res Function(_$AnimeListStateImpl) _then)
|
||||||
: super(_value, (v) => _then(v as _$_AnimeListState));
|
: super(_value, _then);
|
||||||
|
|
||||||
@override
|
|
||||||
_$_AnimeListState get _value => super._value as _$_AnimeListState;
|
|
||||||
|
|
||||||
|
/// Create a copy of AnimeListState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? buttonVisibility = freezed,
|
Object? buttonVisibility = null,
|
||||||
Object? animes = freezed,
|
Object? animes = null,
|
||||||
Object? mangas = freezed,
|
Object? mangas = null,
|
||||||
Object? animeFilterState = freezed,
|
Object? animeFilterState = null,
|
||||||
Object? mangaFilterState = freezed,
|
Object? mangaFilterState = null,
|
||||||
Object? trackingType = freezed,
|
Object? trackingType = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$_AnimeListState(
|
return _then(_$AnimeListStateImpl(
|
||||||
buttonVisibility: buttonVisibility == freezed
|
buttonVisibility: null == buttonVisibility
|
||||||
? _value.buttonVisibility
|
? _value.buttonVisibility
|
||||||
: buttonVisibility // ignore: cast_nullable_to_non_nullable
|
: buttonVisibility // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
animes: animes == freezed
|
animes: null == animes
|
||||||
? _value._animes
|
? _value._animes
|
||||||
: animes // ignore: cast_nullable_to_non_nullable
|
: animes // ignore: cast_nullable_to_non_nullable
|
||||||
as List<AnimeTrackingData>,
|
as List<AnimeTrackingData>,
|
||||||
mangas: mangas == freezed
|
mangas: null == mangas
|
||||||
? _value._mangas
|
? _value._mangas
|
||||||
: mangas // ignore: cast_nullable_to_non_nullable
|
: mangas // ignore: cast_nullable_to_non_nullable
|
||||||
as List<MangaTrackingData>,
|
as List<MangaTrackingData>,
|
||||||
animeFilterState: animeFilterState == freezed
|
animeFilterState: null == animeFilterState
|
||||||
? _value.animeFilterState
|
? _value.animeFilterState
|
||||||
: animeFilterState // ignore: cast_nullable_to_non_nullable
|
: animeFilterState // ignore: cast_nullable_to_non_nullable
|
||||||
as MediumTrackingState,
|
as MediumTrackingState,
|
||||||
mangaFilterState: mangaFilterState == freezed
|
mangaFilterState: null == mangaFilterState
|
||||||
? _value.mangaFilterState
|
? _value.mangaFilterState
|
||||||
: mangaFilterState // ignore: cast_nullable_to_non_nullable
|
: mangaFilterState // ignore: cast_nullable_to_non_nullable
|
||||||
as MediumTrackingState,
|
as MediumTrackingState,
|
||||||
trackingType: trackingType == freezed
|
trackingType: null == trackingType
|
||||||
? _value.trackingType
|
? _value.trackingType
|
||||||
: trackingType // ignore: cast_nullable_to_non_nullable
|
: trackingType // ignore: cast_nullable_to_non_nullable
|
||||||
as TrackingMediumType,
|
as TrackingMediumType,
|
||||||
@@ -158,8 +166,8 @@ class __$$_AnimeListStateCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
class _$_AnimeListState implements _AnimeListState {
|
class _$AnimeListStateImpl implements _AnimeListState {
|
||||||
_$_AnimeListState(
|
_$AnimeListStateImpl(
|
||||||
{this.buttonVisibility = true,
|
{this.buttonVisibility = true,
|
||||||
final List<AnimeTrackingData> animes = const [],
|
final List<AnimeTrackingData> animes = const [],
|
||||||
final List<MangaTrackingData> mangas = const [],
|
final List<MangaTrackingData> mangas = const [],
|
||||||
@@ -176,6 +184,7 @@ class _$_AnimeListState implements _AnimeListState {
|
|||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
List<AnimeTrackingData> get animes {
|
List<AnimeTrackingData> get animes {
|
||||||
|
if (_animes is EqualUnmodifiableListView) return _animes;
|
||||||
// ignore: implicit_dynamic_type
|
// ignore: implicit_dynamic_type
|
||||||
return EqualUnmodifiableListView(_animes);
|
return EqualUnmodifiableListView(_animes);
|
||||||
}
|
}
|
||||||
@@ -184,6 +193,7 @@ class _$_AnimeListState implements _AnimeListState {
|
|||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
List<MangaTrackingData> get mangas {
|
List<MangaTrackingData> get mangas {
|
||||||
|
if (_mangas is EqualUnmodifiableListView) return _mangas;
|
||||||
// ignore: implicit_dynamic_type
|
// ignore: implicit_dynamic_type
|
||||||
return EqualUnmodifiableListView(_mangas);
|
return EqualUnmodifiableListView(_mangas);
|
||||||
}
|
}
|
||||||
@@ -204,36 +214,40 @@ class _$_AnimeListState implements _AnimeListState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(dynamic other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _$_AnimeListState &&
|
other is _$AnimeListStateImpl &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.buttonVisibility, buttonVisibility) ||
|
||||||
.equals(other.buttonVisibility, buttonVisibility) &&
|
other.buttonVisibility == buttonVisibility) &&
|
||||||
const DeepCollectionEquality().equals(other._animes, _animes) &&
|
const DeepCollectionEquality().equals(other._animes, _animes) &&
|
||||||
const DeepCollectionEquality().equals(other._mangas, _mangas) &&
|
const DeepCollectionEquality().equals(other._mangas, _mangas) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.animeFilterState, animeFilterState) ||
|
||||||
.equals(other.animeFilterState, animeFilterState) &&
|
other.animeFilterState == animeFilterState) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.mangaFilterState, mangaFilterState) ||
|
||||||
.equals(other.mangaFilterState, mangaFilterState) &&
|
other.mangaFilterState == mangaFilterState) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.trackingType, trackingType) ||
|
||||||
.equals(other.trackingType, trackingType));
|
other.trackingType == trackingType));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType,
|
runtimeType,
|
||||||
const DeepCollectionEquality().hash(buttonVisibility),
|
buttonVisibility,
|
||||||
const DeepCollectionEquality().hash(_animes),
|
const DeepCollectionEquality().hash(_animes),
|
||||||
const DeepCollectionEquality().hash(_mangas),
|
const DeepCollectionEquality().hash(_mangas),
|
||||||
const DeepCollectionEquality().hash(animeFilterState),
|
animeFilterState,
|
||||||
const DeepCollectionEquality().hash(mangaFilterState),
|
mangaFilterState,
|
||||||
const DeepCollectionEquality().hash(trackingType));
|
trackingType);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of AnimeListState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
_$$_AnimeListStateCopyWith<_$_AnimeListState> get copyWith =>
|
@pragma('vm:prefer-inline')
|
||||||
__$$_AnimeListStateCopyWithImpl<_$_AnimeListState>(this, _$identity);
|
_$$AnimeListStateImplCopyWith<_$AnimeListStateImpl> get copyWith =>
|
||||||
|
__$$AnimeListStateImplCopyWithImpl<_$AnimeListStateImpl>(
|
||||||
|
this, _$identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class _AnimeListState implements AnimeListState {
|
abstract class _AnimeListState implements AnimeListState {
|
||||||
@@ -243,7 +257,7 @@ abstract class _AnimeListState implements AnimeListState {
|
|||||||
final List<MangaTrackingData> mangas,
|
final List<MangaTrackingData> mangas,
|
||||||
final MediumTrackingState animeFilterState,
|
final MediumTrackingState animeFilterState,
|
||||||
final MediumTrackingState mangaFilterState,
|
final MediumTrackingState mangaFilterState,
|
||||||
final TrackingMediumType trackingType}) = _$_AnimeListState;
|
final TrackingMediumType trackingType}) = _$AnimeListStateImpl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get buttonVisibility;
|
bool get buttonVisibility;
|
||||||
@@ -257,8 +271,11 @@ abstract class _AnimeListState implements AnimeListState {
|
|||||||
MediumTrackingState get mangaFilterState;
|
MediumTrackingState get mangaFilterState;
|
||||||
@override
|
@override
|
||||||
TrackingMediumType get trackingType;
|
TrackingMediumType get trackingType;
|
||||||
|
|
||||||
|
/// Create a copy of AnimeListState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$_AnimeListStateCopyWith<_$_AnimeListState> get copyWith =>
|
_$$AnimeListStateImplCopyWith<_$AnimeListStateImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,14 @@ class AnimeEpisodeDecrementedEvent extends AnimeListEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AnimeAddedEvent extends AnimeListEvent {
|
class AnimeAddedEvent extends AnimeListEvent {
|
||||||
AnimeAddedEvent(this.data);
|
AnimeAddedEvent(this.data, {this.checkIfExists = false});
|
||||||
|
|
||||||
/// The anime to add.
|
/// The anime to add.
|
||||||
final AnimeTrackingData data;
|
final AnimeTrackingData data;
|
||||||
|
|
||||||
|
/// If true, checks if the anime with the id is already in the list.
|
||||||
|
/// If it is, does nothing.
|
||||||
|
final bool checkIfExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Triggered when animes are to be loaded from the database
|
/// Triggered when animes are to be loaded from the database
|
||||||
@@ -43,9 +47,12 @@ class AnimeTrackingTypeChanged extends AnimeListEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AnimeUpdatedEvent extends AnimeListEvent {
|
class AnimeUpdatedEvent extends AnimeListEvent {
|
||||||
AnimeUpdatedEvent(this.anime);
|
AnimeUpdatedEvent(this.anime, {this.commit = false});
|
||||||
|
|
||||||
final AnimeTrackingData anime;
|
final AnimeTrackingData anime;
|
||||||
|
|
||||||
|
/// Commit the new anime data to the database.
|
||||||
|
final bool commit;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AnimeRemovedEvent extends AnimeListEvent {
|
class AnimeRemovedEvent extends AnimeListEvent {
|
||||||
@@ -56,10 +63,14 @@ class AnimeRemovedEvent extends AnimeListEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MangaAddedEvent extends AnimeListEvent {
|
class MangaAddedEvent extends AnimeListEvent {
|
||||||
MangaAddedEvent(this.data);
|
MangaAddedEvent(this.data, {this.checkIfExists = false});
|
||||||
|
|
||||||
/// The manga to add.
|
/// The manga to add.
|
||||||
final MangaTrackingData data;
|
final MangaTrackingData data;
|
||||||
|
|
||||||
|
/// If true, checks if the manga with the id is already in the list.
|
||||||
|
/// If it is, does nothing.
|
||||||
|
final bool checkIfExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Triggered when the manga filter is changed
|
/// Triggered when the manga filter is changed
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
|||||||
anime.episodes,
|
anime.episodes,
|
||||||
anime.imageUrl,
|
anime.imageUrl,
|
||||||
anime.synopsis ?? '',
|
anime.synopsis ?? '',
|
||||||
|
anime.airing,
|
||||||
|
anime.broadcast?.split(' ').first,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.toList(),
|
.toList(),
|
||||||
@@ -104,6 +106,9 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
|||||||
manga.chapters,
|
manga.chapters,
|
||||||
manga.imageUrl,
|
manga.imageUrl,
|
||||||
manga.synopsis ?? '',
|
manga.synopsis ?? '',
|
||||||
|
// TODO(Unknown): Implement for Manga
|
||||||
|
false,
|
||||||
|
null,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.toList(),
|
.toList(),
|
||||||
@@ -126,6 +131,8 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
|||||||
0,
|
0,
|
||||||
event.result.total,
|
event.result.total,
|
||||||
event.result.thumbnailUrl,
|
event.result.thumbnailUrl,
|
||||||
|
event.result.isAiring,
|
||||||
|
event.result.broadcastDay,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: list.MangaAddedEvent(
|
: list.MangaAddedEvent(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
part of 'anime_search_bloc.dart';
|
part of 'anime_search_bloc.dart';
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ part of 'anime_search_bloc.dart';
|
|||||||
T _$identity<T>(T value) => value;
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
final _privateConstructorUsedError = UnsupportedError(
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$AnimeSearchState {
|
mixin _$AnimeSearchState {
|
||||||
@@ -21,7 +21,9 @@ mixin _$AnimeSearchState {
|
|||||||
bool get working => throw _privateConstructorUsedError;
|
bool get working => throw _privateConstructorUsedError;
|
||||||
List<SearchResult> get searchResults => throw _privateConstructorUsedError;
|
List<SearchResult> get searchResults => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of AnimeSearchState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$AnimeSearchStateCopyWith<AnimeSearchState> get copyWith =>
|
$AnimeSearchStateCopyWith<AnimeSearchState> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -30,7 +32,8 @@ mixin _$AnimeSearchState {
|
|||||||
abstract class $AnimeSearchStateCopyWith<$Res> {
|
abstract class $AnimeSearchStateCopyWith<$Res> {
|
||||||
factory $AnimeSearchStateCopyWith(
|
factory $AnimeSearchStateCopyWith(
|
||||||
AnimeSearchState value, $Res Function(AnimeSearchState) then) =
|
AnimeSearchState value, $Res Function(AnimeSearchState) then) =
|
||||||
_$AnimeSearchStateCopyWithImpl<$Res>;
|
_$AnimeSearchStateCopyWithImpl<$Res, AnimeSearchState>;
|
||||||
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{TrackingMediumType trackingType,
|
{TrackingMediumType trackingType,
|
||||||
String searchQuery,
|
String searchQuery,
|
||||||
@@ -39,49 +42,54 @@ abstract class $AnimeSearchStateCopyWith<$Res> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$AnimeSearchStateCopyWithImpl<$Res>
|
class _$AnimeSearchStateCopyWithImpl<$Res, $Val extends AnimeSearchState>
|
||||||
implements $AnimeSearchStateCopyWith<$Res> {
|
implements $AnimeSearchStateCopyWith<$Res> {
|
||||||
_$AnimeSearchStateCopyWithImpl(this._value, this._then);
|
_$AnimeSearchStateCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
final AnimeSearchState _value;
|
|
||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function(AnimeSearchState) _then;
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of AnimeSearchState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? trackingType = freezed,
|
Object? trackingType = null,
|
||||||
Object? searchQuery = freezed,
|
Object? searchQuery = null,
|
||||||
Object? working = freezed,
|
Object? working = null,
|
||||||
Object? searchResults = freezed,
|
Object? searchResults = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
trackingType: trackingType == freezed
|
trackingType: null == trackingType
|
||||||
? _value.trackingType
|
? _value.trackingType
|
||||||
: trackingType // ignore: cast_nullable_to_non_nullable
|
: trackingType // ignore: cast_nullable_to_non_nullable
|
||||||
as TrackingMediumType,
|
as TrackingMediumType,
|
||||||
searchQuery: searchQuery == freezed
|
searchQuery: null == searchQuery
|
||||||
? _value.searchQuery
|
? _value.searchQuery
|
||||||
: searchQuery // ignore: cast_nullable_to_non_nullable
|
: searchQuery // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
working: working == freezed
|
working: null == working
|
||||||
? _value.working
|
? _value.working
|
||||||
: working // ignore: cast_nullable_to_non_nullable
|
: working // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
searchResults: searchResults == freezed
|
searchResults: null == searchResults
|
||||||
? _value.searchResults
|
? _value.searchResults
|
||||||
: searchResults // ignore: cast_nullable_to_non_nullable
|
: searchResults // ignore: cast_nullable_to_non_nullable
|
||||||
as List<SearchResult>,
|
as List<SearchResult>,
|
||||||
));
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class _$$_AnimeSearchStateCopyWith<$Res>
|
abstract class _$$AnimeSearchStateImplCopyWith<$Res>
|
||||||
implements $AnimeSearchStateCopyWith<$Res> {
|
implements $AnimeSearchStateCopyWith<$Res> {
|
||||||
factory _$$_AnimeSearchStateCopyWith(
|
factory _$$AnimeSearchStateImplCopyWith(_$AnimeSearchStateImpl value,
|
||||||
_$_AnimeSearchState value, $Res Function(_$_AnimeSearchState) then) =
|
$Res Function(_$AnimeSearchStateImpl) then) =
|
||||||
__$$_AnimeSearchStateCopyWithImpl<$Res>;
|
__$$AnimeSearchStateImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{TrackingMediumType trackingType,
|
{TrackingMediumType trackingType,
|
||||||
String searchQuery,
|
String searchQuery,
|
||||||
@@ -90,37 +98,37 @@ abstract class _$$_AnimeSearchStateCopyWith<$Res>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class __$$_AnimeSearchStateCopyWithImpl<$Res>
|
class __$$AnimeSearchStateImplCopyWithImpl<$Res>
|
||||||
extends _$AnimeSearchStateCopyWithImpl<$Res>
|
extends _$AnimeSearchStateCopyWithImpl<$Res, _$AnimeSearchStateImpl>
|
||||||
implements _$$_AnimeSearchStateCopyWith<$Res> {
|
implements _$$AnimeSearchStateImplCopyWith<$Res> {
|
||||||
__$$_AnimeSearchStateCopyWithImpl(
|
__$$AnimeSearchStateImplCopyWithImpl(_$AnimeSearchStateImpl _value,
|
||||||
_$_AnimeSearchState _value, $Res Function(_$_AnimeSearchState) _then)
|
$Res Function(_$AnimeSearchStateImpl) _then)
|
||||||
: super(_value, (v) => _then(v as _$_AnimeSearchState));
|
: super(_value, _then);
|
||||||
|
|
||||||
@override
|
|
||||||
_$_AnimeSearchState get _value => super._value as _$_AnimeSearchState;
|
|
||||||
|
|
||||||
|
/// Create a copy of AnimeSearchState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? trackingType = freezed,
|
Object? trackingType = null,
|
||||||
Object? searchQuery = freezed,
|
Object? searchQuery = null,
|
||||||
Object? working = freezed,
|
Object? working = null,
|
||||||
Object? searchResults = freezed,
|
Object? searchResults = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$_AnimeSearchState(
|
return _then(_$AnimeSearchStateImpl(
|
||||||
trackingType: trackingType == freezed
|
trackingType: null == trackingType
|
||||||
? _value.trackingType
|
? _value.trackingType
|
||||||
: trackingType // ignore: cast_nullable_to_non_nullable
|
: trackingType // ignore: cast_nullable_to_non_nullable
|
||||||
as TrackingMediumType,
|
as TrackingMediumType,
|
||||||
searchQuery: searchQuery == freezed
|
searchQuery: null == searchQuery
|
||||||
? _value.searchQuery
|
? _value.searchQuery
|
||||||
: searchQuery // ignore: cast_nullable_to_non_nullable
|
: searchQuery // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String,
|
||||||
working: working == freezed
|
working: null == working
|
||||||
? _value.working
|
? _value.working
|
||||||
: working // ignore: cast_nullable_to_non_nullable
|
: working // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
searchResults: searchResults == freezed
|
searchResults: null == searchResults
|
||||||
? _value._searchResults
|
? _value._searchResults
|
||||||
: searchResults // ignore: cast_nullable_to_non_nullable
|
: searchResults // ignore: cast_nullable_to_non_nullable
|
||||||
as List<SearchResult>,
|
as List<SearchResult>,
|
||||||
@@ -130,8 +138,8 @@ class __$$_AnimeSearchStateCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
class _$_AnimeSearchState implements _AnimeSearchState {
|
class _$AnimeSearchStateImpl implements _AnimeSearchState {
|
||||||
_$_AnimeSearchState(
|
_$AnimeSearchStateImpl(
|
||||||
{this.trackingType = TrackingMediumType.anime,
|
{this.trackingType = TrackingMediumType.anime,
|
||||||
this.searchQuery = '',
|
this.searchQuery = '',
|
||||||
this.working = false,
|
this.working = false,
|
||||||
@@ -151,6 +159,7 @@ class _$_AnimeSearchState implements _AnimeSearchState {
|
|||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
List<SearchResult> get searchResults {
|
List<SearchResult> get searchResults {
|
||||||
|
if (_searchResults is EqualUnmodifiableListView) return _searchResults;
|
||||||
// ignore: implicit_dynamic_type
|
// ignore: implicit_dynamic_type
|
||||||
return EqualUnmodifiableListView(_searchResults);
|
return EqualUnmodifiableListView(_searchResults);
|
||||||
}
|
}
|
||||||
@@ -161,31 +170,31 @@ class _$_AnimeSearchState implements _AnimeSearchState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(dynamic other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _$_AnimeSearchState &&
|
other is _$AnimeSearchStateImpl &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.trackingType, trackingType) ||
|
||||||
.equals(other.trackingType, trackingType) &&
|
other.trackingType == trackingType) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.searchQuery, searchQuery) ||
|
||||||
.equals(other.searchQuery, searchQuery) &&
|
other.searchQuery == searchQuery) &&
|
||||||
const DeepCollectionEquality().equals(other.working, working) &&
|
(identical(other.working, working) || other.working == working) &&
|
||||||
const DeepCollectionEquality()
|
const DeepCollectionEquality()
|
||||||
.equals(other._searchResults, _searchResults));
|
.equals(other._searchResults, _searchResults));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(runtimeType, trackingType, searchQuery,
|
||||||
runtimeType,
|
working, const DeepCollectionEquality().hash(_searchResults));
|
||||||
const DeepCollectionEquality().hash(trackingType),
|
|
||||||
const DeepCollectionEquality().hash(searchQuery),
|
|
||||||
const DeepCollectionEquality().hash(working),
|
|
||||||
const DeepCollectionEquality().hash(_searchResults));
|
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of AnimeSearchState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
_$$_AnimeSearchStateCopyWith<_$_AnimeSearchState> get copyWith =>
|
@pragma('vm:prefer-inline')
|
||||||
__$$_AnimeSearchStateCopyWithImpl<_$_AnimeSearchState>(this, _$identity);
|
_$$AnimeSearchStateImplCopyWith<_$AnimeSearchStateImpl> get copyWith =>
|
||||||
|
__$$AnimeSearchStateImplCopyWithImpl<_$AnimeSearchStateImpl>(
|
||||||
|
this, _$identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class _AnimeSearchState implements AnimeSearchState {
|
abstract class _AnimeSearchState implements AnimeSearchState {
|
||||||
@@ -193,7 +202,7 @@ abstract class _AnimeSearchState implements AnimeSearchState {
|
|||||||
{final TrackingMediumType trackingType,
|
{final TrackingMediumType trackingType,
|
||||||
final String searchQuery,
|
final String searchQuery,
|
||||||
final bool working,
|
final bool working,
|
||||||
final List<SearchResult> searchResults}) = _$_AnimeSearchState;
|
final List<SearchResult> searchResults}) = _$AnimeSearchStateImpl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TrackingMediumType get trackingType;
|
TrackingMediumType get trackingType;
|
||||||
@@ -203,8 +212,11 @@ abstract class _AnimeSearchState implements AnimeSearchState {
|
|||||||
bool get working;
|
bool get working;
|
||||||
@override
|
@override
|
||||||
List<SearchResult> get searchResults;
|
List<SearchResult> get searchResults;
|
||||||
|
|
||||||
|
/// Create a copy of AnimeSearchState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$_AnimeSearchStateCopyWith<_$_AnimeSearchState> get copyWith =>
|
_$$AnimeSearchStateImplCopyWith<_$AnimeSearchStateImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|||||||
78
lib/src/ui/bloc/calendar_bloc.dart
Normal file
78
lib/src/ui/bloc/calendar_bloc.dart
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:anitrack/src/ui/bloc/anime_list_bloc.dart';
|
||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:get_it/get_it.dart';
|
||||||
|
import 'package:jikan_api/jikan_api.dart';
|
||||||
|
|
||||||
|
part 'calendar_state.dart';
|
||||||
|
part 'calendar_bloc.freezed.dart';
|
||||||
|
part 'calendar_event.dart';
|
||||||
|
|
||||||
|
class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||||
|
CalendarBloc() : super(CalendarState(false, 0, 0)) {
|
||||||
|
on<RefreshPerformedEvent>(_onRefreshPerformed);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onRefreshPerformed(
|
||||||
|
RefreshPerformedEvent event,
|
||||||
|
Emitter<CalendarState> emit,
|
||||||
|
) async {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
refreshing: true,
|
||||||
|
refreshingCount: 0,
|
||||||
|
refreshingTotal: 0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final al = GetIt.I.get<AnimeListBloc>();
|
||||||
|
final animes = al.unfilteredAnime.where((anime) => anime.airing);
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
refreshing: true,
|
||||||
|
refreshingCount: 0,
|
||||||
|
refreshingTotal: animes.length,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
for (final anime in animes) {
|
||||||
|
emit(state.copyWith(refreshingCount: state.refreshingCount + 1));
|
||||||
|
|
||||||
|
String? broadcastDay;
|
||||||
|
bool airing;
|
||||||
|
try {
|
||||||
|
final apiData = await Jikan().getAnime(int.parse(anime.id));
|
||||||
|
airing = apiData.airing;
|
||||||
|
broadcastDay = apiData.broadcast?.split(' ').first;
|
||||||
|
} catch (ex) {
|
||||||
|
print('API request for anime ${anime.id} failed: $ex');
|
||||||
|
airing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
print('Anime "${anime.title}": airing=$airing');
|
||||||
|
if (!airing) {
|
||||||
|
al.add(
|
||||||
|
AnimeUpdatedEvent(
|
||||||
|
anime.copyWith(airing: false, broadcastDay: null),
|
||||||
|
commit: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (anime.broadcastDay != broadcastDay) {
|
||||||
|
print('Updating Anime "${anime.title}": broadcastDay=$broadcastDay');
|
||||||
|
al.add(
|
||||||
|
AnimeUpdatedEvent(
|
||||||
|
anime.copyWith(airing: true, broadcastDay: broadcastDay),
|
||||||
|
commit: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent hammering Jikan
|
||||||
|
await Future<void>.delayed(const Duration(milliseconds: 500));
|
||||||
|
}
|
||||||
|
|
||||||
|
emit(state.copyWith(refreshing: false));
|
||||||
|
}
|
||||||
|
}
|
||||||
181
lib/src/ui/bloc/calendar_bloc.freezed.dart
Normal file
181
lib/src/ui/bloc/calendar_bloc.freezed.dart
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'calendar_bloc.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$CalendarState {
|
||||||
|
bool get refreshing => throw _privateConstructorUsedError;
|
||||||
|
int get refreshingCount => throw _privateConstructorUsedError;
|
||||||
|
int get refreshingTotal => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
/// Create a copy of CalendarState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
$CalendarStateCopyWith<CalendarState> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $CalendarStateCopyWith<$Res> {
|
||||||
|
factory $CalendarStateCopyWith(
|
||||||
|
CalendarState value, $Res Function(CalendarState) then) =
|
||||||
|
_$CalendarStateCopyWithImpl<$Res, CalendarState>;
|
||||||
|
@useResult
|
||||||
|
$Res call({bool refreshing, int refreshingCount, int refreshingTotal});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$CalendarStateCopyWithImpl<$Res, $Val extends CalendarState>
|
||||||
|
implements $CalendarStateCopyWith<$Res> {
|
||||||
|
_$CalendarStateCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of CalendarState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? refreshing = null,
|
||||||
|
Object? refreshingCount = null,
|
||||||
|
Object? refreshingTotal = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
refreshing: null == refreshing
|
||||||
|
? _value.refreshing
|
||||||
|
: refreshing // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
refreshingCount: null == refreshingCount
|
||||||
|
? _value.refreshingCount
|
||||||
|
: refreshingCount // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
refreshingTotal: null == refreshingTotal
|
||||||
|
? _value.refreshingTotal
|
||||||
|
: refreshingTotal // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$CalendarStateImplCopyWith<$Res>
|
||||||
|
implements $CalendarStateCopyWith<$Res> {
|
||||||
|
factory _$$CalendarStateImplCopyWith(
|
||||||
|
_$CalendarStateImpl value, $Res Function(_$CalendarStateImpl) then) =
|
||||||
|
__$$CalendarStateImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({bool refreshing, int refreshingCount, int refreshingTotal});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$CalendarStateImplCopyWithImpl<$Res>
|
||||||
|
extends _$CalendarStateCopyWithImpl<$Res, _$CalendarStateImpl>
|
||||||
|
implements _$$CalendarStateImplCopyWith<$Res> {
|
||||||
|
__$$CalendarStateImplCopyWithImpl(
|
||||||
|
_$CalendarStateImpl _value, $Res Function(_$CalendarStateImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
/// Create a copy of CalendarState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? refreshing = null,
|
||||||
|
Object? refreshingCount = null,
|
||||||
|
Object? refreshingTotal = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$CalendarStateImpl(
|
||||||
|
null == refreshing
|
||||||
|
? _value.refreshing
|
||||||
|
: refreshing // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
null == refreshingCount
|
||||||
|
? _value.refreshingCount
|
||||||
|
: refreshingCount // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
null == refreshingTotal
|
||||||
|
? _value.refreshingTotal
|
||||||
|
: refreshingTotal // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
class _$CalendarStateImpl implements _CalendarState {
|
||||||
|
_$CalendarStateImpl(
|
||||||
|
this.refreshing, this.refreshingCount, this.refreshingTotal);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final bool refreshing;
|
||||||
|
@override
|
||||||
|
final int refreshingCount;
|
||||||
|
@override
|
||||||
|
final int refreshingTotal;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'CalendarState(refreshing: $refreshing, refreshingCount: $refreshingCount, refreshingTotal: $refreshingTotal)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$CalendarStateImpl &&
|
||||||
|
(identical(other.refreshing, refreshing) ||
|
||||||
|
other.refreshing == refreshing) &&
|
||||||
|
(identical(other.refreshingCount, refreshingCount) ||
|
||||||
|
other.refreshingCount == refreshingCount) &&
|
||||||
|
(identical(other.refreshingTotal, refreshingTotal) ||
|
||||||
|
other.refreshingTotal == refreshingTotal));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
Object.hash(runtimeType, refreshing, refreshingCount, refreshingTotal);
|
||||||
|
|
||||||
|
/// Create a copy of CalendarState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$CalendarStateImplCopyWith<_$CalendarStateImpl> get copyWith =>
|
||||||
|
__$$CalendarStateImplCopyWithImpl<_$CalendarStateImpl>(this, _$identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _CalendarState implements CalendarState {
|
||||||
|
factory _CalendarState(final bool refreshing, final int refreshingCount,
|
||||||
|
final int refreshingTotal) = _$CalendarStateImpl;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get refreshing;
|
||||||
|
@override
|
||||||
|
int get refreshingCount;
|
||||||
|
@override
|
||||||
|
int get refreshingTotal;
|
||||||
|
|
||||||
|
/// Create a copy of CalendarState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$CalendarStateImplCopyWith<_$CalendarStateImpl> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
6
lib/src/ui/bloc/calendar_event.dart
Normal file
6
lib/src/ui/bloc/calendar_event.dart
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
part of 'calendar_bloc.dart';
|
||||||
|
|
||||||
|
abstract class CalendarEvent {}
|
||||||
|
|
||||||
|
/// Triggered by the UI when the user wants to refresh the airing anime list.
|
||||||
|
class RefreshPerformedEvent extends CalendarEvent {}
|
||||||
10
lib/src/ui/bloc/calendar_state.dart
Normal file
10
lib/src/ui/bloc/calendar_state.dart
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
part of 'calendar_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class CalendarState with _$CalendarState {
|
||||||
|
factory CalendarState(
|
||||||
|
bool refreshing,
|
||||||
|
int refreshingCount,
|
||||||
|
int refreshingTotal,
|
||||||
|
) = _CalendarState;
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ class DetailsBloc extends Bloc<DetailsEvent, DetailsState> {
|
|||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
trackingType: TrackingMediumType.anime,
|
trackingType: TrackingMediumType.anime,
|
||||||
|
heroImagePrefix: event.heroImagePrefix,
|
||||||
data: event.anime,
|
data: event.anime,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
part of 'details_bloc.dart';
|
part of 'details_bloc.dart';
|
||||||
|
|
||||||
@@ -12,14 +12,17 @@ part of 'details_bloc.dart';
|
|||||||
T _$identity<T>(T value) => value;
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
final _privateConstructorUsedError = UnsupportedError(
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$DetailsState {
|
mixin _$DetailsState {
|
||||||
TrackingMedium? get data => throw _privateConstructorUsedError;
|
TrackingMedium? get data => throw _privateConstructorUsedError;
|
||||||
|
String? get heroImagePrefix => throw _privateConstructorUsedError;
|
||||||
TrackingMediumType get trackingType => throw _privateConstructorUsedError;
|
TrackingMediumType get trackingType => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of DetailsState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$DetailsStateCopyWith<DetailsState> get copyWith =>
|
$DetailsStateCopyWith<DetailsState> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -28,68 +31,91 @@ mixin _$DetailsState {
|
|||||||
abstract class $DetailsStateCopyWith<$Res> {
|
abstract class $DetailsStateCopyWith<$Res> {
|
||||||
factory $DetailsStateCopyWith(
|
factory $DetailsStateCopyWith(
|
||||||
DetailsState value, $Res Function(DetailsState) then) =
|
DetailsState value, $Res Function(DetailsState) then) =
|
||||||
_$DetailsStateCopyWithImpl<$Res>;
|
_$DetailsStateCopyWithImpl<$Res, DetailsState>;
|
||||||
$Res call({TrackingMedium? data, TrackingMediumType trackingType});
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{TrackingMedium? data,
|
||||||
|
String? heroImagePrefix,
|
||||||
|
TrackingMediumType trackingType});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$DetailsStateCopyWithImpl<$Res> implements $DetailsStateCopyWith<$Res> {
|
class _$DetailsStateCopyWithImpl<$Res, $Val extends DetailsState>
|
||||||
|
implements $DetailsStateCopyWith<$Res> {
|
||||||
_$DetailsStateCopyWithImpl(this._value, this._then);
|
_$DetailsStateCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
final DetailsState _value;
|
|
||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function(DetailsState) _then;
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of DetailsState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? data = freezed,
|
Object? data = freezed,
|
||||||
Object? trackingType = freezed,
|
Object? heroImagePrefix = freezed,
|
||||||
|
Object? trackingType = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
data: data == freezed
|
data: freezed == data
|
||||||
? _value.data
|
? _value.data
|
||||||
: data // ignore: cast_nullable_to_non_nullable
|
: data // ignore: cast_nullable_to_non_nullable
|
||||||
as TrackingMedium?,
|
as TrackingMedium?,
|
||||||
trackingType: trackingType == freezed
|
heroImagePrefix: freezed == heroImagePrefix
|
||||||
|
? _value.heroImagePrefix
|
||||||
|
: heroImagePrefix // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
|
trackingType: null == trackingType
|
||||||
? _value.trackingType
|
? _value.trackingType
|
||||||
: trackingType // ignore: cast_nullable_to_non_nullable
|
: trackingType // ignore: cast_nullable_to_non_nullable
|
||||||
as TrackingMediumType,
|
as TrackingMediumType,
|
||||||
));
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class _$$_DetailsStateCopyWith<$Res>
|
abstract class _$$DetailsStateImplCopyWith<$Res>
|
||||||
implements $DetailsStateCopyWith<$Res> {
|
implements $DetailsStateCopyWith<$Res> {
|
||||||
factory _$$_DetailsStateCopyWith(
|
factory _$$DetailsStateImplCopyWith(
|
||||||
_$_DetailsState value, $Res Function(_$_DetailsState) then) =
|
_$DetailsStateImpl value, $Res Function(_$DetailsStateImpl) then) =
|
||||||
__$$_DetailsStateCopyWithImpl<$Res>;
|
__$$DetailsStateImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
$Res call({TrackingMedium? data, TrackingMediumType trackingType});
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{TrackingMedium? data,
|
||||||
|
String? heroImagePrefix,
|
||||||
|
TrackingMediumType trackingType});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class __$$_DetailsStateCopyWithImpl<$Res>
|
class __$$DetailsStateImplCopyWithImpl<$Res>
|
||||||
extends _$DetailsStateCopyWithImpl<$Res>
|
extends _$DetailsStateCopyWithImpl<$Res, _$DetailsStateImpl>
|
||||||
implements _$$_DetailsStateCopyWith<$Res> {
|
implements _$$DetailsStateImplCopyWith<$Res> {
|
||||||
__$$_DetailsStateCopyWithImpl(
|
__$$DetailsStateImplCopyWithImpl(
|
||||||
_$_DetailsState _value, $Res Function(_$_DetailsState) _then)
|
_$DetailsStateImpl _value, $Res Function(_$DetailsStateImpl) _then)
|
||||||
: super(_value, (v) => _then(v as _$_DetailsState));
|
: super(_value, _then);
|
||||||
|
|
||||||
@override
|
|
||||||
_$_DetailsState get _value => super._value as _$_DetailsState;
|
|
||||||
|
|
||||||
|
/// Create a copy of DetailsState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? data = freezed,
|
Object? data = freezed,
|
||||||
Object? trackingType = freezed,
|
Object? heroImagePrefix = freezed,
|
||||||
|
Object? trackingType = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$_DetailsState(
|
return _then(_$DetailsStateImpl(
|
||||||
data: data == freezed
|
data: freezed == data
|
||||||
? _value.data
|
? _value.data
|
||||||
: data // ignore: cast_nullable_to_non_nullable
|
: data // ignore: cast_nullable_to_non_nullable
|
||||||
as TrackingMedium?,
|
as TrackingMedium?,
|
||||||
trackingType: trackingType == freezed
|
heroImagePrefix: freezed == heroImagePrefix
|
||||||
|
? _value.heroImagePrefix
|
||||||
|
: heroImagePrefix // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
|
trackingType: null == trackingType
|
||||||
? _value.trackingType
|
? _value.trackingType
|
||||||
: trackingType // ignore: cast_nullable_to_non_nullable
|
: trackingType // ignore: cast_nullable_to_non_nullable
|
||||||
as TrackingMediumType,
|
as TrackingMediumType,
|
||||||
@@ -99,53 +125,67 @@ class __$$_DetailsStateCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
class _$_DetailsState implements _DetailsState {
|
class _$DetailsStateImpl implements _DetailsState {
|
||||||
_$_DetailsState({this.data, this.trackingType = TrackingMediumType.anime});
|
_$DetailsStateImpl(
|
||||||
|
{this.data,
|
||||||
|
this.heroImagePrefix,
|
||||||
|
this.trackingType = TrackingMediumType.anime});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final TrackingMedium? data;
|
final TrackingMedium? data;
|
||||||
@override
|
@override
|
||||||
|
final String? heroImagePrefix;
|
||||||
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
final TrackingMediumType trackingType;
|
final TrackingMediumType trackingType;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'DetailsState(data: $data, trackingType: $trackingType)';
|
return 'DetailsState(data: $data, heroImagePrefix: $heroImagePrefix, trackingType: $trackingType)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(dynamic other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _$_DetailsState &&
|
other is _$DetailsStateImpl &&
|
||||||
const DeepCollectionEquality().equals(other.data, data) &&
|
(identical(other.data, data) || other.data == data) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.heroImagePrefix, heroImagePrefix) ||
|
||||||
.equals(other.trackingType, trackingType));
|
other.heroImagePrefix == heroImagePrefix) &&
|
||||||
|
(identical(other.trackingType, trackingType) ||
|
||||||
|
other.trackingType == trackingType));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode =>
|
||||||
runtimeType,
|
Object.hash(runtimeType, data, heroImagePrefix, trackingType);
|
||||||
const DeepCollectionEquality().hash(data),
|
|
||||||
const DeepCollectionEquality().hash(trackingType));
|
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of DetailsState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
_$$_DetailsStateCopyWith<_$_DetailsState> get copyWith =>
|
@pragma('vm:prefer-inline')
|
||||||
__$$_DetailsStateCopyWithImpl<_$_DetailsState>(this, _$identity);
|
_$$DetailsStateImplCopyWith<_$DetailsStateImpl> get copyWith =>
|
||||||
|
__$$DetailsStateImplCopyWithImpl<_$DetailsStateImpl>(this, _$identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class _DetailsState implements DetailsState {
|
abstract class _DetailsState implements DetailsState {
|
||||||
factory _DetailsState(
|
factory _DetailsState(
|
||||||
{final TrackingMedium? data,
|
{final TrackingMedium? data,
|
||||||
final TrackingMediumType trackingType}) = _$_DetailsState;
|
final String? heroImagePrefix,
|
||||||
|
final TrackingMediumType trackingType}) = _$DetailsStateImpl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TrackingMedium? get data;
|
TrackingMedium? get data;
|
||||||
@override
|
@override
|
||||||
TrackingMediumType get trackingType;
|
String? get heroImagePrefix;
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
TrackingMediumType get trackingType;
|
||||||
_$$_DetailsStateCopyWith<_$_DetailsState> get copyWith =>
|
|
||||||
|
/// Create a copy of DetailsState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
_$$DetailsStateImplCopyWith<_$DetailsStateImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,15 @@ part of 'details_bloc.dart';
|
|||||||
abstract class DetailsEvent {}
|
abstract class DetailsEvent {}
|
||||||
|
|
||||||
class AnimeDetailsRequestedEvent extends DetailsEvent {
|
class AnimeDetailsRequestedEvent extends DetailsEvent {
|
||||||
AnimeDetailsRequestedEvent(this.anime);
|
AnimeDetailsRequestedEvent(
|
||||||
|
this.anime, {
|
||||||
|
this.heroImagePrefix,
|
||||||
|
});
|
||||||
|
|
||||||
/// The anime to show details about
|
/// The anime to show details about
|
||||||
final AnimeTrackingData anime;
|
final AnimeTrackingData anime;
|
||||||
|
|
||||||
|
final String? heroImagePrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MangaDetailsRequestedEvent extends DetailsEvent {
|
class MangaDetailsRequestedEvent extends DetailsEvent {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ part of 'details_bloc.dart';
|
|||||||
class DetailsState with _$DetailsState {
|
class DetailsState with _$DetailsState {
|
||||||
factory DetailsState({
|
factory DetailsState({
|
||||||
TrackingMedium? data,
|
TrackingMedium? data,
|
||||||
|
String? heroImagePrefix,
|
||||||
@Default(TrackingMediumType.anime) TrackingMediumType trackingType,
|
@Default(TrackingMediumType.anime) TrackingMediumType trackingType,
|
||||||
}) = _DetailsState;
|
}) = _DetailsState;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,25 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:anitrack/i18n/strings.g.dart';
|
||||||
import 'package:anitrack/src/data/anime.dart';
|
import 'package:anitrack/src/data/anime.dart';
|
||||||
import 'package:anitrack/src/data/manga.dart';
|
import 'package:anitrack/src/data/manga.dart';
|
||||||
import 'package:anitrack/src/data/type.dart';
|
import 'package:anitrack/src/data/type.dart';
|
||||||
import 'package:anitrack/src/service/database.dart';
|
import 'package:anitrack/src/service/database.dart';
|
||||||
|
import 'package:anitrack/src/ui/bloc/anime_list_bloc.dart';
|
||||||
|
import 'package:archive/archive.dart' as archive;
|
||||||
import 'package:archive/archive_io.dart';
|
import 'package:archive/archive_io.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
import 'package:jikan_api/jikan_api.dart';
|
import 'package:jikan_api/jikan_api.dart';
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
import 'package:xml/xml.dart';
|
import 'package:xml/xml.dart';
|
||||||
|
|
||||||
part 'settings_state.dart';
|
|
||||||
part 'settings_event.dart';
|
|
||||||
part 'settings_bloc.freezed.dart';
|
part 'settings_bloc.freezed.dart';
|
||||||
|
part 'settings_event.dart';
|
||||||
|
part 'settings_state.dart';
|
||||||
|
|
||||||
MediumTrackingState malStatusToTrackingState(String status) {
|
MediumTrackingState malStatusToTrackingState(String status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
@@ -39,6 +45,8 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
|
|||||||
SettingsBloc() : super(SettingsState()) {
|
SettingsBloc() : super(SettingsState()) {
|
||||||
on<AnimeListImportedEvent>(_onAnimeListImported);
|
on<AnimeListImportedEvent>(_onAnimeListImported);
|
||||||
on<MangaListImportedEvent>(_onMangaListImported);
|
on<MangaListImportedEvent>(_onMangaListImported);
|
||||||
|
on<DataExportedEvent>(_onDataExported);
|
||||||
|
on<DataImportedEvent>(_onDataImported);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showLoadingSpinner(Emitter<SettingsState> emit) {
|
void _showLoadingSpinner(Emitter<SettingsState> emit) {
|
||||||
@@ -119,6 +127,9 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
|
|||||||
// 0 means that MAL does not know
|
// 0 means that MAL does not know
|
||||||
totalEpisodes == 0 ? null : totalEpisodes,
|
totalEpisodes == 0 ? null : totalEpisodes,
|
||||||
data.imageUrl,
|
data.imageUrl,
|
||||||
|
// NOTE: When the calendar gets refreshed, this should also get cleared
|
||||||
|
true,
|
||||||
|
null,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -202,4 +213,69 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
|
|||||||
// Hide the spinner again
|
// Hide the spinner again
|
||||||
_hideLoadingSpinner(emit);
|
_hideLoadingSpinner(emit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _onDataExported(
|
||||||
|
DataExportedEvent event,
|
||||||
|
Emitter<SettingsState> emit,
|
||||||
|
) async {
|
||||||
|
final al = GetIt.I.get<AnimeListBloc>();
|
||||||
|
final data = {
|
||||||
|
// TODO(Unknown): Track the version here to (maybe) to migrations
|
||||||
|
'animes': al.state.animes.map((anime) => anime.toJson()).toList(),
|
||||||
|
'mangas': al.state.mangas.map((manga) => manga.toJson()).toList(),
|
||||||
|
};
|
||||||
|
final exportData = jsonEncode(data);
|
||||||
|
final date = DateTime.now();
|
||||||
|
final outputPath = path.join(
|
||||||
|
event.path,
|
||||||
|
'anitrack_${date.year}${date.month}${date.day}.json.gz',
|
||||||
|
);
|
||||||
|
archive.GZipEncoder().encode(
|
||||||
|
InputStream(utf8.encode(exportData)),
|
||||||
|
output: OutputFileStream(outputPath),
|
||||||
|
);
|
||||||
|
|
||||||
|
await Fluttertoast.showToast(
|
||||||
|
msg: t.settings.dataExportSuccess,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onDataImported(
|
||||||
|
DataImportedEvent event,
|
||||||
|
Emitter<SettingsState> emit,
|
||||||
|
) async {
|
||||||
|
final al = GetIt.I.get<AnimeListBloc>();
|
||||||
|
final exportArchive = archive.GZipDecoder().decodeBytes(
|
||||||
|
await File(event.path).readAsBytes(),
|
||||||
|
);
|
||||||
|
final json = jsonDecode(utf8.decode(exportArchive)) as Map<String, dynamic>;
|
||||||
|
|
||||||
|
// Process anime
|
||||||
|
for (final animeRaw
|
||||||
|
in (json['animes']! as List<dynamic>).cast<Map<dynamic, dynamic>>()) {
|
||||||
|
final anime = AnimeTrackingData.fromJson(
|
||||||
|
animeRaw.cast<String, dynamic>(),
|
||||||
|
);
|
||||||
|
|
||||||
|
al.add(
|
||||||
|
AnimeAddedEvent(anime, checkIfExists: true),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process manga
|
||||||
|
for (final mangaRaw
|
||||||
|
in (json['mangas']! as List<dynamic>).cast<Map<dynamic, dynamic>>()) {
|
||||||
|
final manga = MangaTrackingData.fromJson(
|
||||||
|
mangaRaw.cast<String, dynamic>(),
|
||||||
|
);
|
||||||
|
|
||||||
|
al.add(
|
||||||
|
MangaAddedEvent(manga, checkIfExists: true),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Fluttertoast.showToast(
|
||||||
|
msg: t.settings.dataImportSuccess,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
part of 'settings_bloc.dart';
|
part of 'settings_bloc.dart';
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ part of 'settings_bloc.dart';
|
|||||||
T _$identity<T>(T value) => value;
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
final _privateConstructorUsedError = UnsupportedError(
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SettingsState {
|
mixin _$SettingsState {
|
||||||
@@ -20,7 +20,9 @@ mixin _$SettingsState {
|
|||||||
int get importCurrent => throw _privateConstructorUsedError;
|
int get importCurrent => throw _privateConstructorUsedError;
|
||||||
int get importTotal => throw _privateConstructorUsedError;
|
int get importTotal => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of SettingsState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
$SettingsStateCopyWith<SettingsState> get copyWith =>
|
$SettingsStateCopyWith<SettingsState> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
@@ -29,79 +31,85 @@ mixin _$SettingsState {
|
|||||||
abstract class $SettingsStateCopyWith<$Res> {
|
abstract class $SettingsStateCopyWith<$Res> {
|
||||||
factory $SettingsStateCopyWith(
|
factory $SettingsStateCopyWith(
|
||||||
SettingsState value, $Res Function(SettingsState) then) =
|
SettingsState value, $Res Function(SettingsState) then) =
|
||||||
_$SettingsStateCopyWithImpl<$Res>;
|
_$SettingsStateCopyWithImpl<$Res, SettingsState>;
|
||||||
|
@useResult
|
||||||
$Res call({bool importSpinnerVisible, int importCurrent, int importTotal});
|
$Res call({bool importSpinnerVisible, int importCurrent, int importTotal});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$SettingsStateCopyWithImpl<$Res>
|
class _$SettingsStateCopyWithImpl<$Res, $Val extends SettingsState>
|
||||||
implements $SettingsStateCopyWith<$Res> {
|
implements $SettingsStateCopyWith<$Res> {
|
||||||
_$SettingsStateCopyWithImpl(this._value, this._then);
|
_$SettingsStateCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
final SettingsState _value;
|
|
||||||
// ignore: unused_field
|
// ignore: unused_field
|
||||||
final $Res Function(SettingsState) _then;
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SettingsState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? importSpinnerVisible = freezed,
|
Object? importSpinnerVisible = null,
|
||||||
Object? importCurrent = freezed,
|
Object? importCurrent = null,
|
||||||
Object? importTotal = freezed,
|
Object? importTotal = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
importSpinnerVisible: importSpinnerVisible == freezed
|
importSpinnerVisible: null == importSpinnerVisible
|
||||||
? _value.importSpinnerVisible
|
? _value.importSpinnerVisible
|
||||||
: importSpinnerVisible // ignore: cast_nullable_to_non_nullable
|
: importSpinnerVisible // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
importCurrent: importCurrent == freezed
|
importCurrent: null == importCurrent
|
||||||
? _value.importCurrent
|
? _value.importCurrent
|
||||||
: importCurrent // ignore: cast_nullable_to_non_nullable
|
: importCurrent // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
importTotal: importTotal == freezed
|
importTotal: null == importTotal
|
||||||
? _value.importTotal
|
? _value.importTotal
|
||||||
: importTotal // ignore: cast_nullable_to_non_nullable
|
: importTotal // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
));
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class _$$_SettingsStateCopyWith<$Res>
|
abstract class _$$SettingsStateImplCopyWith<$Res>
|
||||||
implements $SettingsStateCopyWith<$Res> {
|
implements $SettingsStateCopyWith<$Res> {
|
||||||
factory _$$_SettingsStateCopyWith(
|
factory _$$SettingsStateImplCopyWith(
|
||||||
_$_SettingsState value, $Res Function(_$_SettingsState) then) =
|
_$SettingsStateImpl value, $Res Function(_$SettingsStateImpl) then) =
|
||||||
__$$_SettingsStateCopyWithImpl<$Res>;
|
__$$SettingsStateImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
|
@useResult
|
||||||
$Res call({bool importSpinnerVisible, int importCurrent, int importTotal});
|
$Res call({bool importSpinnerVisible, int importCurrent, int importTotal});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class __$$_SettingsStateCopyWithImpl<$Res>
|
class __$$SettingsStateImplCopyWithImpl<$Res>
|
||||||
extends _$SettingsStateCopyWithImpl<$Res>
|
extends _$SettingsStateCopyWithImpl<$Res, _$SettingsStateImpl>
|
||||||
implements _$$_SettingsStateCopyWith<$Res> {
|
implements _$$SettingsStateImplCopyWith<$Res> {
|
||||||
__$$_SettingsStateCopyWithImpl(
|
__$$SettingsStateImplCopyWithImpl(
|
||||||
_$_SettingsState _value, $Res Function(_$_SettingsState) _then)
|
_$SettingsStateImpl _value, $Res Function(_$SettingsStateImpl) _then)
|
||||||
: super(_value, (v) => _then(v as _$_SettingsState));
|
: super(_value, _then);
|
||||||
|
|
||||||
@override
|
|
||||||
_$_SettingsState get _value => super._value as _$_SettingsState;
|
|
||||||
|
|
||||||
|
/// Create a copy of SettingsState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? importSpinnerVisible = freezed,
|
Object? importSpinnerVisible = null,
|
||||||
Object? importCurrent = freezed,
|
Object? importCurrent = null,
|
||||||
Object? importTotal = freezed,
|
Object? importTotal = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$_SettingsState(
|
return _then(_$SettingsStateImpl(
|
||||||
importSpinnerVisible: importSpinnerVisible == freezed
|
importSpinnerVisible: null == importSpinnerVisible
|
||||||
? _value.importSpinnerVisible
|
? _value.importSpinnerVisible
|
||||||
: importSpinnerVisible // ignore: cast_nullable_to_non_nullable
|
: importSpinnerVisible // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,
|
||||||
importCurrent: importCurrent == freezed
|
importCurrent: null == importCurrent
|
||||||
? _value.importCurrent
|
? _value.importCurrent
|
||||||
: importCurrent // ignore: cast_nullable_to_non_nullable
|
: importCurrent // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
importTotal: importTotal == freezed
|
importTotal: null == importTotal
|
||||||
? _value.importTotal
|
? _value.importTotal
|
||||||
: importTotal // ignore: cast_nullable_to_non_nullable
|
: importTotal // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
@@ -111,8 +119,8 @@ class __$$_SettingsStateCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
class _$_SettingsState implements _SettingsState {
|
class _$SettingsStateImpl implements _SettingsState {
|
||||||
_$_SettingsState(
|
_$SettingsStateImpl(
|
||||||
{this.importSpinnerVisible = false,
|
{this.importSpinnerVisible = false,
|
||||||
this.importCurrent = 0,
|
this.importCurrent = 0,
|
||||||
this.importTotal = 0});
|
this.importTotal = 0});
|
||||||
@@ -133,36 +141,36 @@ class _$_SettingsState implements _SettingsState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(dynamic other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _$_SettingsState &&
|
other is _$SettingsStateImpl &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.importSpinnerVisible, importSpinnerVisible) ||
|
||||||
.equals(other.importSpinnerVisible, importSpinnerVisible) &&
|
other.importSpinnerVisible == importSpinnerVisible) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.importCurrent, importCurrent) ||
|
||||||
.equals(other.importCurrent, importCurrent) &&
|
other.importCurrent == importCurrent) &&
|
||||||
const DeepCollectionEquality()
|
(identical(other.importTotal, importTotal) ||
|
||||||
.equals(other.importTotal, importTotal));
|
other.importTotal == importTotal));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
runtimeType,
|
runtimeType, importSpinnerVisible, importCurrent, importTotal);
|
||||||
const DeepCollectionEquality().hash(importSpinnerVisible),
|
|
||||||
const DeepCollectionEquality().hash(importCurrent),
|
|
||||||
const DeepCollectionEquality().hash(importTotal));
|
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
/// Create a copy of SettingsState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
_$$_SettingsStateCopyWith<_$_SettingsState> get copyWith =>
|
@pragma('vm:prefer-inline')
|
||||||
__$$_SettingsStateCopyWithImpl<_$_SettingsState>(this, _$identity);
|
_$$SettingsStateImplCopyWith<_$SettingsStateImpl> get copyWith =>
|
||||||
|
__$$SettingsStateImplCopyWithImpl<_$SettingsStateImpl>(this, _$identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class _SettingsState implements SettingsState {
|
abstract class _SettingsState implements SettingsState {
|
||||||
factory _SettingsState(
|
factory _SettingsState(
|
||||||
{final bool importSpinnerVisible,
|
{final bool importSpinnerVisible,
|
||||||
final int importCurrent,
|
final int importCurrent,
|
||||||
final int importTotal}) = _$_SettingsState;
|
final int importTotal}) = _$SettingsStateImpl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get importSpinnerVisible;
|
bool get importSpinnerVisible;
|
||||||
@@ -170,8 +178,11 @@ abstract class _SettingsState implements SettingsState {
|
|||||||
int get importCurrent;
|
int get importCurrent;
|
||||||
@override
|
@override
|
||||||
int get importTotal;
|
int get importTotal;
|
||||||
|
|
||||||
|
/// Create a copy of SettingsState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
_$$_SettingsStateCopyWith<_$_SettingsState> get copyWith =>
|
_$$SettingsStateImplCopyWith<_$SettingsStateImpl> get copyWith =>
|
||||||
throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,3 +34,19 @@ class MangaListImportedEvent extends SettingsEvent {
|
|||||||
/// The type of list we're importing
|
/// The type of list we're importing
|
||||||
final ImportListType type;
|
final ImportListType type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Triggered when a data export should be produced.
|
||||||
|
class DataExportedEvent extends SettingsEvent {
|
||||||
|
DataExportedEvent(this.path);
|
||||||
|
|
||||||
|
/// The path where the export should be stored.
|
||||||
|
final String path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Triggered when a data export has been picked for import.
|
||||||
|
class DataImportedEvent extends SettingsEvent {
|
||||||
|
DataImportedEvent(this.path);
|
||||||
|
|
||||||
|
/// The path of the data export to import.
|
||||||
|
final String path;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
const animeListRoute = '/anime/list';
|
const animeListRoute = '/anime/list';
|
||||||
const animeSearchRoute = '/anime/search';
|
const animeSearchRoute = '/anime/search';
|
||||||
const detailsRoute = '/anime/details';
|
const detailsRoute = '/anime/details';
|
||||||
|
const calendarRoute = '/calendar';
|
||||||
const aboutRoute = '/about';
|
const aboutRoute = '/about';
|
||||||
const settingsRoute = '/settings';
|
const settingsRoute = '/settings';
|
||||||
|
|||||||
58
lib/src/ui/helpers.dart
Normal file
58
lib/src/ui/helpers.dart
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import 'package:anitrack/i18n/strings.g.dart';
|
||||||
|
import 'package:anitrack/src/ui/constants.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
Widget getDrawer(BuildContext context) {
|
||||||
|
return Drawer(
|
||||||
|
child: ListView(
|
||||||
|
children: [
|
||||||
|
const DrawerHeader(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xffcf4aff),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'AniTrack',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color(0xff232323),
|
||||||
|
fontSize: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.list),
|
||||||
|
title: Text(t.content.list),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||||
|
animeListRoute,
|
||||||
|
(_) => false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.calendar_today),
|
||||||
|
title: Text(t.calendar.calendar),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||||
|
calendarRoute,
|
||||||
|
(_) => false,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.settings),
|
||||||
|
title: Text(t.settings.title),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pushNamed(settingsRoute);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.info),
|
||||||
|
title: Text(t.about.title),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pushNamed(aboutRoute);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import 'package:anitrack/i18n/strings.g.dart';
|
|||||||
import 'package:anitrack/licenses.g.dart';
|
import 'package:anitrack/licenses.g.dart';
|
||||||
import 'package:anitrack/src/ui/constants.dart';
|
import 'package:anitrack/src/ui/constants.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
class AboutPage extends StatelessWidget {
|
class AboutPage extends StatelessWidget {
|
||||||
@@ -35,15 +36,55 @@ class AboutPage extends StatelessWidget {
|
|||||||
'AniTrack',
|
'AniTrack',
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
|
child: ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await launchUrl(
|
await launchUrl(
|
||||||
Uri.parse('https://codeberg.org/PapaTutuWawa/anitrack'),
|
Uri.parse(
|
||||||
|
'https://codeberg.org/PapaTutuWawa/anitrack',
|
||||||
|
),
|
||||||
mode: LaunchMode.externalApplication,
|
mode: LaunchMode.externalApplication,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Text(t.about.source),
|
child: Text(t.about.source),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () async {
|
||||||
|
final licenseText = await rootBundle.loadString(
|
||||||
|
'LICENSE',
|
||||||
|
);
|
||||||
|
await showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return AlertDialog(
|
||||||
|
content: SingleChildScrollView(
|
||||||
|
child: Text(licenseText),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text(t.about.close),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Text(t.about.license),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -54,14 +95,34 @@ class AboutPage extends StatelessWidget {
|
|||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(dep.name),
|
title: Text(dep.name),
|
||||||
onTap: () async {
|
onTap: () {
|
||||||
if (dep.repository == null) return;
|
showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
content: SingleChildScrollView(
|
||||||
|
child: Text(dep.license ?? ''),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text(t.about.close),
|
||||||
|
),
|
||||||
|
if (dep.repository != null)
|
||||||
|
TextButton(
|
||||||
|
onPressed: () async {
|
||||||
await launchUrl(
|
await launchUrl(
|
||||||
Uri.parse(dep.repository!),
|
Uri.parse(dep.repository!),
|
||||||
mode: LaunchMode.externalApplication,
|
mode: LaunchMode.externalApplication,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
child: Text(t.about.source),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:anitrack/src/ui/bloc/anime_list_bloc.dart';
|
|||||||
import 'package:anitrack/src/ui/bloc/anime_search_bloc.dart';
|
import 'package:anitrack/src/ui/bloc/anime_search_bloc.dart';
|
||||||
import 'package:anitrack/src/ui/bloc/details_bloc.dart';
|
import 'package:anitrack/src/ui/bloc/details_bloc.dart';
|
||||||
import 'package:anitrack/src/ui/constants.dart';
|
import 'package:anitrack/src/ui/constants.dart';
|
||||||
|
import 'package:anitrack/src/ui/helpers.dart';
|
||||||
import 'package:anitrack/src/ui/widgets/grid_item.dart';
|
import 'package:anitrack/src/ui/widgets/grid_item.dart';
|
||||||
import 'package:anitrack/src/ui/widgets/image.dart';
|
import 'package:anitrack/src/ui/widgets/image.dart';
|
||||||
import 'package:bottom_bar/bottom_bar.dart';
|
import 'package:bottom_bar/bottom_bar.dart';
|
||||||
@@ -71,23 +72,23 @@ class AnimeListPageState extends State<AnimeListPage> {
|
|||||||
return [
|
return [
|
||||||
PopupMenuItem<MediumTrackingState>(
|
PopupMenuItem<MediumTrackingState>(
|
||||||
value: MediumTrackingState.ongoing,
|
value: MediumTrackingState.ongoing,
|
||||||
child: Text(MediumTrackingState.ongoing.toNameString(type)),
|
child: Text(MediumTrackingState.ongoing.getName(type)),
|
||||||
),
|
),
|
||||||
PopupMenuItem<MediumTrackingState>(
|
PopupMenuItem<MediumTrackingState>(
|
||||||
value: MediumTrackingState.completed,
|
value: MediumTrackingState.completed,
|
||||||
child: Text(MediumTrackingState.completed.toNameString(type)),
|
child: Text(MediumTrackingState.completed.getName(type)),
|
||||||
),
|
),
|
||||||
PopupMenuItem<MediumTrackingState>(
|
PopupMenuItem<MediumTrackingState>(
|
||||||
value: MediumTrackingState.planned,
|
value: MediumTrackingState.planned,
|
||||||
child: Text(MediumTrackingState.planned.toNameString(type)),
|
child: Text(MediumTrackingState.planned.getName(type)),
|
||||||
),
|
),
|
||||||
PopupMenuItem<MediumTrackingState>(
|
PopupMenuItem<MediumTrackingState>(
|
||||||
value: MediumTrackingState.dropped,
|
value: MediumTrackingState.dropped,
|
||||||
child: Text(MediumTrackingState.dropped.toNameString(type)),
|
child: Text(MediumTrackingState.dropped.getName(type)),
|
||||||
),
|
),
|
||||||
PopupMenuItem<MediumTrackingState>(
|
PopupMenuItem<MediumTrackingState>(
|
||||||
value: MediumTrackingState.paused,
|
value: MediumTrackingState.paused,
|
||||||
child: Text(MediumTrackingState.paused.toNameString(type)),
|
child: Text(MediumTrackingState.paused.getName(type)),
|
||||||
),
|
),
|
||||||
const PopupMenuItem<MediumTrackingState>(
|
const PopupMenuItem<MediumTrackingState>(
|
||||||
value: MediumTrackingState.all,
|
value: MediumTrackingState.all,
|
||||||
@@ -140,38 +141,7 @@ class AnimeListPageState extends State<AnimeListPage> {
|
|||||||
_getPopupButton(context, state),
|
_getPopupButton(context, state),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
drawer: Drawer(
|
drawer: getDrawer(context),
|
||||||
child: ListView(
|
|
||||||
children: [
|
|
||||||
const DrawerHeader(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Color(0xffcf4aff),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
'AniTrack',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Color(0xff232323),
|
|
||||||
fontSize: 24,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
leading: const Icon(Icons.settings),
|
|
||||||
title: Text(t.settings.title),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).pushNamed(settingsRoute);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ListTile(
|
|
||||||
leading: const Icon(Icons.info),
|
|
||||||
title: Text(t.about.title),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).pushNamed(aboutRoute);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: PageView(
|
body: PageView(
|
||||||
// Prevent swiping between pages
|
// Prevent swiping between pages
|
||||||
// (https://github.com/flutter/flutter/issues/37510#issuecomment-612663656)
|
// (https://github.com/flutter/flutter/issues/37510#issuecomment-612663656)
|
||||||
|
|||||||
317
lib/src/ui/pages/calendar.dart
Normal file
317
lib/src/ui/pages/calendar.dart
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
import 'package:anitrack/i18n/strings.g.dart';
|
||||||
|
import 'package:anitrack/src/data/anime.dart';
|
||||||
|
import 'package:anitrack/src/ui/bloc/anime_list_bloc.dart';
|
||||||
|
import 'package:anitrack/src/ui/bloc/calendar_bloc.dart';
|
||||||
|
import 'package:anitrack/src/ui/bloc/details_bloc.dart';
|
||||||
|
import 'package:anitrack/src/ui/constants.dart';
|
||||||
|
import 'package:anitrack/src/ui/helpers.dart';
|
||||||
|
import 'package:anitrack/src/ui/widgets/grid_item.dart';
|
||||||
|
import 'package:anitrack/src/ui/widgets/image.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:get_it/get_it.dart';
|
||||||
|
|
||||||
|
enum Weekday {
|
||||||
|
monday,
|
||||||
|
tuesday,
|
||||||
|
wednesday,
|
||||||
|
thursday,
|
||||||
|
friday,
|
||||||
|
saturday,
|
||||||
|
sunday,
|
||||||
|
unknown;
|
||||||
|
|
||||||
|
String toName() {
|
||||||
|
switch (this) {
|
||||||
|
case Weekday.monday:
|
||||||
|
return t.calendar.days.monday;
|
||||||
|
case Weekday.tuesday:
|
||||||
|
return t.calendar.days.tuesday;
|
||||||
|
case Weekday.wednesday:
|
||||||
|
return t.calendar.days.wednesday;
|
||||||
|
case Weekday.thursday:
|
||||||
|
return t.calendar.days.thursday;
|
||||||
|
case Weekday.friday:
|
||||||
|
return t.calendar.days.friday;
|
||||||
|
case Weekday.saturday:
|
||||||
|
return t.calendar.days.saturday;
|
||||||
|
case Weekday.sunday:
|
||||||
|
return t.calendar.days.sunday;
|
||||||
|
case Weekday.unknown:
|
||||||
|
return t.calendar.days.unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AddIfExists<K, V> on Map<K, List<V>> {
|
||||||
|
void addOrSet(K key, V value) {
|
||||||
|
if (containsKey(key)) {
|
||||||
|
this[key]!.add(value);
|
||||||
|
} else {
|
||||||
|
this[key] = List<V>.from([value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CalendarPage extends StatefulWidget {
|
||||||
|
const CalendarPage({super.key});
|
||||||
|
|
||||||
|
static MaterialPageRoute<dynamic> get route => MaterialPageRoute<dynamic>(
|
||||||
|
builder: (_) => const CalendarPage(),
|
||||||
|
settings: const RouteSettings(
|
||||||
|
name: calendarRoute,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
CalendarPageState createState() => CalendarPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class CalendarPageState extends State<CalendarPage> {
|
||||||
|
List<Widget> _renderWeekdayList(
|
||||||
|
BuildContext context,
|
||||||
|
Weekday day,
|
||||||
|
Map<Weekday, List<AnimeTrackingData>> data,
|
||||||
|
) {
|
||||||
|
if (!data.containsKey(day)) {
|
||||||
|
return const [];
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(data[day]!.isNotEmpty, 'There should be at least one anime');
|
||||||
|
return [
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
right: 16,
|
||||||
|
top: 20,
|
||||||
|
bottom: 4,
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
day.toName(),
|
||||||
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SliverGrid.builder(
|
||||||
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 3,
|
||||||
|
mainAxisSpacing: 8,
|
||||||
|
crossAxisSpacing: 8,
|
||||||
|
childAspectRatio: 120 / (100 * (16 / 9)),
|
||||||
|
),
|
||||||
|
itemCount: data[day]!.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final anime = data[day]![index];
|
||||||
|
return GridItem(
|
||||||
|
child: AnimeCoverImage(
|
||||||
|
url: anime.thumbnailUrl,
|
||||||
|
hero: 'calendar_${anime.id}',
|
||||||
|
onTap: () {
|
||||||
|
context.read<DetailsBloc>().add(
|
||||||
|
AnimeDetailsRequestedEvent(
|
||||||
|
anime,
|
||||||
|
heroImagePrefix: 'calendar_',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final airingAnimeMap = <Weekday, List<AnimeTrackingData>>{};
|
||||||
|
for (final anime in GetIt.I.get<AnimeListBloc>().unfilteredAnime) {
|
||||||
|
if (!anime.airing) continue;
|
||||||
|
|
||||||
|
final Weekday day;
|
||||||
|
switch (anime.broadcastDay) {
|
||||||
|
case 'Mondays':
|
||||||
|
day = Weekday.monday;
|
||||||
|
break;
|
||||||
|
case 'Tuesdays':
|
||||||
|
day = Weekday.tuesday;
|
||||||
|
break;
|
||||||
|
case 'Wednesdays':
|
||||||
|
day = Weekday.wednesday;
|
||||||
|
break;
|
||||||
|
case 'Thursdays':
|
||||||
|
day = Weekday.thursday;
|
||||||
|
break;
|
||||||
|
case 'Fridays':
|
||||||
|
day = Weekday.friday;
|
||||||
|
break;
|
||||||
|
case 'Saturdays':
|
||||||
|
day = Weekday.saturday;
|
||||||
|
break;
|
||||||
|
case 'Sundays':
|
||||||
|
day = Weekday.sunday;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
day = Weekday.unknown;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
airingAnimeMap.addOrSet(day, anime);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BlocListener<CalendarBloc, CalendarState>(
|
||||||
|
listenWhen: (previous, current) =>
|
||||||
|
previous.refreshing != current.refreshing,
|
||||||
|
listener: (context, state) {
|
||||||
|
// Force an update
|
||||||
|
if (!state.refreshing) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: WillPopScope(
|
||||||
|
onWillPop: () async => !context.read<CalendarBloc>().state.refreshing,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Positioned(
|
||||||
|
left: 8,
|
||||||
|
right: 8,
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(t.calendar.calendar),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
context
|
||||||
|
.read<CalendarBloc>()
|
||||||
|
.add(RefreshPerformedEvent());
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.refresh),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
drawer: getDrawer(context),
|
||||||
|
body: CustomScrollView(
|
||||||
|
slivers: [
|
||||||
|
// Render all available weekdays
|
||||||
|
..._renderWeekdayList(
|
||||||
|
context,
|
||||||
|
Weekday.unknown,
|
||||||
|
airingAnimeMap,
|
||||||
|
),
|
||||||
|
..._renderWeekdayList(
|
||||||
|
context,
|
||||||
|
Weekday.monday,
|
||||||
|
airingAnimeMap,
|
||||||
|
),
|
||||||
|
..._renderWeekdayList(
|
||||||
|
context,
|
||||||
|
Weekday.tuesday,
|
||||||
|
airingAnimeMap,
|
||||||
|
),
|
||||||
|
..._renderWeekdayList(
|
||||||
|
context,
|
||||||
|
Weekday.wednesday,
|
||||||
|
airingAnimeMap,
|
||||||
|
),
|
||||||
|
..._renderWeekdayList(
|
||||||
|
context,
|
||||||
|
Weekday.thursday,
|
||||||
|
airingAnimeMap,
|
||||||
|
),
|
||||||
|
..._renderWeekdayList(
|
||||||
|
context,
|
||||||
|
Weekday.friday,
|
||||||
|
airingAnimeMap,
|
||||||
|
),
|
||||||
|
..._renderWeekdayList(
|
||||||
|
context,
|
||||||
|
Weekday.saturday,
|
||||||
|
airingAnimeMap,
|
||||||
|
),
|
||||||
|
..._renderWeekdayList(
|
||||||
|
context,
|
||||||
|
Weekday.sunday,
|
||||||
|
airingAnimeMap,
|
||||||
|
),
|
||||||
|
|
||||||
|
// Provide a nice bottom padding, while keeping the elastic effect attached
|
||||||
|
// to the bottom-most edge.
|
||||||
|
const SliverToBoxAdapter(
|
||||||
|
child: SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
child: BlocBuilder<CalendarBloc, CalendarState>(
|
||||||
|
buildWhen: (previous, current) =>
|
||||||
|
previous.refreshing != current.refreshing,
|
||||||
|
builder: (context, state) {
|
||||||
|
if (!state.refreshing) {
|
||||||
|
return const SizedBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
return const ModalBarrier(
|
||||||
|
dismissible: false,
|
||||||
|
color: Colors.black54,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
child: BlocBuilder<CalendarBloc, CalendarState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
if (!state.refreshing) {
|
||||||
|
return const SizedBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 150,
|
||||||
|
height: 150,
|
||||||
|
child: DecoratedBox(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
color: Colors.grey.shade800,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.all(25),
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
t.settings.importIndicator(
|
||||||
|
current: state.refreshingCount,
|
||||||
|
total: state.refreshingTotal,
|
||||||
|
),
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,7 +42,7 @@ class DetailsPage extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
AnimeCoverImage(
|
AnimeCoverImage(
|
||||||
url: state.data!.thumbnailUrl,
|
url: state.data!.thumbnailUrl,
|
||||||
hero: state.data!.id,
|
hero: '${state.heroImagePrefix}${state.data!.id}',
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
@@ -69,10 +69,14 @@ class DetailsPage extends StatelessWidget {
|
|||||||
builder: (context) {
|
builder: (context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text(
|
title: Text(
|
||||||
t.details.removeTitle(title: state.data!.title),
|
t.details.removeTitle(
|
||||||
|
title: state.data!.title,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
content: Text(
|
content: Text(
|
||||||
t.details.removeBody(title: state.data!.title),
|
t.details.removeBody(
|
||||||
|
title: state.data!.title,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
@@ -83,14 +87,18 @@ class DetailsPage extends StatelessWidget {
|
|||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
foregroundColor: Colors.red,
|
foregroundColor: Colors.red,
|
||||||
),
|
),
|
||||||
child: Text(t.details.removeButton),
|
child: Text(
|
||||||
|
t.details.removeButton,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context)
|
Navigator.of(context)
|
||||||
.pop(false);
|
.pop(false);
|
||||||
},
|
},
|
||||||
child: Text(t.details.cancelButton),
|
child: Text(
|
||||||
|
t.details.cancelButton,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -150,27 +158,27 @@ class DetailsPage extends StatelessWidget {
|
|||||||
SelectorItem(
|
SelectorItem(
|
||||||
MediumTrackingState.ongoing,
|
MediumTrackingState.ongoing,
|
||||||
MediumTrackingState.ongoing
|
MediumTrackingState.ongoing
|
||||||
.toNameString(state.trackingType),
|
.getName(state.trackingType),
|
||||||
),
|
),
|
||||||
SelectorItem(
|
SelectorItem(
|
||||||
MediumTrackingState.completed,
|
MediumTrackingState.completed,
|
||||||
MediumTrackingState.completed
|
MediumTrackingState.completed
|
||||||
.toNameString(state.trackingType),
|
.getName(state.trackingType),
|
||||||
),
|
),
|
||||||
SelectorItem(
|
SelectorItem(
|
||||||
MediumTrackingState.planned,
|
MediumTrackingState.planned,
|
||||||
MediumTrackingState.planned
|
MediumTrackingState.planned
|
||||||
.toNameString(state.trackingType),
|
.getName(state.trackingType),
|
||||||
),
|
),
|
||||||
SelectorItem(
|
SelectorItem(
|
||||||
MediumTrackingState.dropped,
|
MediumTrackingState.dropped,
|
||||||
MediumTrackingState.dropped
|
MediumTrackingState.dropped
|
||||||
.toNameString(state.trackingType),
|
.getName(state.trackingType),
|
||||||
),
|
),
|
||||||
SelectorItem(
|
SelectorItem(
|
||||||
MediumTrackingState.paused,
|
MediumTrackingState.paused,
|
||||||
MediumTrackingState.paused
|
MediumTrackingState.paused
|
||||||
.toNameString(state.trackingType),
|
.getName(state.trackingType),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
initialValue: state.data!.state,
|
initialValue: state.data!.state,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:file_picker/file_picker.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
class SettingsPage extends StatelessWidget {
|
class SettingsPage extends StatelessWidget {
|
||||||
const SettingsPage({super.key});
|
const SettingsPage({super.key});
|
||||||
@@ -91,6 +92,51 @@ class SettingsPage extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text(t.settings.exportData),
|
||||||
|
onTap: () async {
|
||||||
|
// Pick the file
|
||||||
|
final result =
|
||||||
|
await FilePicker.platform.getDirectoryPath();
|
||||||
|
if (result == null) return;
|
||||||
|
|
||||||
|
if (!(await Permission.manageExternalStorage
|
||||||
|
.request())
|
||||||
|
.isGranted) return;
|
||||||
|
|
||||||
|
GetIt.I.get<SettingsBloc>().add(
|
||||||
|
DataExportedEvent(
|
||||||
|
result,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text(t.settings.importData),
|
||||||
|
onTap: () async {
|
||||||
|
// Pick the file
|
||||||
|
final result = await FilePicker.platform.pickFiles();
|
||||||
|
if (result == null) return;
|
||||||
|
|
||||||
|
if (!result.files.first.path!.endsWith('.json.gz')) {
|
||||||
|
await showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (_) => AlertDialog(
|
||||||
|
title: Text(t.settings.importInvalidData.title),
|
||||||
|
content:
|
||||||
|
Text(t.settings.importInvalidData.content),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetIt.I.get<SettingsBloc>().add(
|
||||||
|
DataImportedEvent(
|
||||||
|
result.files.first.path!,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -4,15 +4,18 @@ import 'package:flutter/material.dart';
|
|||||||
class GridItem extends StatefulWidget {
|
class GridItem extends StatefulWidget {
|
||||||
const GridItem({
|
const GridItem({
|
||||||
required this.child,
|
required this.child,
|
||||||
required this.plusCallback,
|
this.plusCallback,
|
||||||
required this.minusCallback,
|
this.minusCallback,
|
||||||
|
this.enableDrag = true,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
final void Function() plusCallback;
|
final bool enableDrag;
|
||||||
final void Function() minusCallback;
|
|
||||||
|
final void Function()? plusCallback;
|
||||||
|
final void Function()? minusCallback;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
GridItemState createState() => GridItemState();
|
GridItemState createState() => GridItemState();
|
||||||
@@ -26,16 +29,20 @@ class GridItemState extends State<GridItem> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onHorizontalDragUpdate: (details) {
|
onHorizontalDragUpdate: (details) {
|
||||||
|
if (!widget.enableDrag) return;
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_offset += details.delta.dx;
|
_offset += details.delta.dx;
|
||||||
_translationX = 160 / (1 + exp(-1 * (1 / 30) * _offset)) - 80;
|
_translationX = 160 / (1 + exp(-1 * (1 / 30) * _offset)) - 80;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onHorizontalDragEnd: (_) {
|
onHorizontalDragEnd: (_) {
|
||||||
if (_translationX <= -60) {
|
if (!widget.enableDrag) return;
|
||||||
widget.plusCallback();
|
|
||||||
} else if (_translationX >= 60) {
|
if (_translationX <= -40) {
|
||||||
widget.minusCallback();
|
widget.plusCallback!();
|
||||||
|
} else if (_translationX >= 40) {
|
||||||
|
widget.minusCallback!();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the view
|
// Reset the view
|
||||||
|
|||||||
563
pubspec.lock
563
pubspec.lock
File diff suppressed because it is too large
Load Diff
61
pubspec.yaml
61
pubspec.yaml
@@ -1,48 +1,53 @@
|
|||||||
name: anitrack
|
name: anitrack
|
||||||
description: An anime and manga tracker
|
description: An anime and manga tracker
|
||||||
publish_to: 'none'
|
publish_to: "none"
|
||||||
|
|
||||||
version: 0.1.2+8
|
version: 0.1.3+2011
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.18.4 <3.0.0'
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
archive: ^3.3.7
|
archive: ^3.6.1
|
||||||
bloc: ^8.1.0
|
bloc: ^8.1.4
|
||||||
bottom_bar: ^2.0.3
|
bottom_bar: ^2.0.3
|
||||||
cached_network_image: ^3.2.3
|
cached_network_image: ^3.4.1
|
||||||
collection: ^1.17.0
|
collection: ^1.18.0
|
||||||
cupertino_icons: ^1.0.2
|
cupertino_icons: ^1.0.8
|
||||||
file_picker: ^5.2.8
|
file_picker: ^8.1.2
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_bloc: ^8.1.1
|
flutter_bloc: ^8.1.6
|
||||||
freezed_annotation: 2.1.0
|
fluttertoast: ^8.2.8
|
||||||
get_it: ^7.2.0
|
freezed_annotation: ^2.4.4
|
||||||
jikan_api: ^2.0.0
|
get_it: ^8.0.0
|
||||||
json_annotation: 4.6.0
|
jikan_api: ^2.2.1
|
||||||
slang: 3.19.0
|
json_annotation: ^4.9.0
|
||||||
slang_flutter: 3.19.0
|
path: ^1.9.0
|
||||||
sqflite: ^2.2.4+1
|
permission_handler: ^11.3.1
|
||||||
swipeable_tile: ^2.0.0+3
|
slang: ^3.31.2
|
||||||
url_launcher: ^6.1.8
|
slang_flutter: ^3.31.0
|
||||||
xml: ^6.2.2
|
sqflite: ^2.3.3+2
|
||||||
|
swipeable_tile: ^2.0.1
|
||||||
|
url_launcher: ^6.3.0
|
||||||
|
xml: ^6.5.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.1.11
|
build_runner: ^2.4.12
|
||||||
flutter_launcher_icons: ^0.11.0
|
flutter_launcher_icons: ^0.14.1
|
||||||
flutter_lints: ^2.0.0
|
flutter_lints: ^5.0.0
|
||||||
flutter_oss_licenses: ^2.0.1
|
flutter_oss_licenses: ^3.0.2
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
freezed: ^2.1.0+1
|
freezed: ^2.5.7
|
||||||
json_serializable: ^6.3.1
|
json_serializable: ^6.8.0
|
||||||
slang_build_runner: 3.19.0
|
slang_build_runner: ^3.31.0
|
||||||
very_good_analysis: ^3.0.1
|
very_good_analysis: ^6.0.0
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
assets:
|
||||||
|
- LICENSE
|
||||||
|
|
||||||
flutter_icons:
|
flutter_icons:
|
||||||
android: "launcher_icon"
|
android: "launcher_icon"
|
||||||
|
|||||||
Reference in New Issue
Block a user