diff --git a/CHANGELOG.md b/CHANGELOG.md index 1038e8b2..72efe128 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ Все заметные изменения в этом проекте будут документированы в этом файле +## [1.1.5] — 13.09.2019 +В этой версии я продолжил работу над внутренним хранилищем. В этой версии изменения коснулись процесса загрузки списка серий и их названий. + +Я реализовал временный кэш для списка серий. Теперь список серий для онгоингов кэшируется на сутки. А для уже вышедших аниме на более долгий срок. + +Кроме того, в кэше хранится не более 5 последних аниме. Таким образом объем потребляемой памяти остаётся низким. + +Благодаря этому нововведению время между началом загрузки страницы и инициализацией видео-плеера уменьшилось на 25-30%. + ## [1.1.3] — 11.09.2019 Кто-то знает, а кто-то нет, но расширение умеет предугадывать в каком переводе вы бы предпочли смотреть аниме. Как это работает. Расширение запоминает историю ваших просмотров и то какой перевод (озвучка/субтитры) и от какой релиз-группы вы выбираете. На основе этой модели строиться ваш персонализированный "Профиль предпочтений".И чем больше аниме вы смотрите, тем умнее и точнее работает прогноз. @@ -100,6 +109,7 @@ - **Приоритетная** помощь в решении проблем +[1.1.5]: https://github.com/cawa-93/play-shikimori-online/compare/v1.1.4...v1.1.5 [1.1.3]: https://github.com/cawa-93/play-shikimori-online/compare/v1.1.2...v1.1.3 [1.1.2]: https://github.com/cawa-93/play-shikimori-online/compare/v1.1.1...v1.1.2 [1.1.1]: https://github.com/cawa-93/play-shikimori-online/compare/v1.1.0...v1.1.1 diff --git a/package-lock.json b/package-lock.json index 3bfcdda7..d0992997 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "play-shiki-online", - "version": "1.1.4", + "version": "1.1.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 1cda36f8..6e91050c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "description": "Расширение позволяет смотреть аниме онлайн и синхронизировать его с вашим списком на Шикимори (shikimori.org и shikimori.one)", "name": "play-shiki-online", - "version": "1.1.4", + "version": "1.1.5", "private": true, "scripts": { "serve": "vue-cli-service serve", diff --git a/src/UI/index.html b/src/UI/index.html index 23cd24c6..f23d8364 100644 --- a/src/UI/index.html +++ b/src/UI/index.html @@ -1,6 +1,11 @@ + + + + + diff --git a/src/UI/store/player/index.ts b/src/UI/store/player/index.ts index 6a96508a..443b8d19 100644 --- a/src/UI/store/player/index.ts +++ b/src/UI/store/player/index.ts @@ -6,6 +6,8 @@ import {findEpisode} from '@/helpers/find-episode'; import router from '@/UI/router'; import store, {worker} from '@/UI/store'; import shikimoriStore from '@/UI/store/shikimori'; +// @ts-ignore +import storage from 'kv-storage-polyfill'; import Vue from 'vue'; import {Action, getModule, Module, Mutation, VuexModule} from 'vuex-module-decorators'; import {SelectedTranslation, WatchingHistoryItem} from '../../../../types/UI'; @@ -312,13 +314,24 @@ export class Player extends VuexModule { */ @Action public async loadEpisodesTitle() { - if (!this.currentEpisode) { + if (!this.currentEpisode || !this.currentEpisode.myAnimelist) { return; } const myAnimelist = this.currentEpisode.myAnimelist; + let cache: Map + = await storage.get('EpisodeTitlesCache') || new Map(); + + if (cache.has(myAnimelist)) { + const cached = cache.get(myAnimelist); + if (cached && cached.maxAge && cached.maxAge > Date.now()) { + return this.setEpisodesTitle(cached.episodes); + } + } + let promise: Promise; let currentPage = 1; let episodesToCommit: myanimelist.Episode[] = []; + const episodesToCache: myanimelist.Episode[] = []; try { @@ -330,6 +343,7 @@ export class Player extends VuexModule { if (episodesToCommit.length) { this.setEpisodesTitle(episodesToCommit); + episodesToCache.push(...episodesToCommit); episodesToCommit = []; } @@ -354,7 +368,17 @@ export class Player extends VuexModule { if (episodesToCommit.length) { this.setEpisodesTitle(episodesToCommit); + episodesToCache.push(...episodesToCommit); + } + + if (episodesToCache.length) { + cache.set(myAnimelist, {episodes: episodesToCache, maxAge: Date.now() + 345600000}); // кэшируем на 4 суток + } + + if (cache.size > 5) { + cache = new Map([...cache.entries()].splice(-5)); } + storage.set('EpisodeTitlesCache', cache); } diff --git a/src/helpers/API/Anime365Provider.ts b/src/helpers/API/Anime365Provider.ts index 7ac10050..92b5edda 100644 --- a/src/helpers/API/Anime365Provider.ts +++ b/src/helpers/API/Anime365Provider.ts @@ -1,9 +1,100 @@ import {RequestProvider} from '@/helpers/API/RequestProvider'; +// @ts-ignore +import storage from 'kv-storage-polyfill'; + +declare interface CachedSeries { + resp: anime365.api.SeriesCollection; + maxAge: number; +} + +const DAY = 1000 * 60 * 60 * 24; + export class Anime365Provider extends RequestProvider { public static baseURL = 'https://smotret-anime-365.ru/api'; public static cachePrefix = 'anime-365-cache-v'; public static cacheVersion = 1; + public static cachedSeries: Map = new Map(); + + public static cachedSeriesReady: Promise = storage.get('cachedSeries') + .then((storeData?: Map) => { + if (storeData) { + Anime365Provider.cachedSeries = storeData; + } + }); + + + public static async request( + url: string, + options: RequestInit & { errorMessage: string }, + ): Promise { + const isSeriesRequest = /\/api\/series\//.test(url); + if (isSeriesRequest) { + await this.cachedSeriesReady; + } + + if (isSeriesRequest && this.cachedSeries.has(url)) { + const cache = this.cachedSeries.get(url); + if (cache && cache.maxAge && cache.maxAge > Date.now()) { + // @ts-ignore + return cache.resp as T; + } + } + + try { + const resp = await super.request(url, options); + + /** + * Если текущий запрос — это запрос к списку серий + * Запустить процесс кэширования + */ + if (isSeriesRequest) { + // @ts-ignore + const SeriesCollection = resp as anime365.api.SeriesCollection; + + /** + * Если список серий не пуст + */ + if (SeriesCollection + && SeriesCollection.data[0] + && SeriesCollection.data[0].episodes + && SeriesCollection.data[0].episodes.length > 0 + ) { + // По умолчанию кэшируем ответ на 24 часа + let maxAge = Date.now() + DAY; + + // Определяем дату последней добавленной серии + const newestEpisodeDateTime = Math.max( + ...SeriesCollection.data[0].episodes.map((e) => new Date(e.firstUploadedDateTime).getTime()), + ); + + // Если последняя серия была добавлена более двух недель назад + // увеличить срок кэширования до 7 дней + if (newestEpisodeDateTime && newestEpisodeDateTime < (Date.now() - DAY * 14)) { + maxAge = Date.now() + DAY * 7; + } + + // Если последняя серия была добавлена более 30 дней назад + // увеличить срок кэширования до 30 дней + if (newestEpisodeDateTime && newestEpisodeDateTime < (Date.now() - DAY * 30)) { + maxAge = Date.now() + DAY * 30; + } + + this.cachedSeries.set(url, {resp: SeriesCollection, maxAge}); + if (this.cachedSeries.size > 5) { + this.cachedSeries = new Map([...this.cachedSeries.entries()].splice(-5)); + } + storage.set('cachedSeries', this.cachedSeries); + } + + } + + return resp; + } catch (e) { + throw e; + } + } + } Anime365Provider.clearLegacyCaches();