Compare commits
4 Commits
1.0.0
...
fe48e6a8c4
| Author | SHA1 | Date | |
|---|---|---|---|
| fe48e6a8c4 | |||
| 24d4d24edf | |||
| b68abfc1c9 | |||
| eadc96fb4f |
58
RELEASE_NOTES.md
Normal file
58
RELEASE_NOTES.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# AniTrack v1.0.0
|
||||
|
||||
After months of iteration and refinement, AniTrack has reached its first stable release! This milestone marks the transition from an evolving prototype to a reliable, polished desktop app for tracking the anime you watch.
|
||||
|
||||
## Highlights
|
||||
|
||||
### Built against webkit2gtk 4.1
|
||||
|
||||
The Linux build now targets **webkit2gtk-4.1**, bringing improved compatibility with modern Linux distributions. A `Makefile` has been added with the `webkit2_41` build tag configured out of the box — simply run `make build` or `make dev` on Linux.
|
||||
|
||||
### Comprehensive error handling
|
||||
|
||||
All three supported services — **AniList**, **MyAnimeList**, and **Simkl** — now have robust error handling throughout the backend. A new error modal component on the frontend surfaces issues to the user instead of failing silently.
|
||||
|
||||
### AniList watchlist sorting
|
||||
|
||||
A new sort component allows you to dynamically reorder your AniList watchlist by various parameters, giving you more control over how you browse your library.
|
||||
|
||||
### UI polish
|
||||
|
||||
- Added a refresh button to the watchlist with smart refresh-on-navigation behavior
|
||||
- Pagination buttons now properly disable at boundary pages
|
||||
- Progress adjustment buttons have disabled-state constraints to prevent invalid values
|
||||
- Media cover images are correctly sized in the watchlist
|
||||
- Dark mode is now the default across all elements
|
||||
|
||||
## Supported Services
|
||||
|
||||
| Service | Status |
|
||||
| ------- | ------ |
|
||||
| AniList | Sync, search, genres, tags, sorting |
|
||||
| MyAnimeList | Sync, search |
|
||||
| Simkl | Sync, search |
|
||||
|
||||
## Building from Source
|
||||
|
||||
Please refer to the [README](README.md) for instructions on setting up API keys, installing Wails, and building the application. Linux users can use the provided `Makefile` targets:
|
||||
|
||||
```bash
|
||||
make dev # run in development mode
|
||||
make build # build a production binary
|
||||
```
|
||||
|
||||
## What's Changed (since v0.7.0)
|
||||
|
||||
- Add Makefile with webkit2\_41 build tag for Linux builds
|
||||
- Integrate comprehensive error handling into the frontend application
|
||||
- Add error modal component for surfacing API failures
|
||||
- Add API error state management
|
||||
- Add comprehensive error handling for Simkl, MAL, and AniList backends
|
||||
- Implement dynamic sort parameter for AniList watchlist
|
||||
- Add sort component to the UI
|
||||
- Standardize code formatting across components
|
||||
- Update author contact information
|
||||
|
||||
---
|
||||
|
||||
Thank you to everyone who tested the pre-release versions. Your feedback helped shape AniTrack into what it is today.
|
||||
@@ -118,7 +118,7 @@
|
||||
</ul>
|
||||
</nav>
|
||||
{/if}
|
||||
<div class="flex mt-5">
|
||||
<div class="flex">
|
||||
<div class="w-20 mx-auto">
|
||||
<select
|
||||
bind:value={perPage}
|
||||
|
||||
18
frontend/src/helperComponents/RefreshWatchListButton.svelte
Normal file
18
frontend/src/helperComponents/RefreshWatchListButton.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { CheckIfAniListLoggedInAndLoadWatchList } from "../helperModules/CheckIfAniListLoggedInAndLoadWatchList.svelte";
|
||||
import { loading } from "../helperModules/GlobalVariablesAndHelperFunctions.svelte";
|
||||
</script>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<button
|
||||
type="button"
|
||||
class="py-2 px-4 mt-4 mr-4 bg-gray-700 rounded-lg"
|
||||
on:click={async () => {
|
||||
loading.set(true);
|
||||
await CheckIfAniListLoggedInAndLoadWatchList();
|
||||
loading.set(false);
|
||||
}}
|
||||
>
|
||||
Refresh WatchList
|
||||
</button>
|
||||
</div>
|
||||
@@ -0,0 +1,77 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
aniListSort,
|
||||
watchListPage,
|
||||
animePerPage,
|
||||
aniListWatchlist,
|
||||
} from "../helperModules/GlobalVariablesAndHelperFunctions.svelte";
|
||||
import { MediaListSort } from "../anilist/types/AniListTypes";
|
||||
import { GetAniListUserWatchingList } from "../../wailsjs/go/main/App";
|
||||
|
||||
const sortTypes = [
|
||||
{ value: MediaListSort.MediaId, name: "Media Id Asc" },
|
||||
{ value: MediaListSort.MediaIdDesc, name: "Media Id Desc" },
|
||||
{ value: MediaListSort.Score, name: "Score Asc" },
|
||||
{ value: MediaListSort.ScoreDesc, name: "Score Desc" },
|
||||
{ value: MediaListSort.Status, name: "Status Asc" },
|
||||
{ value: MediaListSort.StatusDesc, name: "Status Desc" },
|
||||
{ value: MediaListSort.Progress, name: "Progress Asc" },
|
||||
{ value: MediaListSort.ProgressDesc, name: "Progress Desc" },
|
||||
{ value: MediaListSort.ProgressVolumes, name: "Progress Valumes Asc" },
|
||||
{ value: MediaListSort.ProgressVolumesDesc, name: "Progress Valumes Desc" },
|
||||
{ value: MediaListSort.Repeat, name: "Repeat Asc" },
|
||||
{ value: MediaListSort.RepeatDesc, name: "Repeat Desc" },
|
||||
{ value: MediaListSort.Priority, name: "Priority Asc" },
|
||||
{ value: MediaListSort.PriorityDesc, name: "Priority Desc" },
|
||||
{ value: MediaListSort.StartedOn, name: "Started On Asc" },
|
||||
{ value: MediaListSort.StartedOnDesc, name: "Started On Desc" },
|
||||
{ value: MediaListSort.FinishedOn, name: "Finished On Asc" },
|
||||
{ value: MediaListSort.FinishedOnDesc, name: "Finished On Desc" },
|
||||
{ value: MediaListSort.AddedTime, name: "Added Time Asc" },
|
||||
{ value: MediaListSort.AddedTimeDesc, name: "Added Time Desc" },
|
||||
{ value: MediaListSort.UpdatedTime, name: "Updated Time Asc" },
|
||||
{ value: MediaListSort.UpdatedTimeDesc, name: "Updated Time Desc" },
|
||||
{ value: MediaListSort.MediaTitleRomaji, name: "Media Title Romaji Asc" },
|
||||
{
|
||||
value: MediaListSort.MediaTitleRomajiDesc,
|
||||
name: "Media Title Romaji Desc",
|
||||
},
|
||||
{ value: MediaListSort.MediaTitleEnglish, name: "Media Title English Asc" },
|
||||
{
|
||||
value: MediaListSort.MediaTitleEnglishDesc,
|
||||
name: "Media Title English Desc",
|
||||
},
|
||||
{ value: MediaListSort.MediaTitleNative, name: "Media Title Native Asc" },
|
||||
{
|
||||
value: MediaListSort.MediaTitleNativeDesc,
|
||||
name: "Media Title Native Desc",
|
||||
},
|
||||
{ value: MediaListSort.MediaPopularity, name: "Media Popularity Asc" },
|
||||
{ value: MediaListSort.MediaPopularityDesc, name: "Media Popularity Desc" },
|
||||
];
|
||||
|
||||
let sort: string;
|
||||
aniListSort.subscribe((value) => (sort = value));
|
||||
console.log(sort);
|
||||
|
||||
async function changeWatchListSort() {
|
||||
const result = await GetAniListUserWatchingList(
|
||||
$watchListPage,
|
||||
$animePerPage,
|
||||
$aniListSort,
|
||||
);
|
||||
aniListWatchlist.set(result);
|
||||
}
|
||||
</script>
|
||||
|
||||
<select
|
||||
id="sort"
|
||||
class="border rounded-lg block p-1.5 bg-gray-700 border-gray-600 placeholder-gray-400 text-white focus:ring-blue-500 focus:border-blue-500"
|
||||
bind:value={$aniListSort}
|
||||
on:change={() => changeWatchListSort()}
|
||||
>
|
||||
<option value="" disabled>Sort WatchList</option>
|
||||
{#each sortTypes as sort}
|
||||
<option value={sort.value}>{sort.name}</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import { Rating } from "flowbite-svelte";
|
||||
import loader from "../helperFunctions/loader";
|
||||
import { CheckIfAniListLoggedInAndLoadWatchList } from "../helperModules/CheckIfAniListLoggedInAndLoadWatchList.svelte";
|
||||
import Sort from "../helperComponents/Sort.svelte";
|
||||
|
||||
let isAniListLoggedIn: boolean;
|
||||
let aniListWatchListLoaded: AniListCurrentUserWatchList;
|
||||
@@ -25,17 +26,7 @@
|
||||
>
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h1 class="text-left text-xl font-bold">Your AniList WatchList</h1>
|
||||
<button
|
||||
type="button"
|
||||
class="py-2 px-4 bg-gray-700 rounded-lg"
|
||||
on:click={async () => {
|
||||
loading.set(true);
|
||||
await CheckIfAniListLoggedInAndLoadWatchList();
|
||||
loading.set(false);
|
||||
}}
|
||||
>
|
||||
Refresh WatchList
|
||||
</button>
|
||||
<Sort />
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import Pagination from "../helperComponents/Pagination.svelte";
|
||||
import WatchList from "../helperComponents/WatchList.svelte";
|
||||
import RefreshWatchListButton from "../helperComponents/RefreshWatchListButton.svelte";
|
||||
import {
|
||||
aniListLoggedIn,
|
||||
aniListPrimary,
|
||||
@@ -45,6 +46,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{:else if isAniListLoggedIn && isAniListPrimary}
|
||||
<RefreshWatchListButton />
|
||||
<div class="container py-10">
|
||||
<Pagination />
|
||||
<WatchList />
|
||||
|
||||
Reference in New Issue
Block a user