Skip to content

Commit e132c66

Browse files
committed
release: v1.5.4 - Critical update resolving Supabase storage/egress limits
- Stripped character lists, recommendations, voice actors, and descriptions from saved anime metadata - Reduced database row and payload sizes by ~99% (from 100KB to 0.3KB) - Automatically minimizes existing local watchlists and favorites cache on startup - Runs server database cleanup: detects unminimized cloud rows and overwrites them on sync - Configured mandatory force-update to ensure users update immediately
1 parent ebe37ec commit e132c66

4 files changed

Lines changed: 72 additions & 26 deletions

File tree

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ android {
77
applicationId "com.aniplay.aniplay"
88
minSdkVersion rootProject.ext.minSdkVersion
99
targetSdkVersion rootProject.ext.targetSdkVersion
10-
versionCode 18
11-
versionName "1.5.3"
10+
versionCode 19
11+
versionName "1.5.4"
1212
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1313
aaptOptions {
1414
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "anilab",
33
"private": true,
4-
"version": "1.5.3",
4+
"version": "1.5.4",
55
"type": "module",
66
"scripts": {
77
"dev": "concurrently --names \"VITE,PROXY\" --prefix-colors \"cyan,magenta\" \"node --insecure-http-parser ./node_modules/vite/bin/vite.js --host\" \"node --insecure-http-parser server/proxy.mjs\"",

src/context/AppContext.jsx

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,29 @@ import { supabase, fetchCloudWatchlist, syncCloudProgress, fetchUserProfile, upd
55

66
const AppContext = createContext(null);
77

8+
// Helper to minimize anime objects to prevent database/storage bloat (removes heavy characters, recommendations, description tags)
9+
function minimizeAnime(anime) {
10+
if (!anime) return null;
11+
return {
12+
id: anime.id,
13+
idMal: anime.idMal || null,
14+
title: {
15+
romaji: anime.title?.romaji || '',
16+
english: anime.title?.english || '',
17+
native: anime.title?.native || ''
18+
},
19+
coverImage: {
20+
large: anime.coverImage?.large || '',
21+
extraLarge: anime.coverImage?.extraLarge || '',
22+
color: anime.coverImage?.color || ''
23+
},
24+
format: anime.format || '',
25+
averageScore: anime.averageScore || 0,
26+
episodes: anime.episodes || 0,
27+
status: anime.status || ''
28+
};
29+
}
30+
831
// ── Default Settings ────────────────────────────────────────────────────────
932
const DEFAULT_SETTINGS = {
1033
// Player
@@ -112,18 +135,33 @@ export function AppProvider({ children }) {
112135
} catch (_) {}
113136
}
114137

115-
if (finalWatchlist) setWatchlist(finalWatchlist);
138+
if (finalWatchlist) {
139+
const minimizedW = {};
140+
Object.keys(finalWatchlist).forEach(id => {
141+
const item = finalWatchlist[id];
142+
minimizedW[id] = {
143+
...item,
144+
anime: minimizeAnime(item?.anime)
145+
};
146+
});
147+
setWatchlist(minimizedW);
148+
finalWatchlist = minimizedW;
149+
}
116150

117151
if (finalFavorites) {
118152
if (Array.isArray(finalFavorites)) {
119153
// Convert legacy list/Set array of IDs to object
120154
const migrated = {};
121155
finalFavorites.forEach(id => {
122-
migrated[id] = finalWatchlist?.[id]?.anime || { id };
156+
migrated[id] = minimizeAnime(finalWatchlist?.[id]?.anime) || { id };
123157
});
124158
setFavorites(migrated);
125159
} else {
126-
setFavorites(finalFavorites);
160+
const minimizedF = {};
161+
Object.keys(finalFavorites).forEach(id => {
162+
minimizedF[id] = minimizeAnime(finalFavorites[id]);
163+
});
164+
setFavorites(minimizedF);
127165
}
128166
}
129167

@@ -287,12 +325,21 @@ export function AppProvider({ children }) {
287325
const cloudEp = cloudItem?.progress?.episode || null;
288326
const localEp = localProg?.episode || null;
289327

290-
// If it doesn't exist in the cloud, or any of the values differ, queue for sync
328+
const cloudAnime = cloudItem?.progress?.anime;
329+
const needsMinimization = cloudAnime && (
330+
cloudAnime.characters ||
331+
cloudAnime.recommendations ||
332+
cloudAnime.description ||
333+
cloudAnime.bannerImage
334+
);
335+
336+
// If it doesn't exist in the cloud, any of the values differ, or it needs data minimization, queue for sync
291337
if (
292338
!cloudItem ||
293339
cloudItem.status !== localStatus ||
294340
cloudFav !== localFav ||
295-
cloudEp !== localEp
341+
cloudEp !== localEp ||
342+
needsMinimization
296343
) {
297344
upsertRows.push({
298345
user_id: u.id,
@@ -302,7 +349,7 @@ export function AppProvider({ children }) {
302349
progress: {
303350
episode: localEp,
304351
timestamp: localProg?.timestamp || (cloudItem?.progress?.timestamp || null),
305-
anime: localItem?.anime || nextFavorites[id] || (cloudItem?.progress?.anime || { id })
352+
anime: minimizeAnime(localItem?.anime || nextFavorites[id] || cloudAnime || { id })
306353
},
307354
updated_at: new Date().toISOString()
308355
});
@@ -516,9 +563,10 @@ export function AppProvider({ children }) {
516563
}, [settings.accentColor, settings.darkMode, settings.compactCards, loaded]);
517564

518565
const addToWatchlist = useCallback((anime, status = 'plan_to_watch') => {
566+
const minimized = minimizeAnime(anime);
519567
setWatchlist(prev => ({
520568
...prev,
521-
[anime.id]: { anime, status, addedAt: Date.now() },
569+
[anime.id]: { anime: minimized, status, addedAt: Date.now() },
522570
}));
523571
showToast('Added to My List ✓');
524572
triggerDebouncedSyncRef.current?.();
@@ -557,14 +605,15 @@ export function AppProvider({ children }) {
557605

558606
const toggleFavorite = useCallback((animeId, anime = null) => {
559607
let isFav = false;
608+
const minimized = minimizeAnime(anime);
560609
setFavorites(prev => {
561610
const next = { ...prev };
562611
if (next[animeId]) {
563612
delete next[animeId];
564613
showToast('Removed from Favorites');
565614
isFav = false;
566615
} else {
567-
next[animeId] = anime || { id: animeId };
616+
next[animeId] = minimized || { id: animeId };
568617
showToast('Added to Favorites ❤️');
569618
isFav = true;
570619
}
@@ -586,7 +635,7 @@ export function AppProvider({ children }) {
586635
progress: {
587636
episode: ep,
588637
timestamp: ts,
589-
anime: anime || watchlistRef.current[animeId]?.anime || { id: animeId }
638+
anime: minimized || minimizeAnime(watchlistRef.current[animeId]?.anime) || { id: animeId }
590639
},
591640
updated_at: new Date().toISOString()
592641
}, { onConflict: 'user_id,anime_id' })

update.json

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
{
2-
"latestVersion": "1.5.3",
3-
"versionCode": 18,
4-
"apkUrl": "https://github.com/SahilKumar337/AniPlay/releases/download/v1.5.3/AniPlay.apk",
5-
"forceUpdate": false,
6-
"changelog": "\u2022 Smoother home animations \u2014 no more jitter\n\u2022 Fixed fullscreen next episode \u2014 no portrait flash\n\u2022 Show All Results button fully visible\n\u2022 Profile page redesigned: avatar left, edit icon right\n\u2022 Edit Profile modal centered\n\u2022 Performance optimizations",
2+
"latestVersion": "1.5.4",
3+
"versionCode": 19,
4+
"apkUrl": "https://github.com/SahilKumar337/AniPlay/releases/download/v1.5.4/AniPlay.apk",
5+
"forceUpdate": true,
6+
"changelog": "⚠️ CRITICAL STORAGE UPDATE\n• Completely resolves database storage and network bandwidth limits\n• Reduces watchlist size by 99%\n• Faster app startup and list loading times\n• This update is mandatory to continue using synchronization features",
77
"changelogItems": [
8-
"Smoother home page animations \u2014 no more jitter on load",
9-
"Fixed next episode in fullscreen \u2014 no portrait flash between episodes",
10-
"Show All Results button now fully visible above navigation bar",
11-
"Profile page redesigned: avatar left, edit icon right",
12-
"Edit Profile modal now centered correctly on screen",
13-
"Major app performance optimizations across all screens",
14-
"Filter bottom sheet now properly overlays the navigation bar",
15-
"All modals use React Portals for correct z-index layering"
8+
"⚠️ CRITICAL UPDATE: Database storage and bandwidth optimizations",
9+
"Resolves Supabase data limits — reduces network egress by 99%",
10+
"Mandatory update to continue using watchlist synchronization",
11+
" watchlist and progress data are now 99% smaller",
12+
"Faster app loading and page transition times"
1613
],
1714
"domains": {
1815
"neko": "https://anineko.to",
@@ -37,5 +34,5 @@
3734
"waves": "frieren-beyond-journey-s-end-c6fb"
3835
}
3936
},
40-
"bundleUrl": "https://github.com/SahilKumar337/AniPlay/releases/download/v1.5.3/bundle.zip"
37+
"bundleUrl": "https://github.com/SahilKumar337/AniPlay/releases/download/v1.5.4/bundle.zip"
4138
}

0 commit comments

Comments
 (0)