diff --git a/.github/workflows/publish-version-info.yml b/.github/workflows/publish-version-info.yml new file mode 100644 index 0000000..e61aed9 --- /dev/null +++ b/.github/workflows/publish-version-info.yml @@ -0,0 +1,16 @@ +name: Publish NPM Version Info + +on: + release: + types: [published] + +jobs: + dispatch: + runs-on: ubuntu-latest + steps: + - name: Repository Dispatch + uses: peter-evans/repository-dispatch@v2 + with: + token: ${{ secrets.PAT }} + repository: lyswhut/lx-music-mobile-version-info + event-type: npm-release diff --git a/src/config/constant.ts b/src/config/constant.ts index 010c597..be86397 100644 --- a/src/config/constant.ts +++ b/src/config/constant.ts @@ -55,6 +55,7 @@ export const storageDataPrefix = { searchHistoryList: '@search_history_list', listUpdateInfo: '@list_update_info', ignoreVersion: '@ignore_version', + ignoreVersionFailTipTimeKey: '@ignore_version_fail_tip_time', leaderboardSetting: '@leaderboard_setting', songListSetting: '@songist_setting', searchSetting: '@search_setting', diff --git a/src/core/version.ts b/src/core/version.ts index a8b7cf5..52b2235 100644 --- a/src/core/version.ts +++ b/src/core/version.ts @@ -2,7 +2,7 @@ import { compareVer } from '@/utils' import { downloadNewVersion, getVersionInfo } from '@/utils/version' import versionActions from '@/store/version/action' import versionState, { type InitState } from '@/store/version/state' -import { getIgnoreVersion, saveIgnoreVersion } from '@/utils/data' +import { getIgnoreVersion, getIgnoreVersionFailTipTime, saveIgnoreVersion, saveIgnoreVersionFailTipTime } from '@/utils/data' import { showVersionModal } from '@/navigation' import { Navigation } from 'react-native-navigation' @@ -40,21 +40,26 @@ export const checkUpdate = async() => { // desc: '- 更新xxx\n- 修复xxx123的萨达修复xxx123的萨达修复xxx123的萨达修复xxx123的萨达修复xxx123的萨达', // history: [{ version: '1.8.0', desc: '- 更新xxx22\n- 修复xxx22' }, { version: '1.7.0', desc: '- 更新xxx22\n- 修复xxx22' }], // } - if (versionInfo.version == '0.0.0') { + if (versionInfo.newVersion.version == '0.0.0') { versionInfo.isUnknown = true versionInfo.status = 'error' } else { versionInfo.status = 'idle' - } - versionInfo.isUnknown = false - if (compareVer(versionInfo.version, versionInfo.newVersion.version) != -1) { - versionInfo.isLatest = true + versionInfo.isUnknown = false + if (compareVer(versionInfo.version, versionInfo.newVersion.version) != -1) { + versionInfo.isLatest = true + } } versionActions.setVersionInfo(versionInfo) if (!versionInfo.isLatest) { - if (versionInfo.newVersion.version != await getIgnoreVersion()) { + if (versionInfo.isUnknown) { + const time = await getIgnoreVersionFailTipTime() + if (Date.now() - time < 7 * 86400000) return + saveIgnoreVersionFailTipTime(Date.now()) + showModal() + } else if (versionInfo.newVersion.version != await getIgnoreVersion()) { showModal() } } diff --git a/src/utils/data.ts b/src/utils/data.ts index 1ee0490..8093eb1 100644 --- a/src/utils/data.ts +++ b/src/utils/data.ts @@ -15,6 +15,7 @@ const viewPrevStateKey = storageDataPrefix.viewPrevState const listScrollPositionKey = storageDataPrefix.listScrollPosition const listUpdateInfoKey = storageDataPrefix.listUpdateInfo const ignoreVersionKey = storageDataPrefix.ignoreVersion +const ignoreVersionFailTipTimeKey = storageDataPrefix.ignoreVersionFailTipTimeKey const searchSettingKey = storageDataPrefix.searchSetting const searchHistoryListKey = storageDataPrefix.searchHistoryList const songListSettingKey = storageDataPrefix.songListSetting @@ -172,6 +173,21 @@ export const getIgnoreVersion = async() => { return ignoreVersion } +let ignoreVersionFailTipTime: number | null +export const saveIgnoreVersionFailTipTime = (time: number | null) => { + ignoreVersionFailTipTime = time + if (time == null) { + void removeData(ignoreVersionFailTipTimeKey) + } else { + void saveData(ignoreVersionFailTipTimeKey, time) + } +} +// 获取忽略更新的版本号 +export const getIgnoreVersionFailTipTime = async() => { + if (ignoreVersionFailTipTime === undefined) ignoreVersionFailTipTime = (await getData(ignoreVersionFailTipTimeKey)) + return ignoreVersionFailTipTime ?? 0 +} + export const getSearchSetting = async() => { searchSetting ??= await getData(searchSettingKey) ?? { ...DEFAULT_SETTING.search } diff --git a/src/utils/request.js b/src/utils/request.js index dd65ffb..37c3e61 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -186,6 +186,7 @@ const fetchData = (url, { timeout = 15000, ...options }) => { headers: resp.headers.map, body: text, statusCode: resp.status, + statusMessage: resp.statusText, url: resp.url, ok: resp.ok, } diff --git a/src/utils/version.js b/src/utils/version.js index ececd30..e9f3146 100644 --- a/src/utils/version.js +++ b/src/utils/version.js @@ -12,49 +12,64 @@ const abis = [ 'universal', ] -export const getVersionInfo = (retryNum = 0) => { - return new Promise((resolve, reject) => { - httpGet(`https://raw.githubusercontent.com/${author.name}/${name}/master/publish/version.json`, { - timeout: 15000, +const address = [ + [`https://raw.githubusercontent.com/${author.name}/${name}/master/publish/version.json`, 'direct'], + ['https://registry.npmjs.org/lx-music-mobile-version-info/latest', 'npm'], + ['https://registry.npmmirror.com/lx-music-mobile-version-info/latest', 'npm'], + [`https://cdn.jsdelivr.net/gh/${author.name}/${name}/publish/version.json`, 'direct'], + [`https://fastly.jsdelivr.net/gh/${author.name}/${name}/publish/version.json`, 'direct'], + [`https://gcore.jsdelivr.net/gh/${author.name}/${name}/publish/version.json`, 'direct'], + ['https://gitee.com/lyswhut/lx-music-mobile-versions/raw/master/version.json', 'direct'], + ['http://cdn.stsky.cn/lx-music/mobile/version.json', 'direct'], +] + + +const request = async(url, retryNum = 0) => { + return await new Promise((resolve, reject) => { + httpGet(url, { + timeout: 10000, }, (err, resp, body) => { - if (err || body.version == null) { - // toast(err.message) - return ++retryNum > 1 - ? getVersionInfo2().then(resolve).catch(reject) - : getVersionInfo(retryNum).then(resolve).catch(reject) - } - resolve(body) + if (err || resp.statusCode != 200) { + ++retryNum >= 3 + ? reject(err || new Error(resp.statusMessage || resp.statusCode)) + : request(url, retryNum).then(resolve).catch(reject) + } else resolve(body) }) }) } -const getVersionInfo2 = (retryNum = 0) => { - return new Promise((resolve, reject) => { - httpGet('https://gitee.com/lyswhut/lx-music-mobile-versions/raw/master/version.json', { - timeout: 20000, - }, (err, resp, body) => { - if (err || body.version == null) { - return ++retryNum > 3 - ? getVersionInfo3().then(resolve).catch(reject) - : getVersionInfo2(retryNum).then(resolve).catch(reject) - } - resolve(body) - }) +const getDirectInfo = async(url) => { + return request(url).then(info => { + if (info.version == null) throw new Error('failed') + return info }) } -const getVersionInfo3 = (retryNum = 0) => { - return new Promise((resolve, reject) => { - httpGet('https://cdn.stsky.cn/lx-music/mobile/version.json', { - timeout: 20000, - }, (err, resp, body) => { - if (err || body.version == null) { - return ++retryNum > 3 - ? resolve({ version: '0.0.0', desc: '', history: [] }) - : getVersionInfo3(retryNum).then(resolve).catch(reject) - } - resolve(body) - }) +const getNpmPkgInfo = async(url) => { + return request(url).then(json => { + if (!json.versionInfo) throw new Error('failed') + const info = JSON.parse(json.versionInfo) + if (info.version == null) throw new Error('failed') + return info + }) +} + +export const getVersionInfo = async(index = 0) => { + const [url, source] = address[index] + let promise + switch (source) { + case 'direct': + promise = getDirectInfo(url) + break + case 'npm': + promise = getNpmPkgInfo(url) + break + } + + return promise.catch(async(err) => { + index++ + if (index >= address.length) throw err + return getVersionInfo(index) }) }