feat(cache): add songs cache limit feature (#548)

resolve #232
This commit is contained in:
Map1en_ 2021-04-19 10:43:52 +08:00 committed by GitHub
parent a47697fbfa
commit 9ae15c198d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 89 additions and 2 deletions

View File

@ -124,6 +124,10 @@ export default {
high: "High",
lossless: "Lossless",
},
cacheLimit: {
text: "Songs Cache limit",
none: "None",
},
lyricFontSize: {
text: "Lyric Font Size",
small: "Small",

View File

@ -124,6 +124,10 @@ export default {
high: "Yüksek",
lossless: "Kaliteli",
},
cacheLimit: {
text: "Şarkılar Önbellek sınırı",
none: "Yok",
},
lyricFontSize: {
text: "Şarkı Sözleri Yazı Boyutu",
small: "Küçük",

View File

@ -125,6 +125,10 @@ export default {
high: "极高",
lossless: "无损",
},
cacheLimit: {
text: "歌曲缓存上限",
none: "无限制",
},
lyricFontSize: {
text: "歌词字体大小",
small: "小",

View File

@ -12,6 +12,7 @@ let localStorage = {
showPlaylistsByAppleMusic: true,
showUnavailableSongInGreyStyle: true,
automaticallyCacheSongs: false,
cacheLimit: false,
nyancatStyle: false,
showLyricsTranslation: true,
showLyricsDynamicBackground: false,

View File

@ -1,12 +1,49 @@
import axios from "axios";
import Dexie from "dexie";
import store from "@/store";
// import pkg from "../../package.json";
const db = new Dexie("yesplaymusic");
db.version(2)
.stores({
trackSources: "&id, createTime",
})
.upgrade((tx) =>
tx
.table("trackSources")
.toCollection()
.modify(
(track) =>
!track.createTime && (track.createTime = new Date().getTime())
)
);
db.version(1).stores({
trackSources: "&id",
});
let tracksCacheBytes = 0;
async function deleteExcessCache() {
if (
store.state.settings.cacheLimit === false ||
tracksCacheBytes < store.state.settings.cacheLimit * Math.pow(1024, 2)
)
return;
try {
const delCache = await db.trackSources.orderBy("createTime").first();
await db.trackSources.delete(delCache.id);
tracksCacheBytes -= delCache.source.byteLength;
console.debug(
`[debug][db.js] deleteExcessCacheSucces, track: ${delCache.name}, size: ${delCache.source.byteLength}, cacheSize:${tracksCacheBytes}`
);
deleteExcessCache();
} catch (error) {
console.debug("[debug][db.js] deleteExcessCacheFailed", error);
}
}
export function cacheTrackSource(trackInfo, url, bitRate, from = "netease") {
const name = trackInfo.name;
const artist = trackInfo.ar[0]?.name || trackInfo.artists[0]?.name;
@ -22,8 +59,11 @@ export function cacheTrackSource(trackInfo, url, bitRate, from = "netease") {
from,
name,
artist,
createTime: new Date().getTime(),
});
console.debug(`[debug][db.js] cached track 👉 ${name} by ${artist}`);
tracksCacheBytes += response.data.byteLength;
deleteExcessCache();
return { trackID: trackInfo.id, source: response.data, bitRate };
});
}
@ -39,16 +79,21 @@ export function getTrackSource(id) {
}
export function countDBSize() {
let trackSizes = [];
const trackSizes = [];
return db.trackSources
.each((track) => {
trackSizes.push(track.source.byteLength);
})
.then(() => {
return {
const res = {
bytes: trackSizes.reduce((s1, s2) => s1 + s2, 0),
length: trackSizes.length,
};
tracksCacheBytes = res.bytes;
console.debug(
`[debug][db.js] load tracksCacheBytes: ${tracksCacheBytes}`
);
return res;
});
}

View File

@ -65,6 +65,7 @@
import { toplists, recommendPlaylist } from "@/api/playlist";
import { toplistOfArtists } from "@/api/artist";
import { byAppleMusic } from "@/utils/staticData";
import { countDBSize } from "@/utils/db";
import { newAlbums } from "@/api/album";
import NProgress from "nprogress";
import { mapState } from "vuex";
@ -128,6 +129,7 @@ export default {
this.topList.ids.includes(l.id)
);
});
countDBSize();
},
},
activated() {

View File

@ -110,6 +110,22 @@
</div>
</div>
</div>
<div class="item" v-if="isElectron">
<div class="left">
<div class="title"> {{ $t("settings.cacheLimit.text") }} </div>
</div>
<div class="right">
<select v-model="cacheLimit">
<option :value="false">
{{ $t("settings.cacheLimit.none") }}
</option>
<option :value="512"> 500MB </option>
<option :value="1024"> 1GB </option>
<option :value="2048"> 2GB </option>
<option :value="4096"> 4GB </option>
</select>
</div>
</div>
<div class="item" v-if="isElectron">
<div class="left">
<div class="title">
@ -522,6 +538,17 @@ export default {
});
},
},
cacheLimit: {
get() {
return this.settings.cacheLimit || false;
},
set(value) {
this.$store.commit("updateSettings", {
key: "cacheLimit",
value,
});
},
},
isLastfmConnected() {
return this.lastfm.key !== undefined;
},