12 Commits
0.7.0 ... 1.5.0

Author SHA1 Message Date
7f92b1714e chore: bump version to 1.5.0
Update productVersion from 1.0.0 to 1.5.0 in Wails project
configuration to reflect the addition of AniList watchlist sorting,
extracted refresh button component, and pagination improvements.
2026-04-24 23:02:21 -04:00
cd142f7601 chore: remove release notes file 2026-04-24 23:01:29 -04:00
fe48e6a8c4 docs: add release notes for v1.0.0
Add comprehensive release notes documenting the first stable release of
AniTrack, including highlights such as webkit2gtk 4.1 Linux builds,
comprehensive error handling across all services, AniList watchlist
sorting, and various UI polish improvements.
2026-04-24 23:01:00 -04:00
24d4d24edf fix(frontend): remove extraneous top margin from pagination controls
Remove the mt-5 class from the pagination container div to eliminate
unnecessary spacing between the pagination buttons and the per-page
selector.
2026-04-24 23:00:54 -04:00
b68abfc1c9 refactor(frontend): extract refresh button into standalone component and put sort dropdown in watchlist header
Move the refresh button out of the WatchList component header and into
its own RefreshWatchListButton.svelte component, placing it at the top
of the Home route page with right-alignment. This gives the refresh
control better visibility at the page level rather than being buried
inside the watchlist header.

Replace the removed refresh button in the WatchList header with the new
Sort dropdown component, giving users sort controls directly alongside
the watchlist title.
2026-04-24 23:00:50 -04:00
eadc96fb4f feat(frontend): add AniList watchlist sort dropdown component
Implement a Sort.svelte component that provides a dropdown menu allowing
users to dynamically reorder their AniList watchlist by various parameters
including media title, score, status, progress, popularity, and dates.

The component binds to the global aniListSort store and fetches updated
watchlist data from the backend whenever the user selects a new sort option,
providing immediate visual feedback.
2026-04-24 23:00:35 -04:00
6a662cdf6e chore: bump version to 1.0.0
Update productVersion from 0.7.0 to 1.0.0 in Wails project
configuration to reflect the first major release milestone.
2026-04-24 19:39:08 -04:00
2a9777872f chore: update author email address
Change contact email from jokeefe@fastmail.com to admin@linuxhg.com
in the Wails project configuration.
2026-04-24 19:38:56 -04:00
b03d4ab7e3 build: add Makefile with webkit2_41 build tag for Linux
Wails v2 defaults to linking against webkit2gtk-4.0, but modern Linux
distributions (e.g. Fedora) only ship webkit2gtk-4.1. The webkit2_41
build tag tells Wails to link against the correct library.

Provides two targets:
- make dev: run wails dev with the correct tag
- make build: build the production binary with the correct tag
- make clean: remove build artifacts
2026-04-24 17:10:29 -04:00
ff1b8fb742 chore: remove release notes for v0.6.5 2026-04-24 17:10:21 -04:00
cbd4c7cd01 docs: add release notes for v0.6.5
Add detailed release notes for the v0.6.5 patch release covering:
- Enhanced button disabled states in Anime and Pagination components
- Fixed media cover image sizing in WatchList
- AvatarMenu service status indicator
- TypeScript type safety fixes in Pagination event handlers
- Code formatting standardization across components
2026-04-24 17:10:03 -04:00
335d757255 chore: remove release notes file
Release notes will be managed externally. Keeping repository focused on source code only.
2026-03-30 20:17:09 -04:00
8 changed files with 114 additions and 180 deletions

12
Makefile Normal file
View File

@@ -0,0 +1,12 @@
TAGS := webkit2_41
.PHONY: dev build clean
dev:
wails dev -tags $(TAGS)
build:
wails build -tags $(TAGS)
clean:
rm -rf build/bin/*

View File

@@ -1,166 +0,0 @@
# 🎉 AniTrack v0.7.0 Release Notes
## 🚨 Major Feature: Comprehensive Error Handling
This release brings **massive improvements** to application stability and user experience. The app will **no longer crash** when API services are down or experiencing errors!
---
## ✨ What's New
### 🛡️ Graceful API Error Handling
- **Application Stability**: App now remains running even when AniList, MAL, or Simkl APIs are down
- **Visual Error Feedback**: Beautiful modal dialogs display error details instead of silent crashes
- **Manual Retry**: Users can retry failed API connections with a single button click
- **Continue Using App**: Dismiss error messages and continue with limited functionality
### 🔧 Backend Improvements
#### AniList Integration
- Replaced all `log.Fatal()` calls with proper error returns
- Added error handling for API failures, network issues, and authentication errors
- `AniListSearch` now returns detailed error messages
- `GetAniListUserWatchingList` gracefully handles 403/404 responses
#### MyAnimeList Integration
- Updated `MALHelper` to return structured errors
- All MAL API functions now return errors instead of crashing:
- `GetMyAnimeList`
- `MyAnimeListUpdate`
- `GetMyAnimeListAnime`
- `DeleteMyAnimeListEntry`
- Fixed OAuth callback server to prevent shutdown on errors
#### Simkl Integration
- Updated `SimklHelper` with status code validation (200-299 range)
- All Simkl API functions now return errors:
- `SimklGetUserWatchlist`
- `SimklSyncEpisodes`
- `SimklSyncRating`
- `SimklSyncStatus`
- `SimklSearch`
- `SimklSyncRemove`
- Replaced `log.Fatal()` with proper error logging
### 💻 Frontend Improvements
#### New Error Management System
- **Centralized Error State**: New reactive stores for API errors
- `apiError` - Tracks current error with service, message, and status
- `isApiDown` - Quick flag for API availability
- **Error Helper Functions**:
- `setApiError()` - Set error state from any component
- `clearApiError()` - Reset error state
#### New Error Modal Component
- Auto-displays when API errors occur
- Shows service name, error message, and HTTP status code
- **"Retry Connection"** button - Attempts to reconnect to the failed service
- **"Dismiss"** button - Close modal and continue using the app
- Beautiful red-themed styling with Tailwind CSS
- Supports all three services (AniList, MAL, Simkl)
#### Updated User Interface
- Home page now displays "API Unavailable" state when services are down
- Helpful warning messages guide users during outages
- App structure remains visible and functional during errors
---
## 🐛 Bug Fixes
- **Critical**: Fixed app crashes when AniList API returns 403 Forbidden errors
- **Critical**: Fixed app crashes when AniList API is down or unreachable
- **Critical**: Fixed MAL OAuth server crashing on connection errors
- **Critical**: Fixed Simkl JSON marshaling errors crashing the app
- **Improved**: Better error messages for all API failures
---
## 📊 Technical Details
### Go Backend Changes
- **AniListFunctions.go**: Updated 3 functions with error handling
- **MALFunctions.go**: Updated 5 functions with error handling
- **MALUserFunctions.go**: Fixed server error handling
- **SimklFunctions.go**: Updated 7 functions with error handling
- **SimklUserFunctions.go**: Fixed 2 critical error handling issues
### Frontend Changes
- **ErrorModal.svelte**: New component (73 lines)
- **GlobalVariablesAndHelperFunctions.svelte**: Added error state system (27 lines)
- **App.svelte**: Integrated ErrorModal into main layout
- **CheckIfAniListLoggedInAndLoadWatchList.svelte**: Added error handling
- **Home.svelte**: Added API down state display
---
## 🎯 Impact
### Before (v0.6.5)
- ❌ App crashes to desktop when AniList API is down
- ❌ Users see only console error messages
- ❌ Must restart app after API failures
- ❌ No way to retry failed connections
### After (v0.7.0)
- ✅ App stays open during any API failures
- ✅ Beautiful modal dialogs explain what went wrong
- ✅ One-click retry to reconnect services
- ✅ Continue using app with limited functionality
---
## 🔄 Upgrading
No migration needed! This release is fully backward compatible.
Simply run:
```bash
git pull
wails build
```
Or download the latest release from the releases page.
---
## 🙏 Acknowledgments
This release addresses a critical stability issue that was affecting users during API service outages. Special thanks to the community for reporting these crashes and providing detailed error logs.
---
## 📝 Full Changelog
### Added
- Error modal component with retry/dismiss functionality
- Centralized error state management system
- API availability status tracking
- Visual feedback for all API failures
- Manual retry functionality for all services
### Changed
- AniList API functions to return errors instead of crashing
- MAL API functions to return errors instead of crashing
- Simkl API functions to return errors instead of crashing
- Error handling from console-only to UI modal dialogs
- App behavior from crash-on-error to graceful-degradation
### Fixed
- App crashes on AniList 403 errors
- App crashes on network failures
- MAL OAuth server shutdown on errors
- Simkl JSON marshaling crashes
- All `log.Fatal()` calls that terminated the app
### Removed
- `alert()` calls in favor of modal system
- Vite timestamp file (cleanup)
---
**Version**: 0.7.0
**Release Date**: March 2026
**Upgrade Difficulty**: ⭐ Easy (backward compatible)
**Recommended**: ⭐⭐⭐⭐⭐ Highly recommended for all users

View File

@@ -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}

View 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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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 />

View File

@@ -8,10 +8,10 @@
"frontend:dev:serverUrl": "auto",
"author": {
"name": "John O'Keefe",
"email": "jokeefe@fastmail.com"
"email": "admin@linuxhg.com"
},
"info": {
"productName": "AniTrack",
"productVersion": "0.7.0"
"productVersion": "1.5.0"
}
}